@flusys/nestjs-auth 1.1.0-beta → 1.1.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.
Files changed (94) hide show
  1. package/README.md +633 -468
  2. package/cjs/config/auth.constants.js +8 -0
  3. package/cjs/controllers/authentication.controller.js +175 -167
  4. package/cjs/controllers/branch.controller.js +44 -1
  5. package/cjs/controllers/company-selection.controller.js +27 -20
  6. package/cjs/controllers/company.controller.js +44 -1
  7. package/cjs/controllers/email-verification.controller.js +220 -0
  8. package/cjs/controllers/index.js +1 -0
  9. package/cjs/controllers/user-permission.controller.js +82 -154
  10. package/cjs/controllers/user.controller.js +68 -15
  11. package/cjs/docs/auth-swagger.config.js +14 -7
  12. package/cjs/dtos/authentication.dto.js +16 -43
  13. package/cjs/dtos/index.js +0 -1
  14. package/cjs/dtos/user-permission.dto.js +28 -0
  15. package/cjs/dtos/user.dto.js +19 -4
  16. package/cjs/entities/index.js +16 -17
  17. package/cjs/entities/user-company-permission.entity.js +3 -9
  18. package/cjs/interceptors/clear-token.interceptor.js +10 -23
  19. package/cjs/interceptors/set-token.interceptor.js +15 -55
  20. package/cjs/interfaces/auth-email-provider.interface.js +1 -1
  21. package/cjs/modules/auth.module.js +79 -154
  22. package/cjs/services/auth-config.service.js +33 -35
  23. package/cjs/services/auth-datasource.provider.js +18 -42
  24. package/cjs/services/auth-email.service.js +89 -85
  25. package/cjs/services/authentication.service.js +248 -414
  26. package/cjs/services/branch.service.js +9 -4
  27. package/cjs/services/company-selection-session.service.js +1 -1
  28. package/cjs/services/user-permission.service.js +43 -73
  29. package/cjs/services/user.service.js +78 -64
  30. package/cjs/strategies/jwt.strategy.js +44 -44
  31. package/cjs/validators/password.validator.js +45 -0
  32. package/config/auth.constants.d.ts +2 -0
  33. package/controllers/authentication.controller.d.ts +4 -10
  34. package/controllers/company-selection.controller.d.ts +6 -2
  35. package/controllers/email-verification.controller.d.ts +20 -0
  36. package/controllers/index.d.ts +1 -0
  37. package/controllers/user-permission.controller.d.ts +5 -4
  38. package/controllers/user.controller.d.ts +6 -0
  39. package/dtos/authentication.dto.d.ts +0 -4
  40. package/dtos/company-branch.dto.d.ts +0 -1
  41. package/dtos/company.dto.d.ts +0 -1
  42. package/dtos/index.d.ts +0 -1
  43. package/dtos/user-permission.dto.d.ts +4 -0
  44. package/dtos/user.dto.d.ts +1 -3
  45. package/entities/index.d.ts +5 -10
  46. package/entities/user-company-permission.entity.d.ts +1 -3
  47. package/fesm/config/auth.constants.js +6 -13
  48. package/fesm/controllers/authentication.controller.js +178 -170
  49. package/fesm/controllers/branch.controller.js +45 -2
  50. package/fesm/controllers/company-selection.controller.js +28 -21
  51. package/fesm/controllers/company.controller.js +45 -2
  52. package/fesm/controllers/email-verification.controller.js +210 -0
  53. package/fesm/controllers/index.js +1 -0
  54. package/fesm/controllers/user-permission.controller.js +84 -156
  55. package/fesm/controllers/user.controller.js +71 -18
  56. package/fesm/docs/auth-swagger.config.js +14 -7
  57. package/fesm/dtos/authentication.dto.js +17 -44
  58. package/fesm/dtos/index.js +0 -1
  59. package/fesm/dtos/user-permission.dto.js +28 -0
  60. package/fesm/dtos/user.dto.js +20 -5
  61. package/fesm/entities/index.js +17 -9
  62. package/fesm/entities/user-company-permission.entity.js +3 -9
  63. package/fesm/interceptors/clear-token.interceptor.js +9 -22
  64. package/fesm/interceptors/set-token.interceptor.js +14 -54
  65. package/fesm/interfaces/auth-email-provider.interface.js +1 -1
  66. package/fesm/modules/auth.module.js +82 -157
  67. package/fesm/services/auth-config.service.js +34 -36
  68. package/fesm/services/auth-datasource.provider.js +19 -43
  69. package/fesm/services/auth-email.service.js +90 -86
  70. package/fesm/services/authentication.service.js +248 -414
  71. package/fesm/services/branch.service.js +9 -4
  72. package/fesm/services/company-selection-session.service.js +1 -1
  73. package/fesm/services/user-permission.service.js +44 -74
  74. package/fesm/services/user.service.js +79 -65
  75. package/fesm/strategies/jwt.strategy.js +44 -44
  76. package/fesm/validators/password.validator.js +48 -0
  77. package/interceptors/clear-token.interceptor.d.ts +0 -1
  78. package/interceptors/set-token.interceptor.d.ts +1 -1
  79. package/interfaces/authentication.interface.d.ts +0 -4
  80. package/interfaces/user-enricher.interface.d.ts +1 -4
  81. package/modules/auth.module.d.ts +9 -4
  82. package/package.json +4 -4
  83. package/services/auth-config.service.d.ts +7 -8
  84. package/services/auth-datasource.provider.d.ts +3 -4
  85. package/services/auth-email.service.d.ts +8 -4
  86. package/services/authentication.service.d.ts +16 -16
  87. package/services/company-selection-session.service.d.ts +1 -1
  88. package/services/user-permission.service.d.ts +6 -9
  89. package/services/user.service.d.ts +3 -0
  90. package/strategies/jwt.strategy.d.ts +4 -1
  91. package/validators/password.validator.d.ts +10 -0
  92. package/cjs/dtos/user-company-permission.dto.js +0 -110
  93. package/dtos/user-company-permission.dto.d.ts +0 -10
  94. package/fesm/dtos/user-company-permission.dto.js +0 -98
