openxiangda-nest 2.0.0-alpha.100

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.
Files changed (106) hide show
  1. package/README.md +158 -0
  2. package/dist/application-credentials.d.ts +19 -0
  3. package/dist/application-credentials.d.ts.map +1 -0
  4. package/dist/application-credentials.js +158 -0
  5. package/dist/application-credentials.js.map +1 -0
  6. package/dist/assignee-provider.d.ts +35 -0
  7. package/dist/assignee-provider.d.ts.map +1 -0
  8. package/dist/assignee-provider.js +223 -0
  9. package/dist/assignee-provider.js.map +1 -0
  10. package/dist/authz.d.ts +28 -0
  11. package/dist/authz.d.ts.map +1 -0
  12. package/dist/authz.js +207 -0
  13. package/dist/authz.js.map +1 -0
  14. package/dist/bootstrap.d.ts +15 -0
  15. package/dist/bootstrap.d.ts.map +1 -0
  16. package/dist/bootstrap.js +40 -0
  17. package/dist/bootstrap.js.map +1 -0
  18. package/dist/business-action-context.d.ts +14 -0
  19. package/dist/business-action-context.d.ts.map +1 -0
  20. package/dist/business-action-context.js +41 -0
  21. package/dist/business-action-context.js.map +1 -0
  22. package/dist/business-directory.d.ts +14 -0
  23. package/dist/business-directory.d.ts.map +1 -0
  24. package/dist/business-directory.js +40 -0
  25. package/dist/business-directory.js.map +1 -0
  26. package/dist/business-notification.d.ts +23 -0
  27. package/dist/business-notification.d.ts.map +1 -0
  28. package/dist/business-notification.js +58 -0
  29. package/dist/business-notification.js.map +1 -0
  30. package/dist/business-process.d.ts +23 -0
  31. package/dist/business-process.d.ts.map +1 -0
  32. package/dist/business-process.js +106 -0
  33. package/dist/business-process.js.map +1 -0
  34. package/dist/data-api.d.ts +116 -0
  35. package/dist/data-api.d.ts.map +1 -0
  36. package/dist/data-api.js +248 -0
  37. package/dist/data-api.js.map +1 -0
  38. package/dist/event-context.d.ts +15 -0
  39. package/dist/event-context.d.ts.map +1 -0
  40. package/dist/event-context.js +33 -0
  41. package/dist/event-context.js.map +1 -0
  42. package/dist/event-handler.d.ts +36 -0
  43. package/dist/event-handler.d.ts.map +1 -0
  44. package/dist/event-handler.js +174 -0
  45. package/dist/event-handler.js.map +1 -0
  46. package/dist/events.d.ts +64 -0
  47. package/dist/events.d.ts.map +1 -0
  48. package/dist/events.js +513 -0
  49. package/dist/events.js.map +1 -0
  50. package/dist/gateway-transport.d.ts +53 -0
  51. package/dist/gateway-transport.d.ts.map +1 -0
  52. package/dist/gateway-transport.js +369 -0
  53. package/dist/gateway-transport.js.map +1 -0
  54. package/dist/health.d.ts +36 -0
  55. package/dist/health.d.ts.map +1 -0
  56. package/dist/health.js +105 -0
  57. package/dist/health.js.map +1 -0
  58. package/dist/index.d.ts +25 -0
  59. package/dist/index.d.ts.map +1 -0
  60. package/dist/index.js +25 -0
  61. package/dist/index.js.map +1 -0
  62. package/dist/infrastructure-controller.d.ts +8 -0
  63. package/dist/infrastructure-controller.d.ts.map +1 -0
  64. package/dist/infrastructure-controller.js +15 -0
  65. package/dist/infrastructure-controller.js.map +1 -0
  66. package/dist/logger.d.ts +20 -0
  67. package/dist/logger.d.ts.map +1 -0
  68. package/dist/logger.js +62 -0
  69. package/dist/logger.js.map +1 -0
  70. package/dist/module.d.ts +6 -0
  71. package/dist/module.d.ts.map +1 -0
  72. package/dist/module.js +293 -0
  73. package/dist/module.js.map +1 -0
  74. package/dist/notification.d.ts +18 -0
  75. package/dist/notification.d.ts.map +1 -0
  76. package/dist/notification.js +52 -0
  77. package/dist/notification.js.map +1 -0
  78. package/dist/platform-client.d.ts +115 -0
  79. package/dist/platform-client.d.ts.map +1 -0
  80. package/dist/platform-client.js +506 -0
  81. package/dist/platform-client.js.map +1 -0
  82. package/dist/runtime.d.ts +56 -0
  83. package/dist/runtime.d.ts.map +1 -0
  84. package/dist/runtime.js +253 -0
  85. package/dist/runtime.js.map +1 -0
  86. package/dist/standard-operations.d.ts +62 -0
  87. package/dist/standard-operations.d.ts.map +1 -0
  88. package/dist/standard-operations.js +169 -0
  89. package/dist/standard-operations.js.map +1 -0
  90. package/dist/todo.d.ts +20 -0
  91. package/dist/todo.d.ts.map +1 -0
  92. package/dist/todo.js +48 -0
  93. package/dist/todo.js.map +1 -0
  94. package/dist/tokens.d.ts +5 -0
  95. package/dist/tokens.d.ts.map +1 -0
  96. package/dist/tokens.js +5 -0
  97. package/dist/tokens.js.map +1 -0
  98. package/dist/types.d.ts +178 -0
  99. package/dist/types.d.ts.map +1 -0
  100. package/dist/types.js +2 -0
  101. package/dist/types.js.map +1 -0
  102. package/dist/workflow.d.ts +41 -0
  103. package/dist/workflow.d.ts.map +1 -0
  104. package/dist/workflow.js +97 -0
  105. package/dist/workflow.js.map +1 -0
  106. package/package.json +64 -0
