mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-10 18:36:15 -08:00
fix(logging): harden URL and date redaction
This commit is contained in:
1 parent
b770c97c11
commit
4f702cb8a2
2 files changed
+39
-8
No files matched your search
@@ -100,6 +100,25 @@ describe('redactSensitiveData', () => {
|
||||
expect(output).toContain('401');
|
||||
});
|
||||
|
||||
it('redacts credentials in non-HTTP stream URL strings', () => {
|
||||
const username = 'rtsp-user-secret';
|
||||
const password = 'rtsp-password-secret';
|
||||
const token = 'rtmp-token-secret';
|
||||
|
||||
const output = serialized(
|
||||
redactSensitiveData([
|
||||
`rtsp://${username}:${password}@stream.example/live?token=${token}&channel=news`,
|
||||
`Playback failed: rtmp://stream.example/live?password=${password}&channel=sports`,
|
||||
])
|
||||
);
|
||||
|
||||
expect(output).not.toContain(username);
|
||||
expect(output).not.toContain(password);
|
||||
expect(output).not.toContain(token);
|
||||
expect(output).toContain('channel=news');
|
||||
expect(output).toContain('channel=sports');
|
||||
});
|
||||
|
||||
it('redacts a credential from a single-parameter string', () => {
|
||||
const password = 'single-param-password-secret';
|
||||
const token = 'single-param-token-secret';
|
||||
@@ -221,6 +240,13 @@ describe('redactSensitiveData', () => {
|
||||
expect(serialized(result)).toContain('[Truncated');
|
||||
});
|
||||
|
||||
it('serializes invalid dates without throwing', () => {
|
||||
const invalidDate = new Date(Number.NaN);
|
||||
|
||||
expect(() => redactSensitiveData(invalidDate)).not.toThrow();
|
||||
expect(redactSensitiveData([invalidDate])).toEqual(['[Invalid Date]']);
|
||||
});
|
||||
|
||||
it('preserves repeated non-circular references while still redacting them', () => {
|
||||
const shared = {
|
||||
operation: 'get_profile',
|
||||
|
||||
@@ -155,13 +155,16 @@ function redactUrlStrings(
|
||||
value: string,
|
||||
sanitizeValue: (value: string) => string
|
||||
): string {
|
||||
return value.replace(/https?:\/\/[^\s"'<>]+/giu, (candidate) => {
|
||||
try {
|
||||
return redactUrl(new URL(candidate), sanitizeValue);
|
||||
} catch {
|
||||
return candidate;
|
||||
return value.replace(
|
||||
/[a-z][a-z0-9+.-]*:\/\/[^\s"'<>]+/giu,
|
||||
(candidate) => {
|
||||
try {
|
||||
return redactUrl(new URL(candidate), sanitizeValue);
|
||||
} catch {
|
||||
return candidate;
|
||||
}
|
||||
}
|
||||
});
|
||||
);
|
||||
}
|
||||
|
||||
function looksLikeSearchParams(value: string): boolean {
|
||||
@@ -196,7 +199,7 @@ export function redactSensitiveData(
|
||||
}
|
||||
}
|
||||
|
||||
if (/^https?:\/\//iu.test(trimmed)) {
|
||||
if (/^[a-z][a-z0-9+.-]*:\/\//iu.test(trimmed)) {
|
||||
try {
|
||||
return truncateString(
|
||||
redactUrl(new URL(trimmed), (entry) =>
|
||||
@@ -321,7 +324,9 @@ export function redactSensitiveData(
|
||||
return visitError(input, depth);
|
||||
}
|
||||
if (input instanceof Date) {
|
||||
return input.toISOString();
|
||||
return Number.isNaN(input.getTime())
|
||||
? '[Invalid Date]'
|
||||
: input.toISOString();
|
||||
}
|
||||
if (Array.isArray(input)) {
|
||||
const output = input
|
||||
|
||||
Reference in new issue
Block a user