@flusys/nestjs-auth 0.1.0-beta.3 → 1.1.0-beta

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/README.md +1 -11
  2. package/cjs/config/auth.constants.js +14 -4
  3. package/cjs/controllers/authentication.controller.js +173 -36
  4. package/cjs/controllers/branch.controller.js +3 -4
  5. package/cjs/controllers/company.controller.js +3 -4
  6. package/cjs/controllers/user-permission.controller.js +6 -18
  7. package/cjs/controllers/user.controller.js +168 -22
  8. package/cjs/dtos/authentication.dto.js +106 -3
  9. package/cjs/entities/index.js +5 -1
  10. package/cjs/entities/pending-registration.entity.js +125 -0
  11. package/cjs/entities/user-token.entity.js +129 -0
  12. package/cjs/interfaces/auth-email-provider.interface.js +45 -0
  13. package/cjs/interfaces/authentication.interface.js +0 -3
  14. package/cjs/interfaces/index.js +2 -0
  15. package/cjs/interfaces/user-enricher.interface.js +4 -0
  16. package/cjs/modules/auth.module.js +8 -2
  17. package/cjs/services/auth-config.service.js +22 -44
  18. package/cjs/services/auth-datasource.provider.js +17 -33
  19. package/cjs/services/auth-email.service.js +452 -0
  20. package/cjs/services/authentication.service.js +229 -115
  21. package/cjs/services/branch.service.js +10 -44
  22. package/cjs/services/company.service.js +7 -36
  23. package/cjs/services/index.js +1 -0
  24. package/cjs/services/user-permission.service.js +9 -27
  25. package/cjs/services/user.service.js +177 -99
  26. package/cjs/strategies/jwt.strategy.js +14 -1
  27. package/config/auth.constants.d.ts +3 -0
  28. package/controllers/authentication.controller.d.ts +13 -9
  29. package/controllers/user.controller.d.ts +27 -0
  30. package/dtos/authentication.dto.d.ts +21 -3
  31. package/dtos/user.dto.d.ts +1 -0
  32. package/entities/index.d.ts +7 -3
  33. package/entities/pending-registration.entity.d.ts +17 -0
  34. package/entities/user-token.entity.d.ts +15 -0
  35. package/fesm/config/auth.constants.js +18 -8
  36. package/fesm/controllers/authentication.controller.js +174 -37
  37. package/fesm/controllers/branch.controller.js +5 -6
  38. package/fesm/controllers/company.controller.js +5 -6
  39. package/fesm/controllers/user-permission.controller.js +6 -18
  40. package/fesm/controllers/user.controller.js +168 -22
  41. package/fesm/dtos/authentication.dto.js +109 -100
  42. package/fesm/entities/index.js +7 -1
  43. package/fesm/entities/pending-registration.entity.js +115 -0
  44. package/fesm/entities/user-token.entity.js +113 -0
  45. package/fesm/interfaces/auth-email-provider.interface.js +38 -0
  46. package/fesm/interfaces/authentication.interface.js +1 -7
  47. package/fesm/interfaces/index.js +2 -0
  48. package/fesm/interfaces/user-enricher.interface.js +26 -0
  49. package/fesm/modules/auth.module.js +9 -3
  50. package/fesm/services/auth-config.service.js +22 -44
  51. package/fesm/services/auth-datasource.provider.js +17 -33
  52. package/fesm/services/auth-email.service.js +401 -0
  53. package/fesm/services/authentication.service.js +227 -113
  54. package/fesm/services/branch.service.js +11 -45
  55. package/fesm/services/company.service.js +8 -37
  56. package/fesm/services/index.js +1 -0
  57. package/fesm/services/user-permission.service.js +9 -27
  58. package/fesm/services/user.service.js +178 -100
  59. package/fesm/strategies/jwt.strategy.js +14 -1
  60. package/interfaces/auth-email-provider.interface.d.ts +6 -0
  61. package/interfaces/auth-module-options.interface.d.ts +4 -1
  62. package/interfaces/authentication.interface.d.ts +14 -0
  63. package/interfaces/index.d.ts +2 -0
  64. package/interfaces/user-enricher.interface.d.ts +67 -0
  65. package/interfaces/user.interface.d.ts +1 -0
  66. package/package.json +3 -3
  67. package/services/auth-config.service.d.ts +1 -0
  68. package/services/auth-email.service.d.ts +50 -0
  69. package/services/authentication.service.d.ts +21 -5
  70. package/services/branch.service.d.ts +2 -5
  71. package/services/company.service.d.ts +1 -4
  72. package/services/index.d.ts +1 -0
  73. package/services/user.service.d.ts +17 -6
