test(21-01): add failing tests for triage-note sanitizer
- Cover URL query/fragment stripping, malformed-URL no-throw - Cover Bearer token and credential query-param redaction - Cover email/hash preservation (evidence, not secrets)
This commit is contained in:
parent
235bc49810
commit
cc93707e41
1 changed files with 58 additions and 0 deletions
58
lib/services/triage-note-sanitize.test.ts
Normal file
58
lib/services/triage-note-sanitize.test.ts
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
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));
|
||||
});
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue