Skip to content

Commit 4730f36

Browse files
fix: normalize safe keys and strip empty dict-style env values
- Uppercase safe keys in compileConfig so Advanced Settings safe keys work regardless of input casing (matches isSensitiveKey lookup) - Strip empty values from dict-style environment blocks in stripNoise, matching existing array-style behavior - Remove unused openPrivateBin/openGist imports from main.ts - Add regression tests for both fixes Co-authored-by: ajbturnberry <ajbturnberry@users.noreply.github.com>
1 parent b7fb85b commit 4730f36

6 files changed

Lines changed: 58 additions & 3 deletions

File tree

src/config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ export function compileConfig(config: SanitizerConfig): {
6161
}
6262
return {
6363
sensitivePatterns: compiled,
64-
safeKeys: new Set(config.safeKeys),
64+
safeKeys: new Set(config.safeKeys.map(k => k.toUpperCase())),
6565
}
6666
}
6767

src/main.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { redactCompose } from './redact'
55
import { stripNoise } from './noise'
66
import { detectAdvisories, type Advisory } from './advisories'
77
import { loadConfig, saveConfig, resetConfig, compileConfig, type SanitizerConfig } from './config'
8-
import { copyToClipboard, openPrivateBin, openGist } from './clipboard'
8+
import { copyToClipboard } from './clipboard'
99
import { createShortNotice, createPiiWarning, createFullDisclaimer } from './disclaimer'
1010
import { el } from './dom'
1111
import { parseServices } from './services'

src/noise.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,10 @@ function stripNoiseEnvDict(env: Record<string, unknown>): Record<string, unknown
6262
const result: Record<string, unknown> = {}
6363
for (const [key, value] of Object.entries(env)) {
6464
if (!isNoiseEnvKey(key)) {
65-
result[key] = value
65+
const strValue = value == null ? '' : String(value)
66+
if (strValue !== '') {
67+
result[key] = value
68+
}
6669
}
6770
}
6871
return result

tests/config.test.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,17 @@ describe('config', () => {
8585
expect(compiled.safeKeys.has('OTHER')).toBe(false)
8686
})
8787

88+
it('compileConfig normalizes safe keys to uppercase for case-insensitive lookup', () => {
89+
const config = {
90+
sensitivePatterns: ['secret'],
91+
safeKeys: ['auth_token', 'MY_KEY'],
92+
}
93+
const compiled = compileConfig(config)
94+
expect(compiled.safeKeys.has('AUTH_TOKEN')).toBe(true)
95+
expect(compiled.safeKeys.has('MY_KEY')).toBe(true)
96+
expect(compiled.safeKeys.has('auth_token')).toBe(false)
97+
})
98+
8899
it('compileConfig skips invalid regex patterns gracefully', () => {
89100
const config = {
90101
sensitivePatterns: ['valid', '[invalid', 'also_valid'],

tests/noise.test.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,4 +275,25 @@ describe('stripNoise', () => {
275275
expect(env).not.toContain('UNBOUND_NAMESERVERS=')
276276
expect(env).toContain('PUID=1000')
277277
})
278+
279+
it('strips empty env values in dict style', () => {
280+
const input = {
281+
services: {
282+
app: {
283+
environment: {
284+
VPN_PIA_USER: '',
285+
VPN_LAN_NETWORK: '',
286+
UNBOUND_NAMESERVERS: '',
287+
PUID: '1000',
288+
},
289+
},
290+
},
291+
}
292+
const result = stripNoise(input)
293+
const env = (result['services'] as Record<string, Record<string, unknown>>)['app']?.['environment'] as Record<string, unknown>
294+
expect(env).not.toHaveProperty('VPN_PIA_USER')
295+
expect(env).not.toHaveProperty('VPN_LAN_NETWORK')
296+
expect(env).not.toHaveProperty('UNBOUND_NAMESERVERS')
297+
expect(env).toHaveProperty('PUID', '1000')
298+
})
278299
})

tests/redact.test.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { describe, it, expect } from 'vitest'
22
import { redactCompose } from '../src/redact'
3+
import { compileConfig } from '../src/config'
34

45
describe('redactCompose', () => {
56
it('redacts sensitive env vars in dict style', () => {
@@ -262,6 +263,25 @@ services:
262263
expect(result.stats.redactedEnvVars).toBe(1)
263264
})
264265

266+
it('respects lowercase safe keys via compileConfig (Advanced Settings path)', () => {
267+
const input = `
268+
services:
269+
app:
270+
environment:
271+
AUTH_TOKEN: should-be-safe
272+
SECRET: should-be-redacted
273+
`
274+
const compiled = compileConfig({
275+
sensitivePatterns: ['secret', 'auth', 'token'],
276+
safeKeys: ['auth_token'],
277+
})
278+
const result = redactCompose(input, compiled)
279+
expect(result.error).toBeNull()
280+
expect(result.output).toContain('should-be-safe')
281+
expect(result.output).not.toContain('should-be-redacted')
282+
expect(result.stats.redactedEnvVars).toBe(1)
283+
})
284+
265285
it('uses custom config with array-style env vars', () => {
266286
const input = `
267287
services:

0 commit comments

Comments
 (0)