@lark-apaas/nestjs-authzpaas 0.1.7 → 0.1.8

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/index.cjs CHANGED
@@ -41,11 +41,11 @@ __export(index_exports, {
41
41
  module.exports = __toCommonJS(index_exports);
42
42
 
43
43
  // src/authzpaas.module.ts
44
- var import_common6 = require("@nestjs/common");
44
+ var import_common7 = require("@nestjs/common");
45
45
  var import_core2 = require("@nestjs/core");
46
46
 
47
47
  // src/services/permission.service.ts
48
- var import_common4 = require("@nestjs/common");
48
+ var import_common3 = require("@nestjs/common");
49
49
  var import_nestjs_authnpaas = require("@lark-apaas/nestjs-authnpaas");
50
50
 
51
51
  // src/const.ts
@@ -79,6 +79,11 @@ var AbilityFactory = class {
79
79
  for (const role of permissionData.roles) {
80
80
  can(role, ROLE_SUBJECT);
81
81
  }
82
+ if (permissionData.permissions) {
83
+ for (const { action, subject } of permissionData.permissions) {
84
+ can(action, subject);
85
+ }
86
+ }
82
87
  return build();
83
88
  }
84
89
  };
@@ -157,41 +162,471 @@ var PermissionDeniedException = class _PermissionDeniedException extends import_
157
162
  } else {
158
163
  message = or ? `\u7F3A\u5C11\u6743\u9650: \u9700\u8981\u6EE1\u8DB3\u4EE5\u4E0B\u4EFB\u4E00\u6743\u9650\u8981\u6C42: ${requiredPermissions.map(({ actions, subject }) => `\u5BF9 ${subject} \u6267\u884C\u4EE5\u4E0B\u4EFB\u4E00\u64CD\u4F5C [${actions.join(", ")}]`).join(", ")}` : `\u7F3A\u5C11\u6743\u9650: \u9700\u8981\u6EE1\u8DB3\u4EE5\u4E0B\u6240\u6709\u6743\u9650\u8981\u6C42: ${requiredPermissions.map(({ actions, subject }) => `\u5BF9 ${subject} \u6267\u884C\u6240\u6709\u64CD\u4F5C [${actions.join(", ")}]`).join(", ")}`;
159
164
  }
