@marinoscar/platform-api 0.1.0-next.20 → 0.1.0-next.22
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 +22 -0
- package/dist/ai/features/ai-feature.registry.d.ts +7 -0
- package/dist/ai/features/ai-feature.registry.d.ts.map +1 -1
- package/dist/ai/features/ai-feature.registry.js +3 -0
- package/dist/ai/features/ai-feature.registry.js.map +1 -1
- package/dist/ai/keys/ai-key-resolver.service.d.ts +16 -0
- package/dist/ai/keys/ai-key-resolver.service.d.ts.map +1 -1
- package/dist/ai/keys/ai-key-resolver.service.js +44 -0
- package/dist/ai/keys/ai-key-resolver.service.js.map +1 -1
- package/dist/ai/keys/usable-models.service.d.ts +13 -1
- package/dist/ai/keys/usable-models.service.d.ts.map +1 -1
- package/dist/ai/keys/usable-models.service.js +37 -12
- package/dist/ai/keys/usable-models.service.js.map +1 -1
- package/dist/ai/runtime/ai-limits.service.d.ts +2 -1
- package/dist/ai/runtime/ai-limits.service.d.ts.map +1 -1
- package/dist/ai/runtime/ai-limits.service.js +7 -2
- package/dist/ai/runtime/ai-limits.service.js.map +1 -1
- package/dist/ai/runtime/ai-runtime.types.d.ts +46 -1
- package/dist/ai/runtime/ai-runtime.types.d.ts.map +1 -1
- package/dist/ai/runtime/ai-runtime.types.js.map +1 -1
- package/dist/ai/runtime/ai.service.d.ts +142 -5
- package/dist/ai/runtime/ai.service.d.ts.map +1 -1
- package/dist/ai/runtime/ai.service.js +353 -46
- package/dist/ai/runtime/ai.service.js.map +1 -1
- package/dist/ai/runtime/index.d.ts +1 -1
- package/dist/ai/runtime/index.d.ts.map +1 -1
- package/dist/ai/runtime/target-resolver.d.ts +2 -2
- package/dist/ai/runtime/target-resolver.d.ts.map +1 -1
- package/dist/ai/runtime/target-resolver.js +2 -1
- package/dist/ai/runtime/target-resolver.js.map +1 -1
- package/dist/ai/testing/conformance/ai-key-policy.suite.d.ts.map +1 -1
- package/dist/ai/testing/conformance/ai-key-policy.suite.js +54 -0
- package/dist/ai/testing/conformance/ai-key-policy.suite.js.map +1 -1
- package/dist/ai/testing/conformance/ai-secret-egress.suite.d.ts.map +1 -1
- package/dist/ai/testing/conformance/ai-secret-egress.suite.js +59 -0
- package/dist/ai/testing/conformance/ai-secret-egress.suite.js.map +1 -1
- package/dist/identity/device-auth/device-auth.service.d.ts +9 -2
- package/dist/identity/device-auth/device-auth.service.d.ts.map +1 -1
- package/dist/identity/device-auth/device-auth.service.js +44 -4
- package/dist/identity/device-auth/device-auth.service.js.map +1 -1
- package/dist/identity/device-auth/dto/device-code-request.dto.d.ts +12 -0
- package/dist/identity/device-auth/dto/device-code-request.dto.d.ts.map +1 -1
- package/dist/identity/identity.options.d.ts +25 -0
- package/dist/identity/identity.options.d.ts.map +1 -1
- package/dist/identity/identity.options.js +11 -0
- package/dist/identity/identity.options.js.map +1 -1
- package/dist/identity/index.d.ts +1 -1
- package/dist/identity/index.d.ts.map +1 -1
- package/dist/nodes/current-node.decorator.d.ts +18 -0
- package/dist/nodes/current-node.decorator.d.ts.map +1 -0
- package/dist/nodes/current-node.decorator.js +28 -0
- package/dist/nodes/current-node.decorator.js.map +1 -0
- package/dist/nodes/index.d.ts +8 -0
- package/dist/nodes/index.d.ts.map +1 -1
- package/dist/nodes/index.js +21 -2
- package/dist/nodes/index.js.map +1 -1
- package/dist/nodes/node-ownership.d.ts +34 -0
- package/dist/nodes/node-ownership.d.ts.map +1 -0
- package/dist/nodes/node-ownership.js +92 -0
- package/dist/nodes/node-ownership.js.map +1 -0
- package/dist/nodes/node-route.decorator.d.ts +31 -0
- package/dist/nodes/node-route.decorator.d.ts.map +1 -0
- package/dist/nodes/node-route.decorator.js +54 -0
- package/dist/nodes/node-route.decorator.js.map +1 -0
- package/dist/nodes/node-route.guard.d.ts +22 -0
- package/dist/nodes/node-route.guard.d.ts.map +1 -0
- package/dist/nodes/node-route.guard.js +74 -0
- package/dist/nodes/node-route.guard.js.map +1 -0
- package/dist/nodes/node-route.module.d.ts +21 -0
- package/dist/nodes/node-route.module.d.ts.map +1 -0
- package/dist/nodes/node-route.module.js +99 -0
- package/dist/nodes/node-route.module.js.map +1 -0
- package/dist/nodes/node-route.options.d.ts +59 -0
- package/dist/nodes/node-route.options.d.ts.map +1 -0
- package/dist/nodes/node-route.options.js +29 -0
- package/dist/nodes/node-route.options.js.map +1 -0
- package/dist/nodes/node-route.paths.d.ts +47 -0
- package/dist/nodes/node-route.paths.d.ts.map +1 -0
- package/dist/nodes/node-route.paths.js +129 -0
- package/dist/nodes/node-route.paths.js.map +1 -0
- package/dist/nodes/nodes.service.d.ts.map +1 -1
- package/dist/nodes/nodes.service.js +3 -15
- package/dist/nodes/nodes.service.js.map +1 -1
- package/dist/nodes/testing/conformance.d.ts +86 -0
- package/dist/nodes/testing/conformance.d.ts.map +1 -0
- package/dist/nodes/testing/conformance.js +230 -0
- package/dist/nodes/testing/conformance.js.map +1 -0
- package/dist/nodes/testing/discover.d.ts +13 -0
- package/dist/nodes/testing/discover.d.ts.map +1 -0
- package/dist/nodes/testing/discover.js +42 -0
- package/dist/nodes/testing/discover.js.map +1 -0
- package/dist/nodes/testing/index.d.ts +3 -0
- package/dist/nodes/testing/index.d.ts.map +1 -0
- package/dist/nodes/testing/index.js +13 -0
- package/dist/nodes/testing/index.js.map +1 -0
- package/dist/webhooks/handlers/webhook-deliver.handler.d.ts.map +1 -1
- package/dist/webhooks/handlers/webhook-deliver.handler.js +3 -2
- package/dist/webhooks/handlers/webhook-deliver.handler.js.map +1 -1
- package/package.json +7 -3
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// =============================================================================
|
|
3
|
+
// Node ownership: the one rule, and the narrow provider an app route may use
|
|
4
|
+
// =============================================================================
|
|
5
|
+
//
|
|
6
|
+
// `assertNodeOwnedBy` is the rule `NodesService.assertOwnership` has always
|
|
7
|
+
// applied (404 for a node that does not exist, 403 for one that belongs to
|
|
8
|
+
// somebody else; the argument for 403 over 404 is in `nodes.service.ts`). It is
|
|
9
|
+
// extracted so the packaged control plane and the `@NodeRoute()` guard cannot
|
|
10
|
+
// drift into two opinions about who owns a node.
|
|
11
|
+
//
|
|
12
|
+
// `NodeOwnershipService` exists because `NodesService` is deliberately NOT
|
|
13
|
+
// exported from `NodesModule` (a feature module that could inject it could
|
|
14
|
+
// claim jobs or settle them outside the terminal chokepoint). This is the
|
|
15
|
+
// least-privilege handle: one method, read-only.
|
|
16
|
+
// =============================================================================
|
|
17
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
18
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
19
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
20
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
21
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
22
|
+
};
|
|
23
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
24
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
25
|
+
};
|
|
26
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
27
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
28
|
+
};
|
|
29
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
30
|
+
exports.NodeOwnershipService = void 0;
|
|
31
|
+
exports.assertNodeOwnedBy = assertNodeOwnedBy;
|
|
32
|
+
const common_1 = require("@nestjs/common");
|
|
33
|
+
const index_1 = require("../core/index");
|
|
34
|
+
/**
|
|
35
|
+
* Loads node `nodeId` and proves `userId` owns it.
|
|
36
|
+
*
|
|
37
|
+
* @param prisma - anything with the `workerNode` delegate.
|
|
38
|
+
* @param userId - the authenticated owner.
|
|
39
|
+
* @param nodeId - the node's id.
|
|
40
|
+
* @returns the verified node row.
|
|
41
|
+
* @throws NotFoundException when the node does not exist; ForbiddenException when another user owns it.
|
|
42
|
+
*
|
|
43
|
+
* @stability stable
|
|
44
|
+
*/
|
|
45
|
+
async function assertNodeOwnedBy(prisma, userId, nodeId) {
|
|
46
|
+
const node = await prisma.workerNode.findUnique({ where: { id: nodeId } });
|
|
47
|
+
if (!node) {
|
|
48
|
+
throw new common_1.NotFoundException({
|
|
49
|
+
message: `Worker node ${nodeId} was not found.`,
|
|
50
|
+
details: { nodeId },
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
if (node.createdById !== userId) {
|
|
54
|
+
throw new common_1.ForbiddenException({
|
|
55
|
+
message: `Worker node ${nodeId} belongs to another user. Check that this credential and ` +
|
|
56
|
+
`this node id came from the same registration.`,
|
|
57
|
+
details: { nodeId },
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
return node;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* The ownership check an app's node-plane code may inject: the same rule as
|
|
64
|
+
* the packaged control plane, with none of the rest of `NodesService`. Provided
|
|
65
|
+
* and exported by `NodeRouteModule`.
|
|
66
|
+
*
|
|
67
|
+
* @stability stable
|
|
68
|
+
*/
|
|
69
|
+
let NodeOwnershipService = class NodeOwnershipService {
|
|
70
|
+
prisma;
|
|
71
|
+
constructor(prisma) {
|
|
72
|
+
this.prisma = prisma;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Proves `userId` owns node `nodeId`.
|
|
76
|
+
*
|
|
77
|
+
* @param userId - the authenticated owner.
|
|
78
|
+
* @param nodeId - the node's id.
|
|
79
|
+
* @returns the verified node row.
|
|
80
|
+
* @throws NotFoundException (missing node) or ForbiddenException (not yours).
|
|
81
|
+
*/
|
|
82
|
+
assertOwnership(userId, nodeId) {
|
|
83
|
+
return assertNodeOwnedBy(this.prisma, userId, nodeId);
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
exports.NodeOwnershipService = NodeOwnershipService;
|
|
87
|
+
exports.NodeOwnershipService = NodeOwnershipService = __decorate([
|
|
88
|
+
(0, common_1.Injectable)(),
|
|
89
|
+
__param(0, (0, common_1.Inject)(index_1.PLATFORM_PRISMA)),
|
|
90
|
+
__metadata("design:paramtypes", [Object])
|
|
91
|
+
], NodeOwnershipService);
|
|
92
|
+
//# sourceMappingURL=node-ownership.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node-ownership.js","sourceRoot":"","sources":["../../src/nodes/node-ownership.ts"],"names":[],"mappings":";AAAA,gFAAgF;AAChF,6EAA6E;AAC7E,gFAAgF;AAChF,EAAE;AACF,4EAA4E;AAC5E,2EAA2E;AAC3E,gFAAgF;AAChF,8EAA8E;AAC9E,iDAAiD;AACjD,EAAE;AACF,2EAA2E;AAC3E,2EAA2E;AAC3E,0EAA0E;AAC1E,iDAAiD;AACjD,gFAAgF;;;;;;;;;;;;;;;AAkBhF,8CAoBC;AApCD,2CAA2F;AAE3F,yCAAgD;AAGhD;;;;;;;;;;GAUG;AACI,KAAK,UAAU,iBAAiB,CAAC,MAAsC,EAAE,MAAc,EAAE,MAAc;IAC5G,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC;IAE3E,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,IAAI,0BAAiB,CAAC;YAC1B,OAAO,EAAE,eAAe,MAAM,iBAAiB;YAC/C,OAAO,EAAE,EAAE,MAAM,EAAE;SACpB,CAAC,CAAC;IACL,CAAC;IAED,IAAI,IAAI,CAAC,WAAW,KAAK,MAAM,EAAE,CAAC;QAChC,MAAM,IAAI,2BAAkB,CAAC;YAC3B,OAAO,EACL,eAAe,MAAM,2DAA2D;gBAChF,+CAA+C;YACjD,OAAO,EAAE,EAAE,MAAM,EAAE;SACpB,CAAC,CAAC;IACL,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;GAMG;AAEI,IAAM,oBAAoB,GAA1B,MAAM,oBAAoB;IACuB;IAAtD,YAAsD,MAAkB;QAAlB,WAAM,GAAN,MAAM,CAAY;IAAG,CAAC;IAE5E;;;;;;;OAOG;IACH,eAAe,CAAC,MAAc,EAAE,MAAc;QAC5C,OAAO,iBAAiB,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IACxD,CAAC;CACF,CAAA;AAdY,oDAAoB;+BAApB,oBAAoB;IADhC,IAAA,mBAAU,GAAE;IAEE,WAAA,IAAA,eAAM,EAAC,uBAAe,CAAC,CAAA;;GADzB,oBAAoB,CAchC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { type NodeRouteOptions } from './node-route.options';
|
|
2
|
+
/**
|
|
3
|
+
* Marks an app controller (or handler) as a node-plane route. Its path must be
|
|
4
|
+
* under `NODE_ROUTE_PREFIX` (`/api/nodes`) and must not overlap
|
|
5
|
+
* `RESERVED_NODE_SUBPATHS` (checked at bootstrap by `NodeRouteModule` and by
|
|
6
|
+
* the `nodes` conformance suite). The controller's module imports
|
|
7
|
+
* `NodeRouteModule`, which provides the guard.
|
|
8
|
+
*
|
|
9
|
+
* The decorator applies `@Auth({ permissions })` too, so a controller needs no
|
|
10
|
+
* separate `@Auth()`.
|
|
11
|
+
*
|
|
12
|
+
* @param options - see {@link NodeRouteOptions}.
|
|
13
|
+
* @returns a class and method decorator.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```ts
|
|
17
|
+
* @Controller('nodes/:id/reports')
|
|
18
|
+
* @NodeRoute({ credentials: ['nod'] })
|
|
19
|
+
* export class ReportsController {
|
|
20
|
+
* @Get('latest')
|
|
21
|
+
* latest(@CurrentNode() node: WorkerNode) {
|
|
22
|
+
* return this.reports.latestFor(node);
|
|
23
|
+
* }
|
|
24
|
+
* }
|
|
25
|
+
* ```
|
|
26
|
+
*
|
|
27
|
+
* @extensionPoint hook
|
|
28
|
+
* @stability experimental
|
|
29
|
+
*/
|
|
30
|
+
export declare function NodeRoute(options?: NodeRouteOptions): ClassDecorator & MethodDecorator;
|
|
31
|
+
//# sourceMappingURL=node-route.decorator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node-route.decorator.d.ts","sourceRoot":"","sources":["../../src/nodes/node-route.decorator.ts"],"names":[],"mappings":"AAkBA,OAAO,EAAgD,KAAK,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAG3G;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,SAAS,CAAC,OAAO,GAAE,gBAAqB,GAAG,cAAc,GAAG,eAAe,CAO1F"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// =============================================================================
|
|
3
|
+
// @NodeRoute(): an app route on the node plane
|
|
4
|
+
// =============================================================================
|
|
5
|
+
//
|
|
6
|
+
// WHAT IT IS. `JwtAuthGuard` is the outer fence: a `nod_` credential reaches
|
|
7
|
+
// `/api/nodes` and what is under it, nothing else. `@NodeRoute()` is the inner
|
|
8
|
+
// one an app controller mounted there opts into. It composes `@Auth()` (the
|
|
9
|
+
// platform node plane's permission, by default) with `NodeRouteGuard`, which
|
|
10
|
+
// narrows the admitted credential kinds and PROVES the caller owns the node
|
|
11
|
+
// named in the path before the handler runs, so no handler can forget to.
|
|
12
|
+
//
|
|
13
|
+
// It only narrows. It never widens what `JwtAuthGuard` admits, and the prefix
|
|
14
|
+
// allowlist stays authoritative.
|
|
15
|
+
// =============================================================================
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.NodeRoute = NodeRoute;
|
|
18
|
+
const common_1 = require("@nestjs/common");
|
|
19
|
+
const index_1 = require("../identity/index");
|
|
20
|
+
const node_route_options_1 = require("./node-route.options");
|
|
21
|
+
const node_route_guard_1 = require("./node-route.guard");
|
|
22
|
+
/**
|
|
23
|
+
* Marks an app controller (or handler) as a node-plane route. Its path must be
|
|
24
|
+
* under `NODE_ROUTE_PREFIX` (`/api/nodes`) and must not overlap
|
|
25
|
+
* `RESERVED_NODE_SUBPATHS` (checked at bootstrap by `NodeRouteModule` and by
|
|
26
|
+
* the `nodes` conformance suite). The controller's module imports
|
|
27
|
+
* `NodeRouteModule`, which provides the guard.
|
|
28
|
+
*
|
|
29
|
+
* The decorator applies `@Auth({ permissions })` too, so a controller needs no
|
|
30
|
+
* separate `@Auth()`.
|
|
31
|
+
*
|
|
32
|
+
* @param options - see {@link NodeRouteOptions}.
|
|
33
|
+
* @returns a class and method decorator.
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ```ts
|
|
37
|
+
* @Controller('nodes/:id/reports')
|
|
38
|
+
* @NodeRoute({ credentials: ['nod'] })
|
|
39
|
+
* export class ReportsController {
|
|
40
|
+
* @Get('latest')
|
|
41
|
+
* latest(@CurrentNode() node: WorkerNode) {
|
|
42
|
+
* return this.reports.latestFor(node);
|
|
43
|
+
* }
|
|
44
|
+
* }
|
|
45
|
+
* ```
|
|
46
|
+
*
|
|
47
|
+
* @extensionPoint hook
|
|
48
|
+
* @stability experimental
|
|
49
|
+
*/
|
|
50
|
+
function NodeRoute(options = {}) {
|
|
51
|
+
const resolved = (0, node_route_options_1.resolveNodeRouteOptions)(options);
|
|
52
|
+
return (0, common_1.applyDecorators)((0, common_1.SetMetadata)(node_route_options_1.NODE_ROUTE_METADATA, resolved), (0, index_1.Auth)({ permissions: [...resolved.permissions] }), (0, common_1.UseGuards)(node_route_guard_1.NodeRouteGuard));
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=node-route.decorator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node-route.decorator.js","sourceRoot":"","sources":["../../src/nodes/node-route.decorator.ts"],"names":[],"mappings":";AAAA,gFAAgF;AAChF,+CAA+C;AAC/C,gFAAgF;AAChF,EAAE;AACF,6EAA6E;AAC7E,+EAA+E;AAC/E,4EAA4E;AAC5E,6EAA6E;AAC7E,4EAA4E;AAC5E,0EAA0E;AAC1E,EAAE;AACF,8EAA8E;AAC9E,iCAAiC;AACjC,gFAAgF;;AAoChF,8BAOC;AAzCD,2CAAyE;AAEzE,6CAAyC;AACzC,6DAA2G;AAC3G,yDAAoD;AAEpD;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,SAAgB,SAAS,CAAC,UAA4B,EAAE;IACtD,MAAM,QAAQ,GAAG,IAAA,4CAAuB,EAAC,OAAO,CAAC,CAAC;IAClD,OAAO,IAAA,wBAAe,EACpB,IAAA,oBAAW,EAAC,wCAAmB,EAAE,QAAQ,CAAC,EAC1C,IAAA,YAAI,EAAC,EAAE,WAAW,EAAE,CAAC,GAAG,QAAQ,CAAC,WAAW,CAAU,EAAE,CAAC,EACzD,IAAA,kBAAS,EAAC,iCAAc,CAAC,CACU,CAAC;AACxC,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { CanActivate, ExecutionContext } from '@nestjs/common';
|
|
2
|
+
import { Reflector } from '@nestjs/core';
|
|
3
|
+
import { NodeOwnershipService } from './node-ownership';
|
|
4
|
+
/**
|
|
5
|
+
* Applied by `@NodeRoute()`, after `JwtAuthGuard`: refuses a credential kind
|
|
6
|
+
* the route did not admit (403), then, when the route names a node, loads it
|
|
7
|
+
* and proves the caller owns it (404 missing, 403 not yours; the packaged
|
|
8
|
+
* control plane's own semantics) and hands it to `@CurrentNode()`.
|
|
9
|
+
*
|
|
10
|
+
* @stability experimental
|
|
11
|
+
*/
|
|
12
|
+
export declare class NodeRouteGuard implements CanActivate {
|
|
13
|
+
private readonly reflector;
|
|
14
|
+
private readonly ownership;
|
|
15
|
+
constructor(reflector: Reflector, ownership: NodeOwnershipService);
|
|
16
|
+
/**
|
|
17
|
+
* @param context - the execution context.
|
|
18
|
+
* @returns `true` to admit; throws 400, 403 or 404 otherwise.
|
|
19
|
+
*/
|
|
20
|
+
canActivate(context: ExecutionContext): Promise<boolean>;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=node-route.guard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node-route.guard.d.ts","sourceRoot":"","sources":["../../src/nodes/node-route.guard.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,WAAW,EACX,gBAAgB,EAGjB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAKzC,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAcxD;;;;;;;GAOG;AACH,qBACa,cAAe,YAAW,WAAW;IAE9C,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,SAAS;gBADT,SAAS,EAAE,SAAS,EACpB,SAAS,EAAE,oBAAoB;IAGlD;;;OAGG;IACG,WAAW,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,OAAO,CAAC;CA8B/D"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.NodeRouteGuard = void 0;
|
|
13
|
+
const common_1 = require("@nestjs/common");
|
|
14
|
+
const core_1 = require("@nestjs/core");
|
|
15
|
+
const current_node_decorator_1 = require("./current-node.decorator");
|
|
16
|
+
const node_route_options_1 = require("./node-route.options");
|
|
17
|
+
const node_ownership_1 = require("./node-ownership");
|
|
18
|
+
const UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
19
|
+
const KIND = { node: 'nod', pat: 'pat', jwt: 'jwt' };
|
|
20
|
+
/**
|
|
21
|
+
* Applied by `@NodeRoute()`, after `JwtAuthGuard`: refuses a credential kind
|
|
22
|
+
* the route did not admit (403), then, when the route names a node, loads it
|
|
23
|
+
* and proves the caller owns it (404 missing, 403 not yours; the packaged
|
|
24
|
+
* control plane's own semantics) and hands it to `@CurrentNode()`.
|
|
25
|
+
*
|
|
26
|
+
* @stability experimental
|
|
27
|
+
*/
|
|
28
|
+
let NodeRouteGuard = class NodeRouteGuard {
|
|
29
|
+
reflector;
|
|
30
|
+
ownership;
|
|
31
|
+
constructor(reflector, ownership) {
|
|
32
|
+
this.reflector = reflector;
|
|
33
|
+
this.ownership = ownership;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* @param context - the execution context.
|
|
37
|
+
* @returns `true` to admit; throws 400, 403 or 404 otherwise.
|
|
38
|
+
*/
|
|
39
|
+
async canActivate(context) {
|
|
40
|
+
const options = this.reflector.getAllAndOverride(node_route_options_1.NODE_ROUTE_METADATA, [
|
|
41
|
+
context.getHandler(),
|
|
42
|
+
context.getClass(),
|
|
43
|
+
]);
|
|
44
|
+
// Unreachable through the decorator; fail closed rather than admit.
|
|
45
|
+
if (!options)
|
|
46
|
+
throw new common_1.ForbiddenException('Route is not a declared node route.');
|
|
47
|
+
const request = context.switchToHttp().getRequest();
|
|
48
|
+
const credential = request.authCredential ? KIND[request.authCredential.kind] : undefined;
|
|
49
|
+
if (!credential || !options.credentials.includes(credential)) {
|
|
50
|
+
throw new common_1.ForbiddenException({
|
|
51
|
+
message: 'This credential kind is not accepted on this route.',
|
|
52
|
+
details: { accepted: [...options.credentials] },
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
if (options.nodeParam === false)
|
|
56
|
+
return true;
|
|
57
|
+
const userId = (request.requestUser ?? request.user)?.id;
|
|
58
|
+
if (!userId)
|
|
59
|
+
throw new common_1.ForbiddenException('No user in request');
|
|
60
|
+
const nodeId = request.params?.[options.nodeParam];
|
|
61
|
+
if (!nodeId || !UUID.test(nodeId)) {
|
|
62
|
+
throw new common_1.BadRequestException({ message: `Route parameter "${options.nodeParam}" must be a node id (uuid).` });
|
|
63
|
+
}
|
|
64
|
+
request[current_node_decorator_1.NODE_ROUTE_REQUEST_KEY] = await this.ownership.assertOwnership(userId, nodeId);
|
|
65
|
+
return true;
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
exports.NodeRouteGuard = NodeRouteGuard;
|
|
69
|
+
exports.NodeRouteGuard = NodeRouteGuard = __decorate([
|
|
70
|
+
(0, common_1.Injectable)(),
|
|
71
|
+
__metadata("design:paramtypes", [core_1.Reflector,
|
|
72
|
+
node_ownership_1.NodeOwnershipService])
|
|
73
|
+
], NodeRouteGuard);
|
|
74
|
+
//# sourceMappingURL=node-route.guard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node-route.guard.js","sourceRoot":"","sources":["../../src/nodes/node-route.guard.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAMwB;AACxB,uCAAyC;AAGzC,qEAAkE;AAClE,6DAAoH;AACpH,qDAAwD;AAExD,MAAM,IAAI,GAAG,iEAAiE,CAAC;AAU/E,MAAM,IAAI,GAA4D,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC;AAE9G;;;;;;;GAOG;AAEI,IAAM,cAAc,GAApB,MAAM,cAAc;IAEN;IACA;IAFnB,YACmB,SAAoB,EACpB,SAA+B;QAD/B,cAAS,GAAT,SAAS,CAAW;QACpB,cAAS,GAAT,SAAS,CAAsB;IAC/C,CAAC;IAEJ;;;OAGG;IACH,KAAK,CAAC,WAAW,CAAC,OAAyB;QACzC,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,iBAAiB,CAAuC,wCAAmB,EAAE;YAC1G,OAAO,CAAC,UAAU,EAAE;YACpB,OAAO,CAAC,QAAQ,EAAE;SACnB,CAAC,CAAC;QACH,oEAAoE;QACpE,IAAI,CAAC,OAAO;YAAE,MAAM,IAAI,2BAAkB,CAAC,qCAAqC,CAAC,CAAC;QAElF,MAAM,OAAO,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,UAAU,EAAoB,CAAC;QACtE,MAAM,UAAU,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAC1F,IAAI,CAAC,UAAU,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;YAC7D,MAAM,IAAI,2BAAkB,CAAC;gBAC3B,OAAO,EAAE,qDAAqD;gBAC9D,OAAO,EAAE,EAAE,QAAQ,EAAE,CAAC,GAAG,OAAO,CAAC,WAAW,CAAC,EAAE;aAChD,CAAC,CAAC;QACL,CAAC;QAED,IAAI,OAAO,CAAC,SAAS,KAAK,KAAK;YAAE,OAAO,IAAI,CAAC;QAE7C,MAAM,MAAM,GAAG,CAAC,OAAO,CAAC,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;QACzD,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,2BAAkB,CAAC,oBAAoB,CAAC,CAAC;QAEhE,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QACnD,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;YAClC,MAAM,IAAI,4BAAmB,CAAC,EAAE,OAAO,EAAE,oBAAoB,OAAO,CAAC,SAAS,6BAA6B,EAAE,CAAC,CAAC;QACjH,CAAC;QAED,OAAO,CAAC,+CAAsB,CAAC,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,eAAe,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACvF,OAAO,IAAI,CAAC;IACd,CAAC;CACF,CAAA;AAxCY,wCAAc;yBAAd,cAAc;IAD1B,IAAA,mBAAU,GAAE;qCAGmB,gBAAS;QACT,qCAAoB;GAHvC,cAAc,CAwC1B"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { Type } from '@nestjs/common';
|
|
2
|
+
/**
|
|
3
|
+
* The problems with the `@NodeRoute()` controllers given, one message each.
|
|
4
|
+
*
|
|
5
|
+
* @param controllers - controller classes.
|
|
6
|
+
* @returns the violations; empty when every node route is placed correctly.
|
|
7
|
+
*
|
|
8
|
+
* @stability experimental
|
|
9
|
+
*/
|
|
10
|
+
export declare function findNodeRoutePlacementProblems(controllers: ReadonlyArray<Type<unknown>>): string[];
|
|
11
|
+
/**
|
|
12
|
+
* Provides and exports `NodeRouteGuard` and `NodeOwnershipService`, and runs the
|
|
13
|
+
* placement check at bootstrap. Import it where a `@NodeRoute()` controller is
|
|
14
|
+
* declared.
|
|
15
|
+
*
|
|
16
|
+
* @extensionPoint component
|
|
17
|
+
* @stability experimental
|
|
18
|
+
*/
|
|
19
|
+
export declare class NodeRouteModule {
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=node-route.module.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node-route.module.d.ts","sourceRoot":"","sources":["../../src/nodes/node-route.module.ts"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAE3C;;;;;;;GAOG;AACH,wBAAgB,8BAA8B,CAAC,WAAW,EAAE,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,GAAG,MAAM,EAAE,CAkBlG;AAkBD;;;;;;;GAOG;AACH,qBAKa,eAAe;CAAG"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// =============================================================================
|
|
3
|
+
// NodeRouteModule: what a feature module imports to use @NodeRoute()
|
|
4
|
+
// =============================================================================
|
|
5
|
+
//
|
|
6
|
+
// `NodesModule` does not export `NodesService` (a feature module that could
|
|
7
|
+
// inject it could claim and settle jobs). This module is the narrow door: it
|
|
8
|
+
// provides `NodeRouteGuard` (the guard `@NodeRoute()` applies is instantiated
|
|
9
|
+
// in the module of the controller that uses it) and `NodeOwnershipService`
|
|
10
|
+
// (the ownership rule alone), and it fails the application at bootstrap when a
|
|
11
|
+
// `@NodeRoute()` controller sits outside `/api/nodes` or overlaps a reserved
|
|
12
|
+
// sub-path. Import it in each module that declares a node route controller.
|
|
13
|
+
// =============================================================================
|
|
14
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
15
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
16
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
17
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
18
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
19
|
+
};
|
|
20
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
21
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
22
|
+
};
|
|
23
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
24
|
+
exports.NodeRouteModule = void 0;
|
|
25
|
+
exports.findNodeRoutePlacementProblems = findNodeRoutePlacementProblems;
|
|
26
|
+
const common_1 = require("@nestjs/common");
|
|
27
|
+
const core_1 = require("@nestjs/core");
|
|
28
|
+
const index_1 = require("../identity/index");
|
|
29
|
+
const node_route_options_1 = require("./node-route.options");
|
|
30
|
+
const node_route_paths_1 = require("./node-route.paths");
|
|
31
|
+
const node_ownership_1 = require("./node-ownership");
|
|
32
|
+
const node_route_guard_1 = require("./node-route.guard");
|
|
33
|
+
/**
|
|
34
|
+
* The problems with the `@NodeRoute()` controllers given, one message each.
|
|
35
|
+
*
|
|
36
|
+
* @param controllers - controller classes.
|
|
37
|
+
* @returns the violations; empty when every node route is placed correctly.
|
|
38
|
+
*
|
|
39
|
+
* @stability experimental
|
|
40
|
+
*/
|
|
41
|
+
function findNodeRoutePlacementProblems(controllers) {
|
|
42
|
+
const problems = [];
|
|
43
|
+
for (const controller of controllers) {
|
|
44
|
+
const classDeclared = Reflect.getMetadata(node_route_options_1.NODE_ROUTE_METADATA, controller) !== undefined;
|
|
45
|
+
for (const route of (0, node_route_paths_1.controllerRoutes)(controller)) {
|
|
46
|
+
const handler = controller.prototype[route.handler];
|
|
47
|
+
if (!classDeclared && Reflect.getMetadata(node_route_options_1.NODE_ROUTE_METADATA, handler) === undefined)
|
|
48
|
+
continue;
|
|
49
|
+
if (route.nodeSegments === null) {
|
|
50
|
+
problems.push(`${route.id} is a @NodeRoute() but its path "/${route.path}" is not under ${index_1.NODE_ROUTE_PREFIX}.`);
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
const reserved = (0, node_route_paths_1.reservedNodeSubpathOverlap)(route.nodeSegments);
|
|
54
|
+
if (reserved !== null) {
|
|
55
|
+
problems.push(`${route.id} (${index_1.NODE_ROUTE_PREFIX}/${route.nodeSegments.join('/')}) overlaps the platform-reserved sub-path "${reserved}".`);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return problems;
|
|
60
|
+
}
|
|
61
|
+
let NodeRoutePlacementCheck = class NodeRoutePlacementCheck {
|
|
62
|
+
discovery;
|
|
63
|
+
constructor(discovery) {
|
|
64
|
+
this.discovery = discovery;
|
|
65
|
+
}
|
|
66
|
+
onApplicationBootstrap() {
|
|
67
|
+
const controllers = this.discovery
|
|
68
|
+
.getControllers()
|
|
69
|
+
.map((wrapper) => wrapper.metatype)
|
|
70
|
+
.filter((type) => typeof type === 'function');
|
|
71
|
+
const problems = findNodeRoutePlacementProblems(controllers);
|
|
72
|
+
if (problems.length > 0) {
|
|
73
|
+
throw new Error(`Invalid @NodeRoute() placement:\n- ${problems.join('\n- ')}`);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
NodeRoutePlacementCheck = __decorate([
|
|
78
|
+
(0, common_1.Injectable)(),
|
|
79
|
+
__metadata("design:paramtypes", [core_1.DiscoveryService])
|
|
80
|
+
], NodeRoutePlacementCheck);
|
|
81
|
+
/**
|
|
82
|
+
* Provides and exports `NodeRouteGuard` and `NodeOwnershipService`, and runs the
|
|
83
|
+
* placement check at bootstrap. Import it where a `@NodeRoute()` controller is
|
|
84
|
+
* declared.
|
|
85
|
+
*
|
|
86
|
+
* @extensionPoint component
|
|
87
|
+
* @stability experimental
|
|
88
|
+
*/
|
|
89
|
+
let NodeRouteModule = class NodeRouteModule {
|
|
90
|
+
};
|
|
91
|
+
exports.NodeRouteModule = NodeRouteModule;
|
|
92
|
+
exports.NodeRouteModule = NodeRouteModule = __decorate([
|
|
93
|
+
(0, common_1.Module)({
|
|
94
|
+
imports: [core_1.DiscoveryModule],
|
|
95
|
+
providers: [node_ownership_1.NodeOwnershipService, node_route_guard_1.NodeRouteGuard, NodeRoutePlacementCheck],
|
|
96
|
+
exports: [node_ownership_1.NodeOwnershipService, node_route_guard_1.NodeRouteGuard],
|
|
97
|
+
})
|
|
98
|
+
], NodeRouteModule);
|
|
99
|
+
//# sourceMappingURL=node-route.module.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node-route.module.js","sourceRoot":"","sources":["../../src/nodes/node-route.module.ts"],"names":[],"mappings":";AAAA,gFAAgF;AAChF,qEAAqE;AACrE,gFAAgF;AAChF,EAAE;AACF,4EAA4E;AAC5E,6EAA6E;AAC7E,8EAA8E;AAC9E,2EAA2E;AAC3E,+EAA+E;AAC/E,6EAA6E;AAC7E,4EAA4E;AAC5E,gFAAgF;;;;;;;;;;;;AAoBhF,wEAkBC;AApCD,2CAA4E;AAC5E,uCAAiE;AAEjE,6CAAsD;AACtD,6DAA2D;AAC3D,yDAAkF;AAClF,qDAAwD;AACxD,yDAAoD;AAGpD;;;;;;;GAOG;AACH,SAAgB,8BAA8B,CAAC,WAAyC;IACtF,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE,CAAC;QACrC,MAAM,aAAa,GAAG,OAAO,CAAC,WAAW,CAAC,wCAAmB,EAAE,UAAU,CAAC,KAAK,SAAS,CAAC;QACzF,KAAK,MAAM,KAAK,IAAI,IAAA,mCAAgB,EAAC,UAAU,CAAC,EAAE,CAAC;YACjD,MAAM,OAAO,GAAI,UAAU,CAAC,SAAqC,CAAC,KAAK,CAAC,OAAO,CAAW,CAAC;YAC3F,IAAI,CAAC,aAAa,IAAI,OAAO,CAAC,WAAW,CAAC,wCAAmB,EAAE,OAAO,CAAC,KAAK,SAAS;gBAAE,SAAS;YAChG,IAAI,KAAK,CAAC,YAAY,KAAK,IAAI,EAAE,CAAC;gBAChC,QAAQ,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,EAAE,qCAAqC,KAAK,CAAC,IAAI,kBAAkB,yBAAiB,GAAG,CAAC,CAAC;gBAChH,SAAS;YACX,CAAC;YACD,MAAM,QAAQ,GAAG,IAAA,6CAA0B,EAAC,KAAK,CAAC,YAAY,CAAC,CAAC;YAChE,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;gBACtB,QAAQ,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,EAAE,KAAK,yBAAiB,IAAI,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,8CAA8C,QAAQ,IAAI,CAAC,CAAC;YAC7I,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,IACM,uBAAuB,GAD7B,MACM,uBAAuB;IACE;IAA7B,YAA6B,SAA2B;QAA3B,cAAS,GAAT,SAAS,CAAkB;IAAG,CAAC;IAE5D,sBAAsB;QACpB,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS;aAC/B,cAAc,EAAE;aAChB,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,QAAgC,CAAC;aAC1D,MAAM,CAAC,CAAC,IAAI,EAAyB,EAAE,CAAC,OAAO,IAAI,KAAK,UAAU,CAAC,CAAC;QACvE,MAAM,QAAQ,GAAG,8BAA8B,CAAC,WAAW,CAAC,CAAC;QAC7D,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxB,MAAM,IAAI,KAAK,CAAC,sCAAsC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACjF,CAAC;IACH,CAAC;CACF,CAAA;AAbK,uBAAuB;IAD5B,IAAA,mBAAU,GAAE;qCAE6B,uBAAgB;GADpD,uBAAuB,CAa5B;AAED;;;;;;;GAOG;AAMI,IAAM,eAAe,GAArB,MAAM,eAAe;CAAG,CAAA;AAAlB,0CAAe;0BAAf,eAAe;IAL3B,IAAA,eAAM,EAAC;QACN,OAAO,EAAE,CAAC,sBAAe,CAAC;QAC1B,SAAS,EAAE,CAAC,qCAAoB,EAAE,iCAAc,EAAE,uBAAuB,CAAC;QAC1E,OAAO,EAAE,CAAC,qCAAoB,EAAE,iCAAc,CAAC;KAChD,CAAC;GACW,eAAe,CAAG"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The credential kinds a node route can admit: `nod` (a worker-node
|
|
3
|
+
* credential), `pat` (a personal access token) and `jwt` (a session token).
|
|
4
|
+
*
|
|
5
|
+
* @stability stable
|
|
6
|
+
*/
|
|
7
|
+
export type NodeRouteCredential = 'nod' | 'pat' | 'jwt';
|
|
8
|
+
/**
|
|
9
|
+
* Options of {@link NodeRoute}.
|
|
10
|
+
*
|
|
11
|
+
* @stability stable
|
|
12
|
+
*/
|
|
13
|
+
export interface NodeRouteOptions {
|
|
14
|
+
/**
|
|
15
|
+
* Credential kinds admitted. Default `['nod', 'pat', 'jwt']`, as on the
|
|
16
|
+
* platform's own node routes. `['nod']` makes the route node-only: a human's
|
|
17
|
+
* PAT or session is refused with 403.
|
|
18
|
+
*/
|
|
19
|
+
credentials?: ReadonlyArray<NodeRouteCredential>;
|
|
20
|
+
/**
|
|
21
|
+
* The route parameter holding the node id; node ownership is enforced before
|
|
22
|
+
* the handler runs. Default `'id'`. `false` for a route that names no node
|
|
23
|
+
* (it then has no `CurrentNode()`).
|
|
24
|
+
*/
|
|
25
|
+
nodeParam?: string | false;
|
|
26
|
+
/** Permissions required, as `@Auth({ permissions })`. Default `['nodes:write']`, the platform node plane's. */
|
|
27
|
+
permissions?: string[];
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* The options of a node route with the defaults applied.
|
|
31
|
+
*
|
|
32
|
+
* @stability experimental
|
|
33
|
+
*/
|
|
34
|
+
export interface ResolvedNodeRouteOptions {
|
|
35
|
+
/** The admitted credential kinds. */
|
|
36
|
+
readonly credentials: ReadonlyArray<NodeRouteCredential>;
|
|
37
|
+
/** The route parameter holding the node id, or `false`. */
|
|
38
|
+
readonly nodeParam: string | false;
|
|
39
|
+
/** The permissions required. */
|
|
40
|
+
readonly permissions: readonly string[];
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Metadata key under which {@link NodeRoute} records its resolved options.
|
|
44
|
+
*
|
|
45
|
+
* @stability experimental
|
|
46
|
+
*/
|
|
47
|
+
export declare const NODE_ROUTE_METADATA = "platform:node-route";
|
|
48
|
+
/** The default admitted credential kinds. */
|
|
49
|
+
export declare const DEFAULT_NODE_ROUTE_CREDENTIALS: ReadonlyArray<NodeRouteCredential>;
|
|
50
|
+
/**
|
|
51
|
+
* Resolves the options a route declared against the defaults.
|
|
52
|
+
*
|
|
53
|
+
* @param options - what was passed to {@link NodeRoute}.
|
|
54
|
+
* @returns the effective options.
|
|
55
|
+
*
|
|
56
|
+
* @stability experimental
|
|
57
|
+
*/
|
|
58
|
+
export declare function resolveNodeRouteOptions(options?: NodeRouteOptions): ResolvedNodeRouteOptions;
|
|
59
|
+
//# sourceMappingURL=node-route.options.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node-route.options.d.ts","sourceRoot":"","sources":["../../src/nodes/node-route.options.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,MAAM,MAAM,mBAAmB,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,CAAC;AAExD;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;;;OAIG;IACH,WAAW,CAAC,EAAE,aAAa,CAAC,mBAAmB,CAAC,CAAC;IACjD;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IAC3B,+GAA+G;IAC/G,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CACxB;AAED;;;;GAIG;AACH,MAAM,WAAW,wBAAwB;IACvC,qCAAqC;IACrC,QAAQ,CAAC,WAAW,EAAE,aAAa,CAAC,mBAAmB,CAAC,CAAC;IACzD,2DAA2D;IAC3D,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,KAAK,CAAC;IACnC,gCAAgC;IAChC,QAAQ,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;CACzC;AAED;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,wBAAwB,CAAC;AAEzD,6CAA6C;AAC7C,eAAO,MAAM,8BAA8B,EAAE,aAAa,CAAC,mBAAmB,CAAwC,CAAC;AAEvH;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,GAAE,gBAAqB,GAAG,wBAAwB,CAMhG"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DEFAULT_NODE_ROUTE_CREDENTIALS = exports.NODE_ROUTE_METADATA = void 0;
|
|
4
|
+
exports.resolveNodeRouteOptions = resolveNodeRouteOptions;
|
|
5
|
+
const nodes_permissions_1 = require("./nodes.permissions");
|
|
6
|
+
/**
|
|
7
|
+
* Metadata key under which {@link NodeRoute} records its resolved options.
|
|
8
|
+
*
|
|
9
|
+
* @stability experimental
|
|
10
|
+
*/
|
|
11
|
+
exports.NODE_ROUTE_METADATA = 'platform:node-route';
|
|
12
|
+
/** The default admitted credential kinds. */
|
|
13
|
+
exports.DEFAULT_NODE_ROUTE_CREDENTIALS = Object.freeze(['nod', 'pat', 'jwt']);
|
|
14
|
+
/**
|
|
15
|
+
* Resolves the options a route declared against the defaults.
|
|
16
|
+
*
|
|
17
|
+
* @param options - what was passed to {@link NodeRoute}.
|
|
18
|
+
* @returns the effective options.
|
|
19
|
+
*
|
|
20
|
+
* @stability experimental
|
|
21
|
+
*/
|
|
22
|
+
function resolveNodeRouteOptions(options = {}) {
|
|
23
|
+
return {
|
|
24
|
+
credentials: options.credentials && options.credentials.length > 0 ? [...options.credentials] : exports.DEFAULT_NODE_ROUTE_CREDENTIALS,
|
|
25
|
+
nodeParam: options.nodeParam === undefined ? 'id' : options.nodeParam,
|
|
26
|
+
permissions: options.permissions ?? [nodes_permissions_1.NODES_PERMISSIONS.NODES_WRITE.id],
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=node-route.options.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node-route.options.js","sourceRoot":"","sources":["../../src/nodes/node-route.options.ts"],"names":[],"mappings":";;;AAgEA,0DAMC;AAtED,2DAAwD;AA8CxD;;;;GAIG;AACU,QAAA,mBAAmB,GAAG,qBAAqB,CAAC;AAEzD,6CAA6C;AAChC,QAAA,8BAA8B,GAAuC,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;AAEvH;;;;;;;GAOG;AACH,SAAgB,uBAAuB,CAAC,UAA4B,EAAE;IACpE,OAAO;QACL,WAAW,EAAE,OAAO,CAAC,WAAW,IAAI,OAAO,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,sCAA8B;QAC9H,SAAS,EAAE,OAAO,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS;QACrE,WAAW,EAAE,OAAO,CAAC,WAAW,IAAI,CAAC,qCAAiB,CAAC,WAAW,CAAC,EAAE,CAAC;KACvE,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { Type } from '@nestjs/common';
|
|
2
|
+
/**
|
|
3
|
+
* The sub-paths of `/api/nodes` the platform owns, relative to the collection,
|
|
4
|
+
* with `:param` for a path parameter. `''` is the collection itself; a trailing
|
|
5
|
+
* `/*` reserves everything beneath. A `@NodeRoute()` route that overlaps one
|
|
6
|
+
* (a parameter overlaps a literal, the HTTP method is ignored) fails at
|
|
7
|
+
* bootstrap and in the `nodes` conformance suite. Mount an app feature on a
|
|
8
|
+
* sub-path NOT listed here, for example `nodes/:id/<feature>/...`.
|
|
9
|
+
*
|
|
10
|
+
* @stability stable
|
|
11
|
+
*/
|
|
12
|
+
export declare const RESERVED_NODE_SUBPATHS: readonly string[];
|
|
13
|
+
/**
|
|
14
|
+
* One route of a controller, as the node-route checks see it.
|
|
15
|
+
*
|
|
16
|
+
* @stability experimental
|
|
17
|
+
*/
|
|
18
|
+
export interface NodeControllerRoute {
|
|
19
|
+
/** `Controller#handler`. */
|
|
20
|
+
readonly id: string;
|
|
21
|
+
/** The handler's method name. */
|
|
22
|
+
readonly handler: string;
|
|
23
|
+
/** The full path without the global prefix, for example `nodes/:id/backup/changes`. */
|
|
24
|
+
readonly path: string;
|
|
25
|
+
/** The segments of `path` after the `nodes` collection, for example `[':id', 'backup', 'changes']`; `null` when the route is not under `/api/nodes`. */
|
|
26
|
+
readonly nodeSegments: readonly string[] | null;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Every route of `controller` with its full path. A leading `api` segment (the
|
|
30
|
+
* global prefix) is dropped, so `api/nodes/x` and `nodes/x` read the same.
|
|
31
|
+
*
|
|
32
|
+
* @param controller - a controller class.
|
|
33
|
+
* @returns one entry per handler per declared path.
|
|
34
|
+
*
|
|
35
|
+
* @stability experimental
|
|
36
|
+
*/
|
|
37
|
+
export declare function controllerRoutes(controller: Type<unknown>): NodeControllerRoute[];
|
|
38
|
+
/**
|
|
39
|
+
* The reserved sub-path a route overlaps, or `null`.
|
|
40
|
+
*
|
|
41
|
+
* @param nodeSegments - the route's segments after `nodes`.
|
|
42
|
+
* @returns the entry of {@link RESERVED_NODE_SUBPATHS} it collides with.
|
|
43
|
+
*
|
|
44
|
+
* @stability stable
|
|
45
|
+
*/
|
|
46
|
+
export declare function reservedNodeSubpathOverlap(nodeSegments: readonly string[]): string | null;
|
|
47
|
+
//# sourceMappingURL=node-route.paths.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node-route.paths.d.ts","sourceRoot":"","sources":["../../src/nodes/node-route.paths.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAK3C;;;;;;;;;GASG;AACH,eAAO,MAAM,sBAAsB,EAAE,SAAS,MAAM,EAYlD,CAAC;AAEH;;;;GAIG;AACH,MAAM,WAAW,mBAAmB;IAClC,4BAA4B;IAC5B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,iCAAiC;IACjC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,uFAAuF;IACvF,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,wJAAwJ;IACxJ,QAAQ,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAAC;CACjD;AAeD;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,mBAAmB,EAAE,CAyBjF;AAmBD;;;;;;;GAOG;AACH,wBAAgB,0BAA0B,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,GAAG,IAAI,CAUzF"}
|