@zucker-framework/auth 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,2363 @@
1
+ import { Term, DatabaseAdapter } from '@zucker-framework/core';
2
+ export { Term } from '@zucker-framework/core';
3
+ import * as _nestjs_common from '@nestjs/common';
4
+ import { ExecutionContext, Logger, CanActivate, OnModuleInit, DynamicModule, Type, InjectionToken, OptionalFactoryDependency } from '@nestjs/common';
5
+ import * as _nestjs_passport from '@nestjs/passport';
6
+ import { Reflector, DiscoveryService, MetadataScanner } from '@nestjs/core';
7
+ import { Observable } from 'rxjs';
8
+ import { JwtService } from '@nestjs/jwt';
9
+ import { ICache } from '@zucker-framework/cache';
10
+ import * as passport_jwt from 'passport-jwt';
11
+ import { StrategyOptionsWithoutRequest, Strategy } from 'passport-jwt';
12
+ export { DATABASE_ADAPTER } from '@zucker-framework/crud';
13
+
14
+ /**
15
+ * Data access control configuration types.
16
+ */
17
+ /** Data access control type identifier */
18
+ interface DataAccessType {
19
+ id: string;
20
+ name: string;
21
+ }
22
+ /** Built-in data access types */
23
+ declare const DefaultDataAccessType: {
24
+ readonly OWN_CREATED: DataAccessType;
25
+ readonly DENY_FIELDS: DataAccessType;
26
+ readonly SCOPE: DataAccessType;
27
+ readonly DIMENSION_SCOPE: DataAccessType;
28
+ };
29
+ /**
30
+ * Base data access configuration.
31
+ * Each config binds to a specific action (query/update/delete/etc.)
32
+ * and a specific type of access control.
33
+ */
34
+ interface DataAccessConfig {
35
+ /** The action this config applies to (e.g. 'query', 'update', 'delete') */
36
+ action: string;
37
+ /** Access control type */
38
+ type: DataAccessType;
39
+ }
40
+ /**
41
+ * Only allow access to records created by the current user.
42
+ * The creator field name is configurable (defaults to 'creatorId').
43
+ */
44
+ interface OwnCreatedDataAccessConfig extends DataAccessConfig {
45
+ type: typeof DefaultDataAccessType.OWN_CREATED;
46
+ /** The field that stores the creator user ID (default: 'creatorId') */
47
+ creatorField?: string;
48
+ }
49
+ /**
50
+ * Field-level access control: deny access to specific fields.
51
+ */
52
+ interface FieldFilterDataAccessConfig extends DataAccessConfig {
53
+ type: typeof DefaultDataAccessType.DENY_FIELDS;
54
+ /** Fields that should be denied/filtered */
55
+ fields: string[];
56
+ }
57
+ /**
58
+ * Scope-based row-level access control.
59
+ * Injects WHERE conditions based on scope type and values.
60
+ */
61
+ interface ScopeDataAccessConfig extends DataAccessConfig {
62
+ type: typeof DefaultDataAccessType.SCOPE;
63
+ /** Scope type identifier (e.g. 'org', 'department') */
64
+ scopeType: string;
65
+ /** Scope values to filter by */
66
+ scope: unknown[];
67
+ }
68
+ /**
69
+ * Dimension-based row-level access control.
70
+ * Uses the dimension system to filter rows based on user's dimension membership.
71
+ */
72
+ interface DimensionDataAccessConfig extends DataAccessConfig {
73
+ type: typeof DefaultDataAccessType.DIMENSION_SCOPE;
74
+ /** Dimension type / scopeType */
75
+ dimensionType: string;
76
+ /** The field on the resource that holds the dimension value */
77
+ dimensionField?: string;
78
+ /** Whether to include child dimensions in scope */
79
+ children?: boolean;
80
+ }
81
+ /** Helper to create OwnCreated config */
82
+ declare function ownCreatedConfig(action: string, creatorField?: string): OwnCreatedDataAccessConfig;
83
+ /** Helper to create FieldFilter config */
84
+ declare function fieldFilterConfig(action: string, fields: string[]): FieldFilterDataAccessConfig;
85
+ /** Helper to create Scope config */
86
+ declare function scopeConfig(action: string, scopeType: string, scope: unknown[]): ScopeDataAccessConfig;
87
+ /** Helper to create Dimension config */
88
+ declare function dimensionConfig(action: string, dimensionType: string, dimensionField?: string): DimensionDataAccessConfig;
89
+
90
+ /**
91
+ * Standard permission action constants.
92
+ */
93
+ declare const PermissionActions: {
94
+ readonly QUERY: "query";
95
+ readonly GET: "get";
96
+ readonly ADD: "add";
97
+ readonly SAVE: "save";
98
+ readonly UPDATE: "update";
99
+ readonly DELETE: "delete";
100
+ readonly IMPORT: "import";
101
+ readonly EXPORT: "export";
102
+ readonly DISABLE: "disable";
103
+ readonly ENABLE: "enable";
104
+ };
105
+ interface Permission {
106
+ id: string;
107
+ name: string;
108
+ actions: string[];
109
+ describe?: string;
110
+ /** Data-level access control configurations */
111
+ dataAccesses: DataAccessConfig[];
112
+ /** Extension options map */
113
+ options?: Record<string, unknown>;
114
+ /** Find fields that should be denied for the given action */
115
+ findDenyFields(action: string): string[];
116
+ /** Find a specific DataAccessConfig by action and type */
117
+ findDataAccess<T extends DataAccessConfig>(action: string, type: string): T | undefined;
118
+ /** Get all DataAccessConfigs for a given action */
119
+ getDataAccesses(action: string): DataAccessConfig[];
120
+ /** Find a FieldFilterDataAccessConfig for the given action */
121
+ findFieldFilter(action: string): FieldFilterDataAccessConfig | undefined;
122
+ /** Find scope values for the given action, type and scopeType */
123
+ findScope(action: string, type: string, scopeType: string): unknown[];
124
+ /** Deep copy this permission */
125
+ copy(actionFilter?: (action: string) => boolean, dataAccessFilter?: (config: DataAccessConfig) => boolean): Permission;
126
+ }
127
+ /**
128
+ * Simple Permission implementation with data access helpers.
129
+ */
130
+ declare class SimplePermission implements Permission {
131
+ id: string;
132
+ name: string;
133
+ actions: string[];
134
+ describe?: string;
135
+ dataAccesses: DataAccessConfig[];
136
+ options?: Record<string, unknown>;
137
+ constructor(data: {
138
+ id: string;
139
+ name: string;
140
+ actions: string[];
141
+ describe?: string;
142
+ dataAccesses?: DataAccessConfig[];
143
+ options?: Record<string, unknown>;
144
+ });
145
+ /** Check if a config's action matches the requested action (supports '*' wildcard) */
146
+ private actionMatches;
147
+ findDenyFields(action: string): string[];
148
+ findDataAccess<T extends DataAccessConfig>(action: string, type: string): T | undefined;
149
+ getDataAccesses(action: string): DataAccessConfig[];
150
+ findFieldFilter(action: string): FieldFilterDataAccessConfig | undefined;
151
+ findScope(action: string, type: string, scopeType: string): unknown[];
152
+ copy(actionFilter?: (action: string) => boolean, dataAccessFilter?: (config: DataAccessConfig) => boolean): SimplePermission;
153
+ }
154
+ interface Role {
155
+ id: string;
156
+ name: string;
157
+ permissions: Permission[];
158
+ parentId?: string;
159
+ }
160
+ interface RoleTreeNode extends Role {
161
+ children: RoleTreeNode[];
162
+ }
163
+ interface DimensionType {
164
+ id: string;
165
+ name: string;
166
+ isSameType(type: DimensionType | string): boolean;
167
+ }
168
+ interface Dimension {
169
+ id: string;
170
+ name: string;
171
+ type: DimensionType;
172
+ options?: Record<string, unknown>;
173
+ }
174
+ interface DimensionProvider {
175
+ /** 维度类型标识 */
176
+ readonly dimensionType: string;
177
+ getAllTypes(): Promise<DimensionType[]>;
178
+ getDimensionsByUserId(userId: string): Promise<Dimension[]>;
179
+ getDimensionById(type: DimensionType, id: string): Promise<Dimension | null>;
180
+ getUserIdsByDimensionId(dimensionId: string): Promise<string[]>;
181
+ /** 获取用户在该维度下的值列表 */
182
+ getDimensionValues(userId: string): Promise<string[]>;
183
+ /** 级联展开维度树(返回 value 及其所有子节点值) */
184
+ expandDimensionTree(value: string): Promise<string[]>;
185
+ }
186
+ declare const DIMENSION_PROVIDERS: unique symbol;
187
+ declare enum TokenState {
188
+ NORMAL = "normal",
189
+ EXPIRED = "expired",
190
+ LOCK = "lock",
191
+ DENY = "deny",
192
+ REVOKED = "revoked",
193
+ OFFLINE = "offline"
194
+ }
195
+ interface TokenInfo {
196
+ token: string;
197
+ userId: string;
198
+ state: TokenState;
199
+ /** Token type (e.g. 'default', 'api', 'mobile'). */
200
+ type: string;
201
+ signInTime: Date;
202
+ lastRequestTime: Date;
203
+ /** Number of requests made with this token. */
204
+ requestTimes: number;
205
+ maxInactiveInterval?: number;
206
+ }
207
+ /**
208
+ * Allopatric (concurrent) login mode.
209
+ */
210
+ declare enum AllopatricLoginMode {
211
+ /** Deny login if user already logged in elsewhere */
212
+ DENY = "deny",
213
+ /** Allow concurrent login (default) */
214
+ ALLOW = "allow",
215
+ /** Kick existing sessions offline when new login occurs */
216
+ OFFLINE_OTHER = "offlineOther"
217
+ }
218
+ interface AuthUser {
219
+ id: string;
220
+ username: string;
221
+ [key: string]: unknown;
222
+ }
223
+ interface Authentication {
224
+ getUser(): AuthUser;
225
+ getPermissions(): Permission[];
226
+ getDimensions(type?: string): Dimension[];
227
+ /** Get a specific permission by id */
228
+ getPermission(id: string): Permission | undefined;
229
+ /** Get a specific dimension by type and id */
230
+ getDimension(type: string, id: string): Dimension | undefined;
231
+ hasPermission(permissionId: string, ...actions: string[]): boolean;
232
+ hasDimension(type: string, ...ids: string[]): boolean;
233
+ getAttributes(): Record<string, unknown>;
234
+ getAttribute<T>(key: string): T | undefined;
235
+ setAttribute(key: string, value: unknown): void;
236
+ /** Merge another Authentication into this one */
237
+ merge(other: Authentication): Authentication;
238
+ /**
239
+ * Copy with filters.
240
+ * @param permissionFilter - (permission, action) => whether to keep the action
241
+ * @param dimensionFilter - (dimension) => whether to keep the dimension
242
+ */
243
+ copy(permissionFilter?: (permission: Permission, action: string) => boolean, dimensionFilter?: (dimension: Dimension) => boolean): Authentication;
244
+ }
245
+ interface ZuckerAuthModuleOptions {
246
+ jwtSecret?: string;
247
+ /**
248
+ * Register the framework's generic authorization, menu, and third-party
249
+ * account controllers. Defaults to true for backwards compatibility.
250
+ *
251
+ * Products that provide their own authentication surface should disable
252
+ * these controllers to avoid exposing unused routes.
253
+ */
254
+ registerControllers?: boolean;
255
+ dimensionProviders?: Array<new (...args: unknown[]) => DimensionProvider>;
256
+ /** 缓存 provider token(用于 Token 黑名单),指向 ICache 的注入 token */
257
+ cacheProvider?: string | symbol;
258
+ /** 最大并发会话数,0 表示不限制 */
259
+ maxActiveSessions?: number;
260
+ }
261
+ /**
262
+ * A simple DimensionType implementation that can be used as a constructor.
263
+ */
264
+ declare class SimpleDimensionType implements DimensionType {
265
+ readonly id: string;
266
+ readonly name: string;
267
+ constructor(id: string, name: string);
268
+ isSameType(type: DimensionType | string): boolean;
269
+ }
270
+ /**
271
+ * Built-in dimension types.
272
+ */
273
+ declare const DefaultDimensionType: {
274
+ readonly user: SimpleDimensionType;
275
+ readonly role: SimpleDimensionType;
276
+ };
277
+ /**
278
+ * Simple Dimension implementation.
279
+ */
280
+ declare class SimpleDimension implements Dimension {
281
+ id: string;
282
+ name: string;
283
+ type: DimensionType;
284
+ options?: Record<string, unknown>;
285
+ constructor(id: string, name: string, type: DimensionType, options?: Record<string, unknown>);
286
+ static of(id: string, name: string, type: DimensionType, options?: Record<string, unknown>): SimpleDimension;
287
+ }
288
+ /**
289
+ * Predicate function for testing Authentication.
290
+ */
291
+ type AuthenticationPredicate = (auth: Authentication) => boolean;
292
+ /**
293
+ * Factory methods for creating AuthenticationPredicates.
294
+ */
295
+ declare const AuthenticationPredicates: {
296
+ /** Check if authentication has the given permission string (e.g. "user:query") */
297
+ readonly has: (permissionString: string) => AuthenticationPredicate;
298
+ /** Check dimension membership */
299
+ readonly dimension: (dimensionType: string, ...ids: string[]) => AuthenticationPredicate;
300
+ /** Check specific permission with actions */
301
+ readonly permission: (permissionId: string, ...actions: string[]) => AuthenticationPredicate;
302
+ /** Combine two predicates with AND */
303
+ readonly and: (a: AuthenticationPredicate, b: AuthenticationPredicate) => AuthenticationPredicate;
304
+ /** Combine two predicates with OR */
305
+ readonly or: (a: AuthenticationPredicate, b: AuthenticationPredicate) => AuthenticationPredicate;
306
+ };
307
+ /**
308
+ * Parse a permission string like "user:query" or "role:admin" into a predicate.
309
+ */
310
+ declare function createAuthenticationPredicate(permissionString: string): AuthenticationPredicate;
311
+ /**
312
+ * User setting read/write permission levels.
313
+ */
314
+ declare enum UserSettingPermission {
315
+ NONE = "NONE",
316
+ R = "R",
317
+ W = "W",
318
+ RW = "RW"
319
+ }
320
+ /**
321
+ * Holds a user setting value with typed accessors.
322
+ */
323
+ interface SettingValueHolder {
324
+ asString(): string | undefined;
325
+ asNumber(): number | undefined;
326
+ asBoolean(): boolean | undefined;
327
+ asList<T>(): T[] | undefined;
328
+ getValue(): unknown;
329
+ getPermission(): UserSettingPermission;
330
+ }
331
+ /**
332
+ * Null object for SettingValueHolder.
333
+ * All accessors return undefined, permission is NONE.
334
+ */
335
+ declare const NullSettingValueHolder: SettingValueHolder;
336
+ /**
337
+ * Create a SettingValueHolder from a raw value and permission.
338
+ */
339
+ declare function createSettingValueHolder(value: unknown, permission?: UserSettingPermission): SettingValueHolder;
340
+
341
+ /**
342
+ * Utility helpers for TokenInfo
343
+ * (isNormal, isExpired, isOffline, isDeny, isLock, checkExpired, validate).
344
+ */
345
+ declare const TokenInfoUtils: {
346
+ readonly isNormal: (token: TokenInfo) => boolean;
347
+ readonly isExpired: (token: TokenInfo) => boolean;
348
+ readonly isOffline: (token: TokenInfo) => boolean;
349
+ readonly isDeny: (token: TokenInfo) => boolean;
350
+ readonly isLock: (token: TokenInfo) => boolean;
351
+ /** Check if the token has exceeded its maxInactiveInterval. */
352
+ readonly checkExpired: (token: TokenInfo) => boolean;
353
+ /** Validate token is in normal state, throw if not. */
354
+ readonly validate: (token: TokenInfo) => boolean;
355
+ };
356
+
357
+ interface DataAccessResult {
358
+ /** Whether access is allowed */
359
+ allowed: boolean;
360
+ /** WHERE conditions to inject into queries (AND logic) */
361
+ filterConditions?: Term[];
362
+ /** Fields that should be denied/stripped from the result */
363
+ denyFields?: string[];
364
+ }
365
+ /** Create an allowed result with no extra conditions */
366
+ declare function allowResult(): DataAccessResult;
367
+ /** Create a denied result */
368
+ declare function denyResult(): DataAccessResult;
369
+ /** Create an allowed result with filter conditions */
370
+ declare function filterResult(filterConditions: Term[], denyFields?: string[]): DataAccessResult;
371
+ /**
372
+ * Merge multiple DataAccessResults with AND logic.
373
+ * - If any result is denied, the merged result is denied.
374
+ * - All filterConditions are concatenated.
375
+ * - All denyFields are merged (union).
376
+ */
377
+ declare function mergeResults(results: DataAccessResult[]): DataAccessResult;
378
+
379
+ /**
380
+ * Context passed to DataAccessHandler for evaluation.
381
+ */
382
+ interface AuthorizingContext {
383
+ /** Current authenticated user */
384
+ authentication: Authentication;
385
+ /** The permission being checked */
386
+ permissionId: string;
387
+ /** The action being performed (query/update/delete/etc.) */
388
+ action: string;
389
+ /** Data type / resource being accessed */
390
+ dataType: string;
391
+ /** HTTP request object (for accessing params, body, query) */
392
+ request: {
393
+ method: string;
394
+ params: Record<string, string>;
395
+ query: Record<string, unknown>;
396
+ body: unknown;
397
+ path: string;
398
+ [key: string]: unknown;
399
+ };
400
+ }
401
+ /**
402
+ * Data access handler SPI.
403
+ * Implementations handle specific DataAccessConfig types.
404
+ * Registered via NestJS DI and iterated by DataPermissionGuard.
405
+ */
406
+ interface DataAccessHandler {
407
+ /**
408
+ * Whether this handler supports the given config.
409
+ */
410
+ isSupport(config: DataAccessConfig): boolean;
411
+ /**
412
+ * Evaluate data access for the given config and context.
413
+ * Returns a result indicating allowed/denied + optional filter conditions.
414
+ */
415
+ handle(config: DataAccessConfig, context: AuthorizingContext): Promise<DataAccessResult>;
416
+ }
417
+ declare const DATA_ACCESS_HANDLERS: unique symbol;
418
+
419
+ /**
420
+ * Handles OwnCreated data access control.
421
+ * Restricts access to records created by the current user.
422
+ * The creator field name is configurable (defaults to 'creatorId').
423
+ */
424
+ declare class OwnCreatedDataAccessHandler implements DataAccessHandler {
425
+ private readonly db;
426
+ private readonly logger;
427
+ constructor(db: DatabaseAdapter);
428
+ isSupport(config: DataAccessConfig): boolean;
429
+ handle(config: DataAccessConfig, context: AuthorizingContext): Promise<DataAccessResult>;
430
+ }
431
+
432
+ /**
433
+ * Handles field-level access control.
434
+ * Returns denyFields list so that the guard or downstream service
435
+ * can strip these fields from query results or reject mutations on them.
436
+ */
437
+ declare class FieldFilterDataAccessHandler implements DataAccessHandler {
438
+ isSupport(config: DataAccessConfig): boolean;
439
+ handle(config: DataAccessConfig, _context: AuthorizingContext): Promise<DataAccessResult>;
440
+ }
441
+
442
+ /**
443
+ * Handles scope-based row-level access control.
444
+ * Injects WHERE conditions based on scope type and values.
445
+ * E.g., only allow access to records within certain organizations.
446
+ */
447
+ declare class ScopeDataAccessHandler implements DataAccessHandler {
448
+ isSupport(config: DataAccessConfig): boolean;
449
+ handle(config: DataAccessConfig, _context: AuthorizingContext): Promise<DataAccessResult>;
450
+ }
451
+
452
+ /**
453
+ * 维度服务注册中心
454
+ * 管理多个 DimensionProvider,按 dimensionType 索引
455
+ */
456
+ declare class DimensionService {
457
+ private readonly providers;
458
+ private readonly logger;
459
+ private readonly providerMap;
460
+ constructor(providers: DimensionProvider[] | null);
461
+ /** 注册新的维度 Provider */
462
+ registerProvider(provider: DimensionProvider): void;
463
+ /** 获取指定类型的 Provider */
464
+ getProvider(dimensionType: string): DimensionProvider | undefined;
465
+ /** 获取所有已注册的 Provider */
466
+ getAllProviders(): DimensionProvider[];
467
+ getUserDimensions(userId: string): Promise<Dimension[]>;
468
+ /** 获取用户在指定维度类型下的值 */
469
+ getUserDimensionValues(userId: string, dimensionType: string): Promise<string[]>;
470
+ /** 级联展开维度树 */
471
+ expandDimensionTree(dimensionType: string, value: string): Promise<string[]>;
472
+ /** 获取用户在所有维度的完整展开值集合 */
473
+ getExpandedUserDimensions(userId: string): Promise<Map<string, string[]>>;
474
+ hasDimension(userId: string, dimensionType: string, dimensionId: string): Promise<boolean>;
475
+ getAllDimensionTypes(): Promise<DimensionType[]>;
476
+ getDimensionById(type: DimensionType, id: string): Promise<Dimension | null>;
477
+ getUserIdsByDimensionId(dimensionId: string): Promise<string[]>;
478
+ private getActiveProviders;
479
+ }
480
+
481
+ /**
482
+ * Handles dimension-based row-level access control.
483
+ * Uses DimensionService to resolve user dimensions and inject
484
+ * WHERE conditions or check resource membership.
485
+ *
486
+ * Refactored from the original hard-coded logic in DataPermissionGuard.
487
+ */
488
+ declare class DimensionDataAccessHandler implements DataAccessHandler {
489
+ private readonly db;
490
+ private readonly dimensionService?;
491
+ private readonly logger;
492
+ constructor(db: DatabaseAdapter, dimensionService?: DimensionService | undefined);
493
+ isSupport(config: DataAccessConfig): boolean;
494
+ handle(config: DataAccessConfig, context: AuthorizingContext): Promise<DataAccessResult>;
495
+ }
496
+
497
+ /**
498
+ * Authentication supplier interface.
499
+ * Multiple suppliers can be registered to build a complete Authentication
500
+ * from different sources (JWT, database, LDAP, etc.).
501
+ */
502
+ interface AuthenticationSupplier {
503
+ /** Supplier priority — lower values are applied first */
504
+ readonly order?: number;
505
+ /**
506
+ * Get authentication for the current request context.
507
+ * Returns null if this supplier cannot provide authentication.
508
+ */
509
+ get(context: SupplierContext): Promise<Authentication | null>;
510
+ /**
511
+ * Get authentication for a specific user ID.
512
+ * Used for admin impersonation or background jobs.
513
+ */
514
+ getByUserId?(userId: string): Promise<Authentication | null>;
515
+ }
516
+ interface SupplierContext {
517
+ /** The HTTP request object */
518
+ request: {
519
+ headers: Record<string, string | string[] | undefined>;
520
+ user?: Record<string, unknown>;
521
+ [key: string]: unknown;
522
+ };
523
+ }
524
+ declare const AUTHENTICATION_SUPPLIERS: unique symbol;
525
+
526
+ /**
527
+ * Default implementation of Authentication.
528
+ * Supports merge() for combining permissions and dimensions from multiple suppliers.
529
+ */
530
+ declare class DefaultAuthentication implements Authentication {
531
+ private user;
532
+ private permissions;
533
+ private dimensions;
534
+ private attributes;
535
+ constructor(data?: {
536
+ user?: AuthUser;
537
+ permissions?: Permission[];
538
+ dimensions?: Dimension[];
539
+ attributes?: Record<string, unknown>;
540
+ });
541
+ getUser(): AuthUser;
542
+ getPermissions(): Permission[];
543
+ getDimensions(type?: string | DimensionType): Dimension[];
544
+ /**
545
+ * 权限检查
546
+ *
547
+ * 权限 id 为 '*' 时允许所有操作;否则需要匹配权限 id,
548
+ * 并满足全部请求动作或拥有动作通配符 '*'。
549
+ * 在方法入口捕获权限列表引用,整个检查过程使用同一列表。
550
+ */
551
+ hasPermission(permissionId: string, ...actions: string[]): boolean;
552
+ /**
553
+ * 维度检查
554
+ * 先捕获 this.dimensions 到局部变量再操作。
555
+ */
556
+ hasDimension(type: string | DimensionType, ...ids: string[]): boolean;
557
+ getPermission(id: string): Permission | undefined;
558
+ /**
559
+ * Get dimension by type and id.
560
+ * When type is a string, uses case-insensitive comparison.
561
+ * When type is a DimensionType, uses isSameType.
562
+ */
563
+ getDimension(type: string | DimensionType, id: string): Dimension | undefined;
564
+ getAttributes(): Record<string, unknown>;
565
+ getAttribute<T>(key: string): T | undefined;
566
+ setAttribute(key: string, value: unknown): void;
567
+ setAttributes(attributes: Record<string, unknown>): void;
568
+ /**
569
+ * Set the user. Also adds the user as a dimension of type 'user'
570
+ *
571
+ * A user with an id is appended without deduplicating existing dimensions.
572
+ */
573
+ setUser(user: AuthUser): void;
574
+ /**
575
+ * Set user without adding to dimensions list.
576
+ */
577
+ setUser0(user: AuthUser): void;
578
+ setPermissions(permissions: Permission[]): void;
579
+ /**
580
+ * Append dimensions to the existing list.
581
+ */
582
+ setDimensions(dimensions: Dimension[]): void;
583
+ /**
584
+ * Replace all dimensions (for cases where full replacement is needed).
585
+ */
586
+ replaceDimensions(dimensions: Dimension[]): void;
587
+ /**
588
+ * Factory method for subclasses to override.
589
+ */
590
+ protected newInstance(): DefaultAuthentication;
591
+ /**
592
+ * Static factory.
593
+ */
594
+ static of(): DefaultAuthentication;
595
+ /**
596
+ * Copy with filters.
597
+ */
598
+ copy(permissionFilter?: (permission: Permission, action: string) => boolean, dimensionFilter?: (dimension: Dimension) => boolean): DefaultAuthentication;
599
+ /**
600
+ * Add a single dimension.
601
+ */
602
+ addDimension(dimension: Dimension): void;
603
+ /**
604
+ * Merge another Authentication into this one.
605
+ * Merge behavior:
606
+ * - User: later suppliers override the current user when present
607
+ * - Permissions: merge by ID, combining actions and dataAccesses; when
608
+ * other permission is new, use permission.copy()
609
+ * - Dimensions: merge by type+id dedup
610
+ * - Attributes: shallow merge (other wins on conflict)
611
+ */
612
+ merge(other: Authentication): DefaultAuthentication;
613
+ }
614
+ /**
615
+ * Create a DefaultAuthentication from a plain JWT user object (backward compat).
616
+ */
617
+ declare function fromJwtUser(user: Record<string, unknown>): DefaultAuthentication;
618
+
619
+ /**
620
+ * AuthenticationHolder — resolves and caches Authentication per request.
621
+ *
622
+ * Aggregates multiple AuthenticationSuppliers (JWT, database, LDAP, etc.)
623
+ * and merges their results into a single Authentication instance.
624
+ *
625
+ * Uses AsyncLocalStorage for request-scoped caching so that
626
+ * the same request only resolves suppliers once.
627
+ */
628
+ declare class AuthenticationHolder {
629
+ private readonly logger;
630
+ private readonly als;
631
+ private readonly suppliers;
632
+ constructor(suppliers: AuthenticationSupplier[] | null);
633
+ /**
634
+ * Run a function within an AsyncLocalStorage context.
635
+ * Call this in middleware or interceptor to enable request-level caching.
636
+ */
637
+ runInContext<T>(fn: () => T): T;
638
+ /**
639
+ * Resolve the current Authentication from all registered suppliers.
640
+ * Results are cached per-request via AsyncLocalStorage.
641
+ */
642
+ resolve(context: SupplierContext): Promise<Authentication | null>;
643
+ /**
644
+ * Resolve Authentication by user ID (for background jobs, impersonation).
645
+ */
646
+ resolveByUserId(userId: string): Promise<Authentication | null>;
647
+ /**
648
+ * Get the current Authentication from ALS cache without re-resolving.
649
+ */
650
+ getCurrent(): Authentication | null;
651
+ }
652
+
653
+ declare const IS_PUBLIC_KEY = "zucker:auth:isPublic";
654
+ declare const PERMISSIONS_KEY = "zucker:auth:permissions";
655
+ declare const RESOURCE_KEY = "zucker:auth:resource";
656
+ declare const ACTION_KEY = "zucker:auth:action";
657
+ declare const AUTHORIZE_KEY = "zucker:auth:authorize";
658
+ declare const DATA_PERMISSION_KEY = "zucker:auth:dataPermission";
659
+ declare const TWO_FACTOR_KEY = "zucker:auth:twoFactor";
660
+ declare const DIMENSION_KEY = "zucker:auth:dimension";
661
+
662
+ declare const Public: () => _nestjs_common.CustomDecorator<string>;
663
+ declare const Permissions: (...permissions: string[]) => _nestjs_common.CustomDecorator<string>;
664
+ declare const RequirePermissions: (...permissions: string[]) => _nestjs_common.CustomDecorator<string>;
665
+ interface ResourceOptions {
666
+ id: string;
667
+ name: string;
668
+ description?: string;
669
+ optionalFields?: Array<{
670
+ name: string;
671
+ description: string;
672
+ }>;
673
+ }
674
+ interface ActionOptions {
675
+ action: string;
676
+ name: string;
677
+ description?: string;
678
+ }
679
+ type AuthorizeLogical = 'AND' | 'OR' | 'DEFAULT';
680
+ type AuthorizePhased = 'before' | 'after';
681
+ interface AuthorizeResourceOptions extends ResourceOptions {
682
+ actions?: ActionOptions[];
683
+ merge?: boolean;
684
+ logical?: AuthorizeLogical;
685
+ phased?: AuthorizePhased;
686
+ group?: string[];
687
+ }
688
+ declare const Resource: (options: ResourceOptions) => _nestjs_common.CustomDecorator<string>;
689
+ declare const Action: (options: ActionOptions) => _nestjs_common.CustomDecorator<string>;
690
+ declare const QueryAction: (name?: string, description?: string) => _nestjs_common.CustomDecorator<string>;
691
+ /**
692
+ * Create action.
693
+ */
694
+ declare const CreateAction: (name?: string, description?: string) => _nestjs_common.CustomDecorator<string>;
695
+ declare const SaveAction: (name?: string, description?: string) => _nestjs_common.CustomDecorator<string>;
696
+ declare const DeleteAction: (name?: string, description?: string) => _nestjs_common.CustomDecorator<string>;
697
+ declare const UpdateAction: (name?: string, description?: string) => _nestjs_common.CustomDecorator<string>;
698
+ declare const ResourceAction: (options: ActionOptions) => _nestjs_common.CustomDecorator<string>;
699
+ declare const CurrentUser: (...dataOrPipes: (string | _nestjs_common.ParameterDecoratorOptions | _nestjs_common.PipeTransform<any, any> | _nestjs_common.Type<_nestjs_common.PipeTransform<any, any>> | undefined)[]) => ParameterDecorator;
700
+ interface DataPermissionOptions {
701
+ dataType?: string;
702
+ skipDataPermission?: boolean;
703
+ }
704
+ declare const DataPermission: (options?: DataPermissionOptions | string) => _nestjs_common.CustomDecorator<string>;
705
+ declare const SkipDataPermission: () => _nestjs_common.CustomDecorator<string>;
706
+ interface TwoFactorOptions {
707
+ /** 操作标识 — 用于区分不同操作的验证规则 */
708
+ operation: string;
709
+ /** 验证有效期(毫秒),默认 10 分钟 */
710
+ timeout?: number;
711
+ /** 验证器供应商(totp/sms/email),默认 'default' */
712
+ provider?: string;
713
+ /** 验证码的 HTTP 参数名,默认 'verifyCode' */
714
+ parameter?: string;
715
+ /** 是否忽略/关闭验证,默认 false */
716
+ ignore?: boolean;
717
+ /** 验证失败提示消息 */
718
+ message?: string;
719
+ }
720
+ interface ResolvedAuthorizeOptions {
721
+ resources: AuthorizeResourceOptions[];
722
+ dimensions: DimensionOptions[];
723
+ permissions?: string[];
724
+ dataPermission?: DataPermissionOptions;
725
+ ignore: boolean;
726
+ message: string;
727
+ merge: boolean;
728
+ logical: AuthorizeLogical;
729
+ phased: AuthorizePhased;
730
+ description: string[];
731
+ }
732
+ declare const TwoFactor: (options: string | TwoFactorOptions) => ClassDecorator & MethodDecorator;
733
+ interface AuthorizeOptions {
734
+ /** 资源定义 — 用于资源-动作模型 */
735
+ resource?: ResourceOptions;
736
+ /** 动作定义 — 用于资源-动作模型 */
737
+ action?: ActionOptions;
738
+ /** 多资源定义 */
739
+ resources?: AuthorizeResourceOptions[];
740
+ /** 维度定义 */
741
+ dimension?: DimensionOptions[];
742
+ /** 字符串权限列表 — 简单模式 */
743
+ permissions?: string[];
744
+ /** 数据权限选项 */
745
+ dataPermission?: DataPermissionOptions;
746
+ /** 是否忽略(等同 @Public) */
747
+ ignore?: boolean;
748
+ /** 验证失败消息 */
749
+ message?: string;
750
+ /** 是否合并类上的注解 */
751
+ merge?: boolean;
752
+ /** 多个资源/维度时的判断逻辑 */
753
+ logical?: AuthorizeLogical;
754
+ /** 验证时机 */
755
+ phased?: AuthorizePhased;
756
+ /** 说明文本 */
757
+ description?: string[];
758
+ }
759
+ /**
760
+ * @Authorize 组合装饰器
761
+ *
762
+ * 将 @Resource, @Action, @Permissions, @DataPermission, @Public
763
+ * 组合为单个装饰器,简化常用权限声明。
764
+ *
765
+ * 支持类级别和方法级别。
766
+ *
767
+ * @example
768
+ * ```ts
769
+ * @Authorize({ resource: { id: 'user', name: '用户' }, action: { action: 'query', name: '查询' } })
770
+ * async list() { ... }
771
+ *
772
+ * @Authorize({ ignore: true })
773
+ * async publicEndpoint() { ... }
774
+ *
775
+ * @Authorize({ permissions: ['admin:manage'] })
776
+ * async adminOnly() { ... }
777
+ * ```
778
+ */
779
+ declare function Authorize(options: AuthorizeOptions): ClassDecorator & MethodDecorator;
780
+ interface DimensionOptions {
781
+ type: string;
782
+ ids: string[];
783
+ logical?: AuthorizeLogical;
784
+ }
785
+ /**
786
+ * @DimensionCheck 装饰器
787
+ *
788
+ * 通用维度权限检查,支持角色、部门等维度类型。
789
+ */
790
+ declare const DimensionCheck: (options: DimensionOptions) => ClassDecorator & MethodDecorator;
791
+ /**
792
+ * @RequiresRoles 装饰器
793
+ *
794
+ * 要求用户拥有指定角色之一(OR 逻辑)。
795
+ */
796
+ interface RequiresRolesOptions {
797
+ logical?: AuthorizeLogical;
798
+ }
799
+ declare function RequiresRoles(...roles: string[]): ClassDecorator & MethodDecorator;
800
+ declare function RequiresRoles(options: RequiresRolesOptions, ...roles: string[]): ClassDecorator & MethodDecorator;
801
+
802
+ /** Minimal TopicEventBus interface to avoid hard dependency on @zucker-framework/event */
803
+ interface TopicEventBusLike$5 {
804
+ publish(topic: string, payload: unknown): Promise<void>;
805
+ }
806
+ declare const TOKEN_CACHE: unique symbol;
807
+ interface TokenServiceOptions {
808
+ /** 最大并发会话数,0 表示不限制 */
809
+ maxActiveSessions?: number;
810
+ /** Token 黑名单 TTL(毫秒),默认 7 天 */
811
+ blacklistTtlMs?: number;
812
+ /** 异地登录模式 */
813
+ allopatricLoginMode?: AllopatricLoginMode;
814
+ }
815
+ declare class TokenService {
816
+ private readonly cache?;
817
+ private readonly jwtService?;
818
+ private readonly topicEventBus?;
819
+ private readonly logger;
820
+ /** 内存中的 token 会话映射(兜底存储) */
821
+ private readonly tokens;
822
+ private readonly userTokens;
823
+ private maxActiveSessions;
824
+ private blacklistTtlMs;
825
+ private allopatricLoginMode;
826
+ constructor(cache?: ICache | undefined, jwtService?: JwtService | undefined, topicEventBus?: TopicEventBusLike$5 | undefined);
827
+ /** 配置选项(在模块初始化时调用) */
828
+ configure(options: TokenServiceOptions): void;
829
+ signIn(userId: string, token: string, type?: string, maxInactiveInterval?: number): Promise<TokenInfo>;
830
+ signOut(token: string): Promise<void>;
831
+ /** 撤销单个 token,加入黑名单 */
832
+ revokeToken(token: string): Promise<void>;
833
+ /** 撤销用户所有 token(强制登出) */
834
+ revokeUserTokens(userId: string): Promise<void>;
835
+ /** Token 轮换:旧 token 失效,签发新 token */
836
+ rotateToken(oldToken: string, payload: Record<string, unknown>): Promise<{
837
+ token: string;
838
+ tokenInfo: TokenInfo;
839
+ } | null>;
840
+ /** 检查 token 是否在黑名单中 */
841
+ isBlacklisted(token: string): Promise<boolean>;
842
+ /**
843
+ * Get token info, checking for timeout expiration first.
844
+ *
845
+ * A normal token expires when its positive maxInactiveInterval is exceeded.
846
+ * Missing tokens return null; other token states are preserved.
847
+ */
848
+ getByToken(token: string): Promise<TokenInfo | null>;
849
+ getByUserId(userId: string): Promise<TokenInfo[]>;
850
+ changeState(token: string, state: TokenState): Promise<void>;
851
+ touch(token: string): Promise<void>;
852
+ /** Check if a user has any active (normal) sessions. */
853
+ userIsLoggedIn(userId: string): Promise<boolean>;
854
+ /** Check if a specific token is logged in (normal state). */
855
+ tokenIsLoggedIn(token: string): Promise<boolean>;
856
+ /** Total number of unique logged-in users. */
857
+ totalUsers(): Promise<number>;
858
+ /** Get all active tokens. */
859
+ allLoggedTokens(): Promise<TokenInfo[]>;
860
+ /** Change state for all tokens of a user. */
861
+ changeUserState(userId: string, state: TokenState): Promise<void>;
862
+ /**
863
+ * Check all tokens for expiration, expire timed-out ones and remove them.
864
+ *
865
+ * Flux.fromIterable(tokenStorage.values())
866
+ * .doOnNext(this::checkTimeout) // marks as expired via changeTokenState
867
+ * .filter(UserToken::isExpired)
868
+ * .map(UserToken::getToken)
869
+ * .flatMap(this::signOutByToken) // removes and publishes UserTokenRemovedEvent
870
+ * .then()
871
+ */
872
+ checkExpired(): Promise<void>;
873
+ signOutByUserId(userId: string): Promise<void>;
874
+ totalTokens(): Promise<number>;
875
+ private publishEvent;
876
+ }
877
+
878
+ declare const JwtAuthGuard_base: _nestjs_passport.Type<_nestjs_passport.IAuthGuard>;
879
+ declare class JwtAuthGuard extends JwtAuthGuard_base {
880
+ private reflector;
881
+ private tokenService;
882
+ private authenticationHolder?;
883
+ constructor(reflector: Reflector, tokenService: TokenService, authenticationHolder?: AuthenticationHolder | undefined);
884
+ canActivate(context: ExecutionContext): boolean | Promise<boolean> | Observable<boolean>;
885
+ private postValidate;
886
+ }
887
+
888
+ declare class RoleHierarchyService {
889
+ private readonly db;
890
+ private readonly logger;
891
+ /**
892
+ * Cached parent-ID lookup table: roleId -> parentId | undefined.
893
+ * Populated lazily on first hierarchy traversal, cleared on invalidate().
894
+ * Avoids N+1 DB queries when walking the role tree.
895
+ */
896
+ private parentIdMap;
897
+ constructor(db: DatabaseAdapter);
898
+ /**
899
+ * Invalidate the cached role hierarchy.
900
+ * Call after role CRUD operations that change parentId relationships.
901
+ */
902
+ invalidateCache(): void;
903
+ /**
904
+ * Load all role parentId mappings in a single query (lazy, cached).
905
+ */
906
+ private ensureParentIdMap;
907
+ /**
908
+ * 获取角色的所有父角色(递归向上)
909
+ * Uses cached parent-ID map to avoid N+1 DB queries.
910
+ */
911
+ getParentRoles(roleId: string): Promise<string[]>;
912
+ /**
913
+ * 获取角色的所有子角色(递归向下)
914
+ * Uses cached parent-ID map to build child lookup in-memory.
915
+ */
916
+ getChildRoles(roleId: string): Promise<string[]>;
917
+ /**
918
+ * 获取角色的完整权限集(包括继承自父角色的权限)
919
+ * 递归展开角色层级,合并所有权限
920
+ */
921
+ getRolePermissions(roleId: string): Promise<Permission[]>;
922
+ /**
923
+ * 获取角色的所有权限(包括继承自父角色的)
924
+ * 同 getRolePermissions,保持向后兼容
925
+ */
926
+ getExpandedPermissions(roleId: string): Promise<Permission[]>;
927
+ /**
928
+ * 获取角色树
929
+ */
930
+ getRoleTree(): Promise<RoleTreeNode[]>;
931
+ /**
932
+ * 构建角色树
933
+ */
934
+ buildRoleTree(): Promise<RoleTreeNode[]>;
935
+ /**
936
+ * 获取用户通过角色层级展开后的所有权限 ID
937
+ */
938
+ getUserExpandedPermissionIds(userId: string): Promise<string[]>;
939
+ private loadPermissionsByRoleIds;
940
+ private loadRolePermissions;
941
+ }
942
+
943
+ declare class PermissionService {
944
+ private readonly db;
945
+ protected readonly logger: Logger;
946
+ private roleHierarchyService?;
947
+ private readonly permissionCache;
948
+ constructor(db: DatabaseAdapter);
949
+ /** 注入角色层级服务(在模块初始化后调用) */
950
+ setRoleHierarchyService(service: RoleHierarchyService): void;
951
+ /**
952
+ * Invalidate the permission cache for a specific user, or all users.
953
+ * Call after role/permission changes to ensure fresh data.
954
+ */
955
+ invalidatePermissionCache(userId?: string): void;
956
+ /**
957
+ * 获取用户的所有权限(包括角色权限和直接权限)
958
+ * Results are cached for a short TTL to avoid redundant DB queries
959
+ * when multiple guards check permissions in the same request.
960
+ */
961
+ findUserPermissions(userId: string): Promise<string[]>;
962
+ /**
963
+ * Internal: load user permissions from database.
964
+ */
965
+ private _loadUserPermissions;
966
+ /**
967
+ * 检查用户是否拥有所需权限
968
+ */
969
+ hasPermission(userId: string, requiredPermissions: string[]): Promise<boolean>;
970
+ /**
971
+ * 检查用户对特定数据的权限
972
+ */
973
+ hasDataPermission(userId: string, dataType: string, dataId: string, action: string): Promise<boolean>;
974
+ /**
975
+ * 检查用户是否拥有指定维度(角色/部门等)
976
+ *
977
+ * 支持维度条件和角色条件校验。
978
+ *
979
+ * @param userId 用户 ID
980
+ * @param dimensionType 维度类型,如 'role' 或 'department'
981
+ * @param dimensionIds 需要的维度 ID 列表
982
+ * @param logical AND = 全部满足, OR = 满足任一
983
+ */
984
+ hasDimension(userId: string, dimensionType: string, dimensionIds: string[], logical?: 'AND' | 'OR' | 'DEFAULT'): Promise<boolean>;
985
+ /**
986
+ * 检查用户是否拥有某资源的全部指定动作。
987
+ */
988
+ hasResourceActions(userId: string, resourceId: string, actions: string[]): Promise<boolean>;
989
+ /**
990
+ * 批量导入权限
991
+ */
992
+ importPermissions(permissions: Array<{
993
+ id: string;
994
+ name: string;
995
+ description?: string;
996
+ status?: boolean;
997
+ actions?: unknown[];
998
+ optionalFields?: unknown[];
999
+ parents?: string[];
1000
+ }>): Promise<{
1001
+ total: number;
1002
+ success: number;
1003
+ fail: number;
1004
+ results: {
1005
+ id: string;
1006
+ success: boolean;
1007
+ message: string;
1008
+ }[];
1009
+ }>;
1010
+ private addPermissionToSet;
1011
+ }
1012
+
1013
+ declare class PermissionsGuard implements CanActivate {
1014
+ private reflector;
1015
+ private permissionService;
1016
+ private readonly logger;
1017
+ constructor(reflector: Reflector, permissionService: PermissionService);
1018
+ canActivate(context: ExecutionContext): Promise<boolean>;
1019
+ private hasAuthorizeResourcePermission;
1020
+ private hasAuthorizeDimensions;
1021
+ private resolveAuthorizeOptions;
1022
+ private mergeResources;
1023
+ private mergeDimensions;
1024
+ private cloneAuthorizeOptions;
1025
+ private createEmptyAuthorizeOptions;
1026
+ private cloneResource;
1027
+ private normalizeLogical;
1028
+ }
1029
+
1030
+ /** Key to store data access result on the request for downstream use */
1031
+ declare const DATA_ACCESS_RESULT_KEY = "__dataAccessResult";
1032
+ declare class DataPermissionGuard implements CanActivate {
1033
+ private reflector;
1034
+ private readonly handlers;
1035
+ private readonly logger;
1036
+ constructor(reflector: Reflector, handlers: DataAccessHandler[] | null);
1037
+ canActivate(context: ExecutionContext): Promise<boolean>;
1038
+ private isAuthentication;
1039
+ private getActionFromMethod;
1040
+ private getDataTypeFromRequest;
1041
+ }
1042
+
1043
+ /**
1044
+ * Two-factor authentication interfaces.
1045
+ */
1046
+ interface TwoFactorValidator {
1047
+ /**
1048
+ * Returns the provider identifier.
1049
+ */
1050
+ getProvider(): string;
1051
+ /**
1052
+ * Verify a code and keep the validation valid until timeout elapses.
1053
+ */
1054
+ verify(code: string, timeout: number): Promise<boolean> | boolean;
1055
+ /**
1056
+ * Whether the current validation has expired.
1057
+ */
1058
+ expired(): Promise<boolean> | boolean;
1059
+ }
1060
+ interface TwoFactorValidatorProvider {
1061
+ /**
1062
+ * Returns the provider identifier (e.g., 'totp', 'sms').
1063
+ */
1064
+ getProvider(): string;
1065
+ /**
1066
+ * Create a validator instance for a specific user and operation.
1067
+ */
1068
+ createTwoFactorValidator(userId: string, operation: string): TwoFactorValidator;
1069
+ }
1070
+
1071
+ declare const TWO_FACTOR_PROVIDERS: unique symbol;
1072
+ declare class TwoFactorService {
1073
+ private readonly logger;
1074
+ private readonly providerMap;
1075
+ constructor(providers?: TwoFactorValidatorProvider[] | null);
1076
+ registerProvider(provider: TwoFactorValidatorProvider): void;
1077
+ getProvider(name: string): TwoFactorValidatorProvider | undefined;
1078
+ getAvailableProviders(): string[];
1079
+ /**
1080
+ * Validate a two-factor code.
1081
+ * @param userId - the user ID
1082
+ * @param provider - the provider name (e.g. 'totp', 'sms')
1083
+ * @param code - the verification code
1084
+ * @param operation - the operation requiring 2FA
1085
+ */
1086
+ validate(userId: string, provider: string, code: string, operation: string, timeout: number): Promise<boolean>;
1087
+ /**
1088
+ * Get a validator for a user/operation.
1089
+ */
1090
+ getValidator(userId: string, operation: string, provider: string): TwoFactorValidator | undefined;
1091
+ }
1092
+
1093
+ /**
1094
+ * TwoFactorGuard — 双因素认证守卫
1095
+ *
1096
+ * 消费 @TwoFactor 装饰器的元数据,在请求进入 handler 前
1097
+ * 验证双因素认证码。
1098
+ *
1099
+ * 支持类级别和方法级别组合(方法级别优先)。
1100
+ */
1101
+ declare class TwoFactorGuard implements CanActivate {
1102
+ private readonly reflector;
1103
+ private readonly twoFactorService;
1104
+ private readonly logger;
1105
+ constructor(reflector: Reflector, twoFactorService: TwoFactorService);
1106
+ canActivate(context: ExecutionContext): Promise<boolean>;
1107
+ }
1108
+
1109
+ interface ScannedPermission {
1110
+ id: string;
1111
+ name: string;
1112
+ description: string;
1113
+ status: boolean;
1114
+ actions: Array<{
1115
+ action: string;
1116
+ name: string;
1117
+ description: string;
1118
+ properties?: Record<string, unknown>;
1119
+ }>;
1120
+ optionalFields?: Array<{
1121
+ name: string;
1122
+ description: string;
1123
+ }>;
1124
+ }
1125
+ declare class PermissionScannerService {
1126
+ private readonly discoveryService;
1127
+ private readonly metadataScanner;
1128
+ private readonly reflector;
1129
+ constructor(discoveryService: DiscoveryService, metadataScanner: MetadataScanner, reflector: Reflector);
1130
+ scanPermissions(): ScannedPermission[];
1131
+ private ensurePermission;
1132
+ private addAction;
1133
+ }
1134
+
1135
+ interface MenuNode {
1136
+ id: string;
1137
+ name: string;
1138
+ path?: string;
1139
+ icon?: string;
1140
+ parentId?: string;
1141
+ sortOrder: number;
1142
+ status: boolean;
1143
+ permissions: string[];
1144
+ properties?: Record<string, unknown>;
1145
+ children?: MenuNode[];
1146
+ }
1147
+ declare class MenuService {
1148
+ private readonly db;
1149
+ private readonly logger;
1150
+ constructor(db: DatabaseAdapter);
1151
+ /** 获取完整菜单树 */
1152
+ getMenuTree(): Promise<MenuNode[]>;
1153
+ /** 根据用户权限过滤菜单树 */
1154
+ getMenuTreeByUserId(userId: string, userPermissions: string[]): Promise<MenuNode[]>;
1155
+ /** 根据角色获取菜单 ID 列表 */
1156
+ getMenuIdsByRoleId(roleId: string): Promise<string[]>;
1157
+ /** 为角色分配菜单 */
1158
+ assignMenusToRole(roleId: string, menuIds: string[]): Promise<void>;
1159
+ /**
1160
+ * 批量更新菜单(排序、状态等)
1161
+ */
1162
+ batchUpdate(menus: Array<{
1163
+ id: string;
1164
+ sortOrder?: number;
1165
+ status?: boolean;
1166
+ name?: string;
1167
+ path?: string;
1168
+ icon?: string;
1169
+ }>): Promise<number>;
1170
+ private buildTree;
1171
+ }
1172
+
1173
+ interface ThirdPartyProfile {
1174
+ providerAccountId: string;
1175
+ email?: string;
1176
+ displayName?: string;
1177
+ avatarUrl?: string;
1178
+ accessToken?: string;
1179
+ refreshToken?: string;
1180
+ expiresAt?: Date;
1181
+ profileData?: Record<string, unknown>;
1182
+ }
1183
+ declare class ThirdPartyAccountService {
1184
+ private readonly db;
1185
+ private readonly logger;
1186
+ constructor(db: DatabaseAdapter);
1187
+ /** 绑定第三方账号到用户 */
1188
+ bindAccount(userId: string, provider: string, profile: ThirdPartyProfile): Promise<void>;
1189
+ /** 解绑第三方账号(禁止解绑最后一个登录方式) */
1190
+ unbindAccount(userId: string, provider: string): Promise<void>;
1191
+ /**
1192
+ * OAuth 登录时查找或创建用户
1193
+ * 如果第三方账号已绑定,返回绑定的用户
1194
+ * 如果未绑定,创建新用户并绑定
1195
+ */
1196
+ findOrCreateUser(provider: string, profile: ThirdPartyProfile): Promise<{
1197
+ userId: string;
1198
+ isNew: boolean;
1199
+ }>;
1200
+ /** 获取用户的所有第三方绑定 */
1201
+ getUserBinds(userId: string): Promise<Array<{
1202
+ provider: string;
1203
+ displayName?: string;
1204
+ email?: string;
1205
+ }>>;
1206
+ }
1207
+
1208
+ /**
1209
+ * 内置的部门维度 Provider 示例
1210
+ * 基于 dimensions / dimensionUsers 表实现组织架构维度
1211
+ */
1212
+ declare class DepartmentDimensionProvider implements DimensionProvider {
1213
+ private readonly db;
1214
+ readonly dimensionType = "department";
1215
+ private readonly logger;
1216
+ constructor(db: DatabaseAdapter);
1217
+ getAllTypes(): Promise<DimensionType[]>;
1218
+ getDimensionsByUserId(userId: string): Promise<Dimension[]>;
1219
+ getDimensionById(type: DimensionType, id: string): Promise<Dimension | null>;
1220
+ getUserIdsByDimensionId(dimensionId: string): Promise<string[]>;
1221
+ /** 获取用户绑定的维度值列表 */
1222
+ getDimensionValues(userId: string): Promise<string[]>;
1223
+ /** 级联展开:返回该维度节点及其所有子节点的 ID */
1224
+ expandDimensionTree(value: string): Promise<string[]>;
1225
+ }
1226
+
1227
+ /**
1228
+ * Password encoder interface.
1229
+ */
1230
+ interface PasswordEncoder {
1231
+ /**
1232
+ * Encode a raw password into a secure hash.
1233
+ */
1234
+ encode(raw: string): Promise<string>;
1235
+ /**
1236
+ * Check if a raw password matches the encoded hash.
1237
+ */
1238
+ matches(raw: string, encoded: string): Promise<boolean>;
1239
+ }
1240
+
1241
+ /**
1242
+ * Password strength validation.
1243
+ */
1244
+ interface PasswordPolicy {
1245
+ minLength: number;
1246
+ maxLength: number;
1247
+ requireUppercase: boolean;
1248
+ requireLowercase: boolean;
1249
+ requireDigit: boolean;
1250
+ requireSpecialChar: boolean;
1251
+ specialChars?: string;
1252
+ }
1253
+ declare const DEFAULT_PASSWORD_POLICY: PasswordPolicy;
1254
+ /**
1255
+ * Shared validation result — same shape as UsernameValidationResult.
1256
+ * Unified to avoid duplicating the {valid, errors} interface.
1257
+ */
1258
+ interface ValidationResult {
1259
+ valid: boolean;
1260
+ errors: string[];
1261
+ }
1262
+ declare class PasswordValidator {
1263
+ private readonly policy;
1264
+ constructor(policy?: Partial<PasswordPolicy>);
1265
+ validate(password: string): ValidationResult;
1266
+ }
1267
+
1268
+ /**
1269
+ * Username validation
1270
+ *
1271
+ * Provides configurable username policy enforcement including:
1272
+ * - Length constraints
1273
+ * - Character restrictions (alphanumeric, email format, etc.)
1274
+ * - Reserved name blocking
1275
+ */
1276
+ interface UsernamePolicy {
1277
+ minLength: number;
1278
+ maxLength: number;
1279
+ /** Allowed character pattern (regex). Default: alphanumeric + underscore + dot + @ */
1280
+ pattern: RegExp;
1281
+ /** Human-readable description of the pattern for error messages */
1282
+ patternDescription: string;
1283
+ /** Reserved usernames that cannot be used */
1284
+ reservedNames: string[];
1285
+ }
1286
+ declare const DEFAULT_USERNAME_POLICY: UsernamePolicy;
1287
+ interface UsernameValidationResult {
1288
+ valid: boolean;
1289
+ errors: string[];
1290
+ }
1291
+ /**
1292
+ * UsernameValidator — configurable username policy enforcement.
1293
+ */
1294
+ declare class UsernameValidator {
1295
+ private readonly policy;
1296
+ constructor(policy?: Partial<UsernamePolicy>);
1297
+ validate(username: string): UsernameValidationResult;
1298
+ }
1299
+
1300
+ /** Minimal TopicEventBus interface to avoid hard dependency on @zucker-framework/event */
1301
+ interface TopicEventBusLike$4 {
1302
+ publish(topic: string, payload: unknown): Promise<void>;
1303
+ }
1304
+ /** User entity shape — 对齐 Prisma schema `model users` */
1305
+ interface UserEntity {
1306
+ id: string;
1307
+ username: string;
1308
+ password?: string;
1309
+ name: string;
1310
+ typeId: string;
1311
+ status: boolean;
1312
+ creatorId?: string;
1313
+ createTime?: Date | number;
1314
+ email?: string;
1315
+ emailVerified?: boolean;
1316
+ locale?: string;
1317
+ [key: string]: unknown;
1318
+ }
1319
+ declare const PASSWORD_ENCODER: unique symbol;
1320
+
1321
+ /**
1322
+ * UserService
1323
+ *
1324
+ * Provides complete user lifecycle management:
1325
+ * - CRUD operations with duplicate-username protection
1326
+ * - Password encoding with per-user salt
1327
+ * - Username and password validation
1328
+ * - Status management (enable/disable)
1329
+ * - Event publishing for all user mutations
1330
+ * - Authorization cache invalidation on user changes
1331
+ */
1332
+ declare class UserService {
1333
+ private readonly db;
1334
+ private readonly topicEventBus?;
1335
+ private readonly logger;
1336
+ private passwordEncoder;
1337
+ private passwordValidator;
1338
+ private usernameValidator;
1339
+ constructor(db: DatabaseAdapter, passwordEncoder?: PasswordEncoder, topicEventBus?: TopicEventBusLike$4 | undefined);
1340
+ /** Override the password encoder (e.g. for testing or custom schemes) */
1341
+ setPasswordEncoder(encoder: PasswordEncoder): void;
1342
+ /** Override the password validator policy */
1343
+ setPasswordValidator(validator: PasswordValidator): void;
1344
+ /** Override the username validator policy */
1345
+ setUsernameValidator(validator: UsernameValidator): void;
1346
+ /**
1347
+ * Find a user by ID.
1348
+ */
1349
+ findById(id: string): Promise<UserEntity | null>;
1350
+ /**
1351
+ * Find a user by username.
1352
+ */
1353
+ findByUsername(username: string): Promise<UserEntity | null>;
1354
+ /**
1355
+ * Find a user by username and verify the plain-text password matches.
1356
+ * Returns null if user not found or password does not match.
1357
+ */
1358
+ findByUsernameAndPassword(username: string, plainPassword: string): Promise<UserEntity | null>;
1359
+ /**
1360
+ * Save a user (insert if no ID or not found, update if exists).
1361
+ */
1362
+ saveUser(userEntity: Partial<UserEntity> & {
1363
+ username: string;
1364
+ }): Promise<UserEntity>;
1365
+ /**
1366
+ * Add a new user.
1367
+ *
1368
+ * - Validates username and password
1369
+ * - Checks for duplicate username
1370
+ * - Generates salt and encodes password
1371
+ * - Publishes UserCreatedEvent
1372
+ */
1373
+ addUser(data: Partial<UserEntity> & {
1374
+ username: string;
1375
+ password?: string;
1376
+ }): Promise<UserEntity>;
1377
+ /**
1378
+ * Update an existing user.
1379
+ *
1380
+ * - Re-encodes password if changed
1381
+ * - Publishes UserModifiedEvent with passwordChanged flag
1382
+ * - Clears authorization cache for the user
1383
+ */
1384
+ private doUpdate;
1385
+ /**
1386
+ * Change user status (enable/disable).
1387
+ *
1388
+ * - Batch update status for multiple user IDs
1389
+ * - Publishes UserStateChangedEvent
1390
+ */
1391
+ changeState(userIds: string[], state: number | boolean): Promise<number>;
1392
+ /**
1393
+ * Change user password.
1394
+ *
1395
+ * - Verifies old password before allowing change
1396
+ * - Validates new password
1397
+ * - Publishes UserModifiedEvent with passwordChanged flag
1398
+ */
1399
+ changePassword(userId: string, oldPassword: string, newPassword: string): Promise<boolean>;
1400
+ /**
1401
+ * Delete a user.
1402
+ *
1403
+ * - Publishes UserDeletedEvent
1404
+ */
1405
+ deleteUser(userId: string): Promise<boolean>;
1406
+ /**
1407
+ * Lock a user account.
1408
+ */
1409
+ lockUser(userId: string): Promise<void>;
1410
+ /**
1411
+ * Unlock a user account.
1412
+ */
1413
+ unlockUser(userId: string): Promise<void>;
1414
+ /**
1415
+ * Query users with dynamic filters.
1416
+ */
1417
+ findUsers(where?: Record<string, unknown>): Promise<UserEntity[]>;
1418
+ /**
1419
+ * Count users matching a filter.
1420
+ */
1421
+ countUsers(where?: Record<string, unknown>): Promise<number>;
1422
+ private publishEvent;
1423
+ }
1424
+
1425
+ /** Minimal TopicEventBus interface to avoid hard dependency on @zucker-framework/event */
1426
+ interface TopicEventBusLike$3 {
1427
+ publish(topic: string, payload: unknown): Promise<void>;
1428
+ }
1429
+ /** Role entity shape — 对齐 Prisma schema `model roles` */
1430
+ interface RoleEntity {
1431
+ id: string;
1432
+ name: string;
1433
+ description?: string;
1434
+ status?: boolean;
1435
+ parentId?: string;
1436
+ groupId?: string;
1437
+ creatorId?: string;
1438
+ createTime?: Date | number;
1439
+ [key: string]: unknown;
1440
+ }
1441
+ /** Role event topics */
1442
+ declare const ROLE_EVENT_TOPICS: {
1443
+ readonly ROLE_CREATED: "/role/created";
1444
+ readonly ROLE_MODIFIED: "/role/modified";
1445
+ readonly ROLE_DELETED: "/role/deleted";
1446
+ };
1447
+ declare function createRoleCreatedEvent(roleId: string, roleName: string, creatorId?: string): {
1448
+ roleId: string;
1449
+ roleName: string;
1450
+ creatorId: string | undefined;
1451
+ timestamp: number;
1452
+ };
1453
+ declare function createRoleModifiedEvent(roleId: string, changes: Array<{
1454
+ field: string;
1455
+ oldValue: unknown;
1456
+ newValue: unknown;
1457
+ }>): {
1458
+ roleId: string;
1459
+ changes: {
1460
+ field: string;
1461
+ oldValue: unknown;
1462
+ newValue: unknown;
1463
+ }[];
1464
+ timestamp: number;
1465
+ };
1466
+ declare function createRoleDeletedEvent(roleId: string): {
1467
+ roleId: string;
1468
+ timestamp: number;
1469
+ };
1470
+ /**
1471
+ * RoleService
1472
+ *
1473
+ * Provides complete role lifecycle management:
1474
+ * - CRUD operations with name-based lookup
1475
+ * - Permission assignment with transactional guarantee
1476
+ * - Cascade deletion of related rolePermissions/userRoles/roleMenus
1477
+ * - Event publishing for all role mutations
1478
+ */
1479
+ declare class RoleService {
1480
+ private readonly db;
1481
+ private readonly topicEventBus?;
1482
+ private readonly permissionService?;
1483
+ private readonly logger;
1484
+ private roleHierarchyService?;
1485
+ constructor(db: DatabaseAdapter, topicEventBus?: TopicEventBusLike$3 | undefined, permissionService?: PermissionService | undefined);
1486
+ /** 注入角色层级服务(在模块初始化后调用) */
1487
+ setRoleHierarchyService(service: RoleHierarchyService): void;
1488
+ /**
1489
+ * Find a role by ID.
1490
+ */
1491
+ findById(id: string): Promise<RoleEntity | null>;
1492
+ /**
1493
+ * Find a role by name.
1494
+ */
1495
+ findByName(name: string): Promise<RoleEntity | null>;
1496
+ /**
1497
+ * Query roles with dynamic filters.
1498
+ */
1499
+ findRoles(where?: Record<string, unknown>): Promise<RoleEntity[]>;
1500
+ /**
1501
+ * Count roles matching a filter.
1502
+ */
1503
+ countRoles(where?: Record<string, unknown>): Promise<number>;
1504
+ /**
1505
+ * Add a new role.
1506
+ *
1507
+ * - Sets default status and createTime
1508
+ * - Publishes RoleCreatedEvent
1509
+ */
1510
+ addRole(data: Partial<RoleEntity> & {
1511
+ name: string;
1512
+ }): Promise<RoleEntity>;
1513
+ /**
1514
+ * Update an existing role.
1515
+ *
1516
+ * - Tracks field changes
1517
+ * - Publishes RoleModifiedEvent
1518
+ */
1519
+ updateRole(id: string, data: Partial<RoleEntity>): Promise<RoleEntity>;
1520
+ /**
1521
+ * Delete a role with cascade cleanup.
1522
+ *
1523
+ * - Cascade deletes rolePermissions, userRoles, roleMenus
1524
+ * - Publishes RoleDeletedEvent
1525
+ */
1526
+ deleteRole(id: string): Promise<boolean>;
1527
+ /**
1528
+ * Get permission IDs assigned to a role.
1529
+ */
1530
+ getRolePermissions(roleId: string): Promise<string[]>;
1531
+ /**
1532
+ * Set permissions for a role (replace all).
1533
+ * Uses transaction to ensure atomicity.
1534
+ */
1535
+ setRolePermissions(roleId: string, permissionIds: string[]): Promise<void>;
1536
+ private publishEvent;
1537
+ }
1538
+
1539
+ /** Minimal TopicEventBus interface to avoid hard dependency on @zucker-framework/event */
1540
+ interface TopicEventBusLike$2 {
1541
+ publish(topic: string, payload: unknown): Promise<void>;
1542
+ subscribe?(topic: string, handler: (payload: unknown) => void | Promise<void>): void;
1543
+ }
1544
+ /**
1545
+ * Authorization setting entity shape.
1546
+ * Each row maps a permission to a dimension (role/department/etc.)
1547
+ * with specific action access.
1548
+ */
1549
+ interface AuthorizationSettingEntity {
1550
+ id: string;
1551
+ permission: string;
1552
+ dimensionType: string;
1553
+ dimensionTarget: string;
1554
+ /** JSON: the granted actions for this permission+dimension combination */
1555
+ actions?: unknown;
1556
+ /** JSON: data access configurations */
1557
+ dataAccesses?: unknown;
1558
+ /** Merge flag: true = merge with other dimension settings */
1559
+ merge?: boolean;
1560
+ /** Priority: higher = higher precedence when merging */
1561
+ priority?: number;
1562
+ status?: number;
1563
+ }
1564
+ /**
1565
+ * AuthorizationSettingService
1566
+ *
1567
+ * Manages the mapping between permissions and dimensions (roles, departments, etc.).
1568
+ * - Generates deterministic IDs from permission + dimensionType + dimensionTarget
1569
+ * - Clears user authorization cache when settings are modified
1570
+ * - Cascade-deletes settings when a dimension is deleted
1571
+ */
1572
+ declare class AuthorizationSettingService {
1573
+ private readonly db;
1574
+ private readonly dimensionService?;
1575
+ private readonly topicEventBus?;
1576
+ private readonly logger;
1577
+ constructor(db: DatabaseAdapter, dimensionService?: DimensionService | undefined, topicEventBus?: TopicEventBusLike$2 | undefined);
1578
+ /**
1579
+ * Generate a deterministic ID for an authorization setting.
1580
+ *
1581
+ * -- uses DigestUtils.md5Hex(permission + dimensionType + dimensionTarget)
1582
+ */
1583
+ generateId(entity: Pick<AuthorizationSettingEntity, 'permission' | 'dimensionType' | 'dimensionTarget'>): string;
1584
+ /**
1585
+ * Save (upsert) one or more authorization settings.
1586
+ * Auto-generates IDs if not set.
1587
+ */
1588
+ save(settings: AuthorizationSettingEntity | AuthorizationSettingEntity[]): Promise<number>;
1589
+ /**
1590
+ * Delete authorization settings by IDs.
1591
+ */
1592
+ deleteByIds(ids: string[]): Promise<number>;
1593
+ /**
1594
+ * Find settings by dimension type and target.
1595
+ */
1596
+ findByDimension(dimensionType: string, dimensionTarget: string): Promise<AuthorizationSettingEntity[]>;
1597
+ /**
1598
+ * Find settings by permission ID.
1599
+ */
1600
+ findByPermission(permissionId: string): Promise<AuthorizationSettingEntity[]>;
1601
+ /**
1602
+ * Clear user authorization cache for users affected by setting changes.
1603
+ *
1604
+ * -- resolves dimension providers to find all affected user IDs,
1605
+ * then publishes ClearUserAuthorizationCacheEvent
1606
+ */
1607
+ private clearUserAuthCache;
1608
+ /**
1609
+ * Handle dimension deletion -- cascade delete associated authorization settings.
1610
+ */
1611
+ private handleDimensionDeleted;
1612
+ }
1613
+
1614
+ /** Minimal TopicEventBus interface to avoid hard dependency on @zucker-framework/event */
1615
+ interface TopicEventBusLike$1 {
1616
+ publish(topic: string, payload: unknown): Promise<void>;
1617
+ subscribe?(topic: string, handler: (payload: unknown) => void | Promise<void>): void;
1618
+ }
1619
+ /**
1620
+ * Dimension-user binding entity.
1621
+ */
1622
+ interface DimensionUserEntity {
1623
+ id: string;
1624
+ userId: string;
1625
+ dimensionTypeId: string;
1626
+ dimensionId: string;
1627
+ dimensionName?: string;
1628
+ }
1629
+ /**
1630
+ * DimensionUserService
1631
+ *
1632
+ * Manages the binding between users and dimensions (roles, departments, etc.).
1633
+ * Publishes bind/unbind events and handles cascade deletions.
1634
+ *
1635
+ * Key behaviors:
1636
+ * - User deleted -> delete all dimension bindings for that user
1637
+ * - Dimension entity deleted -> delete all bindings for that dimension
1638
+ * - Binding saved/created -> publish DimensionBindEvent + clear auth cache
1639
+ * - Binding deleted -> publish DimensionUnbindEvent + clear auth cache
1640
+ * - Binding modified -> clear auth cache
1641
+ */
1642
+ declare class DimensionUserService {
1643
+ private readonly db;
1644
+ private readonly topicEventBus?;
1645
+ private readonly logger;
1646
+ constructor(db: DatabaseAdapter, topicEventBus?: TopicEventBusLike$1 | undefined);
1647
+ /**
1648
+ * Bind a user to a dimension.
1649
+ */
1650
+ bind(data: {
1651
+ userId: string;
1652
+ dimensionTypeId: string;
1653
+ dimensionId: string;
1654
+ dimensionName?: string;
1655
+ }): Promise<DimensionUserEntity>;
1656
+ /**
1657
+ * Batch bind users to dimensions.
1658
+ */
1659
+ bindBatch(bindings: Array<{
1660
+ userId: string;
1661
+ dimensionTypeId: string;
1662
+ dimensionId: string;
1663
+ dimensionName?: string;
1664
+ }>): Promise<DimensionUserEntity[]>;
1665
+ /**
1666
+ * Unbind a user from a dimension.
1667
+ */
1668
+ unbind(id: string): Promise<boolean>;
1669
+ /**
1670
+ * Find all bindings for a user.
1671
+ */
1672
+ findByUserId(userId: string): Promise<DimensionUserEntity[]>;
1673
+ /**
1674
+ * Find all bindings for a dimension.
1675
+ */
1676
+ findByDimensionId(dimensionId: string): Promise<DimensionUserEntity[]>;
1677
+ /**
1678
+ * Get user IDs bound to a specific dimension.
1679
+ */
1680
+ getUserIdsByDimensionId(dimensionId: string): Promise<string[]>;
1681
+ /**
1682
+ * Get dimension bind info for multiple users.
1683
+ */
1684
+ getDimensionBindInfo(userIds: string[]): Promise<Array<{
1685
+ userId: string;
1686
+ dimensionTypeId: string;
1687
+ dimensionId: string;
1688
+ }>>;
1689
+ /**
1690
+ * Handle user deletion -- cascade delete all dimension bindings.
1691
+ */
1692
+ private handleUserDeleted;
1693
+ /**
1694
+ * Handle dimension entity deletion -- cascade delete all user bindings.
1695
+ */
1696
+ private handleDimensionDeleted;
1697
+ /**
1698
+ * Clear authorization cache for affected users.
1699
+ */
1700
+ private clearUserCache;
1701
+ private publishEvent;
1702
+ }
1703
+
1704
+ /**
1705
+ * PermissionSyncService
1706
+ *
1707
+ * Scans controller decorators (@Resource/@Action) at startup and synchronizes
1708
+ * discovered permission definitions to the database. Existing permissions are
1709
+ * updated (actions merged), new permissions are created.
1710
+ *
1711
+ * Key behaviors:
1712
+ * - Scan @Resource/@Action definitions with PermissionScannerService
1713
+ * - Merge with existing DB records (preserve custom actions, merge new ones)
1714
+ * - Convert ResourceDefinition to PermissionEntity with actions and optionalFields
1715
+ * - Upsert (save) all merged permissions to the database
1716
+ */
1717
+ declare class PermissionSyncService implements OnModuleInit {
1718
+ private readonly db;
1719
+ private readonly scannerService?;
1720
+ private readonly logger;
1721
+ private enabled;
1722
+ constructor(db: DatabaseAdapter, scannerService?: PermissionScannerService | undefined);
1723
+ /** Disable automatic sync on startup (useful for tests) */
1724
+ setEnabled(enabled: boolean): void;
1725
+ /**
1726
+ * NestJS lifecycle hook -- runs permission synchronization on startup.
1727
+ */
1728
+ onModuleInit(): Promise<void>;
1729
+ /**
1730
+ * Perform permission synchronization.
1731
+ *
1732
+ * 1. Scan all controller @Resource/@Action decorators
1733
+ * 2. Load existing permissions from database
1734
+ * 3. Merge scanned definitions with existing records
1735
+ * 4. Upsert merged permissions back to database
1736
+ */
1737
+ synchronize(): Promise<{
1738
+ total: number;
1739
+ created: number;
1740
+ updated: number;
1741
+ }>;
1742
+ /**
1743
+ * Merge a scanned permission definition with an existing database record.
1744
+ *
1745
+ * - Preserves existing name/description if already set
1746
+ * - Merges actions (new actions added, existing preserved)
1747
+ * - Preserves existing optionalFields
1748
+ * - Adds supportDataAccessTypes from scanned definition
1749
+ */
1750
+ private mergePermission;
1751
+ private parseActions;
1752
+ }
1753
+
1754
+ declare class MenuController {
1755
+ private readonly menuService;
1756
+ private readonly permissionService;
1757
+ private readonly db;
1758
+ constructor(menuService: MenuService, permissionService: PermissionService, db: DatabaseAdapter);
1759
+ /** GET /api/menu/tree — 获取当前用户可见的菜单树 */
1760
+ getMenuTree(req: {
1761
+ user: {
1762
+ id: string;
1763
+ };
1764
+ }): Promise<MenuNode[]>;
1765
+ /** GET /api/menu/all — 获取全部菜单列表(管理端用) */
1766
+ getAllMenus(): Promise<unknown[]>;
1767
+ /** GET /api/menu/:id — 查询单个菜单 */
1768
+ findOne(id: string): Promise<unknown>;
1769
+ /** POST /api/menu — 创建菜单 */
1770
+ create(body: Record<string, unknown>): Promise<unknown>;
1771
+ /** PUT /api/menu/:id — 更新菜单 */
1772
+ update(id: string, body: Record<string, unknown>): Promise<unknown>;
1773
+ /** DELETE /api/menu/:id — 递归删除菜单及所有子菜单 */
1774
+ remove(id: string): Promise<void>;
1775
+ /** 递归收集所有后代菜单 ID */
1776
+ private collectDescendantIds;
1777
+ /** PUT /api/menu/:id/sort — 更新菜单排序 */
1778
+ updateSort(id: string, body: {
1779
+ sortOrder: number;
1780
+ }): Promise<unknown>;
1781
+ }
1782
+
1783
+ declare class ThirdPartyAccountController {
1784
+ private readonly thirdPartyAccountService;
1785
+ constructor(thirdPartyAccountService: ThirdPartyAccountService);
1786
+ /** 获取当前用户的所有第三方绑定 */
1787
+ getBinds(req: {
1788
+ user: {
1789
+ id: string;
1790
+ };
1791
+ }): Promise<{
1792
+ provider: string;
1793
+ displayName?: string;
1794
+ email?: string;
1795
+ }[]>;
1796
+ /** 绑定第三方账号 */
1797
+ bind(req: {
1798
+ user: {
1799
+ id: string;
1800
+ };
1801
+ }, provider: string, profile: ThirdPartyProfile): Promise<{
1802
+ success: boolean;
1803
+ }>;
1804
+ /** 解绑第三方账号 */
1805
+ unbind(req: {
1806
+ user: {
1807
+ id: string;
1808
+ };
1809
+ }, provider: string): Promise<{
1810
+ success: boolean;
1811
+ }>;
1812
+ }
1813
+
1814
+ interface TopicEventBusLike {
1815
+ publish(topic: string, payload: unknown): Promise<void>;
1816
+ }
1817
+ interface LoginRequest {
1818
+ username: string;
1819
+ password: string;
1820
+ [key: string]: unknown;
1821
+ }
1822
+ interface LoginResult {
1823
+ userId: string;
1824
+ token: string;
1825
+ expires: number;
1826
+ [key: string]: unknown;
1827
+ }
1828
+ interface AuthenticationManagerLike {
1829
+ authenticate(username: string, password: string): Promise<AuthUser | null>;
1830
+ getByUserId?(userId: string): Promise<Authentication | null>;
1831
+ }
1832
+ declare const AUTHENTICATION_MANAGER = "AUTHENTICATION_MANAGER";
1833
+ declare class AuthorizationController {
1834
+ private readonly tokenService;
1835
+ private readonly authManager;
1836
+ private readonly authHolder?;
1837
+ private readonly eventBus?;
1838
+ private readonly logger;
1839
+ constructor(tokenService: TokenService, authManager: AuthenticationManagerLike, authHolder?: AuthenticationHolder | undefined, eventBus?: TopicEventBusLike | undefined);
1840
+ /**
1841
+ * GET /authorize/me — current user's authentication info.
1842
+ */
1843
+ me(req: {
1844
+ user?: AuthUser;
1845
+ auth?: Authentication;
1846
+ }): Promise<Authentication>;
1847
+ /**
1848
+ * POST /authorize/login — username/password login.
1849
+ * 1. DecodeEvent (可修改密码/用户名)
1850
+ * 2. BeforeEvent (可阻止登录/注入已认证用户)
1851
+ * 3. authenticate
1852
+ * 4. SuccessEvent / FailedEvent
1853
+ */
1854
+ login(body: LoginRequest): Promise<LoginResult>;
1855
+ }
1856
+
1857
+ declare class UserTokenController {
1858
+ private readonly tokenService;
1859
+ constructor(tokenService: TokenService);
1860
+ /**
1861
+ * GET /user-token/reset — reset current user's token (sign out self).
1862
+ */
1863
+ resetToken(): Promise<boolean>;
1864
+ /**
1865
+ * PUT /user-token/check — check and remove all expired tokens.
1866
+ */
1867
+ checkExpiredToken(): Promise<boolean>;
1868
+ /**
1869
+ * GET /user-token/token/:token — get token info by token string.
1870
+ */
1871
+ getByToken(token: string): Promise<TokenInfo | null>;
1872
+ /**
1873
+ * GET /user-token/user/:userId — get all tokens for a user.
1874
+ */
1875
+ getByUserId(userId: string): Promise<TokenInfo[]>;
1876
+ /**
1877
+ * GET /user-token/user/:userId/logged — check if user is logged in.
1878
+ */
1879
+ userIsLoggedIn(userId: string): Promise<boolean>;
1880
+ /**
1881
+ * GET /user-token/token/:token/logged — check if token is active.
1882
+ */
1883
+ tokenIsLoggedIn(token: string): Promise<boolean>;
1884
+ /**
1885
+ * GET /user-token/user/total — total logged-in users.
1886
+ */
1887
+ totalUser(): Promise<number>;
1888
+ /**
1889
+ * GET /user-token/token/total — total active tokens.
1890
+ */
1891
+ totalToken(): Promise<number>;
1892
+ /**
1893
+ * GET /user-token — list all active tokens.
1894
+ */
1895
+ allLoggedUser(): Promise<TokenInfo[]>;
1896
+ /**
1897
+ * DELETE /user-token/user/:userId — kick user offline by userId.
1898
+ */
1899
+ signOutByUserId(userId: string): Promise<void>;
1900
+ /**
1901
+ * DELETE /user-token/token/:token — invalidate a specific token.
1902
+ */
1903
+ signOutByToken(token: string): Promise<void>;
1904
+ /**
1905
+ * PUT /user-token/user/:userId/:state — change all tokens for a user to a state.
1906
+ */
1907
+ changeUserState(userId: string, state: string): Promise<void>;
1908
+ /**
1909
+ * GET /user-token/:token/touch — refresh token TTL.
1910
+ */
1911
+ touch(token: string): Promise<void>;
1912
+ }
1913
+
1914
+ interface JwtPayload {
1915
+ sub: string;
1916
+ username: string;
1917
+ [key: string]: unknown;
1918
+ }
1919
+ declare const JwtStrategy_base: new (...args: [opt: passport_jwt.StrategyOptionsWithRequest] | [opt: StrategyOptionsWithoutRequest]) => Strategy & {
1920
+ validate(...args: any[]): unknown;
1921
+ };
1922
+ declare class JwtStrategy extends JwtStrategy_base {
1923
+ constructor(secret: string);
1924
+ validate(payload: JwtPayload): Record<string, unknown> & {
1925
+ id: string;
1926
+ username: string;
1927
+ };
1928
+ }
1929
+
1930
+ /**
1931
+ * Authorization lifecycle events.
1932
+ */
1933
+ declare const AUTH_EVENT_TOPICS: {
1934
+ readonly USER_CREATED: "auth/user/created";
1935
+ readonly USER_MODIFIED: "auth/user/modified";
1936
+ readonly USER_DELETED: "auth/user/deleted";
1937
+ readonly USER_STATE_CHANGED: "auth/user/state-changed";
1938
+ readonly DIMENSION_BIND: "auth/dimension/bind";
1939
+ readonly DIMENSION_UNBIND: "auth/dimension/unbind";
1940
+ readonly DIMENSION_DELETED: "auth/dimension/deleted";
1941
+ readonly LOGIN_BEFORE: "auth/login/before";
1942
+ readonly LOGIN_DECODE: "auth/login/decode";
1943
+ readonly LOGIN_SUCCESS: "auth/login/success";
1944
+ readonly LOGIN_FAILED: "auth/login/failed";
1945
+ readonly LOGIN_EXIT: "auth/login/exit";
1946
+ readonly AUTH_INITIALIZE: "auth/initialize";
1947
+ readonly AUTH_HANDLE_BEFORE: "auth/handle/before";
1948
+ readonly TOKEN_CREATED: "auth/token/created";
1949
+ readonly TOKEN_CHANGED: "auth/token/changed";
1950
+ readonly TOKEN_REMOVED: "auth/token/removed";
1951
+ readonly CLEAR_AUTH_CACHE: "auth/cache/clear";
1952
+ };
1953
+ interface FieldChange {
1954
+ field: string;
1955
+ oldValue: unknown;
1956
+ newValue: unknown;
1957
+ }
1958
+ interface UserCreatedEvent {
1959
+ userId: string;
1960
+ username: string;
1961
+ creator?: string;
1962
+ timestamp: Date;
1963
+ }
1964
+ interface UserModifiedEvent {
1965
+ userId: string;
1966
+ changes: FieldChange[];
1967
+ /** 密码是否变更 */
1968
+ passwordChanged?: boolean;
1969
+ modifier?: string;
1970
+ timestamp: Date;
1971
+ }
1972
+ interface UserDeletedEvent {
1973
+ userId: string;
1974
+ operator?: string;
1975
+ timestamp: Date;
1976
+ }
1977
+ type UserState = 'enabled' | 'disabled' | 'locked';
1978
+ interface UserStateChangedEvent {
1979
+ userId: string;
1980
+ oldState: UserState;
1981
+ newState: UserState;
1982
+ operator?: string;
1983
+ timestamp: Date;
1984
+ }
1985
+ interface DimensionBindEvent {
1986
+ userId: string;
1987
+ dimensionType: string;
1988
+ dimensionId: string;
1989
+ operator?: string;
1990
+ timestamp: Date;
1991
+ }
1992
+ interface DimensionUnbindEvent {
1993
+ userId: string;
1994
+ dimensionType: string;
1995
+ dimensionId: string;
1996
+ operator?: string;
1997
+ timestamp: Date;
1998
+ }
1999
+ /**
2000
+ * 维度删除事件
2001
+ *
2002
+ * 当维度实体(如角色、部门)被删除时触发,
2003
+ * 用于级联清理该维度关联的授权配置。
2004
+ */
2005
+ interface DimensionDeletedEvent {
2006
+ dimensionType: string;
2007
+ dimensionId: string;
2008
+ timestamp: Date;
2009
+ }
2010
+ /**
2011
+ * 维度用户绑定信息
2012
+ *
2013
+ * 表示用户与维度的绑定关系,
2014
+ * 用于 DimensionUserBindProvider.getDimensionBindInfo() 返回值。
2015
+ */
2016
+ interface DimensionUserBind {
2017
+ userId: string;
2018
+ dimensionTypeId: string;
2019
+ dimensionId: string;
2020
+ }
2021
+ /**
2022
+ * Clear user authorization cache event.
2023
+ * If userId is undefined, all caches should be cleared.
2024
+ */
2025
+ interface ClearUserAuthorizationCacheEvent {
2026
+ userId?: string;
2027
+ reason?: string;
2028
+ timestamp: Date;
2029
+ }
2030
+ /** Fired before login attempt. */
2031
+ interface LoginBeforeEvent {
2032
+ username: string;
2033
+ /** Additional parameters from the login request */
2034
+ parameters?: Record<string, unknown>;
2035
+ /**
2036
+ * Set by event handlers to short-circuit authentication with a known userId.
2037
+ */
2038
+ authorizedUserId?: string;
2039
+ /**
2040
+ * Set to true when pre-authorization has been established
2041
+ */
2042
+ isAuthorized?: boolean;
2043
+ timestamp: Date;
2044
+ }
2045
+ /** Fired to decode/transform credentials. */
2046
+ interface LoginDecodeEvent {
2047
+ username: string;
2048
+ /** Password to decode */
2049
+ password?: string;
2050
+ /** Decoded/transformed username (set by handlers) */
2051
+ decodedUsername?: string;
2052
+ /** Decoded/transformed password (set by handlers) */
2053
+ decodedPassword?: string;
2054
+ /** Additional parameters from the login request */
2055
+ parameters?: Record<string, unknown>;
2056
+ timestamp: Date;
2057
+ }
2058
+ /** Fired after successful login. */
2059
+ interface LoginSuccessEvent {
2060
+ userId: string;
2061
+ username: string;
2062
+ /** Additional result data that handlers can attach */
2063
+ result?: Record<string, unknown>;
2064
+ /** Additional parameters from the login request */
2065
+ parameters?: Record<string, unknown>;
2066
+ timestamp: Date;
2067
+ }
2068
+ /** Fired after failed login attempt. */
2069
+ interface LoginFailedEvent {
2070
+ username: string;
2071
+ error: string;
2072
+ /** The actual exception/error object */
2073
+ exception?: Error;
2074
+ /** Additional parameters from the login request */
2075
+ parameters?: Record<string, unknown>;
2076
+ timestamp: Date;
2077
+ }
2078
+ /** Fired when user logs out. */
2079
+ interface LoginExitEvent {
2080
+ userId: string;
2081
+ username?: string;
2082
+ timestamp: Date;
2083
+ }
2084
+ /** Fired when authentication is initialized/loaded. */
2085
+ interface AuthInitializeEvent {
2086
+ userId: string;
2087
+ timestamp: Date;
2088
+ }
2089
+ /** Fired before authorization check. */
2090
+ interface AuthHandleBeforeEvent {
2091
+ userId: string;
2092
+ permissionId: string;
2093
+ action: string;
2094
+ /** Set to true by handlers to explicitly allow */
2095
+ allow?: boolean;
2096
+ /** Set to true to skip default authorization logic */
2097
+ skip?: boolean;
2098
+ timestamp: Date;
2099
+ }
2100
+ /** Fired when a new token is created. */
2101
+ interface TokenCreatedEvent {
2102
+ token: string;
2103
+ userId: string;
2104
+ type: string;
2105
+ timestamp: Date;
2106
+ }
2107
+ /** Fired when a token state changes. */
2108
+ interface TokenChangedEvent {
2109
+ token: string;
2110
+ userId: string;
2111
+ oldState: string;
2112
+ newState: string;
2113
+ timestamp: Date;
2114
+ }
2115
+ /** Fired when a token is removed. */
2116
+ interface TokenRemovedEvent {
2117
+ token: string;
2118
+ userId: string;
2119
+ timestamp: Date;
2120
+ }
2121
+ declare function createUserCreatedEvent(userId: string, username: string, creator?: string): UserCreatedEvent;
2122
+ declare function createUserModifiedEvent(userId: string, changes: FieldChange[], modifier?: string, passwordChanged?: boolean): UserModifiedEvent;
2123
+ declare function createUserDeletedEvent(userId: string, operator?: string): UserDeletedEvent;
2124
+ declare function createUserStateChangedEvent(userId: string, oldState: UserState, newState: UserState, operator?: string): UserStateChangedEvent;
2125
+ declare function createDimensionBindEvent(userId: string, dimensionType: string, dimensionId: string, operator?: string): DimensionBindEvent;
2126
+ declare function createDimensionUnbindEvent(userId: string, dimensionType: string, dimensionId: string, operator?: string): DimensionUnbindEvent;
2127
+ declare function createDimensionDeletedEvent(dimensionType: string, dimensionId: string): DimensionDeletedEvent;
2128
+ declare function createDimensionUserBind(userId: string, dimensionTypeId: string, dimensionId: string): DimensionUserBind;
2129
+ declare function createClearAuthCacheEvent(userId?: string, reason?: string): ClearUserAuthorizationCacheEvent;
2130
+ declare function createLoginBeforeEvent(username: string, parameters?: Record<string, unknown>): LoginBeforeEvent;
2131
+ declare function createLoginDecodeEvent(username: string, password?: string, parameters?: Record<string, unknown>): LoginDecodeEvent;
2132
+ declare function createLoginSuccessEvent(userId: string, username: string, result?: Record<string, unknown>, parameters?: Record<string, unknown>): LoginSuccessEvent;
2133
+ declare function createLoginFailedEvent(username: string, error: string, exception?: Error, parameters?: Record<string, unknown>): LoginFailedEvent;
2134
+ declare function createLoginExitEvent(userId: string, username?: string): LoginExitEvent;
2135
+ declare function createAuthInitializeEvent(userId: string): AuthInitializeEvent;
2136
+ declare function createAuthHandleBeforeEvent(userId: string, permissionId: string, action: string): AuthHandleBeforeEvent;
2137
+ declare function createTokenCreatedEvent(token: string, userId: string, type: string): TokenCreatedEvent;
2138
+ declare function createTokenChangedEvent(token: string, userId: string, oldState: string, newState: string): TokenChangedEvent;
2139
+ declare function createTokenRemovedEvent(token: string, userId: string): TokenRemovedEvent;
2140
+
2141
+ /**
2142
+ * TOTP (Time-based One-Time Password) validator.
2143
+ * Compatible with Google Authenticator (RFC 6238).
2144
+ *
2145
+ * Implements HMAC-based OTP without external dependencies.
2146
+ */
2147
+ declare class TotpValidator implements TwoFactorValidatorProvider {
2148
+ private readonly period;
2149
+ private readonly digits;
2150
+ private readonly window;
2151
+ private readonly validatedUntil;
2152
+ private secretResolver;
2153
+ constructor(options?: {
2154
+ period?: number;
2155
+ digits?: number;
2156
+ window?: number;
2157
+ secretResolver?: (userId: string) => Promise<string | null>;
2158
+ });
2159
+ getProvider(): string;
2160
+ createTwoFactorValidator(userId: string, operation: string): TwoFactorValidator;
2161
+ setSecretResolver(resolver: (userId: string) => Promise<string | null>): void;
2162
+ /**
2163
+ * Generate a random base32-encoded secret.
2164
+ */
2165
+ generateSecret(): string;
2166
+ /**
2167
+ * Generate a QR code URL (otpauth:// URI) for authenticator apps.
2168
+ */
2169
+ generateQRCodeUrl(secret: string, issuer: string, account: string): string;
2170
+ /**
2171
+ * Verify a TOTP token against a secret.
2172
+ * Accepts tokens within the configured time window.
2173
+ */
2174
+ private verifyToken;
2175
+ private generateToken;
2176
+ private buildCacheKey;
2177
+ }
2178
+
2179
+ /**
2180
+ * Bcrypt-compatible password encoder using Node.js built-in crypto.
2181
+ *
2182
+ * Uses PBKDF2 with SHA-512 as a secure alternative that requires no
2183
+ * external dependencies (bcryptjs). The output format includes the salt
2184
+ * and iteration count for self-contained verification.
2185
+ */
2186
+ declare class BcryptEncoder implements PasswordEncoder {
2187
+ private readonly iterations;
2188
+ private readonly keyLength;
2189
+ private readonly saltLength;
2190
+ constructor(options?: {
2191
+ iterations?: number;
2192
+ keyLength?: number;
2193
+ saltLength?: number;
2194
+ });
2195
+ encode(raw: string): Promise<string>;
2196
+ matches(raw: string, encoded: string): Promise<boolean>;
2197
+ private pbkdf2;
2198
+ }
2199
+
2200
+ /**
2201
+ * User personalization settings service.
2202
+ *
2203
+ * Stores per-user settings keyed by userId + scope + key.
2204
+ */
2205
+ declare class UserSettingsService {
2206
+ private readonly db;
2207
+ private readonly logger;
2208
+ constructor(db: DatabaseAdapter);
2209
+ get<T = unknown>(userId: string, scope: string, key: string): Promise<T | undefined>;
2210
+ /**
2211
+ * Get a setting as a SettingValueHolder.
2212
+ * Returns NullSettingValueHolder if not found.
2213
+ */
2214
+ getSetting(userId: string, key: string, scope?: string): Promise<SettingValueHolder>;
2215
+ set(userId: string, scope: string, key: string, value: unknown, permission?: UserSettingPermission): Promise<void>;
2216
+ /**
2217
+ * Save a setting with permission.
2218
+ */
2219
+ saveSetting(userId: string, key: string, value: string, permission?: UserSettingPermission, scope?: string): Promise<void>;
2220
+ getAll(userId: string, scope: string): Promise<Record<string, unknown>>;
2221
+ delete(userId: string, scope: string, key: string): Promise<void>;
2222
+ deleteAll(userId: string, scope?: string): Promise<void>;
2223
+ }
2224
+
2225
+ /**
2226
+ * Authorization definition types
2227
+ *
2228
+ * ResourceDefinition / ResourceActionDefinition / AuthorizeDefinition
2229
+ * describe the permission model that gets scanned from decorators at startup
2230
+ * and stored for runtime RBAC checks.
2231
+ */
2232
+ /** Logical operator for combining permission checks */
2233
+ type Logical = 'AND' | 'OR' | 'DEFAULT';
2234
+ /** Phase of authorization check */
2235
+ type Phased = 'before' | 'after';
2236
+ /** Handle type for authorization events */
2237
+ type HandleType = 'RBAC' | 'DATA';
2238
+ interface DataAccessTypeDefinition {
2239
+ id: string;
2240
+ name: string;
2241
+ description?: string;
2242
+ controller?: string;
2243
+ configuration?: Record<string, unknown>;
2244
+ }
2245
+ interface DataAccessDefinition {
2246
+ dataAccessTypes: Set<DataAccessTypeDefinition>;
2247
+ }
2248
+ declare function createDataAccessDefinition(): DataAccessDefinition;
2249
+ /**
2250
+ * Defines a single action within a resource (e.g. query, save, delete).
2251
+ */
2252
+ interface ResourceActionDefinition {
2253
+ id: string;
2254
+ name: string;
2255
+ description?: string;
2256
+ dataAccess: DataAccessDefinition;
2257
+ }
2258
+ declare function createResourceActionDefinition(id: string, name: string, description?: string): ResourceActionDefinition;
2259
+ /**
2260
+ * Defines a permission resource (e.g. "user", "device", "role").
2261
+ */
2262
+ interface ResourceDefinition {
2263
+ id: string;
2264
+ name: string;
2265
+ description?: string;
2266
+ actions: Map<string, ResourceActionDefinition>;
2267
+ group?: string[];
2268
+ logical: Logical;
2269
+ phased: Phased;
2270
+ }
2271
+ declare function createResourceDefinition(id: string, name: string, options?: {
2272
+ description?: string;
2273
+ logical?: Logical;
2274
+ phased?: Phased;
2275
+ group?: string[];
2276
+ }): ResourceDefinition;
2277
+ /** Add an action to a resource, merging data access types if action already exists */
2278
+ declare function addActionToResource(resource: ResourceDefinition, action: ResourceActionDefinition): void;
2279
+ /** Get all action IDs for a resource */
2280
+ declare function getActionIds(resource: ResourceDefinition): Set<string>;
2281
+ /** Check if a resource has specific actions (respects logical AND/OR) */
2282
+ declare function hasAction(resource: ResourceDefinition, actions: string[]): boolean;
2283
+ /** Get actions that have data access definitions */
2284
+ declare function getDataAccessActions(resource: ResourceDefinition): ResourceActionDefinition[];
2285
+ interface DimensionDefinition {
2286
+ typeId: string;
2287
+ dimensionIds: Set<string>;
2288
+ logical: Logical;
2289
+ }
2290
+ /**
2291
+ * Complete authorization definition for a controller method.
2292
+ */
2293
+ interface AuthorizeDefinition {
2294
+ resources: ResourceDefinition[];
2295
+ dimensions: DimensionDefinition[];
2296
+ message: string;
2297
+ phased: Phased;
2298
+ isEmpty: boolean;
2299
+ }
2300
+ declare function createEmptyAuthorizeDefinition(): AuthorizeDefinition;
2301
+ /** Get human-readable description of the definition (e.g. "user:query,save") */
2302
+ declare function getDefinitionDescription(def: AuthorizeDefinition): string;
2303
+ /**
2304
+ * Check if an authentication has permission matching the resource definitions.
2305
+ */
2306
+ declare function hasPermissionForResources(resources: ResourceDefinition[], hasPermissionFn: (resourceId: string, actions: string[]) => boolean): boolean;
2307
+
2308
+ interface AllowPermissionConfig {
2309
+ /** Map of dimensionType -> dimensionId -> pattern */
2310
+ allows: Record<string, Record<string, string>>;
2311
+ }
2312
+ declare class UserAllowPermissionHandler {
2313
+ private readonly logger;
2314
+ private config;
2315
+ /**
2316
+ * Set the allows configuration.
2317
+ */
2318
+ setConfig(config: AllowPermissionConfig): void;
2319
+ /**
2320
+ * Check if the authentication is allowed to bypass permission checks
2321
+ * for the given controller path (className.methodName).
2322
+ *
2323
+ * @param authentication Current user authentication
2324
+ * @param controllerPath Full path like "UserController.query"
2325
+ * @returns true if allowed (skip permission check), false otherwise
2326
+ */
2327
+ isAllowed(authentication: Authentication, controllerPath: string): boolean;
2328
+ }
2329
+
2330
+ interface ZuckerAuthModuleAsyncOptions {
2331
+ imports?: Array<Type | DynamicModule>;
2332
+ /**
2333
+ * Register the framework's generic HTTP controllers.
2334
+ * Defaults to true for backwards compatibility.
2335
+ */
2336
+ registerControllers?: boolean;
2337
+ useFactory?: (...args: unknown[]) => ZuckerAuthModuleOptions | Promise<ZuckerAuthModuleOptions>;
2338
+ useClass?: Type<ZuckerAuthModuleOptionsFactory>;
2339
+ useExisting?: Type<ZuckerAuthModuleOptionsFactory>;
2340
+ inject?: Array<InjectionToken | OptionalFactoryDependency>;
2341
+ }
2342
+ interface ZuckerAuthModuleOptionsFactory {
2343
+ createAuthOptions(): ZuckerAuthModuleOptions | Promise<ZuckerAuthModuleOptions>;
2344
+ }
2345
+ declare class ZuckerAuthModule {
2346
+ /**
2347
+ * Build the common provider list shared by both forRoot and forRootAsync.
2348
+ *
2349
+ * @param optionsToken - injection token that resolves to ZuckerAuthModuleOptions
2350
+ * (AUTH_MODULE_OPTIONS for async, or a literal-value provider for sync)
2351
+ */
2352
+ private static buildProviders;
2353
+ /**
2354
+ * Build option-specific providers (cache, dimensions) that differ
2355
+ * between forRoot (has direct options) and forRootAsync (reads from token).
2356
+ */
2357
+ private static buildOptionSpecificProviders;
2358
+ static forRoot(options?: ZuckerAuthModuleOptions): DynamicModule;
2359
+ static forRootAsync(asyncOptions: ZuckerAuthModuleAsyncOptions): DynamicModule;
2360
+ private static createAsyncProviders;
2361
+ }
2362
+
2363
+ export { ACTION_KEY, AUTHENTICATION_MANAGER, AUTHENTICATION_SUPPLIERS, AUTHORIZE_KEY, AUTH_EVENT_TOPICS, Action, type ActionOptions, AllopatricLoginMode, type AllowPermissionConfig, type AuthHandleBeforeEvent, type AuthInitializeEvent, type AuthUser, type Authentication, AuthenticationHolder, type AuthenticationManagerLike, type AuthenticationPredicate, AuthenticationPredicates, type AuthenticationSupplier, AuthorizationController, type AuthorizationSettingEntity, AuthorizationSettingService, Authorize, type AuthorizeDefinition, type AuthorizeLogical, type AuthorizeOptions, type AuthorizePhased, type AuthorizeResourceOptions, type AuthorizingContext, BcryptEncoder, type ClearUserAuthorizationCacheEvent, CreateAction, CurrentUser, DATA_ACCESS_HANDLERS, DATA_ACCESS_RESULT_KEY, DATA_PERMISSION_KEY, DEFAULT_PASSWORD_POLICY, DEFAULT_USERNAME_POLICY, DIMENSION_KEY, DIMENSION_PROVIDERS, type DataAccessConfig, DefaultDataAccessType as DataAccessConfigDefaultType, type DataAccessDefinition, type DataAccessHandler, type DataAccessResult, type DataAccessType, type DataAccessTypeDefinition, DataPermission, DataPermissionGuard, type DataPermissionOptions, DefaultAuthentication, DefaultDataAccessType, DefaultDimensionType, DeleteAction, DepartmentDimensionProvider, type Dimension, type DimensionBindEvent, DimensionCheck, type DimensionDataAccessConfig, DimensionDataAccessHandler, type DimensionDefinition, type DimensionDeletedEvent, type DimensionOptions, type DimensionProvider, DimensionService, type DimensionType, type DimensionUnbindEvent, type DimensionUserBind, type DimensionUserEntity, DimensionUserService, type FieldChange, type FieldFilterDataAccessConfig, FieldFilterDataAccessHandler, type HandleType, IS_PUBLIC_KEY, JwtAuthGuard, type JwtPayload, JwtStrategy, type Logical, type LoginBeforeEvent, type LoginDecodeEvent, type LoginExitEvent, type LoginFailedEvent, type LoginRequest, type LoginResult, type LoginSuccessEvent, MenuController, type MenuNode, MenuService, NullSettingValueHolder, type OwnCreatedDataAccessConfig, OwnCreatedDataAccessHandler, PASSWORD_ENCODER, PERMISSIONS_KEY, type PasswordEncoder, type PasswordPolicy, PasswordValidator, type Permission, PermissionActions, PermissionScannerService, PermissionService, PermissionSyncService, Permissions, PermissionsGuard, type Phased, Public, QueryAction, RESOURCE_KEY, ROLE_EVENT_TOPICS, RequirePermissions, RequiresRoles, type RequiresRolesOptions, type ResolvedAuthorizeOptions, Resource, ResourceAction, type ResourceActionDefinition, type ResourceDefinition, type ResourceOptions, type Role, type RoleEntity, RoleHierarchyService, RoleService, type RoleTreeNode, SaveAction, type ScannedPermission, type ScopeDataAccessConfig, ScopeDataAccessHandler, type SettingValueHolder, SimpleDimension, SimpleDimensionType, SimplePermission, SkipDataPermission, type SupplierContext, TOKEN_CACHE, TWO_FACTOR_KEY, TWO_FACTOR_PROVIDERS, ThirdPartyAccountController, ThirdPartyAccountService, type ThirdPartyProfile, type TokenChangedEvent, type TokenCreatedEvent, type TokenInfo, TokenInfoUtils, type TokenRemovedEvent, TokenService, type TokenServiceOptions, TokenState, TotpValidator, TwoFactor, TwoFactorGuard, type TwoFactorOptions, TwoFactorService, type TwoFactorValidator, type TwoFactorValidatorProvider, UpdateAction, UserAllowPermissionHandler, type UserCreatedEvent, type UserDeletedEvent, type UserEntity, type UserModifiedEvent, UserService, UserSettingPermission, UserSettingsService, type UserState, type UserStateChangedEvent, UserTokenController, type UsernamePolicy, type UsernameValidationResult, UsernameValidator, ZuckerAuthModule, type ZuckerAuthModuleAsyncOptions, type ZuckerAuthModuleOptions, type ZuckerAuthModuleOptionsFactory, addActionToResource, allowResult, createAuthHandleBeforeEvent, createAuthInitializeEvent, createAuthenticationPredicate, createClearAuthCacheEvent, createDataAccessDefinition, createDimensionBindEvent, createDimensionDeletedEvent, createDimensionUnbindEvent, createDimensionUserBind, createEmptyAuthorizeDefinition, createLoginBeforeEvent, createLoginDecodeEvent, createLoginExitEvent, createLoginFailedEvent, createLoginSuccessEvent, createResourceActionDefinition, createResourceDefinition, createRoleCreatedEvent, createRoleDeletedEvent, createRoleModifiedEvent, createSettingValueHolder, createTokenChangedEvent, createTokenCreatedEvent, createTokenRemovedEvent, createUserCreatedEvent, createUserDeletedEvent, createUserModifiedEvent, createUserStateChangedEvent, denyResult, dimensionConfig, fieldFilterConfig, filterResult, fromJwtUser, getActionIds, getDataAccessActions, getDefinitionDescription, hasAction, hasPermissionForResources, mergeResults, ownCreatedConfig, scopeConfig };