160
- return new _PermissionDeniedException({
161
- type: "PERMISSION_REQUIRED",
162
- message,
163
- requiredPermissions,
164
- metadata: {
165
- or
166
- }
167
- });
165
+ return new _PermissionDeniedException({
166
+ type: "PERMISSION_REQUIRED",
167
+ message,
168
+ requiredPermissions,
169
+ metadata: {
170
+ or
171
+ }
172
+ });
173
+ }
174
+ };
175
+
176
+ // src/services/permission.service.ts
177
+ var import_nestjs_common = require("@lark-apaas/nestjs-common");
178
+ function _ts_decorate2(decorators, target, key, desc) {
179
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
180
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
181
+ 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;
182
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
183
+ }
184
+ __name(_ts_decorate2, "_ts_decorate");
185
+ function _ts_metadata(k, v) {
186
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
187
+ }
188
+ __name(_ts_metadata, "_ts_metadata");
189
+ function _ts_param(paramIndex, decorator) {
190
+ return function(target, key) {
191
+ decorator(target, key, paramIndex);
192
+ };
193
+ }
194
+ __name(_ts_param, "_ts_param");
195
+ var PermissionService = class {
196
+ static {
197
+ __name(this, "PermissionService");
198
+ }
199
+ apiConfig;
200
+ abilityFactory;
201
+ client;
202
+ requestContextService;
203
+ permissionResolver;
204
+ constructor(apiConfig, abilityFactory, client, requestContextService, permissionResolver = null) {
205
+ this.apiConfig = apiConfig;
206
+ this.abilityFactory = abilityFactory;
207
+ this.client = client;
208
+ this.requestContextService = requestContextService;
209
+ this.permissionResolver = permissionResolver;
210
+ }
211
+ /**
212
+ * 获取用户权限数据
213
+ */
214
+ async getUserPermissions({ laneId }) {
215
+ const permissionData = await this.fetchFromApi({
216
+ laneId
217
+ });
218
+ const dataWithTimestamp = {
219
+ ...permissionData,
220
+ fetchedAt: /* @__PURE__ */ new Date()
221
+ };
222
+ return dataWithTimestamp;
223
+ }
224
+ /**
225
+ * 从内部 API 获取当前用户的权限数据
226
+ * 通过平台内部接口 /app/{appId}/inner/api/v1/permissions/roles 获取
227
+ */
228
+ async fetchFromApi(options) {
229
+ const { timeout = 5e3 } = this.apiConfig || {};
230
+ const { appId = "", userId = "" } = this.requestContextService.getContext() || {};
231
+ if (!appId) {
232
+ throw new PermissionDeniedException({
233
+ type: PermissionDeniedType.PERMISSION_CONFIG_QUERY_FAILED,
234
+ message: "appId is empty"
235
+ }, import_common3.HttpStatus.BAD_REQUEST);
236
+ }
237
+ const url = `/app/${appId}/inner/api/v1/permissions/roles`;
238
+ const requestHeaders = {
239
+ "Content-Type": "application/json",
240
+ ...options.laneId ? {
241
+ "x-tt-env": options.laneId
242
+ } : {}
243
+ };
244
+ const controller = new AbortController();
245
+ const timeoutId = setTimeout(() => controller.abort(), timeout);
246
+ try {
247
+ const response = await this.client.post(url, {
248
+ userID: userId || ""
249
+ }, {
250
+ credentials: "include",
251
+ headers: requestHeaders,
252
+ signal: controller.signal
253
+ });
254
+ clearTimeout(timeoutId);
255
+ if (!response.ok) {
256
+ throw new Error(`Permission API returned ${response.status}: ${response.statusText}`);
257
+ }
258
+ let data;
259
+ try {
260
+ const responseText = await response.text();
261
+ data = JSON.parse(responseText);
262
+ } catch {
263
+ throw new Error("Permission API returned invalid JSON");
264
+ }
265
+ return {
266
+ userId,
267
+ roles: data.data?.roleList || [],
268
+ fetchedAt: /* @__PURE__ */ new Date()
269
+ };
270
+ } catch (error) {
271
+ clearTimeout(timeoutId);
272
+ const err = error instanceof Error ? error : new Error(String(error));
273
+ if (err.name === "AbortError") {
274
+ throw new PermissionDeniedException({
275
+ cause: err,
276
+ type: PermissionDeniedType.PERMISSION_CONFIG_QUERY_FAILED,
277
+ message: `Permission API request timeout after ${timeout}ms`
278
+ }, import_common3.HttpStatus.INTERNAL_SERVER_ERROR);
279
+ }
280
+ throw new PermissionDeniedException({
281
+ cause: err,
282
+ type: PermissionDeniedType.PERMISSION_CONFIG_QUERY_FAILED,
283
+ message: err.message
284
+ }, import_common3.HttpStatus.INTERNAL_SERVER_ERROR);
285
+ }
286
+ }
287
+ // /**
288
+ // * 获取用户的 Ability 实例(带缓存)
289
+ // * @param userId 用户ID
290
+ // * @returns CASL Ability 实例
291
+ // */
292
+ // private async getUserAbility(
293
+ // userId?: string,
294
+ // mockRoles?: string[]
295
+ // ): Promise<AppAbility> {
296
+ // // 计算缓存 key
297
+ // const key = this.buildCacheKey(userId, mockRoles);
298
+ // // 尝试从缓存获取
299
+ // const cached = this.cache.get(key);
300
+ // if (cached) {
301
+ // return cached.ability;
302
+ // }
303
+ // // 缓存未命中,调用 getUserPermissions 会创建并缓存
304
+ // await this.getUserPermissions(userId, mockRoles);
305
+ // // 再次从缓存获取(此时一定存在)
306
+ // const newCached = this.cache.get(key);
307
+ // return newCached!.ability;
308
+ // }
309
+ /**
310
+ * 检查角色要求
311
+ * 使用 CASL Ability 统一鉴权方式
312
+ * @param requirement 角色要求
313
+ * @param laneId 环境ID
314
+ * @returns 用户权限检查结果,包含结果和详细信息
315
+ * @throws PermissionDeniedException 当权限数据获取失败时
316
+ */
317
+ async checkRoles(requirement, laneId, userContext) {
318
+ const { userId = "" } = this.requestContextService.getContext() || {};
319
+ let permissionData = null;
320
+ if (!userContext || !userContext.roles) {
321
+ permissionData = await this.getUserPermissions({
322
+ laneId
323
+ });
324
+ } else {
325
+ permissionData = {
326
+ userId,
327
+ roles: userContext.roles || [],
328
+ fetchedAt: /* @__PURE__ */ new Date()
329
+ };
330
+ }
331
+ if (!permissionData) {
332
+ throw new PermissionDeniedException({
333
+ cause: new Error("Permission data fetch api is not configured"),
334
+ type: PermissionDeniedType.PERMISSION_CONFIG_QUERY_FAILED,
335
+ message: "Permission data fetch api is not configured"
336
+ }, import_common3.HttpStatus.BAD_REQUEST);
337
+ }
338
+ const ability = this.abilityFactory.createForUser(permissionData);
339
+ const { roles } = requirement;
340
+ if (!roles || roles.length === 0) {
341
+ return {
342
+ result: true
343
+ };
344
+ }
345
+ const hasRole = roles.some((role) => ability.can(role, ROLE_SUBJECT));
346
+ if (!hasRole) {
347
+ const userRoles = permissionData.roles;
348
+ return {
349
+ result: false,
350
+ details: `\u7528\u6237 ${userId}, \u7528\u6237\u89D2\u8272 [${userRoles.join(", ")}], \u9700\u8981 [${roles.join(", ")}]`
351
+ };
352
+ }
353
+ return {
354
+ result: true
355
+ };
356
+ }
357
+ /**
358
+ * 检查权限点位要求
359
+ * 通过 IPermissionResolver 解析用户角色对应的权限点位,然后检查是否满足要求
360
+ * @param requirement 权限点位要求
361
+ * @param laneId 环境ID
362
+ * @param userContext 用户上下文
363
+ * @returns 用户权限检查结果,包含结果和详细信息
364
+ * @throws PermissionDeniedException 当权限解析器未注入或权限数据获取失败时
365
+ */
366
+ async checkPermissions(requirement, laneId, userContext) {
367
+ if (!this.permissionResolver) {
368
+ throw new PermissionDeniedException({
369
+ cause: new Error("PermissionResolver is not registered. Provide permissionResolver in AuthZPaasModule options."),
370
+ type: PermissionDeniedType.PERMISSION_CONFIG_QUERY_FAILED,
371
+ message: "PermissionResolver is not registered. Provide permissionResolver in AuthZPaasModule options."
372
+ }, import_common3.HttpStatus.BAD_REQUEST);
373
+ }
374
+ const { userId = "" } = this.requestContextService.getContext() || {};
375
+ let permissionData = null;
376
+ if (!userContext || !userContext.roles) {
377
+ permissionData = await this.getUserPermissions({
378
+ laneId
379
+ });
380
+ } else {
381
+ permissionData = {
382
+ userId,
383
+ roles: userContext.roles || [],
384
+ fetchedAt: /* @__PURE__ */ new Date()
385
+ };
386
+ }
387
+ if (!permissionData) {
388
+ throw new PermissionDeniedException({
389
+ cause: new Error("Permission data fetch api is not configured"),
390
+ type: PermissionDeniedType.PERMISSION_CONFIG_QUERY_FAILED,
391
+ message: "Permission data fetch api is not configured"
392
+ }, import_common3.HttpStatus.BAD_REQUEST);
393
+ }
394
+ const { action, subject } = requirement;
395
+ if (!action || !subject) {
396
+ return {
397
+ result: true
398
+ };
399
+ }
400
+ const userPermissions = await this.permissionResolver.resolvePermissions(permissionData.roles);
401
+ permissionData.permissions = userPermissions;
402
+ const ability = this.abilityFactory.createForUser(permissionData);
403
+ const hasPermission = ability.can(action, subject);
404
+ if (!hasPermission) {
405
+ return {
406
+ result: false,
407
+ details: `\u7528\u6237 ${userId}, \u9700\u8981 can('${action}', '${subject}'), \u7528\u6237\u6743\u9650\u70B9\u4F4D [${userPermissions.map((p) => `${p.action}:${p.subject}`).join(", ")}]`
408
+ };
409
+ }
410
+ return {
411
+ result: true
412
+ };
413
+ }
414
+ };
415
+ PermissionService = _ts_decorate2([
416
+ (0, import_common3.Injectable)(),
417
+ (0, import_nestjs_authnpaas.Public)(),
418
+ _ts_param(0, (0, import_common3.Inject)(PERMISSION_API_CONFIG_TOKEN)),
419
+ _ts_param(2, (0, import_common3.Inject)(import_nestjs_common.PLATFORM_HTTP_CLIENT)),
420
+ _ts_param(4, (0, import_common3.Optional)()),
421
+ _ts_param(4, (0, import_common3.Inject)(PERMISSION_RESOLVER_TOKEN)),
422
+ _ts_metadata("design:type", Function),
423
+ _ts_metadata("design:paramtypes", [
424
+ typeof PermissionApiConfig === "undefined" ? Object : PermissionApiConfig,
425
+ typeof AbilityFactory === "undefined" ? Object : AbilityFactory,
426
+ typeof import_nestjs_common.PlatformHttpClient === "undefined" ? Object : import_nestjs_common.PlatformHttpClient,
427
+ typeof import_nestjs_common.RequestContextService === "undefined" ? Object : import_nestjs_common.RequestContextService,
428
+ Object
429
+ ])
430
+ ], PermissionService);
431
+
432
+ // src/guards/authzpaas.guard.ts
433
+ var import_common4 = require("@nestjs/common");
434
+ var import_core = require("@nestjs/core");
435
+ var import_nestjs_common2 = require("@lark-apaas/nestjs-common");
436
+ function _ts_decorate3(decorators, target, key, desc) {
437
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
438
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
439
+ 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;
440
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
441
+ }
442
+ __name(_ts_decorate3, "_ts_decorate");
443
+ function _ts_metadata2(k, v) {
444
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
445
+ }
446
+ __name(_ts_metadata2, "_ts_metadata");
447
+ function _ts_param2(paramIndex, decorator) {
448
+ return function(target, key) {
449
+ decorator(target, key, paramIndex);
450
+ };
451
+ }
452
+ __name(_ts_param2, "_ts_param");
453
+ var AuthZPaasGuard = class _AuthZPaasGuard {
454
+ static {
455
+ __name(this, "AuthZPaasGuard");
456
+ }
457
+ reflector;
458
+ permissionService;
459
+ obs;
460
+ constructor(reflector, permissionService, obs) {
461
+ this.reflector = reflector;
462
+ this.permissionService = permissionService;
463
+ this.obs = obs;
464
+ }
465
+ logger = new import_common4.Logger(_AuthZPaasGuard.name);
466
+ /**
467
+ * 验证权限点位要求是否有效
468
+ * @param requirements 权限点位要求
469
+ * @returns 是否有效
470
+ */
471
+ isValidPermissionRequirement(requirements) {
472
+ return Boolean(requirements && requirements.action && requirements.subject);
473
+ }
474
+ /**
475
+ * 验证角色要求是否有效
476
+ * @param requirements 角色要求
477
+ * @returns 是否有效
478
+ */
479
+ isValidRoleRequirement(requirements) {
480
+ return Boolean(requirements && requirements.roles && requirements.roles.length > 0);
481
+ }
482
+ async canActivate(context) {
483
+ const http = context.switchToHttp();
484
+ const request = http.getRequest();
485
+ const laneId = request.headers["x-tt-env"];
486
+ const baseUrl = `${request.protocol}://${request.get("host")}`;
487
+ const userContext = request.userContext;
488
+ userContext.baseUrl = baseUrl;
489
+ const checkRoleRequirement = this.reflector.getAllAndOverride(ROLES_KEY, [
490
+ context.getHandler(),
491
+ context.getClass()
492
+ ]);
493
+ if (this.isValidRoleRequirement(checkRoleRequirement)) {
494
+ const spanName = checkRoleRequirement.roles.join(" or ");
495
+ const logAttrs = {
496
+ source_type: "platform",
497
+ paas_attributes_module: "permission"
498
+ };
499
+ return this.obs.trace(spanName, async (span) => {
500
+ span.setAttributes({
501
+ module: "permission"
502
+ });
503
+ const elapsed = (0, import_nestjs_common2.createTimer)();
504
+ try {
505
+ const checkResult = await this.permissionService.checkRoles(checkRoleRequirement, laneId, userContext);
506
+ const durationMs = elapsed();
507
+ span.setAttribute("duration_ms", durationMs);
508
+ if (!checkResult.result) {
509
+ this.logger.warn(JSON.stringify({
510
+ role: spanName,
511
+ duration_ms: durationMs,
512
+ result: "no_auth",
513
+ result_detail: checkResult.details
514
+ }), {
515
+ ...logAttrs,
516
+ duration_ms: durationMs
517
+ });
518
+ } else {
519
+ this.logger.log(JSON.stringify({
520
+ role: spanName,
521
+ duration_ms: durationMs,
522
+ result: "has_auth"
523
+ }), {
524
+ ...logAttrs,
525
+ duration_ms: durationMs
526
+ });
527
+ }
528
+ return checkResult.result;
529
+ } catch (error) {
530
+ const durationMs = elapsed();
531
+ span.setAttribute("duration_ms", durationMs);
532
+ this.logger.error(JSON.stringify({
533
+ role: spanName,
534
+ duration_ms: durationMs,
535
+ result: "",
536
+ error_message: error.message
537
+ }), {
538
+ ...logAttrs,
539
+ duration_ms: durationMs
540
+ });
541
+ throw error;
542
+ }
543
+ });
544
+ }
545
+ const permissionRequirement = this.reflector.getAllAndOverride(PERMISSIONS_KEY, [
546
+ context.getHandler(),
547
+ context.getClass()
548
+ ]);
549
+ if (this.isValidPermissionRequirement(permissionRequirement)) {
550
+ const spanName = `${permissionRequirement.action}:${permissionRequirement.subject}`;
551
+ return this.obs.trace(spanName, async (span) => {
552
+ span.setAttributes({
553
+ module: "permission"
554
+ });
555
+ const startTime = Date.now();
556
+ try {
557
+ const checkResult = await this.permissionService.checkPermissions(permissionRequirement, laneId, userContext);
558
+ const endTime = Date.now();
559
+ if (!checkResult.result) {
560
+ this.logger.warn(JSON.stringify({
561
+ permission: spanName,
562
+ duration_ms: endTime - startTime,
563
+ result: "no_auth",
564
+ result_detail: checkResult.details
565
+ }), {
566
+ source_type: "platform",
567
+ paas_attributes_module: "permission"
568
+ });
569
+ } else {
570
+ this.logger.log(JSON.stringify({
571
+ permission: spanName,
572
+ duration_ms: endTime - startTime,
573
+ result: "has_auth"
574
+ }), {
575
+ source_type: "platform",
576
+ paas_attributes_module: "permission"
577
+ });
578
+ }
579
+ return checkResult.result;
580
+ } catch (error) {
581
+ const endTime = Date.now();
582
+ this.logger.error(JSON.stringify({
583
+ permission: spanName,
584
+ duration_ms: endTime - startTime,
585
+ result: "",
586
+ error_message: error.message
587
+ }), {
588
+ source_type: "platform",
589
+ paas_attributes_module: "permission"
590
+ });
591
+ throw error;
592
+ }
593
+ });
594
+ }
595
+ return true;
168
596
  }
169
597
  };
