import { test } from 'node:test' import assert from 'node:assert/strict' import { redact, redactDeep } from '../src/redact.mjs' test('redact masks bearer tokens and provider keys', () => { const out = redact('Authorization: Bearer abcdef1234567890 and sk-1234567890abcdefghij') assert.doesNotMatch(out, /abcdef1234567890/) assert.doesNotMatch(out, /sk-1234567890abcdefghij/) assert.match(out, /Bearer \[REDACTED\]/) assert.match(out, /\[REDACTED\]/) }) test('redact keeps key names but drops values', () => { const out = redact('token=supersecretvalue password: "hunter2" api_key=ABCDEF123456') assert.match(out, /token=\[REDACTED\]/) assert.match(out, /password: "\[REDACTED\]/) assert.match(out, /api_key=\[REDACTED\]/) assert.doesNotMatch(out, /supersecretvalue|hunter2|ABCDEF123456/) }) test('redact strips credentials embedded in URLs', () => { const out = redact('remote https://user:tok3n@forgejo.example.com/repo.git') assert.doesNotMatch(out, /tok3n/) assert.match(out, /https:\/\/\[REDACTED\]@forgejo\.example\.com/) }) test('redact masks JWTs and github tokens', () => { const jwt = 'eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.signaturepart' const out = redact(`${jwt} ghp_abcdefghijklmnopqrstuvwxyz012345`) assert.doesNotMatch(out, /eyJhbGciOiJIUzI1NiJ9/) assert.doesNotMatch(out, /ghp_abcdefghijklmnopqrstuvwxyz012345/) }) test('redact leaves ordinary text untouched', () => { assert.equal(redact('pnpm test passed: 34/34'), 'pnpm test passed: 34/34') assert.equal(redact(42), 42) }) test('redactDeep walks objects without mutating the input', () => { const input = { a: 'Bearer xxxxxxxxxxxxxxxx', b: ['token=zzzzzzzz'], c: 1 } const out = redactDeep(input) assert.equal(input.a, 'Bearer xxxxxxxxxxxxxxxx') assert.match(out.a, /\[REDACTED\]/) assert.match(out.b[0], /token=\[REDACTED\]/) assert.equal(out.c, 1) })