mirror of
https://github.com/LukeHagar/redocly-cli.git
synced 2025-12-09 20:57:44 +00:00
chore: improve data obfuscation (#1143)
This commit is contained in:
@@ -29,4 +29,6 @@ RUN npm cache clean --force && rm -rf /build
|
|||||||
|
|
||||||
WORKDIR /spec
|
WORKDIR /spec
|
||||||
|
|
||||||
ENTRYPOINT [ "openapi" ]
|
ENTRYPOINT [ "redocly" ]
|
||||||
|
|
||||||
|
ENV REDOCLY_ENVIRONMENT=docker
|
||||||
|
|||||||
@@ -14,12 +14,12 @@ module.exports = {
|
|||||||
'packages/core/': {
|
'packages/core/': {
|
||||||
statements: 80,
|
statements: 80,
|
||||||
branches: 71,
|
branches: 71,
|
||||||
functions: 69,
|
functions: 70,
|
||||||
lines: 80,
|
lines: 80,
|
||||||
},
|
},
|
||||||
'packages/cli/': {
|
'packages/cli/': {
|
||||||
statements: 55,
|
statements: 55,
|
||||||
branches: 46,
|
branches: 47,
|
||||||
functions: 55,
|
functions: 55,
|
||||||
lines: 55,
|
lines: 55,
|
||||||
},
|
},
|
||||||
|
|||||||
0
packages/cli/src/__tests__/fixtures/openapi.json
Normal file
0
packages/cli/src/__tests__/fixtures/openapi.json
Normal file
0
packages/cli/src/__tests__/fixtures/openapi.yaml
Normal file
0
packages/cli/src/__tests__/fixtures/openapi.yaml
Normal file
0
packages/cli/src/__tests__/fixtures/redocly.yaml
Normal file
0
packages/cli/src/__tests__/fixtures/redocly.yaml
Normal file
@@ -21,7 +21,7 @@ import {
|
|||||||
YamlParseError,
|
YamlParseError,
|
||||||
} from '@redocly/openapi-core';
|
} from '@redocly/openapi-core';
|
||||||
import { blue, red, yellow } from 'colorette';
|
import { blue, red, yellow } from 'colorette';
|
||||||
import { existsSync } from 'fs';
|
import { existsSync, statSync } from 'fs';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
import * as process from 'process';
|
import * as process from 'process';
|
||||||
|
|
||||||
@@ -489,16 +489,23 @@ describe('cleanArgs', () => {
|
|||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
isAbsoluteUrl = jest.requireActual('@redocly/openapi-core').isAbsoluteUrl;
|
isAbsoluteUrl = jest.requireActual('@redocly/openapi-core').isAbsoluteUrl;
|
||||||
|
// @ts-ignore
|
||||||
|
existsSync = (value) => jest.requireActual('fs').existsSync(path.resolve(__dirname, value));
|
||||||
|
// @ts-ignore
|
||||||
|
statSync = (value) => jest.requireActual('fs').statSync(path.resolve(__dirname, value));
|
||||||
|
});
|
||||||
|
afterEach(() => {
|
||||||
|
jest.clearAllMocks();
|
||||||
});
|
});
|
||||||
it('should remove potentially sensitive data from args', () => {
|
it('should remove potentially sensitive data from args', () => {
|
||||||
const testArgs = {
|
const testArgs = {
|
||||||
config: 'some-folder/redocly.yaml',
|
config: './fixtures/redocly.yaml',
|
||||||
apis: ['main@v1', 'openapi.yaml', 'http://some.url/openapi.yaml'],
|
apis: ['main@v1', 'fixtures/openapi.yaml', 'http://some.url/openapi.yaml'],
|
||||||
format: 'codeframe',
|
format: 'codeframe',
|
||||||
};
|
};
|
||||||
expect(cleanArgs(testArgs)).toEqual({
|
expect(cleanArgs(testArgs)).toEqual({
|
||||||
config: '***.yaml',
|
config: 'file-yaml',
|
||||||
apis: ['main@v1', '***.yaml', 'http://***'],
|
apis: ['api-name@api-version', 'file-yaml', 'http://url'],
|
||||||
format: 'codeframe',
|
format: 'codeframe',
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -507,26 +514,51 @@ describe('cleanArgs', () => {
|
|||||||
destination: '@org/name@version',
|
destination: '@org/name@version',
|
||||||
};
|
};
|
||||||
expect(cleanArgs(testArgs)).toEqual({
|
expect(cleanArgs(testArgs)).toEqual({
|
||||||
destination: '@***/name@version',
|
destination: '@organization/api-name@api-version',
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('cleanRawInput', () => {
|
describe('cleanRawInput', () => {
|
||||||
it('should remove potentially sensitive data from raw CLI input', () => {
|
beforeEach(() => {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
isAbsoluteUrl = jest.requireActual('@redocly/openapi-core').isAbsoluteUrl;
|
isAbsoluteUrl = jest.requireActual('@redocly/openapi-core').isAbsoluteUrl;
|
||||||
|
// @ts-ignore
|
||||||
|
existsSync = (value) => jest.requireActual('fs').existsSync(path.resolve(__dirname, value));
|
||||||
|
// @ts-ignore
|
||||||
|
statSync = (value) => jest.requireActual('fs').statSync(path.resolve(__dirname, value));
|
||||||
|
});
|
||||||
|
afterEach(() => {
|
||||||
|
jest.clearAllMocks();
|
||||||
|
});
|
||||||
|
it('should remove potentially sensitive data from raw CLI input', () => {
|
||||||
|
const rawInput = [
|
||||||
|
'redocly',
|
||||||
|
'bundle',
|
||||||
|
'api-name@api-version',
|
||||||
|
'./fixtures/openapi.yaml',
|
||||||
|
'http://some.url/openapi.yaml',
|
||||||
|
'--config=fixtures/redocly.yaml',
|
||||||
|
'--output',
|
||||||
|
'fixtures',
|
||||||
|
];
|
||||||
|
expect(cleanRawInput(rawInput)).toEqual(
|
||||||
|
'redocly bundle api-name@api-version file-yaml http://url --config=file-yaml --output folder'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
it('should preserve safe data from raw CLI input', () => {
|
||||||
const rawInput = [
|
const rawInput = [
|
||||||
'redocly',
|
'redocly',
|
||||||
'lint',
|
'lint',
|
||||||
'main@v1',
|
'./fixtures/openapi.json',
|
||||||
'openapi.yaml',
|
'--format',
|
||||||
'http://some.url/openapi.yaml',
|
'stylish',
|
||||||
'--config=some-folder/redocly.yaml',
|
'--extends=minimal',
|
||||||
|
'--skip-rule',
|
||||||
|
'operation-4xx-response',
|
||||||
];
|
];
|
||||||
expect(cleanRawInput(rawInput)).toEqual(
|
expect(cleanRawInput(rawInput)).toEqual(
|
||||||
'redocly lint main@v1 ***.yaml http://*** --config=***.yaml'
|
'redocly lint file-json --format stylish --extends=minimal --skip-rule operation-4xx-response'
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -496,7 +496,6 @@ export async function sendTelemetry(
|
|||||||
} = argv;
|
} = argv;
|
||||||
const event_time = new Date().toISOString();
|
const event_time = new Date().toISOString();
|
||||||
const redoclyClient = new RedoclyClient();
|
const redoclyClient = new RedoclyClient();
|
||||||
const node_version = process.version;
|
|
||||||
const logged_in = await redoclyClient.isAuthorizedWithRedoclyByRegion();
|
const logged_in = await redoclyClient.isAuthorizedWithRedoclyByRegion();
|
||||||
const data: Analytics = {
|
const data: Analytics = {
|
||||||
event: 'cli_command',
|
event: 'cli_command',
|
||||||
@@ -504,10 +503,11 @@ export async function sendTelemetry(
|
|||||||
logged_in,
|
logged_in,
|
||||||
command,
|
command,
|
||||||
arguments: cleanArgs(args),
|
arguments: cleanArgs(args),
|
||||||
node_version,
|
node_version: process.version,
|
||||||
version,
|
version,
|
||||||
exit_code,
|
exit_code,
|
||||||
environment: process.env.REDOCLY_ENVIRONMENT,
|
environment: process.env.REDOCLY_ENVIRONMENT,
|
||||||
|
environment_ci: process.env.CI,
|
||||||
raw_input: cleanRawInput(process.argv.slice(2)),
|
raw_input: cleanRawInput(process.argv.slice(2)),
|
||||||
has_config,
|
has_config,
|
||||||
};
|
};
|
||||||
@@ -535,22 +535,34 @@ export type Analytics = {
|
|||||||
version: string;
|
version: string;
|
||||||
exit_code: ExitCode;
|
exit_code: ExitCode;
|
||||||
environment?: string;
|
environment?: string;
|
||||||
|
environment_ci?: string;
|
||||||
raw_input: string;
|
raw_input: string;
|
||||||
has_config?: boolean;
|
has_config?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function isFile(value: string) {
|
||||||
|
return fs.existsSync(value) && fs.statSync(value).isFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
function isDirectory(value: string) {
|
||||||
|
return fs.existsSync(value) && fs.statSync(value).isDirectory();
|
||||||
|
}
|
||||||
|
|
||||||
function cleanString(value?: string): string | undefined {
|
function cleanString(value?: string): string | undefined {
|
||||||
if (!value) {
|
if (!value) {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
if (isAbsoluteUrl(value)) {
|
if (isAbsoluteUrl(value)) {
|
||||||
return value.split('://')[0] + '://***';
|
return value.split('://')[0] + '://url';
|
||||||
}
|
}
|
||||||
if (value.endsWith('.json') || value.endsWith('.yaml') || value.endsWith('.yml')) {
|
if (isFile(value)) {
|
||||||
return value.replace(/^(.*)\.(yaml|yml|json)$/gi, (_, __, ext) => '***.' + ext);
|
return value.replace(/.+\.([^.]+)$/, (_, ext) => 'file-' + ext);
|
||||||
|
}
|
||||||
|
if (isDirectory(value)) {
|
||||||
|
return 'folder';
|
||||||
}
|
}
|
||||||
if (DESTINATION_REGEX.test(value)) {
|
if (DESTINATION_REGEX.test(value)) {
|
||||||
return value.replace(/^@[\w\-\s]+\//, () => '@***/');
|
return value.startsWith('@') ? '@organization/api-name@api-version' : 'api-name@api-version';
|
||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user