@lucaapp/service-utils 5.27.0 → 5.29.1
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/dist/lib/api/openapi.js
CHANGED
|
@@ -225,6 +225,27 @@ const hoistCombinatorRequiredFields = (spec) => {
|
|
|
225
225
|
visit(schemas);
|
|
226
226
|
};
|
|
227
227
|
exports.hoistCombinatorRequiredFields = hoistCombinatorRequiredFields;
|
|
228
|
+
/**
|
|
229
|
+
* Turn each middleware's declared schemes into OpenAPI security requirements.
|
|
230
|
+
*
|
|
231
|
+
* OpenAPI expresses the two relations differently: separate objects in the
|
|
232
|
+
* `security` array are alternatives (OR), while several schemes inside one
|
|
233
|
+
* object are all required (AND). A middleware's own `security: [a, b]` means
|
|
234
|
+
* "a or b" -- it accepts either credential -- but two middlewares on the same
|
|
235
|
+
* route both run, so their requirements are combined with AND.
|
|
236
|
+
*
|
|
237
|
+
* That makes the result the cartesian product across middlewares:
|
|
238
|
+
*
|
|
239
|
+
* [[a, b], [c]] -> [{a, c}, {b, c}]
|
|
240
|
+
*
|
|
241
|
+
* A single middleware therefore still renders as plain alternatives, which is
|
|
242
|
+
* what it did before, and stacked middlewares no longer render as if presenting
|
|
243
|
+
* any one of their credentials were enough.
|
|
244
|
+
*/
|
|
245
|
+
const buildSecurityRequirements = (securityByMiddleware) => securityByMiddleware.reduce((requirements, alternatives) => requirements.flatMap(requirement =>
|
|
246
|
+
// Duplicates collapse on their own: the same scheme required twice is
|
|
247
|
+
// still one entry in the object.
|
|
248
|
+
alternatives.map(scheme => ({ ...requirement, [scheme]: [] }))), [{}]);
|
|
228
249
|
const registerEndpoint = (registry, method, prefixPath, rootPrefixPath, path, summary,
|
|
229
250
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
230
251
|
options, tags, debug) => {
|
|
@@ -233,7 +254,11 @@ options, tags, debug) => {
|
|
|
233
254
|
let querySchema = options.schemas?.query || undefined;
|
|
234
255
|
let headersSchema = options.schemas?.headers || undefined;
|
|
235
256
|
let responseSchemas = options.responses;
|
|
236
|
-
|
|
257
|
+
// One entry per security-declaring middleware, each holding that middleware's
|
|
258
|
+
// alternatives. Kept separate because the two levels mean different things:
|
|
259
|
+
// within a middleware the schemes are alternatives, across middlewares they
|
|
260
|
+
// are all enforced. See buildSecurityRequirements.
|
|
261
|
+
const securityByMiddleware = [];
|
|
237
262
|
if (options.errors) {
|
|
238
263
|
for (const errorType of Object.keys(options.errors)) {
|
|
239
264
|
const statusCode = options.errors[errorType];
|
|
@@ -294,8 +319,9 @@ options, tags, debug) => {
|
|
|
294
319
|
});
|
|
295
320
|
}
|
|
296
321
|
}
|
|
297
|
-
|
|
298
|
-
|
|
322
|
+
const middlewareSecurity = middleware.options.security || [];
|
|
323
|
+
if (middlewareSecurity.length > 0) {
|
|
324
|
+
securityByMiddleware.push([...middlewareSecurity]);
|
|
299
325
|
}
|
|
300
326
|
}
|
|
301
327
|
// Add ZodError response
|
|
@@ -355,8 +381,8 @@ options, tags, debug) => {
|
|
|
355
381
|
responses: responseMap,
|
|
356
382
|
operationId: options.operationId ||
|
|
357
383
|
deriveOperationId(registry, method, prefixPath.slice(rootPrefixPath.length) + path),
|
|
358
|
-
...(
|
|
359
|
-
security:
|
|
384
|
+
...(securityByMiddleware.length > 0 && {
|
|
385
|
+
security: buildSecurityRequirements(securityByMiddleware),
|
|
360
386
|
}),
|
|
361
387
|
});
|
|
362
388
|
};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { SecuritySchemeObject } from 'openapi3-ts/oas30';
|
|
2
|
-
export type SecurityScheme = 'jwt_operator' | 'jwt_support' | 'jwt_operator_device' | 'jwt_consumer' | '
|
|
2
|
+
export type SecurityScheme = 'jwt_operator' | 'jwt_support' | 'jwt_operator_device' | 'jwt_consumer' | 'api_key_operator_device' | 'api_key_atworld' | 'api_key_at_support' | 'basic_adyen_webhook' | 'hmac_adyen_webhook';
|
|
3
3
|
export declare const SECURITY_SCHEMES: Record<SecurityScheme, SecuritySchemeObject>;
|
package/dist/lib/api/security.js
CHANGED
|
@@ -1,15 +1,37 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.SECURITY_SCHEMES = void 0;
|
|
4
|
-
const
|
|
4
|
+
const xAuth = (description) => ({
|
|
5
5
|
type: 'apiKey',
|
|
6
6
|
in: 'header',
|
|
7
7
|
name: 'X-Auth',
|
|
8
|
-
|
|
8
|
+
description,
|
|
9
|
+
});
|
|
10
|
+
const xApiKey = (description) => ({
|
|
11
|
+
type: 'apiKey',
|
|
12
|
+
in: 'header',
|
|
13
|
+
name: 'X-Api-Key',
|
|
14
|
+
description,
|
|
15
|
+
});
|
|
16
|
+
const basicAuth = (description) => ({
|
|
17
|
+
type: 'http',
|
|
18
|
+
scheme: 'basic',
|
|
19
|
+
description,
|
|
20
|
+
});
|
|
21
|
+
const hmacHeader = (description) => ({
|
|
22
|
+
type: 'apiKey',
|
|
23
|
+
in: 'header',
|
|
24
|
+
name: 'hmacsignature',
|
|
25
|
+
description,
|
|
26
|
+
});
|
|
9
27
|
exports.SECURITY_SCHEMES = {
|
|
10
|
-
jwt_operator:
|
|
11
|
-
jwt_support:
|
|
12
|
-
jwt_operator_device:
|
|
13
|
-
jwt_consumer:
|
|
14
|
-
|
|
28
|
+
jwt_operator: xAuth('Operator session JWT issued by the luca backend'),
|
|
29
|
+
jwt_support: xAuth('Support session JWT issued by the luca backend'),
|
|
30
|
+
jwt_operator_device: xAuth('Operator device JWT issued by the luca backend (kiosk, terminal, link)'),
|
|
31
|
+
jwt_consumer: xAuth('Consumer JWT'),
|
|
32
|
+
api_key_operator_device: xApiKey('Operator device API key (sk_...) created by the operator for an external device'),
|
|
33
|
+
api_key_atworld: xApiKey('ATworld partner API key'),
|
|
34
|
+
api_key_at_support: xApiKey('AT support API key (partner or luca)'),
|
|
35
|
+
basic_adyen_webhook: basicAuth('Basic auth credential luca configures on the Adyen webhook endpoint'),
|
|
36
|
+
hmac_adyen_webhook: hmacHeader('Adyen HMAC-SHA256 signature over the raw request body, verified against the configured balance platform HMAC keys'),
|
|
15
37
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lucaapp/service-utils",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.29.1",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"files": [
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"scripts": {
|
|
12
12
|
"build": "tsc -p tsconfig.build.json",
|
|
13
13
|
"ts:check": "tsc -p . --noEmit",
|
|
14
|
-
"lint": "eslint .",
|
|
14
|
+
"lint": "eslint --quiet .",
|
|
15
15
|
"test": "vitest run",
|
|
16
16
|
"test:coverage": "vitest run --coverage",
|
|
17
17
|
"test:ci": "VITEST_JUNIT_SUITE_NAME=service-utils CI=true vitest run --coverage",
|