@@ -0,0 +1,115 @@
1
+ function _define_property(obj, key, value) {
2
+ if (key in obj) {
3
+ Object.defineProperty(obj, key, {
4
+ value: value,
5
+ enumerable: true,
6
+ configurable: true,
7
+ writable: true
8
+ });
9
+ } else {
10
+ obj[key] = value;
11
+ }
12
+ return obj;
13
+ }
14
+ function _ts_decorate(decorators, target, key, desc) {
15
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
16
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
17
+ else for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
18
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
19
+ }
20
+ function _ts_metadata(k, v) {
21
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
22
+ }
23
+ import { Column, CreateDateColumn, Entity, Index, PrimaryGeneratedColumn } from 'typeorm';
24
+ export class PendingRegistration {
25
+ constructor(){
26
+ _define_property(this, "id", void 0);
27
+ _define_property(this, "email", void 0);
28
+ _define_property(this, "name", void 0);
29
+ _define_property(this, "phone", void 0);
30
+ _define_property(this, "passwordHash", void 0);
31
+ _define_property(this, "token", void 0);
32
+ _define_property(this, "expiresAt", void 0);
33
+ _define_property(this, "companyData", void 0);
34
+ _define_property(this, "createdAt", void 0);
35
+ }
36
+ }
37
+ _ts_decorate([
38
+ PrimaryGeneratedColumn('uuid'),
39
+ _ts_metadata("design:type", String)
40
+ ], PendingRegistration.prototype, "id", void 0);
41
+ _ts_decorate([
42
+ Column({
43
+ type: 'varchar',
44
+ length: 255
45
+ }),
46
+ _ts_metadata("design:type", String)
47
+ ], PendingRegistration.prototype, "email", void 0);
48
+ _ts_decorate([
49
+ Column({
50
+ type: 'varchar',
51
+ length: 255,
52
+ nullable: true
53
+ }),
54
+ _ts_metadata("design:type", Object)
55
+ ], PendingRegistration.prototype, "name", void 0);
56
+ _ts_decorate([
57
+ Column({
58
+ type: 'varchar',
59
+ length: 255,
60
+ nullable: true
61
+ }),
62
+ _ts_metadata("design:type", Object)
63
+ ], PendingRegistration.prototype, "phone", void 0);
64
+ _ts_decorate([
65
+ Column({
66
+ type: 'text',
67
+ name: 'passwordHash'
68
+ }),
69
+ _ts_metadata("design:type", String)
70
+ ], PendingRegistration.prototype, "passwordHash", void 0);
71
+ _ts_decorate([
72
+ Column({
73
+ type: 'varchar',
74
+ length: 64
75
+ }),
76
+ _ts_metadata("design:type", String)
77
+ ], PendingRegistration.prototype, "token", void 0);
78
+ _ts_decorate([
79
+ Column({
80
+ type: 'timestamp',
81
+ name: 'expires_at'
82
+ }),
83
+ _ts_metadata("design:type", typeof Date === "undefined" ? Object : Date)
84
+ ], PendingRegistration.prototype, "expiresAt", void 0);
85
+ _ts_decorate([
86
+ Column({
87
+ type: 'json',
88
+ nullable: true,
89
+ name: 'company_data'
90
+ }),
91
+ _ts_metadata("design:type", Object)
92
+ ], PendingRegistration.prototype, "companyData", void 0);
93
+ _ts_decorate([
94
+ CreateDateColumn({
95
+ type: 'timestamp',
96
+ name: 'created_at'
97
+ }),
98
+ _ts_metadata("design:type", typeof Date === "undefined" ? Object : Date)
99
+ ], PendingRegistration.prototype, "createdAt", void 0);
100
+ PendingRegistration = _ts_decorate([
101
+ Entity('pending_registrations'),
102
+ Index('IDX_pending_reg_email', [
103
+ 'email'
104
+ ], {
105
+ unique: true
106
+ }),
107
+ Index('IDX_pending_reg_token', [
108
+ 'token'
109
+ ], {
110
+ unique: true
111
+ }),
112
+ Index('IDX_pending_reg_expires', [
113
+ 'expiresAt'
114
+ ])
115
+ ], PendingRegistration);
@@ -0,0 +1,113 @@
1
+ function _define_property(obj, key, value) {
2
+ if (key in obj) {
3
+ Object.defineProperty(obj, key, {
4
+ value: value,
5
+ enumerable: true,
6
+ configurable: true,
7
+ writable: true
8
+ });
9
+ } else {
10
+ obj[key] = value;
11
+ }
12
+ return obj;
13
+ }
14
+ function _ts_decorate(decorators, target, key, desc) {
15
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
16
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
17
+ else for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
18
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
19
+ }
20
+ function _ts_metadata(k, v) {
21
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
22
+ }
23
+ import { Column, CreateDateColumn, Entity, Index, PrimaryGeneratedColumn } from 'typeorm';
24
+ /**
25
+ * Token types for various user actions
26
+ */ export var TokenType = /*#__PURE__*/ function(TokenType) {
27
+ TokenType["PASSWORD_RESET"] = "password_reset";
28
+ TokenType["EMAIL_VERIFICATION"] = "email_verification";
29
+ TokenType["EMAIL_CHANGE"] = "email_change";
30
+ return TokenType;
31
+ }({});
32
+ export class UserToken {
33
+ constructor(){
34
+ _define_property(this, "id", void 0);
35
+ _define_property(this, "userId", void 0);
36
+ _define_property(this, "type", void 0);
37
+ _define_property(this, "token", void 0);
38
+ _define_property(this, "expiresAt", void 0);
39
+ _define_property(this, "usedAt", void 0);
40
+ _define_property(this, "metadata", void 0);
41
+ _define_property(this, "createdAt", void 0);
42
+ }
43
+ }
44
+ _ts_decorate([
45
+ PrimaryGeneratedColumn('uuid'),
46
+ _ts_metadata("design:type", String)
47
+ ], UserToken.prototype, "id", void 0);
48
+ _ts_decorate([
49
+ Column({
50
+ type: 'uuid',
51
+ name: 'user_id'
52
+ }),
53
+ _ts_metadata("design:type", String)
54
+ ], UserToken.prototype, "userId", void 0);
55
+ _ts_decorate([
56
+ Column({
57
+ type: 'varchar',
58
+ length: 32
59
+ }),
60
+ _ts_metadata("design:type", String)
61
+ ], UserToken.prototype, "type", void 0);
62
+ _ts_decorate([
63
+ Column({
64
+ type: 'varchar',
65
+ length: 64
66
+ }),
67
+ _ts_metadata("design:type", String)
68
+ ], UserToken.prototype, "token", void 0);
69
+ _ts_decorate([
70
+ Column({
71
+ type: 'timestamp',
72
+ name: 'expires_at'
73
+ }),
74
+ _ts_metadata("design:type", typeof Date === "undefined" ? Object : Date)
75
+ ], UserToken.prototype, "expiresAt", void 0);
76
+ _ts_decorate([
77
+ Column({
78
+ type: 'timestamp',
79
+ name: 'used_at',
80
+ nullable: true
81
+ }),
82
+ _ts_metadata("design:type", Object)
83
+ ], UserToken.prototype, "usedAt", void 0);
84
+ _ts_decorate([
85
+ Column({
86
+ type: 'varchar',
87
+ length: 255,
88
+ nullable: true
89
+ }),
90
+ _ts_metadata("design:type", Object)
91
+ ], UserToken.prototype, "metadata", void 0);
92
+ _ts_decorate([
93
+ CreateDateColumn({
94
+ type: 'timestamp',
95
+ name: 'created_at'
96
+ }),
97
+ _ts_metadata("design:type", typeof Date === "undefined" ? Object : Date)
98
+ ], UserToken.prototype, "createdAt", void 0);
99
+ UserToken = _ts_decorate([
100
+ Entity('user_tokens'),
101
+ Index('IDX_user_token_token', [
102
+ 'token'
103
+ ], {
104
+ unique: true
105
+ }),
106
+ Index('IDX_user_token_user_type', [
107
+ 'userId',
108
+ 'type'
109
+ ]),
110
+ Index('IDX_user_token_expires', [
111
+ 'expiresAt'
112
+ ])
113
+ ], UserToken);
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Auth Email Provider Interface
3
+ *
4
+ * This interface defines the contract for email sending in the auth module.
5
+ * It allows auth to work independently of the email module.
6
+ *
7
+ * To use email features in auth:
8
+ * 1. Provide AUTH_EMAIL_PROVIDER in your app module
9
+ * 2. Implement IAuthEmailProvider using EmailSendService from nestjs-email
10
+ *
11
+ * @example
12
+ * ```typescript
13
+ * // In app.module.ts or a provider file
14
+ * {
15
+ * provide: AUTH_EMAIL_PROVIDER,
16
+ * useFactory: (emailSendService: EmailSendService) => ({
17
+ * sendPasswordResetEmail: async (email, token, resetUrl) => {
18
+ * await emailSendService.sendTemplateEmail({
19
+ * templateSlug: 'password-reset',
20
+ * to: email,
21
+ * variables: { resetUrl, token },
22
+ * });
23
+ * },
24
+ * sendVerificationEmail: async (email, token, verifyUrl) => {
25
+ * await emailSendService.sendTemplateEmail({
26
+ * templateSlug: 'email-verification',
27
+ * to: email,
28
+ * variables: { verifyUrl, token },
29
+ * });
30
+ * },
31
+ * }),
32
+ * inject: [EmailSendService],
33
+ * }
34
+ * ```
35
+ */ /**
36
+ * Injection token for auth email provider
37
+ * Use this to provide the email implementation
38
+ */ export const AUTH_EMAIL_PROVIDER = 'AUTH_EMAIL_PROVIDER';
@@ -1,7 +1 @@
1
- // =============================================================================
2
- // TOKEN INTERFACES
3
- // =============================================================================
4
- /**
5
- * Login Response when company/branch selection is required
6
- * Frontend shows selection UI and calls /select endpoint with chosen company + branch
7
- */ export { };
1
+ /** Login Response when email verification is required */ export { };
@@ -1,5 +1,7 @@
1
1
  export * from './authentication.interface';