170
-
171
- // src/services/permission.service.ts
172
- var import_nestjs_common3 = require("@lark-apaas/nestjs-common");
598
+ AuthZPaasGuard = _ts_decorate3([
599
+ (0, import_common4.Injectable)(),
600
+ _ts_param2(2, (0, import_common4.Inject)(import_nestjs_common2.OBSERVABLE_SERVICE)),
601
+ _ts_metadata2("design:type", Function),
602
+ _ts_metadata2("design:paramtypes", [
603
+ typeof import_core.Reflector === "undefined" ? Object : import_core.Reflector,
604
+ typeof PermissionService === "undefined" ? Object : PermissionService,
605
+ typeof import_nestjs_common2.ObservableService === "undefined" ? Object : import_nestjs_common2.ObservableService
606
+ ])
607
+ ], AuthZPaasGuard);
173
608
 
174
609
  // src/sdk/authorization.sdk.ts
175
- var import_common3 = require("@nestjs/common");
176
- var import_nestjs_common = require("@lark-apaas/nestjs-common");
177
- var import_nestjs_common2 = require("@lark-apaas/nestjs-common");
178
- function _ts_decorate2(decorators, target, key, desc) {
610
+ var import_common5 = require("@nestjs/common");
611
+ var import_nestjs_common3 = require("@lark-apaas/nestjs-common");
612
+ var import_nestjs_common4 = require("@lark-apaas/nestjs-common");
613
+ function _ts_decorate4(decorators, target, key, desc) {
179
614
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
180
615
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
181
616
  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;
182
617
  return c > 3 && r && Object.defineProperty(target, key, r), r;
183
618
  }
184
- __name(_ts_decorate2, "_ts_decorate");
185
- function _ts_metadata(k, v) {
619
+ __name(_ts_decorate4, "_ts_decorate");
620
+ function _ts_metadata3(k, v) {
186
621
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
187
622
  }
188
- __name(_ts_metadata, "_ts_metadata");
189
- function _ts_param(paramIndex, decorator) {
623
+ __name(_ts_metadata3, "_ts_metadata");
624
+ function _ts_param3(paramIndex, decorator) {
190
625
  return function(target, key) {
191
626
  decorator(target, key, paramIndex);
192
627
  };
193
628
  }
194
- __name(_ts_param, "_ts_param");
629
+ __name(_ts_param3, "_ts_param");
195
630
  var SDK_MODULE = "permission";
196
631
  var LANG_CODE_MAP = {
197
632
  2052: "zh_cn",
@@ -218,9 +653,25 @@ function normalizeDeptList(list) {
218
653
  }
219
654
  __name(normalizeDeptList, "normalizeDeptList");
220
655
  function normalizeRoleMembers(members) {
221
- if (!members) return members;
656
+ if (!members) return {
657
+ userList: [],
658
+ departmentList: [],
659
+ groupChatList: [],
660
+ allEmployees: false,
661
+ public: false,
662
+ presetGroup: {
663
+ isContainsAdmin: false
664
+ }
665
+ };
222
666
  return {
223
667
  ...members,
668
+ userList: members.userList || [],
669
+ groupChatList: members.groupChatList || [],
670
+ allEmployees: members.allEmployees ?? false,
671
+ public: members.public ?? false,
672
+ presetGroup: members.presetGroup ?? {
673
+ isContainsAdmin: false
674
+ },
224
675
  departmentList: normalizeDeptList(members.departmentList)
225
676
  };
226
677
  }
@@ -263,7 +714,7 @@ function normalizeSearchResponse(res) {
263
714
  }
264
715
  __name(normalizeSearchResponse, "normalizeSearchResponse");
265
716
  function throwPlatformError(message, httpStatus, platformCode) {
266
- throw new import_common3.HttpException({
717
+ throw new import_common5.HttpException({
267
718
  statusCode: httpStatus,
268
719
  code: "PLATFORM_API_ERROR",
269
720
  message,
@@ -280,7 +731,7 @@ async function parseResponseWithRaw(response) {
280
731
  } catch {
281
732
  }
282
733
  const message = err?.error_msg || err?.msg || `\u5E73\u53F0 API \u8BF7\u6C42\u5931\u8D25 (${response.status})`;
283
- const httpStatus = response.status >= 500 ? import_common3.HttpStatus.BAD_GATEWAY : response.status;
734
+ const httpStatus = response.status >= 500 ? import_common5.HttpStatus.BAD_GATEWAY : response.status;
284
735
  throwPlatformError(message, httpStatus, err?.status_code ?? err?.code);
285
736
  }
286
737
  if (!text) return {
@@ -290,7 +741,7 @@ async function parseResponseWithRaw(response) {
290
741
  const json = JSON.parse(text);
291
742
  if (json.status_code && json.status_code !== "0") {
292
743
  const message = json.error_msg || `\u5E73\u53F0\u4E1A\u52A1\u9519\u8BEF (${json.status_code})`;
293
- throwPlatformError(message, import_common3.HttpStatus.BAD_GATEWAY, json.status_code);
744
+ throwPlatformError(message, import_common5.HttpStatus.BAD_GATEWAY, json.status_code);
294
745
  }
295
746
  return {
296
747
  data: json.data ?? json,
@@ -314,7 +765,7 @@ function traced(obs, logger, method, ctx, fn) {
314
765
  };
315
766
  return obs.trace(spanName, async (span) => {
316
767
  span.setAttributes(spanAttrs);
317
- const elapsed = (0, import_nestjs_common.createTimer)();
768
+ const elapsed = (0, import_nestjs_common3.createTimer)();
318
769
  try {
319
770
  const { data, raw, logId } = await fn();
320
771
  const durationMs = elapsed();
@@ -341,7 +792,7 @@ function traced(obs, logger, method, ctx, fn) {
341
792
  } catch (error) {
342
793
  const durationMs = elapsed();
343
794
  const errMsg = error instanceof Error ? error.message : String(error);
344
- const errorLogId = error instanceof import_common3.HttpException ? error.getResponse()?.["x-tt-logid"] ?? "" : "";
795
+ const errorLogId = error instanceof import_common5.HttpException ? error.getResponse()?.["x-tt-logid"] ?? "" : "";
345
796
  span.setAttributes({
346
797
  duration_ms: durationMs,
347
798
  success: false,
@@ -377,7 +828,7 @@ async function requestWithTrace(response) {
377
828
  logId
378
829
  };
379
830
  } catch (error) {
380
- if (error instanceof import_common3.HttpException && logId) {
831
+ if (error instanceof import_common5.HttpException && logId) {
381
832
  const res = error.getResponse();
382
833
  res["x-tt-logid"] = logId;
383
834
  }
@@ -421,7 +872,7 @@ var RolesAPI = class RolesAPI2 {
421
872
  const { data, raw, logId } = await requestWithTrace(response);
422
873
  const roles = (data.roles || []).map((r) => ({
423
874
  ...r,
424
- roleMembers: normalizeRoleMembers(r.roleMembers)
875
+ roleMembers: needMember ? normalizeRoleMembers(r.roleMembers) : void 0
425
876
  }));
426
877
  return {
427
878
  data: roles,
@@ -568,6 +1019,21 @@ var MembersAPI = class MembersAPI2 {
568
1019
  const result = await requestWithTrace(response);
569
1020
  if (result.data?.members) {
570
1021
  result.data.members = normalizeRoleMembers(result.data.members);
1022
+ } else {
1023
+ result.data = {
1024
+ members: {
1025
+ userList: [],
1026
+ departmentList: [],
1027
+ groupChatList: [],
1028
+ allEmployees: false,
1029
+ public: false,
1030
+ presetGroup: {
1031
+ isContainsAdmin: false
1032
+ }
1033
+ },
1034
+ total: 0,
1035
+ hasMore: false
1036
+ };
571
1037
  }
572
1038
  return result;
573
1039
  });
@@ -648,454 +1114,131 @@ var SearchAPI = class SearchAPI2 {
648
1114
  enableChatSearch: true,
649
1115
  include_external_user: params.includeExternalUser ?? true,
650
1116
  include_external_group: params.includeExternalGroup ?? true,
651
- pageSize: params.pageSize ?? 20,
652
- page: params.page ?? 1
653
- },
654
- userID: params.userID ?? (this.getUserId() || void 0)
655
- };
656
- return traced(this.obs, this.logger, "search.search", {
657
- httpMethod: "POST",
658
- path: this.basePath,
659
- params: body
660
- }, async () => {
661
- const response = await this.client.post(this.basePath, body);
662
- const result = await requestWithTrace(response);
663
- result.data = normalizeSearchResponse(result?.data);
664
- return result;
665
- });
666
- }
667
- };
668
- var AuthorizationSDK = class _AuthorizationSDK {
669
- static {
670
- __name(this, "AuthorizationSDK");
671
- }
672
- requestContextService;
673
- roles;
674
- members;
675
- search;
676
- logger = new import_common3.Logger(_AuthorizationSDK.name);
677
- constructor(client, obs, requestContextService) {
678
- this.requestContextService = requestContextService;
679
- const getAppId = /* @__PURE__ */ __name(() => {
680
- const { appId = "" } = this.requestContextService.getContext() || {};
681
- return appId;
682
- }, "getAppId");
683
- const getUserId = /* @__PURE__ */ __name(() => {
684
- const { userId = "" } = this.requestContextService.getContext() || {};
685
- return userId;
686
- }, "getUserId");
687
- this.roles = new RolesAPI(client, getAppId, getUserId, obs, this.logger);
688
- this.members = new MembersAPI(client, getAppId, getUserId, obs, this.logger);
689
- this.search = new SearchAPI(client, getAppId, getUserId, obs, this.logger);
690
- }
691
- };
692
- AuthorizationSDK = _ts_decorate2([
693
- (0, import_common3.Injectable)(),
694
- _ts_param(0, (0, import_common3.Inject)(import_nestjs_common.PLATFORM_HTTP_CLIENT)),
695
- _ts_param(1, (0, import_common3.Inject)(import_nestjs_common.OBSERVABLE_SERVICE)),
696
- _ts_metadata("design:type", Function),
697
- _ts_metadata("design:paramtypes", [
698
- typeof import_nestjs_common.PlatformHttpClient === "undefined" ? Object : import_nestjs_common.PlatformHttpClient,
699
- typeof ObservableService === "undefined" ? Object : ObservableService,
700
- typeof import_nestjs_common2.RequestContextService === "undefined" ? Object : import_nestjs_common2.RequestContextService
701
- ])
702
- ], AuthorizationSDK);
703
-
704
- // src/services/permission.service.ts
705
- function _ts_decorate3(decorators, target, key, desc) {
706
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
707
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
708
- 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;
709
- return c > 3 && r && Object.defineProperty(target, key, r), r;
710
- }
711
- __name(_ts_decorate3, "_ts_decorate");
712
- function _ts_metadata2(k, v) {
713
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
714
- }
715
- __name(_ts_metadata2, "_ts_metadata");
716
- function _ts_param2(paramIndex, decorator) {
717
- return function(target, key) {
718
- decorator(target, key, paramIndex);
719
- };
720
- }
721
- __name(_ts_param2, "_ts_param");
722
- var PermissionService = class {
723
- static {
724
- __name(this, "PermissionService");
725
- }
726
- abilityFactory;
727
- authorizationSDK;
728
- requestContextService;
729
- permissionResolver;
730
- constructor(abilityFactory, authorizationSDK, requestContextService, permissionResolver = null) {
731
- this.abilityFactory = abilityFactory;
732
- this.authorizationSDK = authorizationSDK;
733
- this.requestContextService = requestContextService;
734
- this.permissionResolver = permissionResolver;
735
- }
736
- /**
737
- * 获取用户权限数据
738
- */
739
- async getUserPermissions({ laneId }) {
740
- const permissionData = await this.fetchFromApi({
741
- laneId
742
- });
743
- const dataWithTimestamp = {
744
- ...permissionData,
745
- fetchedAt: /* @__PURE__ */ new Date()
746
- };
747
- return dataWithTimestamp;
748
- }
749
- /**
750
- * 从 AuthorizationSDK 获取权限数据
751
- * 通过 roles.list() 获取用户关联的角色列表
752
- */
753
- async fetchFromApi(_options) {
754
- const { userId = "" } = this.requestContextService.getContext() || {};
755
- try {
756
- const roles = await this.authorizationSDK.roles.list({
757
- userID: userId || void 0
758
- });
759
- return {
760
- userId,
761
- roles: roles.map((role) => role.bizID).filter((id) => !!id),
762
- fetchedAt: /* @__PURE__ */ new Date()
763
- };
764
- } catch (error) {
765
- const err = error instanceof Error ? error : new Error(String(error));
766
- throw new PermissionDeniedException({
767
- cause: err,
768
- type: PermissionDeniedType.PERMISSION_CONFIG_QUERY_FAILED,
769
- message: err.message
770
- }, import_common4.HttpStatus.INTERNAL_SERVER_ERROR);
771
- }
772
- }
773
- // /**
774
- // * 获取用户的 Ability 实例(带缓存)
775
- // * @param userId 用户ID
776
- // * @returns CASL Ability 实例
777
- // */
778
- // private async getUserAbility(
779
- // userId?: string,
780
- // mockRoles?: string[]
781
- // ): Promise<AppAbility> {
782
- // // 计算缓存 key
783
- // const key = this.buildCacheKey(userId, mockRoles);
784
- // // 尝试从缓存获取
785
- // const cached = this.cache.get(key);
786
- // if (cached) {
787
- // return cached.ability;
788
- // }
789
- // // 缓存未命中,调用 getUserPermissions 会创建并缓存
790
- // await this.getUserPermissions(userId, mockRoles);
791
- // // 再次从缓存获取(此时一定存在)
792
- // const newCached = this.cache.get(key);
793
- // return newCached!.ability;
794
- // }
795
- /**
796
- * 检查角色要求
797
- * 使用 CASL Ability 统一鉴权方式
798
- * @param requirement 角色要求
799
- * @param laneId 环境ID
800
- * @returns 用户权限检查结果,包含结果和详细信息
801
- * @throws PermissionDeniedException 当权限数据获取失败时
802
- */
803
- async checkRoles(requirement, laneId, userContext) {
804
- const { userId = "" } = this.requestContextService.getContext() || {};
805
- let permissionData = null;
806
- if (!userContext || !userContext.roles) {
807
- permissionData = await this.getUserPermissions({
808
- laneId
809
- });
810
- } else {
811
- permissionData = {
812
- userId,
813
- roles: userContext.roles || [],
814
- fetchedAt: /* @__PURE__ */ new Date()
815
- };
816
- }
817
- if (!permissionData) {
818
- throw new PermissionDeniedException({
819
- cause: new Error("Permission data fetch api is not configured"),
820
- type: PermissionDeniedType.PERMISSION_CONFIG_QUERY_FAILED,
821
- message: "Permission data fetch api is not configured"
822
- }, import_common4.HttpStatus.BAD_REQUEST);
823
- }
824
- const ability = this.abilityFactory.createForUser(permissionData);
825
- const { roles } = requirement;
826
- if (!roles || roles.length === 0) {
827
- return {
828
- result: true
829
- };
830
- }
831
- const hasRole = roles.some((role) => ability.can(role, ROLE_SUBJECT));
832
- if (!hasRole) {
833
- const userRoles = permissionData.roles;
834
- return {
835
- result: false,
836
- details: `\u7528\u6237 ${userId}, \u7528\u6237\u89D2\u8272 [${userRoles.join(", ")}], \u9700\u8981 [${roles.join(", ")}]`
837
- };
838
- }
839
- return {
840
- result: true
1117
+ pageSize: params.pageSize ?? 20,
1118
+ page: params.page ?? 1
1119
+ },
1120
+ userID: params.userID ?? (this.getUserId() || void 0)
841
1121
  };
1122
+ return traced(this.obs, this.logger, "search.search", {
1123
+ httpMethod: "POST",
1124
+ path: this.basePath,
1125
+ params: body
1126
+ }, async () => {
1127
+ const response = await this.client.post(this.basePath, body);
1128
+ const result = await requestWithTrace(response);
1129
+ result.data = normalizeSearchResponse(result?.data);
1130
+ return result;
1131
+ });
842
1132
  }
843
- /**
844
- * 检查权限点位要求
845
- * 通过 IPermissionResolver 解析用户角色对应的权限点位,然后检查是否满足要求
846
- * @param requirement 权限点位要求
847
- * @param laneId 环境ID
848
- * @param userContext 用户上下文
849
- * @returns 用户权限检查结果,包含结果和详细信息
850
- * @throws PermissionDeniedException 当权限解析器未注入或权限数据获取失败时
851
- */
852
- async checkPermissions(requirement, laneId, userContext) {
853
- if (!this.permissionResolver) {
854
- throw new PermissionDeniedException({
855
- cause: new Error("PermissionResolver is not registered. Provide permissionResolver in AuthZPaasModule options."),
856
- type: PermissionDeniedType.PERMISSION_CONFIG_QUERY_FAILED,
857
- message: "PermissionResolver is not registered. Provide permissionResolver in AuthZPaasModule options."
858
- }, import_common4.HttpStatus.BAD_REQUEST);
859
- }
860
- const { userId = "" } = this.requestContextService.getContext() || {};
861
- let permissionData = null;
862
- if (!userContext || !userContext.roles) {
863
- permissionData = await this.getUserPermissions({
864
- laneId
865
- });
866
- } else {
867
- permissionData = {
868
- userId,
869
- roles: userContext.roles || [],
870
- fetchedAt: /* @__PURE__ */ new Date()
871
- };
872
- }
873
- if (!permissionData) {
874
- throw new PermissionDeniedException({
875
- cause: new Error("Permission data fetch api is not configured"),
876
- type: PermissionDeniedType.PERMISSION_CONFIG_QUERY_FAILED,
877
- message: "Permission data fetch api is not configured"
878
- }, import_common4.HttpStatus.BAD_REQUEST);
879
- }
880
- const { permissions } = requirement;
881
- if (!permissions || permissions.length === 0) {
882
- return {
883
- result: true
884
- };
885
- }
886
- const userPermissions = await this.permissionResolver.resolvePermissions(permissionData.roles);
887
- const hasAllPermissions = permissions.every((p) => userPermissions.includes(p));
888
- if (!hasAllPermissions) {
889
- const missingPermissions = permissions.filter((p) => !userPermissions.includes(p));
890
- return {
891
- result: false,
892
- details: `\u7528\u6237 ${userId}, \u7528\u6237\u6743\u9650 [${userPermissions.join(", ")}], \u7F3A\u5C11 [${missingPermissions.join(", ")}]`
893
- };
894
- }
895
- return {
896
- result: true
897
- };
1133
+ };
1134
+ var AuthorizationSDK = class _AuthorizationSDK {
1135
+ static {
1136
+ __name(this, "AuthorizationSDK");
1137
+ }
1138
+ requestContextService;
1139
+ roles;
1140
+ members;
1141
+ search;
1142
+ logger = new import_common5.Logger(_AuthorizationSDK.name);
1143
+ constructor(client, obs, requestContextService) {
1144
+ this.requestContextService = requestContextService;
1145
+ const getAppId = /* @__PURE__ */ __name(() => {
1146
+ const { appId = "" } = this.requestContextService.getContext() || {};
1147
+ return appId;
1148
+ }, "getAppId");
1149
+ const getUserId = /* @__PURE__ */ __name(() => {
1150
+ const { userId = "" } = this.requestContextService.getContext() || {};
1151
+ return userId;
1152
+ }, "getUserId");
1153
+ this.roles = new RolesAPI(client, getAppId, getUserId, obs, this.logger);
1154
+ this.members = new MembersAPI(client, getAppId, getUserId, obs, this.logger);
1155
+ this.search = new SearchAPI(client, getAppId, getUserId, obs, this.logger);
898
1156
  }
899
1157
  };
900
- PermissionService = _ts_decorate3([
901
- (0, import_common4.Injectable)(),
902
- (0, import_nestjs_authnpaas.Public)(),
903
- _ts_param2(3, (0, import_common4.Optional)()),
904
- _ts_param2(3, (0, import_common4.Inject)(PERMISSION_RESOLVER_TOKEN)),
905
- _ts_metadata2("design:type", Function),
906
- _ts_metadata2("design:paramtypes", [
907
- typeof AbilityFactory === "undefined" ? Object : AbilityFactory,
908
- typeof AuthorizationSDK === "undefined" ? Object : AuthorizationSDK,
909
- typeof import_nestjs_common3.RequestContextService === "undefined" ? Object : import_nestjs_common3.RequestContextService,
910
- Object
1158
+ AuthorizationSDK = _ts_decorate4([
1159
+ (0, import_common5.Injectable)(),
1160
+ _ts_param3(0, (0, import_common5.Inject)(import_nestjs_common3.PLATFORM_HTTP_CLIENT)),
1161
+ _ts_param3(1, (0, import_common5.Inject)(import_nestjs_common3.OBSERVABLE_SERVICE)),
1162
+ _ts_metadata3("design:type", Function),
1163
+ _ts_metadata3("design:paramtypes", [
1164
+ typeof import_nestjs_common3.PlatformHttpClient === "undefined" ? Object : import_nestjs_common3.PlatformHttpClient,
1165
+ typeof ObservableService === "undefined" ? Object : ObservableService,
1166
+ typeof import_nestjs_common4.RequestContextService === "undefined" ? Object : import_nestjs_common4.RequestContextService
911
1167
  ])
912
- ], PermissionService);
1168
+ ], AuthorizationSDK);
913
1169
 
914
- // src/guards/authzpaas.guard.ts
915
- var import_common5 = require("@nestjs/common");
916
- var import_core = require("@nestjs/core");
917
- var import_nestjs_common4 = require("@lark-apaas/nestjs-common");
918
- function _ts_decorate4(decorators, target, key, desc) {
1170
+ // src/controllers/platform-permission.controller.ts
1171
+ var import_common6 = require("@nestjs/common");
1172
+ function _ts_decorate5(decorators, target, key, desc) {
919
1173
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
920
1174
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
921
1175
  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;
922
1176
  return c > 3 && r && Object.defineProperty(target, key, r), r;
923
1177
  }
924
- __name(_ts_decorate4, "_ts_decorate");
925
- function _ts_metadata3(k, v) {
1178
+ __name(_ts_decorate5, "_ts_decorate");
1179
+ function _ts_metadata4(k, v) {
926
1180
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
927
1181
  }
928
- __name(_ts_metadata3, "_ts_metadata");
929
- function _ts_param3(paramIndex, decorator) {
1182
+ __name(_ts_metadata4, "_ts_metadata");
1183
+ function _ts_param4(paramIndex, decorator) {
930
1184
  return function(target, key) {
931
1185
  decorator(target, key, paramIndex);
932
1186
  };
933
1187
  }
934
- __name(_ts_param3, "_ts_param");
935
- var AuthZPaasGuard = class _AuthZPaasGuard {
1188
+ __name(_ts_param4, "_ts_param");
1189
+ var PlatformPermissionController = class {
936
1190
  static {
937
- __name(this, "AuthZPaasGuard");
1191
+ __name(this, "PlatformPermissionController");
938
1192
  }
939
- reflector;
940
1193
  permissionService;
941
- obs;
942
- constructor(reflector, permissionService, obs) {
943
- this.reflector = reflector;
1194
+ permissionResolver;
1195
+ constructor(permissionService, permissionResolver = null) {
944
1196
  this.permissionService = permissionService;
945
- this.obs = obs;
946
- }
947
- logger = new import_common5.Logger(_AuthZPaasGuard.name);
948
- /**
949
- * 验证权限点位要求是否有效
950
- * @param requirements 权限点位要求
951
- * @returns 是否有效
952
- */
953
- isValidPermissionRequirement(requirements) {
954
- return Boolean(requirements && requirements.permissions && requirements.permissions.length > 0);
955
- }
956
- /**
957
- * 验证角色要求是否有效
958
- * @param requirements 角色要求
959
- * @returns 是否有效
960
- */
961
- isValidRoleRequirement(requirements) {
962
- return Boolean(requirements && requirements.roles && requirements.roles.length > 0);
1197
+ this.permissionResolver = permissionResolver;
963
1198
  }
964
- async canActivate(context) {
965
- const http = context.switchToHttp();
966
- const request = http.getRequest();
967
- const laneId = request.headers["x-tt-env"];
968
- const baseUrl = `${request.protocol}://${request.get("host")}`;
969
- const userContext = request.userContext;
970
- userContext.baseUrl = baseUrl;
971
- const checkRoleRequirement = this.reflector.getAllAndOverride(ROLES_KEY, [
972
- context.getHandler(),
973
- context.getClass()
974
- ]);
975
- if (this.isValidRoleRequirement(checkRoleRequirement)) {
976
- const spanName = checkRoleRequirement.roles.join(" or ");
977
- const logAttrs = {
978
- source_type: "platform",
979
- paas_attributes_module: "permission"
980
- };
981
- return this.obs.trace(spanName, async (span) => {
982
- span.setAttributes({
983
- module: "permission"
984
- });
985
- const elapsed = (0, import_nestjs_common4.createTimer)();
986
- try {
987
- const checkResult = await this.permissionService.checkRoles(checkRoleRequirement, laneId, userContext);
988
- const durationMs = elapsed();
989
- span.setAttribute("duration_ms", durationMs);
990
- if (!checkResult.result) {
991
- this.logger.warn(JSON.stringify({
992
- role: spanName,
993
- duration_ms: durationMs,
994
- result: "no_auth",
995
- result_detail: checkResult.details
996
- }), {
997
- ...logAttrs,
998
- duration_ms: durationMs
999
- });
1000
- } else {
1001
- this.logger.log(JSON.stringify({
1002
- role: spanName,
1003
- duration_ms: durationMs,
1004
- result: "has_auth"
1005
- }), {
1006
- ...logAttrs,
1007
- duration_ms: durationMs
1008
- });
1009
- }
1010
- return checkResult.result;
1011
- } catch (error) {
1012
- const durationMs = elapsed();
1013
- span.setAttribute("duration_ms", durationMs);
1014
- this.logger.error(JSON.stringify({
1015
- role: spanName,
1016
- duration_ms: durationMs,
1017
- result: "",
1018
- error_message: error.message
1019
- }), {
1020
- ...logAttrs,
1021
- duration_ms: durationMs
1022
- });
1023
- throw error;
1024
- }
1025
- });
1199
+ async getUserPoints(req) {
1200
+ if (!this.permissionResolver) {
1201
+ return [];
1026
1202
  }
1027
- const permissionRequirement = this.reflector.getAllAndOverride(PERMISSIONS_KEY, [
1028
- context.getHandler(),
1029
- context.getClass()
1030
- ]);
1031
- if (this.isValidPermissionRequirement(permissionRequirement)) {
1032
- const spanName = permissionRequirement.permissions.join(" and ");
1033
- return this.obs.trace(spanName, async (span) => {
1034
- span.setAttributes({
1035
- module: "permission"
1036
- });
1037
- const startTime = Date.now();
1038
- try {
1039
- const checkResult = await this.permissionService.checkPermissions(permissionRequirement, laneId, userContext);
1040
- const endTime = Date.now();
1041
- if (!checkResult.result) {
1042
- this.logger.warn(JSON.stringify({
1043
- permission: spanName,
1044
- duration_ms: endTime - startTime,
1045
- result: checkResult.result ? "has_auth" : "no_auth",
1046
- result_detail: checkResult.details
1047
- }), {
1048
- source_type: "platform",
1049
- paas_attributes_module: "permission"
1050
- });
1051
- } else {
1052
- this.logger.log(JSON.stringify({
1053
- permission: spanName,
1054
- duration_ms: endTime - startTime,
1055
- result: checkResult.result ? "has_auth" : "no_auth"
1056
- }), {
1057
- source_type: "platform",
1058
- paas_attributes_module: "permission"
1059
- });
1060
- }
1061
- return checkResult.result;
1062
- } catch (error) {
1063
- const endTime = Date.now();
1064
- this.logger.error(JSON.stringify({
1065
- permission: spanName,
1066
- duration_ms: endTime - startTime,
1067
- result: "",
1068
- error_message: error.message
1069
- }), {
1070
- source_type: "platform",
1071
- paas_attributes_module: "permission"
1072
- });
1073
- throw error;
1074
- }
1075
- });
1203
+ const userContext = req.userContext;
1204
+ let roleKeys;
1205
+ if (userContext?.roles) {
1206
+ roleKeys = userContext.roles;
1207
+ } else {
1208
+ const permissionData = await this.permissionService.getUserPermissions({});
1209
+ roleKeys = permissionData?.roles || [];
1076
1210
  }
1077
- return true;
1211
+ return this.permissionResolver.resolvePermissions(roleKeys);
1078
1212
  }
1079
1213
  };
1080
- AuthZPaasGuard = _ts_decorate4([
1081
- (0, import_common5.Injectable)(),
1082
- _ts_param3(2, (0, import_common5.Inject)(import_nestjs_common4.OBSERVABLE_SERVICE)),
1083
- _ts_metadata3("design:type", Function),
1084
- _ts_metadata3("design:paramtypes", [
1085
- typeof import_core.Reflector === "undefined" ? Object : import_core.Reflector,
1214
+ _ts_decorate5([
1215
+ (0, import_common6.Get)("user-points"),
1216
+ _ts_param4(0, (0, import_common6.Req)()),
1217
+ _ts_metadata4("design:type", Function),
1218
+ _ts_metadata4("design:paramtypes", [
1219
+ typeof Request === "undefined" ? Object : Request
1220
+ ]),
1221
+ _ts_metadata4("design:returntype", Promise)
1222
+ ], PlatformPermissionController.prototype, "getUserPoints", null);
1223
+ PlatformPermissionController = _ts_decorate5([
1224
+ (0, import_common6.Controller)("api/sdk_innerapi/permission"),
1225
+ _ts_param4(1, (0, import_common6.Optional)()),
1226
+ _ts_param4(1, (0, import_common6.Inject)(PERMISSION_RESOLVER_TOKEN)),
1227
+ _ts_metadata4("design:type", Function),
1228
+ _ts_metadata4("design:paramtypes", [
1086
1229
  typeof PermissionService === "undefined" ? Object : PermissionService,
1087
- typeof import_nestjs_common4.ObservableService === "undefined" ? Object : import_nestjs_common4.ObservableService
1230
+ Object
1088
1231
  ])
1089
- ], AuthZPaasGuard);
1232
+ ], PlatformPermissionController);
1090
1233
 
1091
1234
  // src/authzpaas.module.ts
1092
- function _ts_decorate5(decorators, target, key, desc) {
1235
+ function _ts_decorate6(decorators, target, key, desc) {
1093
1236
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1094
1237
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1095
1238
  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;
1096
1239
  return c > 3 && r && Object.defineProperty(target, key, r), r;
1097
1240
  }
1098
- __name(_ts_decorate5, "_ts_decorate");
1241
+ __name(_ts_decorate6, "_ts_decorate");
1099
1242
  var AuthZPaasModule = class _AuthZPaasModule {
1100
1243
  static {
1101
1244
  __name(this, "AuthZPaasModule");
@@ -1105,7 +1248,9 @@ var AuthZPaasModule = class _AuthZPaasModule {
1105
1248
  return {
1106
1249
  module: _AuthZPaasModule,
1107
1250
  global: true,
1108
- controllers: [],
1251
+ controllers: [
1252
+ PlatformPermissionController
1253
+ ],
1109
1254
  providers: [
1110
1255
  // 配置提供者
1111
1256
  {
@@ -1186,7 +1331,9 @@ var AuthZPaasModule = class _AuthZPaasModule {
1186
1331
  module: _AuthZPaasModule,
1187
1332
  global: true,
1188
1333
  imports,
1189
- controllers: [],
1334
+ controllers: [
1335
+ PlatformPermissionController
1336
+ ],
1190
1337
  providers: [
1191
1338
  // 异步配置提供者
1192
1339
  {
@@ -1237,12 +1384,12 @@ var AuthZPaasModule = class _AuthZPaasModule {
1237
1384
  };
1238
1385
  }
1239
1386
  };
1240
- AuthZPaasModule = _ts_decorate5([
1241
- (0, import_common6.Module)({})
1387
+ AuthZPaasModule = _ts_decorate6([
1388
+ (0, import_common7.Module)({})
1242
1389
  ], AuthZPaasModule);
1243
1390
 
1244
1391
  // src/decorators/can-role.decorator.ts
1245
- var import_common7 = require("@nestjs/common");
1392
+ var import_common8 = require("@nestjs/common");
1246
1393
  var CanRole = /* @__PURE__ */ __name((role) => {
1247
1394
  let requirement;
1248
1395
  if (!Array.isArray(role) && typeof role === "string") {
@@ -1258,19 +1405,17 @@ var CanRole = /* @__PURE__ */ __name((role) => {
1258
1405
  } else {
1259
1406
  throw new Error("Invalid CanRole parameter: " + JSON.stringify(role));
1260
1407
  }
1261
- return (0, import_common7.SetMetadata)(ROLES_KEY, requirement);
1408
+ return (0, import_common8.SetMetadata)(ROLES_KEY, requirement);
1262
1409
  }, "CanRole");
1263
1410
 
1264
1411
  // src/decorators/can.decorator.ts
1265
- var import_common8 = require("@nestjs/common");
1266
- var Can = /* @__PURE__ */ __name((permissions) => {
1267
- if (!Array.isArray(permissions) || !permissions.every((p) => typeof p === "string")) {
1268
- throw new Error("Invalid Can parameter: " + JSON.stringify(permissions));
1269
- }
1412
+ var import_common9 = require("@nestjs/common");
1413
+ var Can = /* @__PURE__ */ __name((action, subject) => {
1270
1414
  const requirement = {
1271
- permissions
1415
+ action,
1416
+ subject
1272
1417
  };
1273
- return (0, import_common8.SetMetadata)(PERMISSIONS_KEY, requirement);
1418
+ return (0, import_common9.SetMetadata)(PERMISSIONS_KEY, requirement);
1274
1419
  }, "Can");
1275
1420
  // Annotate the CommonJS export names for ESM import in node:
1276
1421
  0 && (module.exports = {