Skip to content

Commit a9ae0cd

Browse files
authored
fix: skip Redis auth when credentials are unset with unit test (#541) (#545)
1 parent faa7ed2 commit a9ae0cd

3 files changed

Lines changed: 125 additions & 7 deletions

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"nostream": patch
3+
---
4+
5+
Fix Redis cache connection config to skip AUTH when `REDIS_PASSWORD` is unset

src/cache/client.ts

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

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

7-
export const getCacheConfig = (): RedisClientOptions => ({
8-
url: process.env.REDIS_URI
9-
? process.env.REDIS_URI
10-
: `redis://${process.env.REDIS_USER}:${process.env.REDIS_PASSWORD}@${process.env.REDIS_HOST}:${process.env.REDIS_PORT}`,
11-
password: process.env.REDIS_PASSWORD,
12-
})
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+
24+
export const getCacheConfig = (): RedisClientOptions => {
25+
const password = process.env.REDIS_PASSWORD
26+
27+
if (process.env.REDIS_URI) {
28+
return {
29+
url: process.env.REDIS_URI,
30+
...(password ? { password } : {}),
31+
}
32+
}
33+
34+
const host = process.env.REDIS_HOST
35+
const port = process.env.REDIS_PORT
36+
37+
if (password) {
38+
const username = process.env.REDIS_USER ?? 'default'
39+
40+
return {
41+
url: `redis://${host}:${port}`,
42+
username,
43+
password,
44+
}
45+
}
46+
47+
return {
48+
url: `redis://${host}:${port}`,
49+
}
50+
}
1351

1452
let instance: CacheClient | undefined = undefined
1553

@@ -18,7 +56,10 @@ export const getCacheClient = (): CacheClient => {
1856
const config = getCacheConfig()
1957
// eslint-disable-next-line @typescript-eslint/no-unused-vars
2058
const { password: _, ...loggableConfig } = config
21-
logger('config: %o', loggableConfig)
59+
logger('config: %o', {
60+
...loggableConfig,
61+
...(loggableConfig.url ? { url: redactRedisUrlCredentials(loggableConfig.url) } : {}),
62+
})
2263
instance = createClient(config)
2364
}
2465

test/unit/cache/client.spec.ts

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import { expect } from 'chai'
2+
3+
import { getCacheConfig } from '../../../src/cache/client'
4+
5+
describe('getCacheConfig', () => {
6+
const originalEnv = process.env
7+
8+
beforeEach(() => {
9+
process.env = { ...originalEnv }
10+
delete process.env.REDIS_URI
11+
delete process.env.REDIS_USER
12+
delete process.env.REDIS_PASSWORD
13+
delete process.env.REDIS_HOST
14+
delete process.env.REDIS_PORT
15+
})
16+
17+
afterEach(() => {
18+
process.env = originalEnv
19+
})
20+
21+
it('builds unauthenticated redis url when REDIS_URI and REDIS_PASSWORD are unset', () => {
22+
process.env.REDIS_HOST = 'localhost'
23+
process.env.REDIS_PORT = '6379'
24+
25+
const config = getCacheConfig()
26+
27+
expect(config).to.deep.equal({
28+
url: 'redis://localhost:6379',
29+
})
30+
})
31+
32+
it('builds authenticated redis config when REDIS_PASSWORD is set', () => {
33+
process.env.REDIS_HOST = 'localhost'
34+
process.env.REDIS_PORT = '6379'
35+
process.env.REDIS_USER = 'default'
36+
process.env.REDIS_PASSWORD = 'secret'
37+
38+
const config = getCacheConfig()
39+
40+
expect(config).to.deep.equal({
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',
57+
password: 'secret',
58+
})
59+
})
60+
61+
it('prefers REDIS_URI over host/port settings', () => {
62+
process.env.REDIS_URI = 'redis://cache.internal:6380'
63+
process.env.REDIS_PASSWORD = 'secret'
64+
65+
const config = getCacheConfig()
66+
67+
expect(config).to.deep.equal({
68+
url: 'redis://cache.internal:6380',
69+
password: 'secret',
70+
})
71+
})
72+
})

0 commit comments

Comments
 (0)