Skip to content

Commit c00beb9

Browse files
authored
feat: obscure cross-space headers from response errors (#532)
1 parent a6a9836 commit c00beb9

File tree

2 files changed

+50
-5
lines changed

2 files changed

+50
-5
lines changed

src/error-handler.ts

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,19 @@
11
import isPlainObject from 'lodash/isPlainObject.js'
22
import type { ContentfulErrorData } from './types.js'
33

4+
function obscureHeaders(config: any) {
5+
// Management, Delivery and Preview API tokens
6+
if (config?.headers?.['Authorization']) {
7+
const token = `...${config.headers['Authorization'].toString().substr(-5)}`
8+
config.headers['Authorization'] = `Bearer ${token}`
9+
}
10+
// Encoded Delivery or Preview token map for Cross-Space References
11+
if (config?.headers?.['X-Contentful-Resource-Resolution']) {
12+
const token = `...${config.headers['X-Contentful-Resource-Resolution'].toString().substr(-5)}`
13+
config.headers['X-Contentful-Resource-Resolution'] = token
14+
}
15+
}
16+
417
/**
518
* Handles errors received from the server. Parses the error into a more useful
619
* format, places it in an exception and throws it.
@@ -13,11 +26,7 @@ export default function errorHandler(errorResponse: any): never {
1326
const { config, response } = errorResponse
1427
let errorName
1528

16-
// Obscure the Management token
17-
if (config && config.headers && config.headers['Authorization']) {
18-
const token = `...${config.headers['Authorization'].toString().substr(-5)}`
19-
config.headers['Authorization'] = `Bearer ${token}`
20-
}
29+
obscureHeaders(config)
2130

2231
if (!isPlainObject(response) || !isPlainObject(config)) {
2332
throw errorResponse

test/unit/error-handler-test.spec.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,4 +104,40 @@ describe('A errorHandler', () => {
104104
expect(err.config.headers.Authorization).toBe('Bearer ...token')
105105
}
106106
})
107+
108+
it('Obscures encoded cross-space reference tokens in any error message', async () => {
109+
const responseError: any = cloneDeep(errorMock)
110+
responseError.config.headers = {
111+
'X-Contentful-Resource-Resolution': 'secret-token',
112+
}
113+
114+
try {
115+
errorHandler(responseError)
116+
} catch (err: any) {
117+
const parsedMessage = JSON.parse(err.message)
118+
expect(parsedMessage.request.headers['X-Contentful-Resource-Resolution']).toBe('...token')
119+
}
120+
121+
const requestError: any = {
122+
config: {
123+
url: 'requesturl',
124+
headers: {},
125+
},
126+
data: {},
127+
request: {
128+
status: 404,
129+
statusText: 'Not Found',
130+
},
131+
}
132+
133+
requestError.config.headers = {
134+
'X-Contentful-Resource-Resolution': 'secret-token',
135+
}
136+
137+
try {
138+
errorHandler(requestError)
139+
} catch (err: any) {
140+
expect(err.config.headers['X-Contentful-Resource-Resolution']).toBe('...token')
141+
}
142+
})
107143
})

0 commit comments

Comments
 (0)