import { describe, expect, it } from 'vitest'; import { redactSensitiveText } from '../utils/safeLog'; describe('redactSensitiveText', () => { it('redacts credentials from durable log text', () => { const text = redactSensitiveText( 'connect https://user:pass@example.invalid failed Authorization: Bearer abc.def.ghi token=secret123 password=hunter2', ); expect(text).toContain('https://[redacted]@example.invalid'); expect(text).toContain('Authorization: [redacted]'); expect(text).toContain('token=[redacted]'); expect(text).toContain('password=[redacted]'); expect(text).not.toContain('user:pass'); expect(text).not.toContain('abc.def.ghi'); expect(text).not.toContain('secret123'); expect(text).not.toContain('hunter2'); }); it('strips Linux-style homedir usernames while keeping the /home/ prefix', () => { const text = redactSensitiveText('compose error reading /home/user-linux/docker/compose.yaml'); expect(text).not.toContain('user-linux'); expect(text).toContain('/home//docker/compose.yaml'); }); it('strips macOS-style homedir usernames while keeping the /Users/ prefix', () => { const text = redactSensitiveText('failed to open /Users/user.macos/Projects/app/.env'); expect(text).not.toContain('user.macos'); expect(text).toContain('/Users//Projects/app/.env'); }); it('strips Windows-style homedir usernames while preserving the drive letter', () => { const text = redactSensitiveText( 'ENOENT: no such file or directory, open \'D:\\Users\\user.windows\\Sencho\\compose.yaml\'', ); expect(text).not.toContain('user.windows'); expect(text).toContain('D:\\Users\\\\Sencho\\compose.yaml'); }); it('strips Windows-style homedir usernames when the drive letter is lowercase', () => { const text = redactSensitiveText('failed: c:\\Users\\user.lowercase\\app\\compose.yaml'); expect(text).not.toContain('user.lowercase'); expect(text).toContain('c:\\Users\\\\app\\compose.yaml'); }); it('redacts Basic auth credentials embedded after Authorization header', () => { const text = redactSensitiveText( 'upstream 401: Authorization: Basic dXNlcjpwYXNzd29yZA== rejected by registry', ); expect(text).not.toContain('dXNlcjpwYXNzd29yZA'); expect(text).toContain('[redacted]'); }); it('redacts a bare Basic auth scheme without an Authorization header', () => { const text = redactSensitiveText('curl error: header Basic c2VjcmV0OnZhbHVl was rejected'); expect(text).not.toContain('c2VjcmV0OnZhbHVl'); expect(text).toContain('Basic [redacted]'); }); });