@@ -8,8 +8,10 @@ Object.defineProperty(exports, "ClearToken", {
8
8
  return ClearToken;
9
9
  }
10
10
  });
11
+ const _utils = require("@flusys/nestjs-shared/utils");
11
12
  const _common = require("@nestjs/common");
12
13
  const _rxjs = require("rxjs");
14
+ const _config = require("../config");
13
15
  const _authconfigservice = require("../services/auth-config.service");
14
16
  function _define_property(obj, key, value) {
15
17
  if (key in obj) {
@@ -38,39 +40,24 @@ function _ts_param(paramIndex, decorator) {
38
40
  decorator(target, key, paramIndex);
39
41
  };
40
42
  }
41
- const DEFAULT_COOKIE_NAME = 'fsn_refresh_token';
42
43
  let ClearToken = class ClearToken {
43
44
  get cookieName() {
44
- return this.authConfig?.getRefreshTokenCookieName() ?? DEFAULT_COOKIE_NAME;
45
+ return this.authConfig?.getRefreshTokenCookieName() ?? _config.DEFAULT_COOKIE_NAME;
45
46
  }
46
47
  intercept(context, next) {
47
48
  const req = context.switchToHttp().getRequest();
48
49
  const res = context.switchToHttp().getResponse();
49
50
  return next.handle().pipe((0, _rxjs.map)((value)=>{
50
- // Clear the refresh token cookie
51
- this.clearRefreshTokenCookie(req, res);
51
+ if ((0, _utils.isBrowserRequest)(req)) {
52
+ res.clearCookie(this.cookieName, {
53
+ httpOnly: true,
54
+ path: '/',
55
+ ...(0, _utils.buildCookieOptions)(req)
56
+ });
57
+ }
52
58
  return value;
53
59
  }));
54
60
  }
55
- /**
56
- * Clear refresh token cookie
57
- */ clearRefreshTokenCookie(req, res) {
58
- const origin = req.headers.origin || '';
59
- const hostname = req.hostname || '';
60
- const isHttps = origin.startsWith('https://') || req.secure;
61
- let cookieDomain = hostname;
62
- const domainParts = hostname.split('.');
63
- if (domainParts.length > 2) {
64
- cookieDomain = '.' + domainParts.slice(-2).join('.');
65
- }
66
- res.clearCookie(this.cookieName, {
67
- httpOnly: true,
68
- secure: isHttps,
69
- sameSite: isHttps ? 'strict' : 'lax',
70
- domain: cookieDomain,
71
- path: '/'
72
- });
73
- }
74
61
  constructor(authConfig){
75
62
  _define_property(this, "authConfig", void 0);
76
63
  this.authConfig = authConfig;
@@ -8,9 +8,11 @@ Object.defineProperty(exports, "SetToken", {
8
8
  return SetToken;
9
9
  }
10
10
  });
11
+ const _utils = require("@flusys/nestjs-shared/utils");
11
12
  const _common = require("@nestjs/common");
12
13
  const _buffer = require("buffer");
13
14
  const _rxjs = require("rxjs");
15
+ const _config = require("../config");
14
16
  const _authconfigservice = require("../services/auth-config.service");
15
17
  function _define_property(obj, key, value) {
16
18
  if (key in obj) {
@@ -39,80 +41,37 @@ function _ts_param(paramIndex, decorator) {
39
41
  decorator(target, key, paramIndex);
40
42
  };
41
43
  }
42
- const DEFAULT_COOKIE_NAME = 'fsn_refresh_token';
43
- const MAX_COOKIE_BYTES = 3500;
44
44
  let SetToken = class SetToken {
45
45
  get cookieName() {
46
- return this.authConfig?.getRefreshTokenCookieName() ?? DEFAULT_COOKIE_NAME;
46
+ return this.authConfig?.getRefreshTokenCookieName() ?? _config.DEFAULT_COOKIE_NAME;
47
+ }
48
+ get maxAgeMs() {
49
+ return (0, _utils.parseDurationToMs)(this.authConfig?.getRefreshTokenExpiration() ?? '7d');
47
50
  }
48
51
  intercept(context, next) {
49
52
  const req = context.switchToHttp().getRequest();
50
53
  const res = context.switchToHttp().getResponse();
51
54
  return next.handle().pipe((0, _rxjs.map)((value)=>{
52
- // Skip if no refreshToken in response
53
- if (!value || !value.refreshToken) {
54
- return value;
55
- }
56
- const isBrowser = this.isBrowserRequest(req);
57
- const tokenValue = value.refreshToken;
58
- if (isBrowser) {
59
- // Browser: Set cookie and remove from response body
60
- this.setRefreshTokenCookie(req, res, tokenValue);
61
- // Return response without refreshToken for browsers
55
+ if (!value?.refreshToken) return value;
56
+ if ((0, _utils.isBrowserRequest)(req)) {
57
+ this.setRefreshTokenCookie(req, res, value.refreshToken);
62
58
  const { refreshToken, ...responseWithoutToken } = value;
63
59
  return responseWithoutToken;
64
60
  }
65
- // API/Mobile: Keep refreshToken in response body
66
61
  return value;
67
62
  }), (0, _rxjs.catchError)((err)=>(0, _rxjs.throwError)(()=>err)));
68
63
  }
69
- /**
70
- * Detect if request is from a browser
71
- * Checks Accept header and custom X-Client-Type header
72
- */ isBrowserRequest(req) {
73
- // Check custom header first (allows explicit client identification)
74
- const clientType = req.headers['x-client-type'];
75
- if (clientType) {
76
- return clientType.toLowerCase() === 'browser' || clientType.toLowerCase() === 'web';
77
- }
78
- // Check Accept header - browsers typically include text/html
79
- const accept = req.headers['accept'] || '';
80
- if (accept.includes('text/html')) {
81
- return true;
82
- }
83
- // Check User-Agent for common browsers
84
- const userAgent = req.headers['user-agent'] || '';
85
- const browserPatterns = /mozilla|chrome|safari|firefox|edge|opera|msie/i;
86
- if (browserPatterns.test(userAgent) && !userAgent.includes('Postman')) {
87
- return true;
88
- }
89
- return false;
90
- }
91
- /**
92
- * Set refresh token in HTTP-only cookie
93
- */ setRefreshTokenCookie(req, res, tokenValue) {
94
- const origin = req.headers.origin || '';
95
- const hostname = req.hostname || '';
96
- const isHttps = origin.startsWith('https://') || req.secure;
97
- let cookieDomain = hostname;
98
- const domainParts = hostname.split('.');
99
- if (domainParts.length > 2) {
100
- cookieDomain = '.' + domainParts.slice(-2).join('.');
101
- }
102
- // Check cookie size
103
- const rawCookieString = `${this.cookieName}=${tokenValue}; HttpOnly; Domain=${cookieDomain}`;
64
+ setRefreshTokenCookie(req, res, tokenValue) {
65
+ const rawCookieString = `${this.cookieName}=${tokenValue}; HttpOnly`;
104
66
  const estimatedBytes = _buffer.Buffer.byteLength(rawCookieString, 'utf8');
105
- if (estimatedBytes > MAX_COOKIE_BYTES) {
67
+ if (estimatedBytes > _config.MAX_COOKIE_BYTES) {
106
68
  throw new _common.PayloadTooLargeException(`Refresh token too large (≈${estimatedBytes} bytes)`);
107
69
  }
108
- // Set HTTP-only secure cookie
109
70
  res.cookie(this.cookieName, tokenValue, {
110
71
  httpOnly: true,
111
- secure: isHttps,
112
- sameSite: isHttps ? 'strict' : 'lax',
113
- domain: cookieDomain,
114
72
  path: '/',
115
- maxAge: 7 * 24 * 60 * 60 * 1000
73
+ maxAge: this.maxAgeMs,
74
+ ...(0, _utils.buildCookieOptions)(req)
116
75
  });
117
76
  }
118
77
  constructor(authConfig){
@@ -123,6 +82,7 @@ let SetToken = class SetToken {
123
82
  SetToken = _ts_decorate([
124
83
  (0, _common.Injectable)(),
125
84
  _ts_param(0, (0, _common.Optional)()),
85
+ _ts_param(0, (0, _common.Inject)(_authconfigservice.AuthConfigService)),
126
86
  _ts_metadata("design:type", Function),
127
87
  _ts_metadata("design:paramtypes", [
128
88
  typeof _authconfigservice.AuthConfigService === "undefined" ? Object : _authconfigservice.AuthConfigService
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Auth Email Provider Interface
2
+ * Auth Email Provider Interface
3
3
  *
4
4
  * This interface defines the contract for email sending in the auth module.
5
5
  * It allows auth to work independently of the email module.
@@ -12,16 +12,15 @@ const _modules = require("@flusys/nestjs-shared/modules");
12
12
  const _common = require("@nestjs/common");
13
13
  const _jwt = require("@nestjs/jwt");
14
14
  const _passport = require("@nestjs/passport");
15
- const _typeorm = require("@nestjs/typeorm");
16
- const _authconfigservice = require("../services/auth-config.service");
17
- const _authdatasourceprovider = require("../services/auth-datasource.provider");
15
+ const _guards = require("@flusys/nestjs-shared/guards");
18
16
  const _authconstants = require("../config/auth.constants");
19
17
  const _controllers = require("../controllers");
20
18
  const _entities = require("../entities");
21
- const _guards = require("@flusys/nestjs-shared/guards");
22
19
  const _cleartokeninterceptor = require("../interceptors/clear-token.interceptor");
23
20
  const _settokeninterceptor = require("../interceptors/set-token.interceptor");
24
21
  const _services = require("../services");
22
+ const _authconfigservice = require("../services/auth-config.service");
23
+ const _authdatasourceprovider = require("../services/auth-datasource.provider");
25
24
  const _jwtstrategy = require("../strategies/jwt.strategy");
26
25
  function _ts_decorate(decorators, target, key, desc) {
27
26
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
@@ -31,82 +30,48 @@ function _ts_decorate(decorators, target, key, desc) {
31
30
  }
32
31
  let AuthModule = class AuthModule {
33
32
  static forRoot(options) {
34
- return this.buildDynamicModule(options);
33
+ const optionsProvider = {
34
+ provide: _authconstants.AUTH_MODULE_OPTIONS,
35
+ useValue: options
36
+ };
37
+ return this.buildModule(options, [
38
+ optionsProvider,
39
+ ...options.providers ?? []
40
+ ]);
35
41
  }
36
- static forRootAsync(asyncOptions) {
37
- const { global = false, includeController = true, bootstrapAppConfig: { enableCompanyFeature } = {}, imports: externalImports = [], providers: additionalProviders = [] } = asyncOptions;
38
- const asyncProviders = this.createAsyncProviders(asyncOptions);
39
- // Build imports
40
- const imports = [
41
- ...externalImports,
42
- _passport.PassportModule.register({
43
- defaultStrategy: 'jwt'
44
- }),
45
- _jwt.JwtModule.register({}),
46
- _modules.CacheModule,
47
- _modules.UtilsModule
48
- ];
49
- // Build controllers based on configuration
50
- const controllers = [];
51
- if (includeController) {
52
- // Core authentication controller (always included)
53
- controllers.push(_controllers.AuthenticationController);
54
- // User controller (always included)
55
- controllers.push(_controllers.UserController);
56
- // Company feature controllers (conditional)
57
- if (enableCompanyFeature) {
58
- controllers.push(_controllers.CompanySelectionController, _controllers.CompanyController, _controllers.BranchController, _controllers.UserPermissionController);
59
- }
60
- }
61
- // Build providers
62
- const providers = [
42
+ static forRootAsync(options) {
43
+ const asyncProviders = this.createAsyncProviders(options);
44
+ return this.buildModule(options, [
63
45
  ...asyncProviders,
64
- ...additionalProviders,
65
- // Config & Infrastructure
66
- _authconfigservice.AuthConfigService,
67
- _authdatasourceprovider.AuthDataSourceProvider,
68
- // Auth core
69
- _jwtstrategy.JwtStrategy,
70
- _guards.JwtAuthGuard,
71
- _services.AuthenticationService,
72
- _services.AuthEmailService,
73
- // Interceptors
74
- _settokeninterceptor.SetToken,
75
- _cleartokeninterceptor.ClearToken,
76
- // Core services (always included)
77
- _services.UserService
78
- ];
79
- // Company feature services (conditional)
80
- if (enableCompanyFeature) {
81
- providers.push(_services.CompanySelectionSessionService, _services.CompanyService, _services.BranchService, _services.UserPermissionService);
82
- }
83
- // Build exports
84
- const exports1 = [
85
- _passport.PassportModule,
86
- _authconstants.AUTH_MODULE_OPTIONS,
87
- _authconfigservice.AuthConfigService,
88
- _authdatasourceprovider.AuthDataSourceProvider,
89
- _jwtstrategy.JwtStrategy,
90
- _guards.JwtAuthGuard,
91
- _services.AuthenticationService,
92
- _services.AuthEmailService,
93
- _services.UserService
94
- ];
95
- if (enableCompanyFeature) {
96
- exports1.push(_services.CompanySelectionSessionService, _services.CompanyService, _services.BranchService, _services.UserPermissionService);
97
- }
46
+ ...options.providers ?? []
47
+ ], options.imports);
48
+ }
49
+ static buildModule(options, providers, externalImports = []) {
50
+ const { global = false, includeController = true, bootstrapAppConfig } = options;
51
+ const featureFlags = this.getFeatureFlags(bootstrapAppConfig);
98
52
  return {
99
53
  module: AuthModule,
100
54
  global,
101
- imports,
102
- controllers,
103
- providers,
104
- exports: exports1
55
+ imports: [
56
+ ...externalImports,
57
+ ...this.buildImports()
58
+ ],
59
+ controllers: this.buildControllers(includeController, featureFlags),
60
+ providers: [
61
+ ...providers,
62
+ ...this.buildProviders(featureFlags)
63
+ ],
64
+ exports: this.buildExports(featureFlags)
65
+ };
66
+ }
67
+ static getFeatureFlags(bootstrapAppConfig) {
68
+ return {
69
+ enableCompanyFeature: bootstrapAppConfig?.enableCompanyFeature ?? false,
70
+ enableEmailVerification: bootstrapAppConfig?.enableEmailVerification ?? true
105
71
  };
106
72
  }
107
- static buildDynamicModule(options) {
108
- const { bootstrapAppConfig: { enableCompanyFeature } = {}, includeController = true, global = false, providers: additionalProviders = [] } = options;
109
- const imports = [
73
+ static buildImports() {
74
+ return [
110
75
  _passport.PassportModule.register({
111
76
  defaultStrategy: 'jwt'
112
77
  }),
@@ -114,42 +79,41 @@ let AuthModule = class AuthModule {
114
79
  _modules.CacheModule,
115
80
  _modules.UtilsModule
116
81
  ];
117
- // Build controllers based on configuration
118
- const controllers = [];
119
- if (includeController) {
120
- // Core authentication controller (always included)
121
- controllers.push(_controllers.AuthenticationController);
122
- // User controller (always included)
123
- controllers.push(_controllers.UserController);
124
- // Company feature controllers (conditional)
125
- if (enableCompanyFeature) {
126
- controllers.push(_controllers.CompanySelectionController, _controllers.CompanyController, _controllers.BranchController, _controllers.UserPermissionController);
127
- }
82
+ }
83
+ static buildControllers(includeController, flags) {
84
+ if (!includeController) return [];
85
+ const controllers = [
86
+ _controllers.AuthenticationController,
87
+ _controllers.UserController
88
+ ];
89
+ if (flags.enableEmailVerification) {
90
+ controllers.push(_controllers.EmailVerificationController);
128
91
  }
92
+ if (flags.enableCompanyFeature) {
93
+ controllers.push(_controllers.CompanySelectionController, _controllers.CompanyController, _controllers.BranchController, _controllers.UserPermissionController);
94
+ }
95
+ return controllers;
96
+ }
97
+ static buildProviders(flags) {
129
98
  const providers = [
130
- {
131
- provide: _authconstants.AUTH_MODULE_OPTIONS,
132
- useValue: options
133
- },
134
- ...additionalProviders,
135
- // Config & Infrastructure
136
99
  _authconfigservice.AuthConfigService,
137
100
  _authdatasourceprovider.AuthDataSourceProvider,
138
- // Auth core
139
101
  _jwtstrategy.JwtStrategy,
140
102
  _guards.JwtAuthGuard,
141
103
  _services.AuthenticationService,
142
- _services.AuthEmailService,
143
- // Interceptors
144
104
  _settokeninterceptor.SetToken,
145
105
  _cleartokeninterceptor.ClearToken,
146
- // Core services (always included)
147
106
  _services.UserService
148
107
  ];
149
- // Company feature services (conditional)
150
- if (enableCompanyFeature) {
108
+ if (flags.enableEmailVerification) {
109
+ providers.push(_services.AuthEmailService);
110
+ }
111
+ if (flags.enableCompanyFeature) {
151
112
  providers.push(_services.CompanySelectionSessionService, _services.CompanyService, _services.BranchService, _services.UserPermissionService);
152
113
  }
114
+ return providers;
115
+ }
116
+ static buildExports(flags) {
153
117
  const exports1 = [
154
118
  _passport.PassportModule,
155
119
  _authconstants.AUTH_MODULE_OPTIONS,
@@ -158,20 +122,15 @@ let AuthModule = class AuthModule {
158
122
  _jwtstrategy.JwtStrategy,
159
123
  _guards.JwtAuthGuard,
160
124
  _services.AuthenticationService,
161
- _services.AuthEmailService,
162
125
  _services.UserService
163
126
  ];
164
- if (enableCompanyFeature) {
127
+ if (flags.enableEmailVerification) {
128
+ exports1.push(_services.AuthEmailService);
129
+ }
130
+ if (flags.enableCompanyFeature) {
165
131
  exports1.push(_services.CompanySelectionSessionService, _services.CompanyService, _services.BranchService, _services.UserPermissionService);
166
132
  }
167
- return {
168
- module: AuthModule,
169
- global,
170
- imports,
171
- controllers,
172
- providers,
173
- exports: exports1
174
- };
133
+ return exports1;
175
134
  }
176
135
  static createAsyncProviders(options) {
177
136
  const staticOptions = {
@@ -183,13 +142,10 @@ let AuthModule = class AuthModule {
183
142
  return [
184
143
  {
185
144
  provide: _authconstants.AUTH_MODULE_OPTIONS,
186
- useFactory: async (...args)=>{
187
- const config = await options.useFactory(...args);
188
- return {
145
+ useFactory: async (...args)=>({
189
146
  ...staticOptions,
190
- config
191
- };
192
- },
147
+ config: await options.useFactory(...args)
148
+ }),
193
149
  inject: options.inject || []
194
150
  }
195
151
  ];
@@ -202,13 +158,10 @@ let AuthModule = class AuthModule {
202
158
  },
203
159
  {
204
160
  provide: _authconstants.AUTH_MODULE_OPTIONS,
205
- useFactory: async (factory)=>{
206
- const config = await factory.createAuthOptions();
207
- return {
161
+ useFactory: async (factory)=>({
208
162
  ...staticOptions,
209
- config
210
- };
211
- },
163
+ config: await factory.createAuthOptions()
164
+ }),
212
165
  inject: [
213
166
  options.useClass
214
167
  ]
@@ -219,13 +172,10 @@ let AuthModule = class AuthModule {
219
172
  return [
220
173
  {
221
174
  provide: _authconstants.AUTH_MODULE_OPTIONS,
222
- useFactory: async (factory)=>{
223
- const config = await factory.createAuthOptions();
224
- return {
175
+ useFactory: async (factory)=>({
225
176
  ...staticOptions,
226
- config
227
- };
228
- },
177
+ config: await factory.createAuthOptions()
178
+ }),
229
179
  inject: [
230
180
  options.useExisting
231
181
  ]
@@ -239,36 +189,11 @@ let AuthModule = class AuthModule {
239
189
  }
240
190
  ];
241
191
  }
242
- /**
243
- * Create repository providers that use AuthDataSourceProvider
244
- * This replaces TypeOrmModule.forFeature() functionality
245
- * Note: Must be REQUEST-scoped since AuthDataSourceProvider is REQUEST-scoped
246
- */ static getRepositoryProviders(enableCompanyFeature) {
247
- const entities = this.getEntities(enableCompanyFeature);
248
- return entities.map((entity)=>({
249
- provide: (0, _typeorm.getRepositoryToken)(entity),
250
- scope: _common.Scope.REQUEST,
251
- useFactory: async (dataSourceProvider)=>{
252
- return await dataSourceProvider.getRepository(entity);
253
- },
254
- inject: [
255
- _authdatasourceprovider.AuthDataSourceProvider
256
- ]
257
- }));
258
- }
259
- static getEntities(enableCompanyFeature = false) {
260
- const coreEntities = [
261
- _entities.User
262
- ];
263
- const companyEntities = enableCompanyFeature ? [
264
- _entities.Company,
265
- _entities.CompanyBranch,
266
- _entities.UserCompanyPermission
267
- ] : [];
268
- return [
269
- ...coreEntities,
270
- ...companyEntities
271
- ];
192
+ static getEntities(config) {
193
+ return (0, _entities.getEntitiesByConfig)({
194
+ enableCompanyFeature: config.enableCompanyFeature ?? false,
195
+ enableEmailVerification: config.enableEmailVerification ?? true
196
+ });
272
197
  }
273
198
  };
274
199
  AuthModule = _ts_decorate([
@@ -8,9 +8,10 @@ Object.defineProperty(exports, "AuthConfigService", {
8
8
  return AuthConfigService;
9
9
  }
10
10
  });
11
+ const _config = require("@flusys/nestjs-core/config");
11
12
  const _common = require("@nestjs/common");
12
- const _authmoduleoptionsinterface = require("../interfaces/auth-module-options.interface");
13
13
  const _authconstants = require("../config/auth.constants");
14
+ const _authmoduleoptionsinterface = require("../interfaces/auth-module-options.interface");
14
15
  function _define_property(obj, key, value) {
15
16
  if (key in obj) {
16
17
  Object.defineProperty(obj, key, {
@@ -39,61 +40,58 @@ function _ts_param(paramIndex, decorator) {
39
40
  };
40
41
  }
41
42
  let AuthConfigService = class AuthConfigService {
42
- // Database Mode
43
- /** Get database mode (single or multi-tenant) */ getDatabaseMode() {
43
+ // Database Mode (required by IModuleConfigService)
44
+ getDatabaseMode() {
44
45
  return this.options.bootstrapAppConfig?.databaseMode ?? 'single';
45
46
  }
46
- /** Check if running in multi-tenant mode */ isMultiTenant() {
47
+ isMultiTenant() {
47
48
  return this.getDatabaseMode() === 'multi-tenant';
48
49
  }
49
50
  // Feature Flags
50
- /** Check if company feature is enabled */ isCompanyFeatureEnabled() {
51
+ isCompanyFeatureEnabled() {
51
52
  return this.options.bootstrapAppConfig?.enableCompanyFeature ?? false;
52
53
  }
54
+ isEmailVerificationEnabled() {
55
+ return this.options.bootstrapAppConfig?.enableEmailVerification ?? true;
56
+ }
53
57
  // JWT Configuration
54
- /** Get JWT secret key */ getJwtSecret() {
55
- return this.config.jwtSecret ?? 'default-secret-change-in-production';
58
+ getJwtSecret() {
59
+ if (!this.config.jwtSecret) {
60
+ throw new _common.InternalServerErrorException('[AuthModule] JWT_SECRET is required - set via environment or module config');
61
+ }
62
+ return this.config.jwtSecret;
56
63
  }
57
- /** Get JWT expiration time */ getJwtExpiration() {
64
+ getJwtExpiration() {
58
65
  return this.config.jwtExpiration ?? '1h';
59
66
  }
60
- /** Get refresh token secret key */ getRefreshTokenSecret() {
61
- return this.config.refreshTokenSecret ?? this.getJwtSecret();
62
- }
63
- /** Get refresh token expiration time */ getRefreshTokenExpiration() {
67
+ getRefreshTokenSecret() {
68
+ if (this.config.refreshTokenSecret) {
69
+ return this.config.refreshTokenSecret;
70
+ }
71
+ if (_config.envConfig.isProduction()) {
72
+ throw new _common.InternalServerErrorException('[AuthModule] REFRESH_TOKEN_SECRET is required in production - ' + 'using the same secret for access and refresh tokens is a security risk');
73
+ }
74
+ if (!this.refreshTokenSecretWarned) {
75
+ this.refreshTokenSecretWarned = true;
76
+ this.logger.warn('REFRESH_TOKEN_SECRET not configured - using JWT_SECRET as fallback. ' + 'For better security, configure a separate refresh token secret.');
77
+ }
78
+ return this.getJwtSecret();
79
+ }
80
+ getRefreshTokenExpiration() {
64
81
  return this.config.refreshTokenExpiration ?? '7d';
65
82
  }
66
- /** Get refresh token cookie name */ getRefreshTokenCookieName() {
83
+ getRefreshTokenCookieName() {
67
84
  return this.config.refreshTokenCookieName ?? 'fsn_refresh_token';
68
85
  }
69
86
  // Frontend Configuration
70
- /** Get frontend URL for email links */ getFrontendUrl() {
87
+ getFrontendUrl() {
71
88
  return this.config.frontendUrl;
72
89
  }
73
- // Database Configuration
74
- /** Get default database config */ getDefaultDatabaseConfig() {
75
- return this.config.defaultDatabaseConfig ?? this.config.tenantDefaultDatabaseConfig;
76
- }
77
- /** Get tenant default database config (for multi-tenant) */ getTenantDefaultDatabaseConfig() {
78
- return this.config.tenantDefaultDatabaseConfig;
79
- }
80
- /** Get registered tenants */ getTenants() {
81
- return this.config.tenants ?? [];
82
- }
83
- // Raw Options
84
- /** Get full module options */ getOptions() {
85
- return {
86
- ...this.options
87
- };
88
- }
89
- /** Get runtime config */ getConfig() {
90
- return {
91
- ...this.config
92
- };
93
- }
94
90
  constructor(injectedOptions){
91
+ _define_property(this, "logger", new _common.Logger(AuthConfigService.name));
95
92
  _define_property(this, "options", void 0);
96
93
  _define_property(this, "config", void 0);
94
+ _define_property(this, "refreshTokenSecretWarned", false);
97
95
  this.options = injectedOptions ?? {
98
96
  global: false,
99
97
  includeController: true