@authuser/nest 0.2.2 → 1.1.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.
- package/CHANGELOG.md +57 -0
- package/README.md +53 -2
- package/SECURITY.md +17 -0
- package/SUPPORT.md +11 -0
- package/dist/configure-http-app.d.ts.map +1 -1
- package/dist/configure-http-app.js +49 -4
- package/dist/configure-http-app.js.map +1 -1
- package/dist/create-app.d.ts.map +1 -1
- package/dist/create-app.js +19 -6
- package/dist/create-app.js.map +1 -1
- package/dist/http-exception.filter.d.ts +3 -0
- package/dist/http-exception.filter.d.ts.map +1 -1
- package/dist/http-exception.filter.js +37 -7
- package/dist/http-exception.filter.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/nest-fastify.logger.d.ts +2 -1
- package/dist/nest-fastify.logger.d.ts.map +1 -1
- package/dist/nest-fastify.logger.js +9 -6
- package/dist/nest-fastify.logger.js.map +1 -1
- package/dist/options.d.ts +17 -2
- package/dist/options.d.ts.map +1 -1
- package/dist/options.js +240 -7
- package/dist/options.js.map +1 -1
- package/dist/types.d.ts +45 -3
- package/dist/types.d.ts.map +1 -1
- package/docs/api-stability.md +26 -0
- package/docs/configuration.md +64 -6
- package/docs/migration.md +12 -0
- package/docs/performance.md +16 -0
- package/docs/production.md +45 -0
- package/docs/releasing.md +28 -0
- package/docs/security.md +14 -2
- package/docs/threat-model.md +41 -0
- package/package.json +11 -3
package/dist/options.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"options.d.ts","sourceRoot":"","sources":["../src/options.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,kBAAkB,EAClB,uBAAuB,EACvB,WAAW,EACX,aAAa,EACb,cAAc,EACd,gBAAgB,EAChB,cAAc,EACf,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,cAAc,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,uBAAuB,CAAC,YAAY,CAAC,CAAC;IAClD,UAAU,EAAE,uBAAuB,CAAC,YAAY,CAAC,CAAC;IAClD,QAAQ,EAAE;QACR,MAAM,EAAE,OAAO,CAAC;QAChB,qBAAqB,EAAE,OAAO,CAAC;QAC/B,IAAI,EAAE,KAAK,GAAG,WAAW,CAAC;QAC1B,SAAS,EAAE,KAAK,IAAG,QAAQ,CAAC,IAAI,CAAC,gBAAgB,EAAE,SAAS,GAAG,KAAK,GAAG,YAAY,GAAG,KAAK,CAAC,CAAC,GAAG,gBAAgB,CAAA,CAAC;KAClH,CAAC;IACF,WAAW,EAAE,QAAQ,CAAC,kBAAkB,CAAC,CAAC;IAC1C,OAAO,EAAE,QAAQ,CAAC,IAAI,CAAC,cAAc,EAAE,YAAY,CAAC,CAAC,GAAG,IAAI,CAAC,cAAc,EAAE,YAAY,CAAC,CAAC;IAC3F,MAAM,EAAE,
|
|
1
|
+
{"version":3,"file":"options.d.ts","sourceRoot":"","sources":["../src/options.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,kBAAkB,EAClB,uBAAuB,EACvB,WAAW,EACX,YAAY,EACZ,mBAAmB,EACnB,aAAa,EACb,WAAW,EACX,cAAc,EACd,gBAAgB,EAChB,cAAc,EACf,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,cAAc,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,uBAAuB,CAAC,YAAY,CAAC,CAAC;IAClD,UAAU,EAAE,uBAAuB,CAAC,YAAY,CAAC,CAAC;IAClD,QAAQ,EAAE;QACR,MAAM,EAAE,OAAO,CAAC;QAChB,qBAAqB,EAAE,OAAO,CAAC;QAC/B,IAAI,EAAE,KAAK,GAAG,WAAW,CAAC;QAC1B,SAAS,EAAE,KAAK,IAAG,QAAQ,CAAC,IAAI,CAAC,gBAAgB,EAAE,SAAS,GAAG,KAAK,GAAG,YAAY,GAAG,KAAK,CAAC,CAAC,GAAG,gBAAgB,CAAA,CAAC;KAClH,CAAC;IACF,WAAW,EAAE,QAAQ,CAAC,kBAAkB,CAAC,CAAC;IAC1C,OAAO,EAAE,QAAQ,CAAC,IAAI,CAAC,cAAc,EAAE,YAAY,CAAC,CAAC,GAAG,IAAI,CAAC,cAAc,EAAE,YAAY,CAAC,CAAC;IAC3F,MAAM,EAAE;QACN,OAAO,EAAE,OAAO,CAAC;QACjB,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;QAC5C,KAAK,CAAC,EAAE,WAAW,CAAC;QACpB,UAAU,CAAC,EAAE,aAAa,CAAC,YAAY,CAAC,CAAC;QACzC,SAAS,EAAE,KAAK,GAAG;YACjB,IAAI,EAAE,MAAM,CAAC;YACb,KAAK,EAAE,WAAW,CAAC;YACnB,UAAU,CAAC,EAAE,aAAa,CAAC,YAAY,CAAC,CAAC;SAC1C,CAAC;KACH,CAAC;IACF,aAAa,EAAE,QAAQ,CAAC,WAAW,CAAC,uBAAuB,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;IAC/E,MAAM,EAAE,KAAK,GAAG;QACd,MAAM,EAAE,mBAAmB,CAAC;QAC5B,MAAM,CAAC,EAAE,YAAY,CAAC,QAAQ,CAAC,CAAC;KACjC,CAAC;IACF,aAAa,EAAE,OAAO,CAAC;CACxB;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,uBAAuB,GAAG,eAAe,CA4GhF"}
|
package/dist/options.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export function resolveOptions(options) {
|
|
2
|
+
validateInputOptions(options);
|
|
2
3
|
const preset = options.preset ?? 'secure';
|
|
3
4
|
const isSecure = preset !== 'minimal';
|
|
4
5
|
const isFull = preset === 'full';
|
|
@@ -7,6 +8,11 @@ export function resolveOptions(options) {
|
|
|
7
8
|
const compressionInput = typeof options.compression === 'object' ? options.compression : {};
|
|
8
9
|
const openApiInput = typeof options.openApi === 'object' ? options.openApi : {};
|
|
9
10
|
const healthInput = typeof options.health === 'object' ? options.health : {};
|
|
11
|
+
const readinessInput = healthInput.readiness === false || healthInput.readiness === undefined
|
|
12
|
+
? false
|
|
13
|
+
: healthInput.readiness;
|
|
14
|
+
const includeQueryString = options.observability?.includeQueryString ?? false;
|
|
15
|
+
const errorsInput = options.errors === false ? false : options.errors ?? {};
|
|
10
16
|
const openApiEnabled = typeof options.openApi === 'boolean'
|
|
11
17
|
? options.openApi
|
|
12
18
|
: openApiInput.enabled ?? openApiInput.ui ?? isFull;
|
|
@@ -69,14 +75,30 @@ export function resolveOptions(options) {
|
|
|
69
75
|
enabled: typeof options.health === 'boolean' ? options.health : healthInput.enabled ?? isFull,
|
|
70
76
|
path: normalizePath(healthInput.path ?? '/health'),
|
|
71
77
|
response: healthInput.response ?? { status: 'ok' },
|
|
78
|
+
...(healthInput.check ? { check: healthInput.check } : {}),
|
|
72
79
|
...(healthInput.preHandler ? { preHandler: healthInput.preHandler } : {}),
|
|
80
|
+
readiness: readinessInput === false
|
|
81
|
+
? false
|
|
82
|
+
: {
|
|
83
|
+
path: normalizePath(readinessInput.path ?? '/ready'),
|
|
84
|
+
check: readinessInput.check,
|
|
85
|
+
...(readinessInput.preHandler ? { preHandler: readinessInput.preHandler } : {}),
|
|
86
|
+
},
|
|
73
87
|
},
|
|
74
88
|
observability: {
|
|
75
|
-
logger: resolveLogger(options.observability?.logger ?? true),
|
|
89
|
+
logger: resolveLogger(options.observability?.logger ?? true, includeQueryString),
|
|
76
90
|
loggerFormat: options.observability?.loggerFormat ?? 'json',
|
|
77
91
|
requestLogging: options.observability?.requestLogging ?? false,
|
|
92
|
+
includeQueryString,
|
|
93
|
+
requestIdResponseHeader: options.observability?.requestIdResponseHeader ?? 'x-request-id',
|
|
78
94
|
responseTimeHeader: options.observability?.responseTimeHeader ?? false,
|
|
79
95
|
},
|
|
96
|
+
errors: errorsInput === false
|
|
97
|
+
? false
|
|
98
|
+
: {
|
|
99
|
+
format: errorsInput.format ?? 'authuser',
|
|
100
|
+
...(errorsInput.filter ? { filter: errorsInput.filter } : {}),
|
|
101
|
+
},
|
|
80
102
|
shutdownHooks: options.shutdownHooks ?? true,
|
|
81
103
|
};
|
|
82
104
|
if (options.apiPrefix !== undefined)
|
|
@@ -93,17 +115,183 @@ const SENSITIVE_LOG_PATHS = [
|
|
|
93
115
|
'req.headers.cookie',
|
|
94
116
|
'res.headers["set-cookie"]',
|
|
95
117
|
];
|
|
96
|
-
function resolveLogger(logger) {
|
|
118
|
+
function resolveLogger(logger, includeQueryString) {
|
|
97
119
|
if (logger === false)
|
|
98
120
|
return false;
|
|
121
|
+
const requestSerializer = (request) => ({
|
|
122
|
+
method: request.method,
|
|
123
|
+
url: safePath(typeof request.url === 'string' ? request.url : '', includeQueryString),
|
|
124
|
+
host: request.host,
|
|
125
|
+
remoteAddress: request.ip,
|
|
126
|
+
});
|
|
99
127
|
if (logger === true) {
|
|
100
|
-
return {
|
|
128
|
+
return {
|
|
129
|
+
redact: { paths: SENSITIVE_LOG_PATHS, censor: '[REDACTED]' },
|
|
130
|
+
serializers: { req: requestSerializer },
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
return {
|
|
134
|
+
...logger,
|
|
135
|
+
...(logger.redact === undefined
|
|
136
|
+
? { redact: { paths: SENSITIVE_LOG_PATHS, censor: '[REDACTED]' } }
|
|
137
|
+
: {}),
|
|
138
|
+
serializers: {
|
|
139
|
+
req: requestSerializer,
|
|
140
|
+
...logger.serializers,
|
|
141
|
+
},
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
function validateInputOptions(options) {
|
|
145
|
+
if (!isRecord(options))
|
|
146
|
+
throw new TypeError('Options must be an object');
|
|
147
|
+
assertOptionalString(options, 'appName', 'appName');
|
|
148
|
+
assertOptionalString(options, 'apiPrefix', 'apiPrefix');
|
|
149
|
+
assertOptionalEnum(options, 'preset', ['minimal', 'secure', 'full'], 'preset');
|
|
150
|
+
assertOptionalBoolean(options, 'shutdownHooks', 'shutdownHooks');
|
|
151
|
+
assertFalseOrObject(options, 'validation', 'validation');
|
|
152
|
+
assertBooleanOrObject(options, 'versioning', 'versioning');
|
|
153
|
+
const security = optionalObject(options, 'security', 'security');
|
|
154
|
+
if (security) {
|
|
155
|
+
assertOptionalBoolean(security, 'helmet', 'security.helmet');
|
|
156
|
+
assertOptionalBoolean(security, 'contentSecurityPolicy', 'security.contentSecurityPolicy');
|
|
157
|
+
assertFalseOrObject(security, 'cors', 'security.cors');
|
|
158
|
+
assertFalseOrObject(security, 'rateLimit', 'security.rateLimit');
|
|
159
|
+
const rateLimit = optionalObjectUnlessFalse(security.rateLimit);
|
|
160
|
+
if (rateLimit)
|
|
161
|
+
assertOptionalBoolean(rateLimit, 'enabled', 'security.rateLimit.enabled');
|
|
162
|
+
}
|
|
163
|
+
const compression = booleanOrObject(options.compression, 'compression');
|
|
164
|
+
if (compression) {
|
|
165
|
+
assertOptionalBoolean(compression, 'enabled', 'compression.enabled');
|
|
166
|
+
if (compression.encodings !== undefined) {
|
|
167
|
+
if (!Array.isArray(compression.encodings) || compression.encodings.some((encoding) => (!['br', 'gzip', 'deflate', 'identity'].includes(String(encoding))))) {
|
|
168
|
+
throw new TypeError('compression.encodings contains an unsupported encoding');
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
const openApi = booleanOrObject(options.openApi, 'openApi');
|
|
173
|
+
if (openApi) {
|
|
174
|
+
for (const key of ['enabled', 'json', 'ui', 'bearerAuth']) {
|
|
175
|
+
assertOptionalBoolean(openApi, key, `openApi.${key}`);
|
|
176
|
+
}
|
|
177
|
+
for (const key of ['title', 'description', 'version', 'jsonPath', 'uiPath']) {
|
|
178
|
+
assertOptionalString(openApi, key, `openApi.${key}`);
|
|
179
|
+
}
|
|
180
|
+
assertOptionalFunction(openApi, 'preHandler', 'openApi.preHandler');
|
|
181
|
+
}
|
|
182
|
+
const health = booleanOrObject(options.health, 'health');
|
|
183
|
+
if (health) {
|
|
184
|
+
assertOptionalBoolean(health, 'enabled', 'health.enabled');
|
|
185
|
+
assertOptionalString(health, 'path', 'health.path');
|
|
186
|
+
assertOptionalFunction(health, 'check', 'health.check');
|
|
187
|
+
assertOptionalFunction(health, 'preHandler', 'health.preHandler');
|
|
188
|
+
if (health.readiness !== undefined && health.readiness !== false) {
|
|
189
|
+
if (!isRecord(health.readiness))
|
|
190
|
+
throw new TypeError('health.readiness must be false or an object');
|
|
191
|
+
assertOptionalString(health.readiness, 'path', 'health.readiness.path');
|
|
192
|
+
if (typeof health.readiness.check !== 'function') {
|
|
193
|
+
throw new TypeError('health.readiness.check must be a function');
|
|
194
|
+
}
|
|
195
|
+
assertOptionalFunction(health.readiness, 'preHandler', 'health.readiness.preHandler');
|
|
196
|
+
}
|
|
101
197
|
}
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
198
|
+
const observability = optionalObject(options, 'observability', 'observability');
|
|
199
|
+
if (observability) {
|
|
200
|
+
for (const key of ['requestLogging', 'includeQueryString', 'responseTimeHeader']) {
|
|
201
|
+
assertOptionalBoolean(observability, key, `observability.${key}`);
|
|
202
|
+
}
|
|
203
|
+
assertOptionalEnum(observability, 'loggerFormat', ['json', 'nest'], 'observability.loggerFormat');
|
|
204
|
+
if (observability.logger !== undefined
|
|
205
|
+
&& typeof observability.logger !== 'boolean'
|
|
206
|
+
&& !isRecord(observability.logger)) {
|
|
207
|
+
throw new TypeError('observability.logger must be a boolean or an object');
|
|
208
|
+
}
|
|
209
|
+
if (observability.requestIdResponseHeader !== undefined
|
|
210
|
+
&& observability.requestIdResponseHeader !== false
|
|
211
|
+
&& typeof observability.requestIdResponseHeader !== 'string') {
|
|
212
|
+
throw new TypeError('observability.requestIdResponseHeader must be false or a string');
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
if (options.errors !== undefined && options.errors !== false) {
|
|
216
|
+
if (!isRecord(options.errors))
|
|
217
|
+
throw new TypeError('errors must be false or an object');
|
|
218
|
+
assertOptionalEnum(options.errors, 'format', ['authuser', 'problem-details'], 'errors.format');
|
|
219
|
+
if (options.errors.filter !== undefined
|
|
220
|
+
&& (!isRecord(options.errors.filter) || typeof options.errors.filter.catch !== 'function')) {
|
|
221
|
+
throw new TypeError('errors.filter must implement ExceptionFilter');
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
function booleanOrObject(value, name) {
|
|
226
|
+
if (value === undefined || typeof value === 'boolean')
|
|
227
|
+
return undefined;
|
|
228
|
+
if (!isRecord(value))
|
|
229
|
+
throw new TypeError(`${name} must be a boolean or an object`);
|
|
230
|
+
return value;
|
|
231
|
+
}
|
|
232
|
+
function assertBooleanOrObject(record, key, name) {
|
|
233
|
+
const value = record[key];
|
|
234
|
+
if (value !== undefined && typeof value !== 'boolean' && !isRecord(value)) {
|
|
235
|
+
throw new TypeError(`${name} must be a boolean or an object`);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
function assertFalseOrObject(record, key, name) {
|
|
239
|
+
const value = record[key];
|
|
240
|
+
if (value !== undefined && value !== false && !isRecord(value)) {
|
|
241
|
+
throw new TypeError(`${name} must be false or an object`);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
function optionalObject(record, key, name) {
|
|
245
|
+
const value = record[key];
|
|
246
|
+
if (value === undefined)
|
|
247
|
+
return undefined;
|
|
248
|
+
if (!isRecord(value))
|
|
249
|
+
throw new TypeError(`${name} must be an object`);
|
|
250
|
+
return value;
|
|
251
|
+
}
|
|
252
|
+
function optionalObjectUnlessFalse(value) {
|
|
253
|
+
return value === undefined || value === false ? undefined : value;
|
|
254
|
+
}
|
|
255
|
+
function assertOptionalBoolean(record, key, name) {
|
|
256
|
+
if (record[key] !== undefined && typeof record[key] !== 'boolean') {
|
|
257
|
+
throw new TypeError(`${name} must be a boolean`);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
function assertOptionalString(record, key, name) {
|
|
261
|
+
if (record[key] !== undefined && typeof record[key] !== 'string') {
|
|
262
|
+
throw new TypeError(`${name} must be a string`);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
function assertOptionalFunction(record, key, name) {
|
|
266
|
+
if (record[key] !== undefined && typeof record[key] !== 'function') {
|
|
267
|
+
throw new TypeError(`${name} must be a function`);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
function assertOptionalEnum(record, key, values, name) {
|
|
271
|
+
const value = record[key];
|
|
272
|
+
if (value !== undefined && (typeof value !== 'string' || !values.includes(value))) {
|
|
273
|
+
throw new TypeError(`${name} must be one of: ${values.join(', ')}`);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
function isRecord(value) {
|
|
277
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
105
278
|
}
|
|
106
279
|
function validateResolvedOptions(options) {
|
|
280
|
+
if (options.appName.trim().length === 0
|
|
281
|
+
|| options.appName.length > 128
|
|
282
|
+
|| /[\u0000-\u001f\u007f]/.test(options.appName)) {
|
|
283
|
+
throw new TypeError('Application name must contain 1 to 128 characters without control characters');
|
|
284
|
+
}
|
|
285
|
+
if (options.apiPrefix !== undefined && (options.apiPrefix.length > 1_024
|
|
286
|
+
|| options.apiPrefix.includes('?')
|
|
287
|
+
|| options.apiPrefix.includes('#')
|
|
288
|
+
|| options.apiPrefix.includes('\0')
|
|
289
|
+
|| hasUnsafeRoutePattern(`/${options.apiPrefix}`))) {
|
|
290
|
+
throw new TypeError('API prefix must be a valid URL path prefix');
|
|
291
|
+
}
|
|
292
|
+
if (!Number.isSafeInteger(options.compression.threshold) || options.compression.threshold < 0) {
|
|
293
|
+
throw new TypeError('Compression threshold must be a non-negative safe integer');
|
|
294
|
+
}
|
|
107
295
|
const cors = options.security.cors;
|
|
108
296
|
if (cors !== false && cors.credentials === true && cors.origin === true) {
|
|
109
297
|
throw new TypeError('CORS credentials cannot be combined with an unrestricted origin');
|
|
@@ -112,13 +300,58 @@ function validateResolvedOptions(options) {
|
|
|
112
300
|
options.health.enabled ? options.health.path : undefined,
|
|
113
301
|
options.openApi.enabled && options.openApi.json ? options.openApi.jsonPath : undefined,
|
|
114
302
|
options.openApi.enabled && options.openApi.ui ? options.openApi.uiPath : undefined,
|
|
303
|
+
options.health.readiness !== false ? options.health.readiness.path : undefined,
|
|
115
304
|
].filter((path) => path !== undefined);
|
|
116
|
-
if (
|
|
305
|
+
if (paths.some((path, index) => paths.some((other, otherIndex) => (index !== otherIndex && (path === other || path.startsWith(`${other}/`) || other.startsWith(`${path}/`)))))) {
|
|
117
306
|
throw new TypeError('Health, OpenAPI JSON and Swagger UI paths must be unique');
|
|
118
307
|
}
|
|
308
|
+
for (const path of paths)
|
|
309
|
+
validateInternalPath(path);
|
|
310
|
+
const requestIdHeader = options.observability.requestIdResponseHeader;
|
|
311
|
+
if (requestIdHeader !== false && !/^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/.test(requestIdHeader)) {
|
|
312
|
+
throw new TypeError('Request ID response header must be a valid HTTP header name');
|
|
313
|
+
}
|
|
314
|
+
if (requestIdHeader !== false && RESERVED_RESPONSE_HEADERS.has(requestIdHeader.toLowerCase())) {
|
|
315
|
+
throw new TypeError(`Request ID response header is reserved: ${requestIdHeader}`);
|
|
316
|
+
}
|
|
119
317
|
const rateLimit = options.security.rateLimit;
|
|
120
318
|
if (rateLimit !== false && typeof rateLimit.max === 'number' && (!Number.isFinite(rateLimit.max) || rateLimit.max <= 0)) {
|
|
121
319
|
throw new TypeError('Rate limit max must be a positive number');
|
|
122
320
|
}
|
|
123
321
|
}
|
|
322
|
+
function validateInternalPath(path) {
|
|
323
|
+
if (path.length > 2_048
|
|
324
|
+
|| path.includes('?')
|
|
325
|
+
|| path.includes('#')
|
|
326
|
+
|| path.includes('\0')
|
|
327
|
+
|| hasUnsafeRoutePattern(path)) {
|
|
328
|
+
throw new TypeError(`Invalid internal route path: ${path}`);
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
function hasUnsafeRoutePattern(path) {
|
|
332
|
+
const segments = path.split('/');
|
|
333
|
+
return /[\u0000-\u001f\u007f\\*:{}]/.test(path)
|
|
334
|
+
|| segments.includes('.')
|
|
335
|
+
|| segments.includes('..');
|
|
336
|
+
}
|
|
337
|
+
function safePath(url, includeQueryString) {
|
|
338
|
+
return includeQueryString ? url : url.split('?', 1)[0] ?? '';
|
|
339
|
+
}
|
|
340
|
+
const RESERVED_RESPONSE_HEADERS = new Set([
|
|
341
|
+
'connection',
|
|
342
|
+
'content-encoding',
|
|
343
|
+
'content-length',
|
|
344
|
+
'content-type',
|
|
345
|
+
'date',
|
|
346
|
+
'keep-alive',
|
|
347
|
+
'set-cookie',
|
|
348
|
+
'te',
|
|
349
|
+
'trailer',
|
|
350
|
+
'transfer-encoding',
|
|
351
|
+
'upgrade',
|
|
352
|
+
'www-authenticate',
|
|
353
|
+
'proxy-authenticate',
|
|
354
|
+
'traceparent',
|
|
355
|
+
'tracestate',
|
|
356
|
+
]);
|
|
124
357
|
//# sourceMappingURL=options.js.map
|
package/dist/options.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"options.js","sourceRoot":"","sources":["../src/options.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"options.js","sourceRoot":"","sources":["../src/options.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { LoggerOptions } from 'pino';
|
|
2
2
|
import type rateLimit from '@fastify/rate-limit';
|
|
3
|
-
import type { Type, ValidationPipeOptions, VersioningOptions } from '@nestjs/common';
|
|
3
|
+
import type { ExceptionFilter, Type, ValidationPipeOptions, VersioningOptions } from '@nestjs/common';
|
|
4
4
|
import type { NestApplicationOptions } from '@nestjs/common/interfaces/nest-application-options.interface';
|
|
5
|
-
import type { preHandlerHookHandler } from 'fastify';
|
|
5
|
+
import type { FastifyRequest, preHandlerHookHandler } from 'fastify';
|
|
6
6
|
export type SecurityPreset = 'minimal' | 'secure' | 'full';
|
|
7
7
|
export interface CorsOptions {
|
|
8
8
|
/** No cross-origin requests are allowed by default. */
|
|
@@ -50,8 +50,18 @@ export interface HealthOptions {
|
|
|
50
50
|
enabled?: boolean;
|
|
51
51
|
path?: string;
|
|
52
52
|
response?: Readonly<Record<string, unknown>>;
|
|
53
|
+
/** Dynamic liveness check. Throwing produces a safe HTTP 503 response. */
|
|
54
|
+
check?: HealthCheck;
|
|
53
55
|
/** Fastify hook for restricting the health route. */
|
|
54
56
|
preHandler?: preHandlerHookHandler;
|
|
57
|
+
/** Optional dependency-readiness endpoint. */
|
|
58
|
+
readiness?: false | ReadinessOptions;
|
|
59
|
+
}
|
|
60
|
+
export type HealthCheck = (request: FastifyRequest) => Readonly<Record<string, unknown>> | Promise<Readonly<Record<string, unknown>>>;
|
|
61
|
+
export interface ReadinessOptions {
|
|
62
|
+
path?: string;
|
|
63
|
+
check: HealthCheck;
|
|
64
|
+
preHandler?: preHandlerHookHandler;
|
|
55
65
|
}
|
|
56
66
|
export interface ObservabilityOptions {
|
|
57
67
|
/** Fastify logging. An options object configures the default Pino JSON logger. */
|
|
@@ -59,8 +69,37 @@ export interface ObservabilityOptions {
|
|
|
59
69
|
/** JSON is optimal for production ingestion; nest uses Nest's readable console format. */
|
|
60
70
|
loggerFormat?: 'json' | 'nest';
|
|
61
71
|
requestLogging?: boolean;
|
|
72
|
+
/** Query strings may contain secrets or personal data and are omitted by default. */
|
|
73
|
+
includeQueryString?: boolean;
|
|
74
|
+
/** Response correlation header. False disables it. */
|
|
75
|
+
requestIdResponseHeader?: string | false;
|
|
62
76
|
responseTimeHeader?: boolean;
|
|
63
77
|
}
|
|
78
|
+
export type ErrorResponseFormat = 'authuser' | 'problem-details';
|
|
79
|
+
export interface ErrorOptions {
|
|
80
|
+
/** Response contract used by the built-in exception filter. */
|
|
81
|
+
format?: ErrorResponseFormat;
|
|
82
|
+
/** Replaces the built-in exception filter when supplied. */
|
|
83
|
+
filter?: ExceptionFilter;
|
|
84
|
+
}
|
|
85
|
+
export interface HttpErrorResponse {
|
|
86
|
+
statusCode: number;
|
|
87
|
+
error: string;
|
|
88
|
+
message: unknown;
|
|
89
|
+
requestId: string;
|
|
90
|
+
path: string;
|
|
91
|
+
}
|
|
92
|
+
/** RFC 9457 problem details with a correlation ID extension. */
|
|
93
|
+
export interface ProblemDetailsResponse {
|
|
94
|
+
type: string;
|
|
95
|
+
title: string;
|
|
96
|
+
status: number;
|
|
97
|
+
detail: string;
|
|
98
|
+
instance: string;
|
|
99
|
+
requestId: string;
|
|
100
|
+
/** Original structured client-error messages, such as DTO validation errors. */
|
|
101
|
+
errors?: unknown;
|
|
102
|
+
}
|
|
64
103
|
export interface NetworkOptions {
|
|
65
104
|
trustProxy?: boolean | string | string[];
|
|
66
105
|
bodyLimit?: number;
|
|
@@ -82,12 +121,15 @@ export interface ConfigureHttpAppOptions {
|
|
|
82
121
|
compression?: boolean | CompressionOptions;
|
|
83
122
|
openApi?: boolean | OpenApiOptions;
|
|
84
123
|
health?: boolean | HealthOptions;
|
|
124
|
+
/** Safe built-in error responses by default. False preserves application filters. */
|
|
125
|
+
errors?: false | ErrorOptions;
|
|
85
126
|
observability?: ObservabilityOptions;
|
|
86
127
|
shutdownHooks?: boolean;
|
|
87
128
|
}
|
|
88
129
|
export interface CreateAppOptions extends ConfigureHttpAppOptions {
|
|
89
130
|
rootModule: Type<unknown>;
|
|
90
131
|
network?: NetworkOptions;
|
|
91
|
-
|
|
132
|
+
/** Native Nest factory options, including an independent Nest logger. */
|
|
133
|
+
nest?: NestApplicationOptions;
|
|
92
134
|
}
|
|
93
135
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,MAAM,CAAC;AAC1C,OAAO,KAAK,SAAS,MAAM,qBAAqB,CAAC;AACjD,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# API stability policy
|
|
2
|
+
|
|
3
|
+
Version 1 follows Semantic Versioning. The supported public API is the root export
|
|
4
|
+
documented in `README.md` and the TypeScript declarations reachable from it.
|
|
5
|
+
|
|
6
|
+
## Compatibility guarantees
|
|
7
|
+
|
|
8
|
+
- Patch releases fix bugs and security issues without intentionally breaking valid
|
|
9
|
+
1.x configurations.
|
|
10
|
+
- Minor releases may add optional exports, options and preset capabilities. Existing
|
|
11
|
+
explicit options retain their behavior.
|
|
12
|
+
- Removed or renamed APIs require a deprecation in a minor release and removal in
|
|
13
|
+
the next major release, except when continued behavior creates a critical security
|
|
14
|
+
vulnerability.
|
|
15
|
+
- Undocumented `dist/*` paths and internal classes are not public API.
|
|
16
|
+
- Node, Nest and Fastify support ranges are declared in `package.json`. Dropping a
|
|
17
|
+
supported major runtime requires a new package major version.
|
|
18
|
+
|
|
19
|
+
The stable runtime exports are `createApp`, `configureHttpApp`, `Public`, `Roles`,
|
|
20
|
+
their metadata keys, and `HttpExceptionFilter`. Exported configuration and response
|
|
21
|
+
types are part of the TypeScript contract.
|
|
22
|
+
|
|
23
|
+
## Deprecation process
|
|
24
|
+
|
|
25
|
+
A deprecation is documented in the changelog and migration guide. When practical,
|
|
26
|
+
the previous behavior remains available throughout the current major release.
|
package/docs/configuration.md
CHANGED
|
@@ -13,7 +13,8 @@ All settings are optional except `rootModule` when using `createApp`.
|
|
|
13
13
|
| `versioning` | `false` | `true` for URI versioning, or Nest versioning options. |
|
|
14
14
|
| `shutdownHooks` | `true` | Enable Nest shutdown signal hooks. |
|
|
15
15
|
| `validation` | strict defaults | `false` or Nest `ValidationPipeOptions`. |
|
|
16
|
-
| `
|
|
16
|
+
| `errors` | `{ format: 'authuser' }` | Built-in safe errors, `false`, or error options. |
|
|
17
|
+
| `nest` | `{}` | Native `NestApplicationOptions`, including its independent logger. |
|
|
17
18
|
|
|
18
19
|
Default validation uses `whitelist: true`, `forbidNonWhitelisted: true`, and
|
|
19
20
|
`transform: false`. Transformation is off because implicit coercion costs work and
|
|
@@ -43,6 +44,8 @@ CORS remains disabled unless an explicit configuration is supplied.
|
|
|
43
44
|
When enabled, the default advertised methods are GET, HEAD, POST, PUT, PATCH,
|
|
44
45
|
DELETE, OPTIONS and QUERY. Successful browser preflights return HTTP 204 by default;
|
|
45
46
|
`optionsSuccessStatus` can change this for a legacy client that requires 200.
|
|
47
|
+
Without a CORS configuration, the module does not install a catch-all OPTIONS route;
|
|
48
|
+
an OPTIONS request then requires an application route of its own.
|
|
46
49
|
|
|
47
50
|
Rate-limit defaults are 100 requests per minute per client IP. Available settings
|
|
48
51
|
include the complete `@fastify/rate-limit` plugin surface: `max`, `timeWindow`,
|
|
@@ -71,12 +74,27 @@ known payloads rather than automatically for every API.
|
|
|
71
74
|
|
|
72
75
|
Set `openApi: false` to guarantee the documentation integration is never loaded.
|
|
73
76
|
|
|
74
|
-
## Health
|
|
77
|
+
## Health
|
|
75
78
|
|
|
76
79
|
The full preset serves `{ "status": "ok" }` at `/health`. This is a liveness probe,
|
|
77
|
-
not a dependency-readiness check.
|
|
78
|
-
|
|
79
|
-
|
|
80
|
+
not a dependency-readiness check. `health.check` supplies a dynamic liveness result.
|
|
81
|
+
`health.readiness.check` adds a separate `/ready` endpoint for dependencies. A thrown
|
|
82
|
+
check returns only `{ "status": "unavailable" }` with HTTP 503 and logs the original
|
|
83
|
+
error internally. Health endpoints bypass the global rate limit so probes cannot
|
|
84
|
+
evict application traffic. Use `preHandler` when an endpoint must not be public.
|
|
85
|
+
|
|
86
|
+
| Option | Default | Description |
|
|
87
|
+
| --- | --- | --- |
|
|
88
|
+
| `health.enabled` | full preset only | Enable liveness. |
|
|
89
|
+
| `health.path` | `/health` | Liveness route. |
|
|
90
|
+
| `health.response` | `{ status: 'ok' }` | Static liveness response. |
|
|
91
|
+
| `health.check` | none | Dynamic liveness callback. |
|
|
92
|
+
| `health.preHandler` | none | Access-control hook for liveness. |
|
|
93
|
+
| `health.readiness` | `false` | Object containing a required `check`. |
|
|
94
|
+
| `health.readiness.path` | `/ready` | Readiness route. |
|
|
95
|
+
| `health.readiness.preHandler` | none | Access-control hook for readiness. |
|
|
96
|
+
|
|
97
|
+
## Observability
|
|
80
98
|
|
|
81
99
|
Fastify's Pino JSON logger is enabled by default, while per-request logging is
|
|
82
100
|
disabled to reduce noise and overhead. Enable it with
|
|
@@ -87,4 +105,44 @@ metadata and never serializes headers or bodies.
|
|
|
87
105
|
|
|
88
106
|
The optional `responseTimeHeader` emits a standards-compatible `Server-Timing`
|
|
89
107
|
value. Default JSON logging redacts authorization, cookie and set-cookie fields. A
|
|
90
|
-
custom Pino `redact` configuration overrides those defaults.
|
|
108
|
+
custom Pino `redact` configuration overrides those defaults. Likewise, a custom
|
|
109
|
+
`serializers.req` replaces the safe request serializer, so redaction of URL data
|
|
110
|
+
then becomes the application's responsibility.
|
|
111
|
+
|
|
112
|
+
| Option | Default | Description |
|
|
113
|
+
| --- | --- | --- |
|
|
114
|
+
| `observability.logger` | `true` | `false`, or Pino configuration for JSON logs. |
|
|
115
|
+
| `observability.loggerFormat` | `json` | `json` or readable `nest`. |
|
|
116
|
+
| `observability.requestLogging` | `false` | Log request start and completion. |
|
|
117
|
+
| `observability.includeQueryString` | `false` | Include potentially sensitive query strings in request logs. |
|
|
118
|
+
| `observability.requestIdResponseHeader` | `x-request-id` | Correlation response header, or `false`. |
|
|
119
|
+
| `observability.responseTimeHeader` | `false` | Emit `Server-Timing`. |
|
|
120
|
+
|
|
121
|
+
The Fastify logger and Nest logger are independent. Disable both explicitly with
|
|
122
|
+
`observability.logger: false` and `nest.logger: false`.
|
|
123
|
+
|
|
124
|
+
## Error response contract
|
|
125
|
+
|
|
126
|
+
Client-visible errors use the exported `HttpErrorResponse` shape: `statusCode`,
|
|
127
|
+
`error`, `message`, `requestId`, and `path`. Query strings never appear in `path`.
|
|
128
|
+
Every status from 500 through 599 receives the generic message `Internal server
|
|
129
|
+
error`; the original exception is available only in server logs.
|
|
130
|
+
|
|
131
|
+
Use the standardized [RFC 9457 Problem Details](https://www.rfc-editor.org/rfc/rfc9457)
|
|
132
|
+
shape as an opt-in:
|
|
133
|
+
|
|
134
|
+
```ts
|
|
135
|
+
errors: { format: 'problem-details' }
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
It responds with `application/problem+json` and the fields `type`, `title`, `status`,
|
|
139
|
+
`detail`, `instance`, and `requestId`. Structured client validation messages are
|
|
140
|
+
preserved in the `errors` extension, while server details remain hidden.
|
|
141
|
+
|
|
142
|
+
Set `errors: false` to preserve an existing application's filters, or pass
|
|
143
|
+
`errors: { filter: customExceptionFilter }` to install a replacement. Call
|
|
144
|
+
`configureHttpApp` exactly once and before `app.init()` or `app.listen()`.
|
|
145
|
+
|
|
146
|
+
Configuration is validated at runtime as well as by TypeScript. Invalid presets,
|
|
147
|
+
callbacks, route patterns, encodings, header names and unsafe network values fail
|
|
148
|
+
early during bootstrap.
|
package/docs/migration.md
CHANGED
|
@@ -24,3 +24,15 @@ application and this package share one framework instance.
|
|
|
24
24
|
`AuthuserModule` and `AUTHUSER_OPTIONS` were removed because their configuration was
|
|
25
25
|
not connected to adapter creation. Configure the application exclusively through
|
|
26
26
|
`createApp` or `configureHttpApp`.
|
|
27
|
+
|
|
28
|
+
## Migrating from 0.x to 1.x
|
|
29
|
+
|
|
30
|
+
- `observability.logger: false` disables Fastify logging only. Use
|
|
31
|
+
`nest.logger: false` when Nest logs must also be disabled.
|
|
32
|
+
- Responses include `x-request-id` by default. Set
|
|
33
|
+
`observability.requestIdResponseHeader: false` to opt out.
|
|
34
|
+
- Request logs omit query strings by default. Set
|
|
35
|
+
`observability.includeQueryString: true` only after reviewing data exposure.
|
|
36
|
+
- All 5xx response messages are generic and error paths omit query strings.
|
|
37
|
+
- Internal route paths must be unique and cannot contain query strings or fragments.
|
|
38
|
+
- `health.check` and `health.readiness` provide dynamic probe callbacks.
|
package/docs/performance.md
CHANGED
|
@@ -17,6 +17,10 @@ trades bandwidth for CPU. OpenAPI generation happens at startup, and its modules
|
|
|
17
17
|
not imported when disabled. Helmet, CORS, rate limiting and compression are also
|
|
18
18
|
dynamically imported only when their configuration enables them.
|
|
19
19
|
|
|
20
|
+
Pino JSON is the production logging default. The Nest-formatted adapter prioritizes
|
|
21
|
+
human readability and is intended primarily for local development; benchmark it
|
|
22
|
+
before enabling per-request Nest logs on a high-throughput service.
|
|
23
|
+
|
|
20
24
|
## Reproducible baseline
|
|
21
25
|
|
|
22
26
|
Run the dependency-free local regression benchmark:
|
|
@@ -30,6 +34,18 @@ Change duration and concurrency with `BENCHMARK_DURATION_MS` and
|
|
|
30
34
|
minimal preset and the secure preset. Treat them as a regression signal rather than
|
|
31
35
|
a production capacity promise.
|
|
32
36
|
|
|
37
|
+
The 1.1.0 release check on Node 22.14 with 100 local connections produced this
|
|
38
|
+
single-run baseline:
|
|
39
|
+
|
|
40
|
+
| Scenario | Requests/s | p50 | p99 | Errors |
|
|
41
|
+
| --- | ---: | ---: | ---: | ---: |
|
|
42
|
+
| Fastify raw | 28,859 | 3.22 ms | 3.92 ms | 0 |
|
|
43
|
+
| `@authuser/nest` minimal | 26,507 | 3.69 ms | 4.60 ms | 0 |
|
|
44
|
+
| `@authuser/nest` secure | 19,818 | 4.96 ms | 5.59 ms | 0 |
|
|
45
|
+
|
|
46
|
+
That run retained about 92% of raw Fastify throughput in `minimal` and 69% in
|
|
47
|
+
`secure`. It is a local regression reference, not a service capacity guarantee.
|
|
48
|
+
|
|
33
49
|
## Choosing a lower-level stack
|
|
34
50
|
|
|
35
51
|
If profiling shows Nest itself is the bottleneck, raw Fastify is the closest smaller
|