package/README.md ADDED
@@ -0,0 +1,158 @@
1
+ # openxiangda-nest
2
+
3
+ NestJS integration for platform-gateway requests. The global transport guard verifies the gateway assertion and exposes `@CurrentUser()` with the verified user, role union and capability union. `@OpenXiangdaOperation()` binds typed business actions to declared capabilities.
4
+
5
+ Ordinary CRUD remains in the platform Data API. Use NestJS only for real business actions, and keep the platform as the authoritative identity and authorization owner.
6
+
7
+ A declared interactive action injects `OpenXiangdaBusinessDataApiService` (or
8
+ `OpenXiangdaStandardOperations`, which uses it). `@OpenXiangdaOperation` checks
9
+ the caller's action capability once at App API ingress. Native Data then runs
10
+ as the trusted backend for that exact application/environment without applying
11
+ the caller's ordinary resource, row and field permissions again. The platform
12
+ retains the initiating user and operation code in records, files, events and
13
+ audit. Do not author or forward an `authorizationJSON` permission mirror.
14
+
15
+ Start application backends with the canonical bootstrap so gateway signatures
16
+ are verified against the exact incoming request bytes:
17
+
18
+ ```ts
19
+ import 'reflect-metadata';
20
+ import { bootstrapOpenXiangdaApplication } from 'openxiangda-nest';
21
+ import { AppModule } from './app.module.js';
22
+
23
+ await bootstrapOpenXiangdaApplication(AppModule);
24
+ ```
25
+
26
+ Do not create a separate `NestFactory` or `FastifyAdapter` in application code.
27
+ The standard bootstrap owns raw-body capture, proxy trust, shutdown hooks, and
28
+ the runtime listen contract.
29
+
30
+ `OpenXiangdaStandardOperations` provides the default transaction patterns for
31
+ meeting interval overlap, course capacity/duplicate selection, and visitor
32
+ duplicate reservation checks. Each pattern submits one stable command to the
33
+ verified Native Data API transaction kernel. Mutable business state is never
34
+ pre-read by the application: record assertions lock their row, bounded integer
35
+ increments update derived counters, and the platform idempotency receipt is
36
+ consulted before guards or mutations.
37
+
38
+ For a verified Named Action, the SDK propagates the platform Gateway
39
+ `x-request-id` to nested platform calls automatically. Application code must
40
+ not replace it. Reuse the exact transaction payload and `idempotencyKey` after
41
+ a retryable authorization-projection readiness response; a previously
42
+ committed transaction returns its stored result with `replayed: true` without
43
+ duplicating rows or events.
44
+
45
+ Visitor duplicate detection accepts actual submitted values, not a field-name
46
+ list:
47
+
48
+ ```ts
49
+ await operations.createVisitorReservation({
50
+ reservationResourceCode: 'visitor-reservations',
51
+ duplicateMatch: {
52
+ visitorIdentityNumber: body.visitorIdentityNumber,
53
+ visitDate: body.visitDate,
54
+ },
55
+ data: body,
56
+ idempotencyKey: body.idempotencyKey,
57
+ activeStatusField: 'status',
58
+ activeStatusValues: ['pending', 'approved'],
59
+ });
60
+ ```
61
+
62
+ `duplicateMatch` must be a non-empty object. Its values and `data` come from
63
+ the same immutable request body; the application does not perform a pre-read.
64
+
65
+ ## Standard application notifications
66
+
67
+ `OpenXiangdaBusinessNotificationService.send()` is the application-facing API
68
+ inside an `@OpenXiangdaOperation`. App Gateway authorizes the current user once,
69
+ then the platform revalidates the immutable operation proof and sends as a
70
+ platform-managed application principal. The original login token never reaches
71
+ the application; the audit retains the initiating user and action. Ordinary
72
+ users do not need `app:notification2:send`.
73
+
74
+ ```ts
75
+ import {
76
+ OPENXIANGDA_NOTIFICATION_BUSINESS_SEND_V2,
77
+ } from 'openxiangda-contracts';
78
+ import { OpenXiangdaBusinessNotificationService } from 'openxiangda-nest';
79
+
80
+ await notifications.send({
81
+ schemaVersion: OPENXIANGDA_NOTIFICATION_BUSINESS_SEND_V2,
82
+ eventId: request.submittedEventId,
83
+ correlationId: `purchase:${request.id}`,
84
+ messageKey: `purchase:${request.id}:applicant`,
85
+ sourceSequence: request.revision,
86
+ state: 'informational',
87
+ recipients: [{ userId: request.applicantUserId }],
88
+ title: '采购申请已提交',
89
+ summary: '点击查看申请详情',
90
+ navigationTarget: {
91
+ kind: 'APP_ROUTE',
92
+ appCode: 'purchase_app',
93
+ routeCodes: {
94
+ desktop: 'purchase.detail',
95
+ mobile: 'purchase.detail-mobile',
96
+ },
97
+ pathParams: { id: request.id },
98
+ access: 'AUTHENTICATED',
99
+ },
100
+ idempotencyKey: `purchase:${request.id}:revision:${request.revision}`,
101
+ });
102
+ ```
103
+
104
+ The platform-owned `application.informational.standard` template renders
105
+ `title` and optional `summary`. Replaying the same `eventId` or
106
+ `idempotencyKey` returns the existing message. Reuse the same `messageKey` with
107
+ a greater `sourceSequence` and a new `idempotencyKey` to converge state.
108
+
109
+ In a signed Application Events or date-trigger handler, use
110
+ `notifications.sendFromEvent()`. Declare `recipientPaths`, `titlePath` and an
111
+ optional `summaryPath` beneath the immutable event `data`. The SDK forwards the
112
+ current event/delivery proof with an application credential; Notification Hub
113
+ verifies the active delivery and resolves recipients and presentation itself.
114
+ The event path never accepts caller-supplied recipient IDs or a user identity.
115
+
116
+ `OpenXiangdaNotificationService` remains the privileged management facade for
117
+ platform administrators that explicitly own `app:notification2:send` and need
118
+ to select an already activated template. It is not the default Named Action
119
+ path.
120
+
121
+ ## Advanced DingTalk cards
122
+
123
+ `OpenXiangdaNotificationService` exposes the opt-in DingTalk card channel. The
124
+ platform owns the robot credentials and delivery state; application code only
125
+ selects an active binding, supplies its own template ID and string parameters,
126
+ and provides a canonical authenticated detail target. This channel is not the
127
+ default Workflow notification route.
128
+
129
+ ```ts
130
+ import {
131
+ OPENXIANGDA_NOTIFICATION_DINGTALK_ADVANCED_CARD_SEND_V2,
132
+ } from 'openxiangda-contracts';
133
+ import { OpenXiangdaNotificationService } from 'openxiangda-nest';
134
+
135
+ await notifications.sendDingTalkCard({
136
+ schemaVersion: OPENXIANGDA_NOTIFICATION_DINGTALK_ADVANCED_CARD_SEND_V2,
137
+ bindingCode: 'dingtalk_card_advanced',
138
+ idempotencyKey: `purchase-created:${request.id}`,
139
+ title: '采购申请已创建',
140
+ recipients: [{ userId: approverUserId }],
141
+ cardTemplateId: 'purchase-result-v2',
142
+ cardParamMap: { applicant: request.applicantName },
143
+ navigationTarget: {
144
+ kind: 'APP_ROUTE',
145
+ appCode: 'purchase_app',
146
+ routeCodes: {
147
+ desktop: 'purchase.detail',
148
+ mobile: 'purchase.detail-mobile',
149
+ },
150
+ pathParams: { id: request.id },
151
+ access: 'AUTHENTICATED',
152
+ },
153
+ });
154
+ ```
155
+
156
+ This privileged service is request-scoped and requires the platform permission
157
+ `app:notification2:send`; recipient, parameter, URL and idempotency bounds are
158
+ enforced by Notification Hub 2.0.
@@ -0,0 +1,19 @@
1
+ import type { OpenXiangdaModuleOptions } from "./types.js";
2
+ export declare class OpenXiangdaApplicationCredentials {
3
+ private readonly options;
4
+ private readonly baseUrl;
5
+ private readonly fetch;
6
+ private cached;
7
+ private inFlight;
8
+ constructor(options: OpenXiangdaModuleOptions);
9
+ configured(): boolean;
10
+ getAuthorizationHeader(): Promise<string>;
11
+ invalidate(expectedAccessToken?: string): void;
12
+ withAuthorization<T>(operation: (authorization: string) => Promise<T>): Promise<T>;
13
+ private token;
14
+ private exchange;
15
+ private normalizedScopes;
16
+ private oauthErrorCode;
17
+ private isUnauthorized;
18
+ }
19
+ //# sourceMappingURL=application-credentials.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"application-credentials.d.ts","sourceRoot":"","sources":["../src/application-credentials.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAC;AAmB3D,qBACa,iCAAiC;IAQ1C,OAAO,CAAC,QAAQ,CAAC,OAAO;IAP1B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAiD;IACvE,OAAO,CAAC,MAAM,CAAqC;IACnD,OAAO,CAAC,QAAQ,CAA8C;gBAI3C,OAAO,EAAE,wBAAwB;IAMpD,UAAU,IAAI,OAAO;IAOf,sBAAsB,IAAI,OAAO,CAAC,MAAM,CAAC;IAI/C,UAAU,CAAC,mBAAmB,CAAC,EAAE,MAAM,GAAG,IAAI;IAUxC,iBAAiB,CAAC,CAAC,EACvB,SAAS,EAAE,CAAC,aAAa,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,GAC/C,OAAO,CAAC,CAAC,CAAC;YAYC,KAAK;YAcL,QAAQ;IAsGtB,OAAO,CAAC,gBAAgB;IAIxB,OAAO,CAAC,cAAc;IAQtB,OAAO,CAAC,cAAc;CAOvB"}
@@ -0,0 +1,158 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ 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;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __metadata = (this && this.__metadata) || function (k, v) {
8
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
+ };
10
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
11
+ return function (target, key) { decorator(target, key, paramIndex); }
12
+ };
13
+ import { Inject, Injectable } from "@nestjs/common";
14
+ import { OpenXiangdaPlatformError } from "./platform-client.js";
15
+ import { OPENXIANGDA_MODULE_OPTIONS } from "./tokens.js";
16
+ let OpenXiangdaApplicationCredentials = class OpenXiangdaApplicationCredentials {
17
+ options;
18
+ baseUrl;
19
+ fetch;
20
+ cached;
21
+ inFlight;
22
+ constructor(options) {
23
+ this.options = options;
24
+ this.baseUrl = options.platformBaseUrl.replace(/\/+$/, "");
25
+ this.fetch = options.fetch || globalThis.fetch.bind(globalThis);
26
+ }
27
+ configured() {
28
+ return Boolean(this.options.oauthClient?.clientId &&
29
+ this.options.oauthClient?.clientSecret);
30
+ }
31
+ async getAuthorizationHeader() {
32
+ return (await this.token()).authorization;
33
+ }
34
+ invalidate(expectedAccessToken) {
35
+ if (expectedAccessToken &&
36
+ this.cached?.accessToken !== expectedAccessToken) {
37
+ return;
38
+ }
39
+ this.cached = undefined;
40
+ }
41
+ async withAuthorization(operation) {
42
+ const first = await this.token();
43
+ try {
44
+ return await operation(first.authorization);
45
+ }
46
+ catch (error) {
47
+ if (!this.isUnauthorized(error))
48
+ throw error;
49
+ this.invalidate(first.accessToken);
50
+ const refreshed = await this.token();
51
+ return await operation(refreshed.authorization);
52
+ }
53
+ }
54
+ async token() {
55
+ if (this.cached && Date.now() < this.cached.refreshAt)
56
+ return this.cached;
57
+ if (this.inFlight)
58
+ return await this.inFlight;
59
+ const pending = this.exchange();
60
+ this.inFlight = pending;
61
+ try {
62
+ const token = await pending;
63
+ this.cached = token;
64
+ return token;
65
+ }
66
+ finally {
67
+ if (this.inFlight === pending)
68
+ this.inFlight = undefined;
69
+ }
70
+ }
71
+ async exchange() {
72
+ const oauth = this.options.oauthClient;
73
+ if (!oauth?.clientId || !oauth.clientSecret) {
74
+ throw new OpenXiangdaPlatformError(503, "APPLICATION_OAUTH_NOT_CONFIGURED", "OpenXiangda 应用后端尚未配置 OAuth2 Client Credentials");
75
+ }
76
+ const controller = new AbortController();
77
+ const timeout = setTimeout(() => controller.abort(), this.options.requestTimeoutMs || 5000);
78
+ try {
79
+ const body = new URLSearchParams({ grant_type: "client_credentials" });
80
+ const scopes = this.normalizedScopes(oauth.scopes);
81
+ if (scopes.length)
82
+ body.set("scope", scopes.join(" "));
83
+ const basic = Buffer.from(`${oauth.clientId}:${oauth.clientSecret}`, "utf8").toString("base64");
84
+ const response = await this.fetch(`${this.baseUrl}/openxiangda-api/v2/oauth2/token`, {
85
+ method: "POST",
86
+ signal: controller.signal,
87
+ headers: {
88
+ Accept: "application/json",
89
+ Authorization: `Basic ${basic}`,
90
+ "Content-Type": "application/x-www-form-urlencoded",
91
+ },
92
+ body: body.toString(),
93
+ });
94
+ let payload;
95
+ try {
96
+ payload = (await response.json());
97
+ }
98
+ catch {
99
+ throw new OpenXiangdaPlatformError(response.status, "APPLICATION_OAUTH_RESPONSE_INVALID", "OAuth2 token endpoint 返回的不是有效 JSON");
100
+ }
101
+ if (!response.ok || payload.error) {
102
+ throw new OpenXiangdaPlatformError(response.status || 503, this.oauthErrorCode(payload.error), String(payload.error_description || "OAuth2 token 获取失败"));
103
+ }
104
+ const accessToken = String(payload.access_token || "").trim();
105
+ const tokenType = String(payload.token_type || "").trim();
106
+ const expiresIn = Math.floor(Number(payload.expires_in));
107
+ if (!accessToken ||
108
+ tokenType.toLowerCase() !== "bearer" ||
109
+ !Number.isFinite(expiresIn) ||
110
+ expiresIn < 1) {
111
+ throw new OpenXiangdaPlatformError(502, "APPLICATION_OAUTH_RESPONSE_INVALID", "OAuth2 token endpoint 返回了无效 token");
112
+ }
113
+ const now = Date.now();
114
+ const configuredSkew = Math.max(0, Math.floor(Number(oauth.refreshSkewSeconds ?? 30)));
115
+ const refreshWindow = Math.min(configuredSkew, Math.max(0, Math.floor(expiresIn / 2)));
116
+ return {
117
+ accessToken,
118
+ authorization: `Bearer ${accessToken}`,
119
+ scope: String(payload.scope || ""),
120
+ expiresAt: now + expiresIn * 1000,
121
+ refreshAt: now + Math.max(1, expiresIn - refreshWindow) * 1000,
122
+ };
123
+ }
124
+ catch (error) {
125
+ if (error instanceof OpenXiangdaPlatformError)
126
+ throw error;
127
+ if (error?.name === "AbortError") {
128
+ throw new OpenXiangdaPlatformError(504, "APPLICATION_OAUTH_TIMEOUT", "OAuth2 token 获取超时");
129
+ }
130
+ throw new OpenXiangdaPlatformError(503, "APPLICATION_OAUTH_UNAVAILABLE", error?.message || "OAuth2 token endpoint 不可用");
131
+ }
132
+ finally {
133
+ clearTimeout(timeout);
134
+ }
135
+ }
136
+ normalizedScopes(scopes) {
137
+ return [...new Set((scopes || []).map((scope) => scope.trim()).filter(Boolean))];
138
+ }
139
+ oauthErrorCode(error) {
140
+ const normalized = String(error || "token_exchange_failed")
141
+ .toUpperCase()
142
+ .replace(/[^A-Z0-9_]/g, "_")
143
+ .slice(0, 80);
144
+ return `APPLICATION_OAUTH_${normalized || "TOKEN_EXCHANGE_FAILED"}`;
145
+ }
146
+ isUnauthorized(error) {
147
+ return ((error instanceof OpenXiangdaPlatformError && error.httpStatus === 401) ||
148
+ Number(error?.status) === 401 ||
149
+ Number(error?.statusCode) === 401);
150
+ }
151
+ };
152
+ OpenXiangdaApplicationCredentials = __decorate([
153
+ Injectable(),
154
+ __param(0, Inject(OPENXIANGDA_MODULE_OPTIONS)),
155
+ __metadata("design:paramtypes", [Object])
156
+ ], OpenXiangdaApplicationCredentials);
157
+ export { OpenXiangdaApplicationCredentials };
158
+ //# sourceMappingURL=application-credentials.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"application-credentials.js","sourceRoot":"","sources":["../src/application-credentials.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ import { OnModuleInit } from '@nestjs/common';
2
+ import { DiscoveryService, Reflector } from '@nestjs/core';
3
+ import type { WorkflowAssigneeRequest, WorkflowAssigneeResponse, WorkflowCandidatePrincipal } from 'openxiangda-contracts';
4
+ import type { OpenXiangdaModuleOptions } from './types.js';
5
+ export declare function WorkflowAssigneeProvider(code: string): ClassDecorator;
6
+ export interface WorkflowAssigneeProviderHandler {
7
+ resolve(request: WorkflowAssigneeRequest): Promise<WorkflowCandidatePrincipal[]> | WorkflowCandidatePrincipal[];
8
+ }
9
+ export declare class OpenXiangdaAssigneeProviderRegistry implements OnModuleInit {
10
+ private readonly discovery;
11
+ private readonly reflector;
12
+ private readonly handlers;
13
+ constructor(discovery: DiscoveryService, reflector: Reflector);
14
+ onModuleInit(): void;
15
+ resolve(code: string, request: WorkflowAssigneeRequest): Promise<WorkflowCandidatePrincipal[]>;
16
+ }
17
+ export declare function normalizeWorkflowCandidates(value: unknown): WorkflowCandidatePrincipal[];
18
+ export declare class OpenXiangdaAssigneeProviderReceiver {
19
+ private readonly options;
20
+ private readonly validateRequest;
21
+ constructor(options: OpenXiangdaModuleOptions);
22
+ accept(providerCode: string, headers: Record<string, string | string[] | undefined>, rawBody: Buffer | string): WorkflowAssigneeRequest;
23
+ private assertTimestamp;
24
+ private assertSignature;
25
+ private header;
26
+ }
27
+ export declare class OpenXiangdaAssigneeProviderController {
28
+ private readonly receiver;
29
+ private readonly registry;
30
+ constructor(receiver: OpenXiangdaAssigneeProviderReceiver, registry: OpenXiangdaAssigneeProviderRegistry);
31
+ resolve(providerCode: string, headers: Record<string, string | string[] | undefined>, request: {
32
+ rawBody?: Buffer;
33
+ }, body: unknown): Promise<WorkflowAssigneeResponse>;
34
+ }
35
+ //# sourceMappingURL=assignee-provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assignee-provider.d.ts","sourceRoot":"","sources":["../src/assignee-provider.ts"],"names":[],"mappings":"AACA,OAAO,EAOL,YAAY,EAMb,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE3D,OAAO,KAAK,EACV,uBAAuB,EACvB,wBAAwB,EACxB,0BAA0B,EAC3B,MAAM,uBAAuB,CAAC;AAO/B,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAC;AAI3D,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,CAMrE;AAED,MAAM,WAAW,+BAA+B;IAC9C,OAAO,CACL,OAAO,EAAE,uBAAuB,GAE9B,OAAO,CAAC,0BAA0B,EAAE,CAAC,GACrC,0BAA0B,EAAE,CAAC;CAClC;AAED,qBACa,mCAAoC,YAAW,YAAY;IAKpE,OAAO,CAAC,QAAQ,CAAC,SAAS;IAE1B,OAAO,CAAC,QAAQ,CAAC,SAAS;IAN5B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAsD;gBAI5D,SAAS,EAAE,gBAAgB,EAE3B,SAAS,EAAE,SAAS;IAGvC,YAAY;IAgBN,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,uBAAuB;CAQ7D;AAED,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,OAAO,gCAoCzD;AAED,qBACa,mCAAmC;IAS5C,OAAO,CAAC,QAAQ,CAAC,OAAO;IAR1B,OAAO,CAAC,QAAQ,CAAC,eAAe,CAIU;gBAIvB,OAAO,EAAE,wBAAwB;IAGpD,MAAM,CACJ,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,EACtD,OAAO,EAAE,MAAM,GAAG,MAAM,GACvB,uBAAuB;IAkC1B,OAAO,CAAC,eAAe;IAcvB,OAAO,CAAC,eAAe;IA+BvB,OAAO,CAAC,MAAM;CAWf;AAED,qBAEa,qCAAqC;IAG9C,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAEzB,OAAO,CAAC,QAAQ,CAAC,QAAQ;gBAFR,QAAQ,EAAE,mCAAmC,EAE7C,QAAQ,EAAE,mCAAmC;IAI1D,OAAO,CACY,YAAY,EAAE,MAAM,EAChC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,EAC1D,OAAO,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,EAC5B,IAAI,EAAE,OAAO,GACpB,OAAO,CAAC,wBAAwB,CAAC;CAUrC"}
@@ -0,0 +1,223 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ 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;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __metadata = (this && this.__metadata) || function (k, v) {
8
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
+ };
10
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
11
+ return function (target, key) { decorator(target, key, paramIndex); }
12
+ };
13
+ import { createHmac, timingSafeEqual } from 'node:crypto';
14
+ import { BadRequestException, Body, Controller, Headers, Inject, Injectable, Param, Post, Req, SetMetadata, UnauthorizedException, } from '@nestjs/common';
15
+ import { DiscoveryService, Reflector } from '@nestjs/core';
16
+ import { Ajv2020 } from 'ajv/dist/2020.js';
17
+ import { SCHEMA_VERSIONS, workflowAssigneeRequestSchema, } from 'openxiangda-contracts';
18
+ import { OpenXiangdaInfrastructureController } from './infrastructure-controller.js';
19
+ import { OPENXIANGDA_MODULE_OPTIONS } from './tokens.js';
20
+ const WORKFLOW_ASSIGNEE_PROVIDER = Symbol('OPENXIANGDA_WORKFLOW_ASSIGNEE_PROVIDER');
21
+ export function WorkflowAssigneeProvider(code) {
22
+ const normalized = String(code || '').trim();
23
+ if (!/^[a-z][a-z0-9]*(?:[-_][a-z0-9]+)*$/.test(normalized)) {
24
+ throw new Error('WorkflowAssigneeProvider code 不合法');
25
+ }
26
+ return SetMetadata(WORKFLOW_ASSIGNEE_PROVIDER, normalized);
27
+ }
28
+ let OpenXiangdaAssigneeProviderRegistry = class OpenXiangdaAssigneeProviderRegistry {
29
+ discovery;
30
+ reflector;
31
+ handlers = new Map();
32
+ constructor(discovery, reflector) {
33
+ this.discovery = discovery;
34
+ this.reflector = reflector;
35
+ }
36
+ onModuleInit() {
37
+ for (const wrapper of this.discovery.getProviders()) {
38
+ const code = wrapper.metatype
39
+ ? this.reflector.get(WORKFLOW_ASSIGNEE_PROVIDER, wrapper.metatype)
40
+ : undefined;
41
+ if (!code || !wrapper.instance)
42
+ continue;
43
+ if (typeof wrapper.instance.resolve !== 'function') {
44
+ throw new Error(`Workflow Assignee Provider ${code} 缺少 resolve()`);
45
+ }
46
+ if (this.handlers.has(code)) {
47
+ throw new Error(`Workflow Assignee Provider 重复: ${code}`);
48
+ }
49
+ this.handlers.set(code, wrapper.instance);
50
+ }
51
+ }
52
+ async resolve(code, request) {
53
+ const handler = this.handlers.get(code);
54
+ if (!handler) {
55
+ throw new BadRequestException(`Workflow Assignee Provider 未注册: ${code}`);
56
+ }
57
+ const candidates = await handler.resolve(request);
58
+ return normalizeWorkflowCandidates(candidates);
59
+ }
60
+ };
61
+ OpenXiangdaAssigneeProviderRegistry = __decorate([
62
+ Injectable(),
63
+ __param(0, Inject(DiscoveryService)),
64
+ __param(1, Inject(Reflector)),
65
+ __metadata("design:paramtypes", [DiscoveryService,
66
+ Reflector])
67
+ ], OpenXiangdaAssigneeProviderRegistry);
68
+ export { OpenXiangdaAssigneeProviderRegistry };
69
+ export function normalizeWorkflowCandidates(value) {
70
+ if (!Array.isArray(value) || value.length > 200) {
71
+ throw new BadRequestException('Workflow Assignee Provider 返回值不合法');
72
+ }
73
+ const unique = new Map();
74
+ for (const item of value) {
75
+ if (!item || typeof item !== 'object' || Array.isArray(item)) {
76
+ throw new BadRequestException('Workflow Assignee Provider 候选人不合法');
77
+ }
78
+ const source = item;
79
+ const userId = String(source.userId || '').trim();
80
+ const candidateSource = String(source.source || '').trim();
81
+ if (!userId || !candidateSource) {
82
+ throw new BadRequestException('Workflow Assignee Provider 候选人不合法');
83
+ }
84
+ const candidate = {
85
+ userId,
86
+ source: candidateSource,
87
+ ...(source.roleSubjectKey
88
+ ? { roleSubjectKey: String(source.roleSubjectKey).trim() }
89
+ : {}),
90
+ ...(source.roleCode
91
+ ? { roleCode: String(source.roleCode).trim() }
92
+ : {}),
93
+ ...(source.displayName
94
+ ? { displayName: String(source.displayName).trim() }
95
+ : {}),
96
+ };
97
+ unique.set([candidate.userId, candidate.roleSubjectKey || '', candidate.roleCode || ''].join('\u0000'), candidate);
98
+ }
99
+ return [...unique.values()];
100
+ }
101
+ let OpenXiangdaAssigneeProviderReceiver = class OpenXiangdaAssigneeProviderReceiver {
102
+ options;
103
+ validateRequest = new Ajv2020({
104
+ allErrors: true,
105
+ strict: false,
106
+ validateFormats: false,
107
+ }).compile(workflowAssigneeRequestSchema);
108
+ constructor(options) {
109
+ this.options = options;
110
+ }
111
+ accept(providerCode, headers, rawBody) {
112
+ const body = Buffer.isBuffer(rawBody)
113
+ ? rawBody.toString('utf8')
114
+ : String(rawBody || '');
115
+ if (!body)
116
+ throw new BadRequestException('Provider raw body 不能为空');
117
+ const headerProvider = this.header(headers, 'x-openxiangda-workflow-provider');
118
+ const timestamp = this.header(headers, 'x-openxiangda-timestamp');
119
+ const signature = this.header(headers, 'x-openxiangda-signature');
120
+ this.header(headers, 'x-openxiangda-request-id');
121
+ if (headerProvider !== providerCode) {
122
+ throw new UnauthorizedException('Provider code 与请求路径不一致');
123
+ }
124
+ this.assertTimestamp(timestamp);
125
+ this.assertSignature(providerCode, timestamp, signature, body);
126
+ let value;
127
+ try {
128
+ value = JSON.parse(body);
129
+ }
130
+ catch {
131
+ throw new BadRequestException('Provider body 不是有效 JSON');
132
+ }
133
+ const request = value;
134
+ if (!this.validateRequest(value) ||
135
+ request.providerCode !== providerCode ||
136
+ request.appCode !== this.options.appCode) {
137
+ throw new BadRequestException('Provider 请求不符合 v2.1 协议');
138
+ }
139
+ return request;
140
+ }
141
+ assertTimestamp(value) {
142
+ const timestamp = Number(value);
143
+ const maxAgeSeconds = Math.max(30, this.options.workflowAssigneeProviderMaxAgeSeconds || 300);
144
+ if (!Number.isSafeInteger(timestamp) ||
145
+ Math.abs(Math.floor(Date.now() / 1000) - timestamp) > maxAgeSeconds) {
146
+ throw new UnauthorizedException('Provider 签名时间戳无效或已过期');
147
+ }
148
+ }
149
+ assertSignature(providerCode, timestamp, value, body) {
150
+ const configured = this.options.workflowAssigneeProviderSecrets?.[providerCode];
151
+ const secrets = (Array.isArray(configured) ? configured : [configured])
152
+ .map(secret => String(secret || '').trim())
153
+ .filter(Boolean);
154
+ if (!secrets.length) {
155
+ throw new UnauthorizedException('Provider 签名密钥未配置');
156
+ }
157
+ const actual = value.startsWith('v1=') ? value.slice(3) : '';
158
+ const actualBuffer = Buffer.from(actual, 'hex');
159
+ const valid = secrets.some(secret => {
160
+ const expected = createHmac('sha256', secret)
161
+ .update(`${timestamp}.${body}`)
162
+ .digest('hex');
163
+ const expectedBuffer = Buffer.from(expected, 'hex');
164
+ return (actualBuffer.length === expectedBuffer.length &&
165
+ timingSafeEqual(actualBuffer, expectedBuffer));
166
+ });
167
+ if (!valid) {
168
+ throw new UnauthorizedException('Provider 签名无效');
169
+ }
170
+ }
171
+ header(headers, name) {
172
+ const value = headers[name] ?? headers[name.toLowerCase()];
173
+ const normalized = Array.isArray(value) ? value[0] : value;
174
+ if (!String(normalized || '').trim()) {
175
+ throw new UnauthorizedException(`缺少 Provider 请求头 ${name}`);
176
+ }
177
+ return String(normalized).trim();
178
+ }
179
+ };
180
+ OpenXiangdaAssigneeProviderReceiver = __decorate([
181
+ Injectable(),
182
+ __param(0, Inject(OPENXIANGDA_MODULE_OPTIONS)),
183
+ __metadata("design:paramtypes", [Object])
184
+ ], OpenXiangdaAssigneeProviderReceiver);
185
+ export { OpenXiangdaAssigneeProviderReceiver };
186
+ let OpenXiangdaAssigneeProviderController = class OpenXiangdaAssigneeProviderController {
187
+ receiver;
188
+ registry;
189
+ constructor(receiver, registry) {
190
+ this.receiver = receiver;
191
+ this.registry = registry;
192
+ }
193
+ async resolve(providerCode, headers, request, body) {
194
+ const rawBody = request.rawBody || Buffer.from(JSON.stringify(body));
195
+ const input = this.receiver.accept(providerCode, headers, rawBody);
196
+ const candidates = await this.registry.resolve(providerCode, input);
197
+ return {
198
+ schemaVersion: SCHEMA_VERSIONS.workflowAssigneeResponse,
199
+ requestId: input.requestId,
200
+ candidates,
201
+ };
202
+ }
203
+ };
204
+ __decorate([
205
+ Post('/:providerCode'),
206
+ __param(0, Param('providerCode')),
207
+ __param(1, Headers()),
208
+ __param(2, Req()),
209
+ __param(3, Body()),
210
+ __metadata("design:type", Function),
211
+ __metadata("design:paramtypes", [String, Object, Object, Object]),
212
+ __metadata("design:returntype", Promise)
213
+ ], OpenXiangdaAssigneeProviderController.prototype, "resolve", null);
214
+ OpenXiangdaAssigneeProviderController = __decorate([
215
+ OpenXiangdaInfrastructureController(),
216
+ Controller('/openxiangda/workflow/assignee-providers'),
217
+ __param(0, Inject(OpenXiangdaAssigneeProviderReceiver)),
218
+ __param(1, Inject(OpenXiangdaAssigneeProviderRegistry)),
219
+ __metadata("design:paramtypes", [OpenXiangdaAssigneeProviderReceiver,
220
+ OpenXiangdaAssigneeProviderRegistry])
221
+ ], OpenXiangdaAssigneeProviderController);
222
+ export { OpenXiangdaAssigneeProviderController };
223
+ //# sourceMappingURL=assignee-provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assignee-provider.js","sourceRoot":"","sources":["../src/assignee-provider.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC1D,OAAO,EACL,mBAAmB,EACnB,IAAI,EACJ,UAAU,EACV,OAAO,EACP,MAAM,EACN,UAAU,EAEV,KAAK,EACL,IAAI,EACJ,GAAG,EACH,WAAW,EACX,qBAAqB,GACtB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC3D,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAM3C,OAAO,EACL,eAAe,EACf,6BAA6B,GAC9B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,mCAAmC,EAAE,MAAM,gCAAgC,CAAC;AACrF,OAAO,EAAE,0BAA0B,EAAE,MAAM,aAAa,CAAC;AAGzD,MAAM,0BAA0B,GAAG,MAAM,CAAC,wCAAwC,CAAC,CAAC;AAEpF,MAAM,UAAU,wBAAwB,CAAC,IAAY;IACnD,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IAC7C,IAAI,CAAC,oCAAoC,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;QAC3D,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;IACvD,CAAC;IACD,OAAO,WAAW,CAAC,0BAA0B,EAAE,UAAU,CAAC,CAAC;AAC7D,CAAC;AAWM,IAAM,mCAAmC,GAAzC,MAAM,mCAAmC;IAK3B;IAEA;IANF,QAAQ,GAAG,IAAI,GAAG,EAA2C,CAAC;IAE/E,YAEmB,SAA2B,EAE3B,SAAoB;QAFpB,cAAS,GAAT,SAAS,CAAkB;QAE3B,cAAS,GAAT,SAAS,CAAW;IACpC,CAAC;IAEJ,YAAY;QACV,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,SAAS,CAAC,YAAY,EAAE,EAAE,CAAC;YACpD,MAAM,IAAI,GAAG,OAAO,CAAC,QAAQ;gBAC3B,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAS,0BAA0B,EAAE,OAAO,CAAC,QAAQ,CAAC;gBAC1E,CAAC,CAAC,SAAS,CAAC;YACd,IAAI,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,QAAQ;gBAAE,SAAS;YACzC,IAAI,OAAO,OAAO,CAAC,QAAQ,CAAC,OAAO,KAAK,UAAU,EAAE,CAAC;gBACnD,MAAM,IAAI,KAAK,CAAC,8BAA8B,IAAI,eAAe,CAAC,CAAC;YACrE,CAAC;YACD,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC5B,MAAM,IAAI,KAAK,CAAC,kCAAkC,IAAI,EAAE,CAAC,CAAC;YAC5D,CAAC;YACD,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,QAA2C,CAAC,CAAC;QAC/E,CAAC;IACH,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,IAAY,EAAE,OAAgC;QAC1D,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACxC,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,IAAI,mBAAmB,CAAC,mCAAmC,IAAI,EAAE,CAAC,CAAC;QAC3E,CAAC;QACD,MAAM,UAAU,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAClD,OAAO,2BAA2B,CAAC,UAAU,CAAC,CAAC;IACjD,CAAC;CACF,CAAA;AAlCY,mCAAmC;IAD/C,UAAU,EAAE;IAKR,WAAA,MAAM,CAAC,gBAAgB,CAAC,CAAA;IAExB,WAAA,MAAM,CAAC,SAAS,CAAC,CAAA;qCADU,gBAAgB;QAEhB,SAAS;GAP5B,mCAAmC,CAkC/C;;AAED,MAAM,UAAU,2BAA2B,CAAC,KAAc;IACxD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC;QAChD,MAAM,IAAI,mBAAmB,CAAC,mCAAmC,CAAC,CAAC;IACrE,CAAC;IACD,MAAM,MAAM,GAAG,IAAI,GAAG,EAAsC,CAAC;IAC7D,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;YAC7D,MAAM,IAAI,mBAAmB,CAAC,mCAAmC,CAAC,CAAC;QACrE,CAAC;QACD,MAAM,MAAM,GAAG,IAA2C,CAAC;QAC3D,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QAClD,MAAM,eAAe,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QAC3D,IAAI,CAAC,MAAM,IAAI,CAAC,eAAe,EAAE,CAAC;YAChC,MAAM,IAAI,mBAAmB,CAAC,mCAAmC,CAAC,CAAC;QACrE,CAAC;QACD,MAAM,SAAS,GAA+B;YAC5C,MAAM;YACN,MAAM,EAAE,eAAe;YACvB,GAAG,CAAC,MAAM,CAAC,cAAc;gBACvB,CAAC,CAAC,EAAE,cAAc,EAAE,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,IAAI,EAAE,EAAE;gBAC1D,CAAC,CAAC,EAAE,CAAC;YACP,GAAG,CAAC,MAAM,CAAC,QAAQ;gBACjB,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,IAAI,EAAE,EAAE;gBAC9C,CAAC,CAAC,EAAE,CAAC;YACP,GAAG,CAAC,MAAM,CAAC,WAAW;gBACpB,CAAC,CAAC,EAAE,WAAW,EAAE,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,IAAI,EAAE,EAAE;gBACpD,CAAC,CAAC,EAAE,CAAC;SACR,CAAC;QACF,MAAM,CAAC,GAAG,CACR,CAAC,SAAS,CAAC,MAAM,EAAE,SAAS,CAAC,cAAc,IAAI,EAAE,EAAE,SAAS,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,IAAI,CAC/E,QAAQ,CACT,EACD,SAAS,CACV,CAAC;IACJ,CAAC;IACD,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;AAC9B,CAAC;AAGM,IAAM,mCAAmC,GAAzC,MAAM,mCAAmC;IAS3B;IARF,eAAe,GAAG,IAAI,OAAO,CAAC;QAC7C,SAAS,EAAE,IAAI;QACf,MAAM,EAAE,KAAK;QACb,eAAe,EAAE,KAAK;KACvB,CAAC,CAAC,OAAO,CAAC,6BAA6B,CAAC,CAAC;IAE1C,YAEmB,OAAiC;QAAjC,YAAO,GAAP,OAAO,CAA0B;IACjD,CAAC;IAEJ,MAAM,CACJ,YAAoB,EACpB,OAAsD,EACtD,OAAwB;QAExB,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC;YACnC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;YAC1B,CAAC,CAAC,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;QAC1B,IAAI,CAAC,IAAI;YAAE,MAAM,IAAI,mBAAmB,CAAC,wBAAwB,CAAC,CAAC;QACnE,MAAM,cAAc,GAAG,IAAI,CAAC,MAAM,CAChC,OAAO,EACP,iCAAiC,CAClC,CAAC;QACF,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,yBAAyB,CAAC,CAAC;QAClE,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,yBAAyB,CAAC,CAAC;QAClE,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,0BAA0B,CAAC,CAAC;QACjD,IAAI,cAAc,KAAK,YAAY,EAAE,CAAC;YACpC,MAAM,IAAI,qBAAqB,CAAC,wBAAwB,CAAC,CAAC;QAC5D,CAAC;QACD,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC;QAChC,IAAI,CAAC,eAAe,CAAC,YAAY,EAAE,SAAS,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC;QAC/D,IAAI,KAAc,CAAC;QACnB,IAAI,CAAC;YACH,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC3B,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,IAAI,mBAAmB,CAAC,yBAAyB,CAAC,CAAC;QAC3D,CAAC;QACD,MAAM,OAAO,GAAG,KAAyC,CAAC;QAC1D,IACE,CAAC,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC;YAC5B,OAAO,CAAC,YAAY,KAAK,YAAY;YACrC,OAAO,CAAC,OAAO,KAAK,IAAI,CAAC,OAAO,CAAC,OAAO,EACxC,CAAC;YACD,MAAM,IAAI,mBAAmB,CAAC,wBAAwB,CAAC,CAAC;QAC1D,CAAC;QACD,OAAO,OAAkC,CAAC;IAC5C,CAAC;IAEO,eAAe,CAAC,KAAa;QACnC,MAAM,SAAS,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;QAChC,MAAM,aAAa,GAAG,IAAI,CAAC,GAAG,CAC5B,EAAE,EACF,IAAI,CAAC,OAAO,CAAC,qCAAqC,IAAI,GAAG,CAC1D,CAAC;QACF,IACE,CAAC,MAAM,CAAC,aAAa,CAAC,SAAS,CAAC;YAChC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,SAAS,CAAC,GAAG,aAAa,EACnE,CAAC;YACD,MAAM,IAAI,qBAAqB,CAAC,sBAAsB,CAAC,CAAC;QAC1D,CAAC;IACH,CAAC;IAEO,eAAe,CACrB,YAAoB,EACpB,SAAiB,EACjB,KAAa,EACb,IAAY;QAEZ,MAAM,UAAU,GACd,IAAI,CAAC,OAAO,CAAC,+BAA+B,EAAE,CAAC,YAAY,CAAC,CAAC;QAC/D,MAAM,OAAO,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;aACpE,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;aAC1C,MAAM,CAAC,OAAO,CAAC,CAAC;QACnB,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;YACpB,MAAM,IAAI,qBAAqB,CAAC,kBAAkB,CAAC,CAAC;QACtD,CAAC;QACD,MAAM,MAAM,GAAG,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7D,MAAM,YAAY,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QAChD,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE;YAClC,MAAM,QAAQ,GAAG,UAAU,CAAC,QAAQ,EAAE,MAAM,CAAC;iBAC1C,MAAM,CAAC,GAAG,SAAS,IAAI,IAAI,EAAE,CAAC;iBAC9B,MAAM,CAAC,KAAK,CAAC,CAAC;YACjB,MAAM,cAAc,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;YACpD,OAAO,CACL,YAAY,CAAC,MAAM,KAAK,cAAc,CAAC,MAAM;gBAC7C,eAAe,CAAC,YAAY,EAAE,cAAc,CAAC,CAC9C,CAAC;QACJ,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,MAAM,IAAI,qBAAqB,CAAC,eAAe,CAAC,CAAC;QACnD,CAAC;IACH,CAAC;IAEO,MAAM,CACZ,OAAsD,EACtD,IAAY;QAEZ,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;QAC3D,MAAM,UAAU,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;QAC3D,IAAI,CAAC,MAAM,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;YACrC,MAAM,IAAI,qBAAqB,CAAC,mBAAmB,IAAI,EAAE,CAAC,CAAC;QAC7D,CAAC;QACD,OAAO,MAAM,CAAC,UAAU,CAAC,CAAC,IAAI,EAAE,CAAC;IACnC,CAAC;CACF,CAAA;AA1GY,mCAAmC;IAD/C,UAAU,EAAE;IASR,WAAA,MAAM,CAAC,0BAA0B,CAAC,CAAA;;GAR1B,mCAAmC,CA0G/C;;AAIM,IAAM,qCAAqC,GAA3C,MAAM,qCAAqC;IAG7B;IAEA;IAJnB,YAEmB,QAA6C,EAE7C,QAA6C;QAF7C,aAAQ,GAAR,QAAQ,CAAqC;QAE7C,aAAQ,GAAR,QAAQ,CAAqC;IAC7D,CAAC;IAGE,AAAN,KAAK,CAAC,OAAO,CACY,YAAoB,EAChC,OAAsD,EAC1D,OAA6B,EAC5B,IAAa;QAErB,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;QACrE,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,YAAY,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;QACnE,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC;QACpE,OAAO;YACL,aAAa,EAAE,eAAe,CAAC,wBAAwB;YACvD,SAAS,EAAE,KAAK,CAAC,SAAS;YAC1B,UAAU;SACX,CAAC;IACJ,CAAC;CACF,CAAA;AAfO;IADL,IAAI,CAAC,gBAAgB,CAAC;IAEpB,WAAA,KAAK,CAAC,cAAc,CAAC,CAAA;IACrB,WAAA,OAAO,EAAE,CAAA;IACT,WAAA,GAAG,EAAE,CAAA;IACL,WAAA,IAAI,EAAE,CAAA;;;;oEAUR;AAvBU,qCAAqC;IAFjD,mCAAmC,EAAE;IACrC,UAAU,CAAC,0CAA0C,CAAC;IAGlD,WAAA,MAAM,CAAC,mCAAmC,CAAC,CAAA;IAE3C,WAAA,MAAM,CAAC,mCAAmC,CAAC,CAAA;qCADjB,mCAAmC;QAEnC,mCAAmC;GALrD,qCAAqC,CAwBjD"}
@@ -0,0 +1,28 @@
1
+ import { CanActivate, ExecutionContext } from "@nestjs/common";
2
+ import { Reflector } from "@nestjs/core";
3
+ import type { NativePrincipal } from "openxiangda-contracts";
4
+ import type { AppApiOperationContract } from "openxiangda-contracts";
5
+ import { OPENXIANGDA_REQUIRED_CAPABILITY } from "./tokens.js";
6
+ import type { OpenXiangdaCurrentUser, OpenXiangdaVerifiedContext } from "./types.js";
7
+ export declare const RequireCapability: (capability: string) => import("@nestjs/common").CustomDecorator<typeof OPENXIANGDA_REQUIRED_CAPABILITY>;
8
+ /**
9
+ * Binds one controller route to the immutable App API contract and protects it
10
+ * with the same generated capability constant. The release verifier can inspect
11
+ * this metadata without bootstrapping application business code.
12
+ */
13
+ export declare function OpenXiangdaOperation(operation: AppApiOperationContract): (target: object, propertyKey?: string | symbol, descriptor?: TypedPropertyDescriptor<any>) => void;
14
+ export declare const CurrentPrincipal: (...dataOrPipes: unknown[]) => ParameterDecorator;
15
+ export declare const CurrentUser: (...dataOrPipes: unknown[]) => ParameterDecorator;
16
+ export declare function currentUserFromVerifiedContext(verified: OpenXiangdaVerifiedContext): OpenXiangdaCurrentUser;
17
+ export declare function currentUserFromPrincipal(principal: NativePrincipal, roleCodes?: string[]): OpenXiangdaCurrentUser;
18
+ export declare const CurrentPerspective: (...dataOrPipes: unknown[]) => ParameterDecorator;
19
+ export declare const CurrentApplicationPrincipal: (...dataOrPipes: unknown[]) => ParameterDecorator;
20
+ export declare const CurrentOpenXiangdaContext: (...dataOrPipes: unknown[]) => ParameterDecorator;
21
+ export declare class OpenXiangdaAuthzGuard implements CanActivate {
22
+ private readonly reflector;
23
+ constructor(reflector: Reflector);
24
+ canActivate(context: ExecutionContext): Promise<boolean>;
25
+ private isVerifiedRoleUnion;
26
+ private servicePrincipal;
27
+ }
28
+ //# sourceMappingURL=authz.d.ts.map