2
+ export * from './auth-email-provider.interface';
2
3
  export * from './company-branch.interface';
3
4
  export * from './company.interface';
4
5
  export * from './user.interface';
6
+ export * from './user-enricher.interface';
5
7
  export * from './auth-module-options.interface';
@@ -0,0 +1,26 @@
1
+ /**
2
+ * User Enricher Provider Interface
3
+ *
4
+ * Allows consuming applications to extend user list and profile
5
+ * without modifying the base nestjs-auth package.
6
+ *
7
+ * This follows the Provider Interface Pattern:
8
+ * - nestjs-auth defines the interface (this file)
9
+ * - Consuming apps implement the interface
10
+ * - nestjs-auth optionally injects the implementation
11
+ *
12
+ * @example
13
+ * // In your app module
14
+ * providers: [
15
+ * { provide: USER_ENRICHER, useClass: MyUserEnricher },
16
+ * ]
17
+ *
18
+ * // Your enricher implementation
19
+ * @Injectable()
20
+ * export class MyUserEnricher implements IUserEnricher {
21
+ * async enrichListQuery(query, user) {
22
+ * query.leftJoinAndSelect('user.department', 'department');
23
+ * return { extraFields: ['department.name'] };
24
+ * }
25
+ * }
26
+ */ export { };
@@ -17,14 +17,14 @@ import { Company, CompanyBranch, User, UserCompanyPermission } from '../entities
17
17
  import { JwtAuthGuard } from '@flusys/nestjs-shared/guards';
