Skip to content

Commit 8737afd

Browse files
committed
fix: harden Redis cache config and env test isolation (#541)
1 parent c9576cb commit 8737afd

2 files changed

Lines changed: 42 additions & 6 deletions

File tree

src/cache/client.ts

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,23 @@ import { createLogger } from '../factories/logger-factory'
44

55
const logger = createLogger('cache-client')
66

7+
const redactRedisUrlCredentials = (url: string): string => {
8+
try {
9+
const parsedUrl = new URL(url)
10+
11+
if (!parsedUrl.username && !parsedUrl.password) {
12+
return url
13+
}
14+
15+
parsedUrl.username = parsedUrl.username ? '***' : ''
16+
parsedUrl.password = parsedUrl.password ? '***' : ''
17+
18+
return parsedUrl.toString()
19+
} catch {
20+
return url
21+
}
22+
}
23+
724
export const getCacheConfig = (): RedisClientOptions => {
825
if (process.env.REDIS_URI) {
926
return {
@@ -20,7 +37,8 @@ export const getCacheConfig = (): RedisClientOptions => {
2037
const username = process.env.REDIS_USER ?? 'default'
2138

2239
return {
23-
url: `redis://${username}:${process.env.REDIS_PASSWORD}@${host}:${port}`,
40+
url: `redis://${host}:${port}`,
41+
username,
2442
password: process.env.REDIS_PASSWORD,
2543
}
2644
}
@@ -37,7 +55,10 @@ export const getCacheClient = (): CacheClient => {
3755
const config = getCacheConfig()
3856
// eslint-disable-next-line @typescript-eslint/no-unused-vars
3957
const { password: _, ...loggableConfig } = config
40-
logger('config: %o', loggableConfig)
58+
logger('config: %o', {
59+
...loggableConfig,
60+
...(loggableConfig.url ? { url: redactRedisUrlCredentials(loggableConfig.url) } : {}),
61+
})
4162
instance = createClient(config)
4263
}
4364

test/unit/cache/client.spec.ts

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { expect } from 'chai'
33
import { getCacheConfig } from '../../../src/cache/client'
44

55
describe('getCacheConfig', () => {
6-
const originalEnv = { ...process.env }
6+
const originalEnv = process.env
77

88
beforeEach(() => {
99
process.env = { ...originalEnv }
@@ -14,7 +14,7 @@ describe('getCacheConfig', () => {
1414
delete process.env.REDIS_PORT
1515
})
1616

17-
after(() => {
17+
afterEach(() => {
1818
process.env = originalEnv
1919
})
2020

@@ -29,7 +29,7 @@ describe('getCacheConfig', () => {
2929
})
3030
})
3131

32-
it('builds authenticated redis url when REDIS_PASSWORD is set', () => {
32+
it('builds authenticated redis config when REDIS_PASSWORD is set', () => {
3333
process.env.REDIS_HOST = 'localhost'
3434
process.env.REDIS_PORT = '6379'
3535
process.env.REDIS_USER = 'default'
@@ -38,7 +38,22 @@ describe('getCacheConfig', () => {
3838
const config = getCacheConfig()
3939

4040
expect(config).to.deep.equal({
41-
url: 'redis://default:secret@localhost:6379',
41+
url: 'redis://localhost:6379',
42+
username: 'default',
43+
password: 'secret',
44+
})
45+
})
46+
47+
it('defaults REDIS_USER to default when REDIS_PASSWORD is set and REDIS_USER is unset', () => {
48+
process.env.REDIS_HOST = 'localhost'
49+
process.env.REDIS_PORT = '6379'
50+
process.env.REDIS_PASSWORD = 'secret'
51+
52+
const config = getCacheConfig()
53+
54+
expect(config).to.deep.equal({
55+
url: 'redis://localhost:6379',
56+
username: 'default',
4257
password: 'secret',
4358
})
4459
})

0 commit comments

Comments
 (0)