@trayio/express 4.93.0 → 4.95.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExpressHttpController.d.ts","sourceRoot":"","sources":["../../src/http/ExpressHttpController.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,CAAC,MAAM,cAAc,CAAC;AAClC,OAAO,EAAE,MAAM,EAAE,MAAM,2BAA2B,CAAC;AASnD,OAAO,EACN,cAAc,EAEd,MAAM,qCAAqC,CAAC;AAG7C,OAAO,EAAE,OAAO,EAAE,MAAM,iCAAiC,CAAC;AAW1D,qBAAa,qBAAqB;IAEhC,SAAS,CAAC,UAAU,EAAE,cAAc;IACpC,SAAS,CAAC,2BAA2B,EAAE,MAAM;IAC7C,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC;gBAFzB,UAAU,EAAE,cAAc,EAC1B,2BAA2B,EAAE,MAAe,EAC5C,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC;IAGpC,OAAO,CAAC,QAAQ,
|
|
1
|
+
{"version":3,"file":"ExpressHttpController.d.ts","sourceRoot":"","sources":["../../src/http/ExpressHttpController.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,CAAC,MAAM,cAAc,CAAC;AAClC,OAAO,EAAE,MAAM,EAAE,MAAM,2BAA2B,CAAC;AASnD,OAAO,EACN,cAAc,EAEd,MAAM,qCAAqC,CAAC;AAG7C,OAAO,EAAE,OAAO,EAAE,MAAM,iCAAiC,CAAC;AAW1D,qBAAa,qBAAqB;IAEhC,SAAS,CAAC,UAAU,EAAE,cAAc;IACpC,SAAS,CAAC,2BAA2B,EAAE,MAAM;IAC7C,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC;gBAFzB,UAAU,EAAE,cAAc,EAC1B,2BAA2B,EAAE,MAAe,EAC5C,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC;IAGpC,OAAO,CAAC,QAAQ,CA2Fd;IAEF,SAAS,WAAY,MAAM,YAKzB;IAEF,OAAO,CAAC,gBAAgB,CAoBtB;IAGF,OAAO,CAAC,uBAAuB,CAI7B;IAEF,OAAO,CAAC,sBAAsB,CAmC3B;IAEH,OAAO,CAAC,aAAa,CAenB;IAEF,OAAO,CAAC,YAAY,CAkBlB;IAEF,OAAO,CAAC,+BAA+B,CAWpC;CACH"}
|
|
@@ -84,14 +84,10 @@ class ExpressHttpController {
|
|
|
84
84
|
processedValue = value.join(','); // flatten arrays
|
|
85
85
|
}
|
|
86
86
|
// Convert to string and sanitize for HTTP header compliance
|
|
87
|
-
//
|
|
88
|
-
return
|
|
89
|
-
.replace(
|
|
90
|
-
.
|
|
91
|
-
// eslint-disable-next-line no-control-regex
|
|
92
|
-
.replace(/[\u0000-\u0009\u000B\u000C\u000E-\u001F\u007F]/g, '_') // other control characters (excluding \n and \r)
|
|
93
|
-
.replace(/["\\]/g, '_') // quotes and backslashes
|
|
94
|
-
.trim()); // remove leading/trailing whitespace
|
|
87
|
+
// Keep only valid HTTP header characters: tab, printable ASCII (0x20-0x7E), and extended ASCII (0x80-0xFF)
|
|
88
|
+
return String(processedValue)
|
|
89
|
+
.replace(/[^\t\x20-\x7e\x80-\xff]/g, '_')
|
|
90
|
+
.trim();
|
|
95
91
|
};
|
|
96
92
|
const response = Object.entries(httpResponse.headers)
|
|
97
93
|
.reduce((acc, [key, value]) => acc.setHeader(key, sanitizeHeaderValue(value)), res)
|
|
@@ -141,9 +141,9 @@ describe('ExpressHttpController', () => {
|
|
|
141
141
|
};
|
|
142
142
|
mockEndpoint.execute.mockReturnValue(() => T.of(httpResponse));
|
|
143
143
|
await routeHandler(mockReq, mockRes);
|
|
144
|
-
expect(mockRes.setHeader).toHaveBeenCalledWith('test-header', '
|
|
144
|
+
expect(mockRes.setHeader).toHaveBeenCalledWith('test-header', 'value_with_line__breaks');
|
|
145
145
|
});
|
|
146
|
-
it('should
|
|
146
|
+
it('should preserve quotes and backslashes as valid characters', async () => {
|
|
147
147
|
const httpResponse = {
|
|
148
148
|
statusCode: 200,
|
|
149
149
|
headers: {
|
|
@@ -157,7 +157,7 @@ describe('ExpressHttpController', () => {
|
|
|
157
157
|
};
|
|
158
158
|
mockEndpoint.execute.mockReturnValue(() => T.of(httpResponse));
|
|
159
159
|
await routeHandler(mockReq, mockRes);
|
|
160
|
-
expect(mockRes.setHeader).toHaveBeenCalledWith('test-header', '
|
|
160
|
+
expect(mockRes.setHeader).toHaveBeenCalledWith('test-header', 'value"with\\quotes');
|
|
161
161
|
});
|
|
162
162
|
it('should trim whitespace from header values', async () => {
|
|
163
163
|
const httpResponse = {
|
|
@@ -221,7 +221,23 @@ describe('ExpressHttpController', () => {
|
|
|
221
221
|
};
|
|
222
222
|
mockEndpoint.execute.mockReturnValue(() => T.of(httpResponse));
|
|
223
223
|
await routeHandler(mockReq, mockRes);
|
|
224
|
-
expect(mockRes.setHeader).toHaveBeenCalledWith('test-header', '
|
|
224
|
+
expect(mockRes.setHeader).toHaveBeenCalledWith('test-header', 'value_with__"multiple\\issues"');
|
|
225
|
+
});
|
|
226
|
+
it('should sanitize header values with em dash character', async () => {
|
|
227
|
+
const httpResponse = {
|
|
228
|
+
statusCode: 200,
|
|
229
|
+
headers: {
|
|
230
|
+
'test-header': 'value–with–em–dash',
|
|
231
|
+
},
|
|
232
|
+
body: new stream_1.Readable({
|
|
233
|
+
read() {
|
|
234
|
+
this.push(null);
|
|
235
|
+
},
|
|
236
|
+
}),
|
|
237
|
+
};
|
|
238
|
+
mockEndpoint.execute.mockReturnValue(() => T.of(httpResponse));
|
|
239
|
+
await routeHandler(mockReq, mockRes);
|
|
240
|
+
expect(mockRes.setHeader).toHaveBeenCalledWith('test-header', 'value_with_em_dash');
|
|
225
241
|
});
|
|
226
242
|
});
|
|
227
243
|
describe('error handling', () => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@trayio/express",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.95.0",
|
|
4
4
|
"description": "Express extensions and implementations",
|
|
5
5
|
"exports": {
|
|
6
6
|
"./*": "./dist/*.js"
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"access": "public"
|
|
15
15
|
},
|
|
16
16
|
"dependencies": {
|
|
17
|
-
"@trayio/commons": "4.
|
|
17
|
+
"@trayio/commons": "4.95.0",
|
|
18
18
|
"cors": "2.8.5",
|
|
19
19
|
"express": "4.20.0",
|
|
20
20
|
"formidable": "3.5.1"
|