18
18
  import { ClearToken } from '../interceptors/clear-token.interceptor';
19
19
  import { SetToken } from '../interceptors/set-token.interceptor';
20
- import { AuthenticationService, BranchService, CompanySelectionSessionService, CompanyService, UserPermissionService, UserService } from '../services';
20
+ import { AuthEmailService, AuthenticationService, BranchService, CompanySelectionSessionService, CompanyService, UserPermissionService, UserService } from '../services';
21
21
  import { JwtStrategy } from '../strategies/jwt.strategy';
22
22
  export class AuthModule {
23
23
  static forRoot(options) {
24
24
  return this.buildDynamicModule(options);
25
25
  }
26
26
  static forRootAsync(asyncOptions) {
27
- const { global = false, includeController = true, bootstrapAppConfig: { enableCompanyFeature } = {}, imports: externalImports = [] } = asyncOptions;
27
+ const { global = false, includeController = true, bootstrapAppConfig: { enableCompanyFeature } = {}, imports: externalImports = [], providers: additionalProviders = [] } = asyncOptions;
28
28
  const asyncProviders = this.createAsyncProviders(asyncOptions);
29
29
  // Build imports
30
30
  const imports = [
@@ -51,6 +51,7 @@ export class AuthModule {
51
51
  // Build providers
52
52
  const providers = [
53
53
  ...asyncProviders,
54
+ ...additionalProviders,
54
55
  // Config & Infrastructure
55
56
  AuthConfigService,
56
57
  AuthDataSourceProvider,
@@ -58,6 +59,7 @@ export class AuthModule {
58
59
  JwtStrategy,
59
60
  JwtAuthGuard,
60
61
  AuthenticationService,
62
+ AuthEmailService,
61
63
  // Interceptors
62
64
  SetToken,
63
65
  ClearToken,
@@ -77,6 +79,7 @@ export class AuthModule {
77
79
  JwtStrategy,
78
80
  JwtAuthGuard,
79
81
  AuthenticationService,
82
+ AuthEmailService,
80
83
  UserService
81
84
  ];
82
85
  if (enableCompanyFeature) {
@@ -92,7 +95,7 @@ export class AuthModule {
92
95
  };
93
96
  }
94
97
  static buildDynamicModule(options) {
95
- const { bootstrapAppConfig: { enableCompanyFeature } = {}, includeController = true, global = false } = options;
98
+ const { bootstrapAppConfig: { enableCompanyFeature } = {}, includeController = true, global = false, providers: additionalProviders = [] } = options;
96
99
  const imports = [
97
100
  PassportModule.register({
98
101
  defaultStrategy: 'jwt'
@@ -118,6 +121,7 @@ export class AuthModule {
118
121
  provide: AUTH_MODULE_OPTIONS,
119
122
  useValue: options
120
123
  },
124
+ ...additionalProviders,
121
125
  // Config & Infrastructure
122
126
  AuthConfigService,
123
127
  AuthDataSourceProvider,
@@ -125,6 +129,7 @@ export class AuthModule {
125
129
  JwtStrategy,
126
130
  JwtAuthGuard,
127
131
  AuthenticationService,
132
+ AuthEmailService,
128
133
  // Interceptors
129
134
  SetToken,
130
135
  ClearToken,
@@ -143,6 +148,7 @@ export class AuthModule {
143
148
  JwtStrategy,
144
149
  JwtAuthGuard,
145
150
  AuthenticationService,
151
+ AuthEmailService,
146
152
  UserService
147
153
  ];
148
154
  if (enableCompanyFeature) {
@@ -29,76 +29,54 @@ import { Inject, Injectable, Optional } from '@nestjs/common';
29
29
  import { AuthModuleOptions } from '../interfaces/auth-module-options.interface';
30
30
  import { AUTH_MODULE_OPTIONS } from '../config/auth.constants';
31
31
  export class AuthConfigService {
32
- // ==================== Database Mode ====================
33
- /**
34
- * Get database mode (single or multi-tenant)
35
- */ getDatabaseMode() {
32
+ // Database Mode
33
+ /** Get database mode (single or multi-tenant) */ getDatabaseMode() {
36
34
  return this.options.bootstrapAppConfig?.databaseMode ?? 'single';
37
35
  }
38
- /**
39
- * Check if running in multi-tenant mode
40
- */ isMultiTenant() {
36
+ /** Check if running in multi-tenant mode */ isMultiTenant() {
41
37
  return this.getDatabaseMode() === 'multi-tenant';
42
38
  }
43
- // ==================== Feature Flags ====================
44
- /**
45
- * Check if company feature is enabled
46
- */ isCompanyFeatureEnabled() {
39
+ // Feature Flags
40
+ /** Check if company feature is enabled */ isCompanyFeatureEnabled() {
47
41
  return this.options.bootstrapAppConfig?.enableCompanyFeature ?? false;
48
42
  }
49
- // ==================== JWT Configuration ====================
50
- /**
51
- * Get JWT secret key
52
- */ getJwtSecret() {
43
+ // JWT Configuration
44
+ /** Get JWT secret key */ getJwtSecret() {
53
45
  return this.config.jwtSecret ?? 'default-secret-change-in-production';
54
46
  }
55
- /**
56
- * Get JWT expiration time
57
- */ getJwtExpiration() {
47
+ /** Get JWT expiration time */ getJwtExpiration() {
58
48
  return this.config.jwtExpiration ?? '1h';
59
49
  }
60
- /**
61
- * Get refresh token secret key
62
- */ getRefreshTokenSecret() {
50
+ /** Get refresh token secret key */ getRefreshTokenSecret() {
63
51
  return this.config.refreshTokenSecret ?? this.getJwtSecret();
64
52
  }
65
- /**
66
- * Get refresh token expiration time
67
- */ getRefreshTokenExpiration() {
53
+ /** Get refresh token expiration time */ getRefreshTokenExpiration() {
68
54
  return this.config.refreshTokenExpiration ?? '7d';
69
55
  }
70
- /**
71
- * Get refresh token cookie name
72
- */ getRefreshTokenCookieName() {
56
+ /** Get refresh token cookie name */ getRefreshTokenCookieName() {
73
57
  return this.config.refreshTokenCookieName ?? 'fsn_refresh_token';
74
58
  }
75
- // ==================== Database Configuration ====================
76
- /**
77
- * Get default database config
78
- */ getDefaultDatabaseConfig() {
59
+ // Frontend Configuration
60
+ /** Get frontend URL for email links */ getFrontendUrl() {
61
+ return this.config.frontendUrl;
62
+ }
63
+ // Database Configuration
64
+ /** Get default database config */ getDefaultDatabaseConfig() {
79
65
  return this.config.defaultDatabaseConfig ?? this.config.tenantDefaultDatabaseConfig;
80
66
  }
81
- /**
82
- * Get tenant default database config (for multi-tenant)
83
- */ getTenantDefaultDatabaseConfig() {
67
+ /** Get tenant default database config (for multi-tenant) */ getTenantDefaultDatabaseConfig() {
84
68
  return this.config.tenantDefaultDatabaseConfig;
85
69
  }
86
- /**
87
- * Get registered tenants
88
- */ getTenants() {
70
+ /** Get registered tenants */ getTenants() {
89
71
  return this.config.tenants ?? [];
90
72
  }
91
- // ==================== Raw Options ====================
92
- /**
93
- * Get full module options
94
- */ getOptions() {
73
+ // Raw Options
74
+ /** Get full module options */ getOptions() {
95
75
  return {
96
76
  ...this.options
97
77
  };
98
78
  }
99
- /**
100
- * Get runtime config
101
- */ getConfig() {
79
+ /** Get runtime config */ getConfig() {
102
80
  return {
103
81
  ...this.config
104
82
  };
@@ -32,11 +32,8 @@ import { Request } from 'express';
32
32
  import { AuthModuleOptions } from '../interfaces/auth-module-options.interface';
33
33
  import { AUTH_MODULE_OPTIONS } from '../config/auth.constants';
34
34
  export class AuthDataSourceProvider extends MultiTenantDataSourceService {
35
- // ==================== Override Static Cache Access Methods ====================
36
- /**
37
- * CRITICAL: Override to access Auth-specific static properties
38
- * Without this, parent class methods would access parent's static properties
39
- */ async getSingleDataSource() {
35
+ // Override Static Cache Access Methods
36
+ /** Override to access Auth-specific static properties */ async getSingleDataSource() {
40
37
  if (!AuthDataSourceProvider.singleDataSource) {
41
38
  if (AuthDataSourceProvider.singleConnectionLock) {
42
39
  return AuthDataSourceProvider.singleConnectionLock;
@@ -60,9 +57,7 @@ export class AuthDataSourceProvider extends MultiTenantDataSourceService {
60
57
  }
61
58
  return AuthDataSourceProvider.singleDataSource;
62
59
  }
63
- /**
64
- * CRITICAL: Override to use Auth-specific static cache for tenant connections
65
- */ async getOrCreateTenantConnection(tenant) {
60
+ /** Override to use Auth-specific static cache for tenant connections */ async getOrCreateTenantConnection(tenant) {
66
61
  // Return existing initialized connection from Auth-specific cache
67
62
  const existing = AuthDataSourceProvider.tenantConnections.get(tenant.id);
68
63
  if (existing?.isInitialized) {
@@ -85,10 +80,8 @@ export class AuthDataSourceProvider extends MultiTenantDataSourceService {
85
80
  AuthDataSourceProvider.connectionLocks.delete(tenant.id);
86
81
  }
87
82
  }
88
- // ==================== Factory Methods ====================
89
- /**
90
- * Build parent options from AuthModuleOptions
91
- */ static buildParentOptions(options) {
83
+ // Factory Methods
84
+ /** Build parent options from AuthModuleOptions */ static buildParentOptions(options) {
92
85
  return {
93
86
  bootstrapAppConfig: options.bootstrapAppConfig,
94
87
  defaultDatabaseConfig: options.config?.defaultDatabaseConfig,
@@ -96,31 +89,24 @@ export class AuthDataSourceProvider extends MultiTenantDataSourceService {
96
89
  tenants: options.config?.tenants
97
90
  };
98
91
  }
99
- // ==================== Feature Flags ====================
100
- /**
101
- * Get global enable company feature flag
102
- */ getEnableCompanyFeature() {
92
+ // Feature Flags
93
+ /** Get global enable company feature flag */ getEnableCompanyFeature() {
103
94
  return this.authOptions.bootstrapAppConfig?.enableCompanyFeature ?? false;
104
95
  }
105
- /**
106
- * Get enable company feature for specific tenant
107
- * Falls back to global setting if not specified per-tenant
108
- */ getEnableCompanyFeatureForTenant(tenant) {
96
+ /** Get enable company feature for specific tenant. Falls back to global setting. */ getEnableCompanyFeatureForTenant(tenant) {
109
97
  return tenant?.enableCompanyFeature ?? this.getEnableCompanyFeature();
110
98
  }
111
- /**
112
- * Get enable company feature for current request context
113
- */ getEnableCompanyFeatureForCurrentTenant() {
99
+ /** Get enable company feature for current request context */ getEnableCompanyFeatureForCurrentTenant() {
114
100
  return this.getEnableCompanyFeatureForTenant(this.getCurrentTenant() ?? undefined);
115
101
  }
116
- // ==================== Entity Management ====================
117
- /**
118
- * Get auth entities based on company feature flag
119
- */ async getAuthEntities(enableCompanyFeature) {
102
+ // Entity Management
103
+ /** Get auth entities based on company feature flag */ async getAuthEntities(enableCompanyFeature) {
120
104
  const enable = enableCompanyFeature ?? this.getEnableCompanyFeature();
121
- const { Company, CompanyBranch, User, UserCompanyPermission } = await import('../entities');
105
+ const { Company, CompanyBranch, User, UserCompanyPermission, UserToken, PendingRegistration } = await import('../entities');
122
106
  const coreEntities = [
123
- User
107
+ User,
108
+ UserToken,
109
+ PendingRegistration
124
110
  ];
125
111
  const companyEntities = enable ? [
126
112
  Company,
@@ -132,10 +118,8 @@ export class AuthDataSourceProvider extends MultiTenantDataSourceService {
132
118
  ...companyEntities
133
119
  ];
134
120
  }
135
- // ==================== Overrides ====================
136
- /**
137
- * Override to dynamically set entities based on tenant config
138
- */ async createDataSourceFromConfig(config) {
121
+ // Overrides
122
+ /** Override to dynamically set entities based on tenant config */ async createDataSourceFromConfig(config) {
139
123
  const currentTenant = this.getCurrentTenant();
140
124
  const enableCompanyFeature = this.getEnableCompanyFeatureForTenant(currentTenant ?? undefined);
141
125
  const entities = await this.getAuthEntities(enableCompanyFeature);