- Cover URL query/fragment stripping, malformed-URL no-throw - Cover Bearer token and credential query-param redaction - Cover email/hash preservation (evidence, not secrets)
58 lines
2.1 KiB
TypeScript
58 lines
2.1 KiB
TypeScript
import { describe, it, expect } from 'vitest';
|
|
import { sanitizeUrl, sanitizeNoteText } from './triage-note-sanitize';
|
|
|
|
describe('sanitizeUrl', () => {
|
|
it('strips query string and fragment, keeping scheme+host+path', () => {
|
|
expect(sanitizeUrl('https://evil.example/login?token=abc123&next=/x#frag')).toBe(
|
|
'https://evil.example/login'
|
|
);
|
|
});
|
|
|
|
it('returns exactly the scheme+host+path for a token+fragment URL', () => {
|
|
expect(sanitizeUrl('https://evil.example/a?token=abc#f')).toBe('https://evil.example/a');
|
|
});
|
|
|
|
it('does not throw on a malformed/non-URL string and strips any ?/# tail', () => {
|
|
expect(() => sanitizeUrl('not a url')).not.toThrow();
|
|
expect(sanitizeUrl('not a url')).toBe('not a url');
|
|
|
|
expect(() => sanitizeUrl('')).not.toThrow();
|
|
|
|
expect(sanitizeUrl('not-a-url?foo=bar#baz')).toBe('not-a-url');
|
|
});
|
|
|
|
it('always strips query even for benign params (not selective)', () => {
|
|
expect(sanitizeUrl('https://good.example/path?utm_source=newsletter')).toBe(
|
|
'https://good.example/path'
|
|
);
|
|
});
|
|
});
|
|
|
|
describe('sanitizeNoteText', () => {
|
|
it('redacts an Authorization/Bearer token', () => {
|
|
const input = 'Header seen: Bearer eyJabc.def.ghi in the request';
|
|
const output = sanitizeNoteText(input);
|
|
expect(output).not.toContain('eyJabc.def.ghi');
|
|
expect(output).toContain('[REDACTED]');
|
|
});
|
|
|
|
it('redacts credential-style query-param values inside free text', () => {
|
|
const input = 'see http://x/y?access_token=SECRET&password=p';
|
|
const output = sanitizeNoteText(input);
|
|
expect(output).not.toContain('access_token=SECRET');
|
|
expect(output).not.toContain('password=p');
|
|
});
|
|
|
|
it('preserves a bare sender email and a 64-char hex attachment hash unchanged', () => {
|
|
const hash = 'a'.repeat(64);
|
|
const input = `Reported by attacker@evil.example with attachment hash ${hash}`;
|
|
const output = sanitizeNoteText(input);
|
|
expect(output).toContain('attacker@evil.example');
|
|
expect(output).toContain(hash);
|
|
});
|
|
|
|
it('is pure and deterministic', () => {
|
|
const input = 'plain text with no secrets';
|
|
expect(sanitizeNoteText(input)).toBe(sanitizeNoteText(input));
|
|
});
|
|
});
|