@flusys/nestjs-auth 1.0.1 → 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.
@@ -34,26 +34,16 @@ import { ApiBearerAuth, ApiBody, ApiExtraModels, ApiHeader, ApiOperation, ApiRes
34
34
  import { SkipThrottle, Throttle } from '@nestjs/throttler';
35
35
  import { Request } from 'express';
36
36
  import { DEFAULT_COOKIE_NAME } from '../config';
37
- import { ChangePasswordDto, CompanySelectionResponseDto, ForgotPasswordDto, LoginDto, LoginResponseDto, LoginResponseRequiresEmailVerificationDto, MeResponseDto, RefreshTokenDto, RegistrationDto, RegistrationResponseDto, ResendVerificationDto, ResetPasswordDto, VerifyEmailDto } from '../dtos/authentication.dto';
37
+ import { ChangePasswordDto, CompanySelectionResponseDto, LoginDto, LoginResponseDto, LoginResponseRequiresEmailVerificationDto, MeResponseDto, RefreshTokenDto, RegistrationDto, RegistrationResponseDto } from '../dtos/authentication.dto';
38
38
  import { ClearToken } from '../interceptors/clear-token.interceptor';
39
39
  import { SetToken } from '../interceptors/set-token.interceptor';
40
40
  import { AuthConfigService } from '../services/auth-config.service';
41
- import { AuthEmailService } from '../services/auth-email.service';
42
41
  import { AuthenticationService } from '../services/authentication.service';
43
42
  export class AuthenticationController {
44
43
  buildAuthUrl(req, path) {
45
44
  const frontendUrl = this.authConfig?.getFrontendUrl();
46
45
  return frontendUrl ? `${frontendUrl}${path}` : `${req.protocol}://${req.get('host')}${path}`;
47
46
  }
48
- get emailService() {
49
- if (!this.authEmailService) {
50
- throw new Error('Email service is not configured');
51
- }
52
- return this.authEmailService;
53
- }
54
- get isEmailEnabled() {
55
- return !!this.authEmailService;
56
- }
57
47
  async login(loginDto) {
58
48
  const result = await this.authService.login(loginDto.email, loginDto.password);
59
49
  if ('requiresEmailVerification' in result) {
@@ -99,56 +89,11 @@ export class AuthenticationController {
99
89
  message: 'Password changed successfully'
100
90
  };
101
91
  }
102
- async forgotPassword(req, dto) {
103
- if (!this.isEmailEnabled) {
104
- return {
105
- success: false,
106
- message: 'Email service is not configured'
107
- };
108
- }
109
- return this.emailService.forgotPassword(dto.email, this.buildAuthUrl(req, '/auth/reset-password'));
110
- }
111
- async resetPassword(dto) {
112
- if (!this.isEmailEnabled) {
113
- return {
114
- success: false,
115
- message: 'Email service is not configured'
116
- };
117
- }
118
- return this.emailService.resetPassword(dto.token, dto.newPassword);
119
- }
120
- async resendVerification(req, dto) {
121
- if (!this.isEmailEnabled) {
122
- return {
123
- success: false,
124
- message: 'Email service is not configured'
125
- };
126
- }
127
- return this.emailService.resendVerificationEmail(dto.email, this.buildAuthUrl(req, '/auth/verify-email'));
128
- }
129
- /** Verify email - Verify email using token. Handles both pending registration and existing user verification. */ async verifyEmail(dto) {
130
- if (!this.isEmailEnabled) {
131
- return {
132
- success: false,
133
- message: 'Email service is not configured'
134
- };
135
- }
136
- const result = await this.emailService.verifyEmail(dto.token);
137
- if (result.type === 'pending') {
138
- return this.authService.createUserFromPendingRegistration(result.pending);
139
- }
140
- return {
141
- success: true,
142
- message: result.message
143
- };
144
- }
145
- constructor(authService, authConfig, authEmailService){
92
+ constructor(authService, authConfig){
146
93
  _define_property(this, "authService", void 0);
147
94
  _define_property(this, "authConfig", void 0);
148
- _define_property(this, "authEmailService", void 0);
149
95
  this.authService = authService;
150
96
  this.authConfig = authConfig;
151
- this.authEmailService = authEmailService;
152
97
  }
153
98
  }
154
99
  _ts_decorate([
@@ -427,131 +372,15 @@ _ts_decorate([
427
372
  ]),
428
373
  _ts_metadata("design:returntype", Promise)
429
374
  ], AuthenticationController.prototype, "changePassword", null);
430
- _ts_decorate([
431
- Post('forgot-password'),
432
- HttpCode(HttpStatus.OK),
433
- Throttle({
434
- default: {
435
- limit: 3,
436
- ttl: 300000
437
- }
438
- }),
439
- ApiOperation({
440
- summary: 'Request password reset email'
441
- }),
442
- ApiBody({
443
- type: ForgotPasswordDto
444
- }),
445
- ApiResponse({
446
- status: 200,
447
- type: MessageResponseDto
448
- }),
449
- _ts_param(0, Req()),
450
- _ts_param(1, Body()),
451
- _ts_metadata("design:type", Function),
452
- _ts_metadata("design:paramtypes", [
453
- typeof Request === "undefined" ? Object : Request,
454
- typeof ForgotPasswordDto === "undefined" ? Object : ForgotPasswordDto
455
- ]),
456
- _ts_metadata("design:returntype", Promise)
457
- ], AuthenticationController.prototype, "forgotPassword", null);
458
- _ts_decorate([
459
- Post('reset-password'),
460
- HttpCode(HttpStatus.OK),
461
- Throttle({
462
- default: {
463
- limit: 5,
464
- ttl: 900000
465
- }
466
- }),
467
- ApiOperation({
468
- summary: 'Reset password using token'
469
- }),
470
- ApiBody({
471
- type: ResetPasswordDto
472
- }),
473
- ApiResponse({
474
- status: 200,
475
- type: MessageResponseDto
476
- }),
477
- _ts_param(0, Body()),
478
- _ts_metadata("design:type", Function),
479
- _ts_metadata("design:paramtypes", [
480
- typeof ResetPasswordDto === "undefined" ? Object : ResetPasswordDto
481
- ]),
482
- _ts_metadata("design:returntype", Promise)
483
- ], AuthenticationController.prototype, "resetPassword", null);
484
- _ts_decorate([
485
- Post('resend-verification'),
486
- HttpCode(HttpStatus.OK),
487
- Throttle({
488
- default: {
489
- limit: 3,
490
- ttl: 300000
491
- }
492
- }),
493
- ApiOperation({
494
- summary: 'Resend email verification link'
495
- }),
496
- ApiBody({
497
- type: ResendVerificationDto
498
- }),
499
- ApiResponse({
500
- status: 200,
501
- type: MessageResponseDto
502
- }),
503
- _ts_param(0, Req()),
504
- _ts_param(1, Body()),
505
- _ts_metadata("design:type", Function),
506
- _ts_metadata("design:paramtypes", [
507
- typeof Request === "undefined" ? Object : Request,
508
- typeof ResendVerificationDto === "undefined" ? Object : ResendVerificationDto
509
- ]),
510
- _ts_metadata("design:returntype", Promise)
511
- ], AuthenticationController.prototype, "resendVerification", null);
512
- _ts_decorate([
513
- Post('verify-email'),
514
- HttpCode(HttpStatus.OK),
515
- Throttle({
516
- default: {
517
- limit: 10,
518
- ttl: 60000
519
- }
520
- }),
521
- UseInterceptors(SetToken),
522
- ApiOperation({
523
- summary: 'Verify email using token'
524
- }),
525
- ApiBody({
526
- type: VerifyEmailDto
527
- }),
528
- ApiResponse({
529
- status: 200,
530
- type: MessageResponseDto
531
- }),
532
- ApiResponse({
533
- status: 200,
534
- type: RegistrationResponseDto
535
- }),
536
- _ts_param(0, Body()),
537
- _ts_metadata("design:type", Function),
538
- _ts_metadata("design:paramtypes", [
539
- typeof VerifyEmailDto === "undefined" ? Object : VerifyEmailDto
540
- ]),
541
- _ts_metadata("design:returntype", Promise)
542
- ], AuthenticationController.prototype, "verifyEmail", null);
543
375
  AuthenticationController = _ts_decorate([
544
376
  ApiTags('Authentication'),
545
377
  Controller('auth'),
546
378
  _ts_param(0, Inject(AuthenticationService)),
547
379
  _ts_param(1, Optional()),
548
380
  _ts_param(1, Inject(AuthConfigService)),
549
- _ts_param(2, Optional()),
550
- _ts_param(2, Inject(AuthEmailService)),
551
381
  _ts_metadata("design:type", Function),
552
382
  _ts_metadata("design:paramtypes", [
553
383
  typeof AuthenticationService === "undefined" ? Object : AuthenticationService,
554
- typeof AuthConfigService === "undefined" ? Object : AuthConfigService,
555
- typeof AuthEmailService === "undefined" ? Object : AuthEmailService
384
+ typeof AuthConfigService === "undefined" ? Object : AuthConfigService
556
385
  ])
557
386
  ], AuthenticationController);
@@ -0,0 +1,210 @@
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
+ function _ts_param(paramIndex, decorator) {
24
+ return function(target, key) {
25
+ decorator(target, key, paramIndex);
26
+ };
27
+ }
28
+ import { MessageResponseDto } from '@flusys/nestjs-shared/dtos';
29
+ import { BadRequestException, Body, Controller, HttpCode, HttpStatus, Inject, Post, Req, UseInterceptors } from '@nestjs/common';
30
+ import { ApiBody, ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
31
+ import { Throttle } from '@nestjs/throttler';
32
+ import { Request } from 'express';
33
+ import { ForgotPasswordDto, RegistrationResponseDto, ResendVerificationDto, ResetPasswordDto, VerifyEmailDto } from '../dtos/authentication.dto';
34
+ import { SetToken } from '../interceptors/set-token.interceptor';
35
+ import { AuthConfigService } from '../services/auth-config.service';
36
+ import { AuthDataSourceProvider } from '../services/auth-datasource.provider';
37
+ import { AuthEmailService } from '../services/auth-email.service';
38
+ import { AuthenticationService } from '../services/authentication.service';
39
+ export class EmailVerificationController {
40
+ ensureEmailVerificationEnabled() {
41
+ if (!this.dataSourceProvider.isEmailVerificationEnabled()) {
42
+ throw new BadRequestException('Email verification is not enabled for this tenant');
43
+ }
44
+ }
45
+ buildAuthUrl(req, path) {
46
+ const frontendUrl = this.authConfig.getFrontendUrl();
47
+ return frontendUrl ? `${frontendUrl}${path}` : `${req.protocol}://${req.get('host')}${path}`;
48
+ }
49
+ async forgotPassword(req, dto) {
50
+ this.ensureEmailVerificationEnabled();
51
+ return this.authEmailService.forgotPassword(dto.email, this.buildAuthUrl(req, '/auth/reset-password'));
52
+ }
53
+ async resetPassword(dto) {
54
+ this.ensureEmailVerificationEnabled();
55
+ return this.authEmailService.resetPassword(dto.token, dto.newPassword);
56
+ }
57
+ async resendVerification(req, dto) {
58
+ this.ensureEmailVerificationEnabled();
59
+ return this.authEmailService.resendVerificationEmail(dto.email, this.buildAuthUrl(req, '/auth/verify-email'));
60
+ }
61
+ async verifyEmail(dto) {
62
+ this.ensureEmailVerificationEnabled();
63
+ const result = await this.authEmailService.verifyEmail(dto.token);
64
+ if (result.type === 'pending') {
65
+ return this.authService.createUserFromPendingRegistration(result.pending);
66
+ }
67
+ return {
68
+ success: true,
69
+ message: result.message
70
+ };
71
+ }
72
+ constructor(authService, authEmailService, authConfig, dataSourceProvider){
73
+ _define_property(this, "authService", void 0);
74
+ _define_property(this, "authEmailService", void 0);
75
+ _define_property(this, "authConfig", void 0);
76
+ _define_property(this, "dataSourceProvider", void 0);
77
+ this.authService = authService;
78
+ this.authEmailService = authEmailService;
79
+ this.authConfig = authConfig;
80
+ this.dataSourceProvider = dataSourceProvider;
81
+ }
82
+ }
83
+ _ts_decorate([
84
+ Post('forgot-password'),
85
+ HttpCode(HttpStatus.OK),
86
+ Throttle({
87
+ default: {
88
+ limit: 3,
89
+ ttl: 300000
90
+ }
91
+ }),
92
+ ApiOperation({
93
+ summary: 'Request password reset email'
94
+ }),
95
+ ApiBody({
96
+ type: ForgotPasswordDto
97
+ }),
98
+ ApiResponse({
99
+ status: 200,
100
+ type: MessageResponseDto
101
+ }),
102
+ _ts_param(0, Req()),
103
+ _ts_param(1, Body()),
104
+ _ts_metadata("design:type", Function),
105
+ _ts_metadata("design:paramtypes", [
106
+ typeof Request === "undefined" ? Object : Request,
107
+ typeof ForgotPasswordDto === "undefined" ? Object : ForgotPasswordDto
108
+ ]),
109
+ _ts_metadata("design:returntype", Promise)
110
+ ], EmailVerificationController.prototype, "forgotPassword", null);
111
+ _ts_decorate([
112
+ Post('reset-password'),
113
+ HttpCode(HttpStatus.OK),
114
+ Throttle({
115
+ default: {
116
+ limit: 5,
117
+ ttl: 900000
118
+ }
119
+ }),
120
+ ApiOperation({
121
+ summary: 'Reset password using token'
122
+ }),
123
+ ApiBody({
124
+ type: ResetPasswordDto
125
+ }),
126
+ ApiResponse({
127
+ status: 200,
128
+ type: MessageResponseDto
129
+ }),
130
+ _ts_param(0, Body()),
131
+ _ts_metadata("design:type", Function),
132
+ _ts_metadata("design:paramtypes", [
133
+ typeof ResetPasswordDto === "undefined" ? Object : ResetPasswordDto
134
+ ]),
135
+ _ts_metadata("design:returntype", Promise)
136
+ ], EmailVerificationController.prototype, "resetPassword", null);
137
+ _ts_decorate([
138
+ Post('resend-verification'),
139
+ HttpCode(HttpStatus.OK),
140
+ Throttle({
141
+ default: {
142
+ limit: 3,
143
+ ttl: 300000
144
+ }
145
+ }),
146
+ ApiOperation({
147
+ summary: 'Resend email verification link'
148
+ }),
149
+ ApiBody({
150
+ type: ResendVerificationDto
151
+ }),
152
+ ApiResponse({
153
+ status: 200,
154
+ type: MessageResponseDto
155
+ }),
156
+ _ts_param(0, Req()),
157
+ _ts_param(1, Body()),
158
+ _ts_metadata("design:type", Function),
159
+ _ts_metadata("design:paramtypes", [
160
+ typeof Request === "undefined" ? Object : Request,
161
+ typeof ResendVerificationDto === "undefined" ? Object : ResendVerificationDto
162
+ ]),
163
+ _ts_metadata("design:returntype", Promise)
164
+ ], EmailVerificationController.prototype, "resendVerification", null);
165
+ _ts_decorate([
166
+ Post('verify-email'),
167
+ HttpCode(HttpStatus.OK),
168
+ Throttle({
169
+ default: {
170
+ limit: 10,
171
+ ttl: 60000
172
+ }
173
+ }),
174
+ UseInterceptors(SetToken),
175
+ ApiOperation({
176
+ summary: 'Verify email using token'
177
+ }),
178
+ ApiBody({
179
+ type: VerifyEmailDto
180
+ }),
181
+ ApiResponse({
182
+ status: 200,
183
+ type: MessageResponseDto
184
+ }),
185
+ ApiResponse({
186
+ status: 200,
187
+ type: RegistrationResponseDto
188
+ }),
189
+ _ts_param(0, Body()),
190
+ _ts_metadata("design:type", Function),
191
+ _ts_metadata("design:paramtypes", [
192
+ typeof VerifyEmailDto === "undefined" ? Object : VerifyEmailDto
193
+ ]),
194
+ _ts_metadata("design:returntype", Promise)
195
+ ], EmailVerificationController.prototype, "verifyEmail", null);
196
+ EmailVerificationController = _ts_decorate([
197
+ ApiTags('Authentication'),
198
+ Controller('auth'),
199
+ _ts_param(0, Inject(AuthenticationService)),
200
+ _ts_param(1, Inject(AuthEmailService)),
201
+ _ts_param(2, Inject(AuthConfigService)),
202
+ _ts_param(3, Inject(AuthDataSourceProvider)),
203
+ _ts_metadata("design:type", Function),
204
+ _ts_metadata("design:paramtypes", [
205
+ typeof AuthenticationService === "undefined" ? Object : AuthenticationService,
206
+ typeof AuthEmailService === "undefined" ? Object : AuthEmailService,
207
+ typeof AuthConfigService === "undefined" ? Object : AuthConfigService,
208
+ typeof AuthDataSourceProvider === "undefined" ? Object : AuthDataSourceProvider
209
+ ])
210
+ ], EmailVerificationController);
@@ -1,5 +1,6 @@
1
1
  export * from './authentication.controller';
2
2
  export * from './company-selection.controller';
3
+ export * from './email-verification.controller';
3
4
  export * from './user.controller';
4
5
  export * from './company.controller';
5
6
  export * from './branch.controller';
@@ -10,20 +10,28 @@ import { PendingRegistration } from './pending-registration.entity';
10
10
  import { UserCompanyPermission } from './user-company-permission.entity';
11
11
  import { User } from './user.entity';
12
12
  import { UserToken } from './user-token.entity';
13
- export const CoreEntities = [
13
+ const BaseEntities = [
14
14
  User,
15
- UserToken,
15
+ UserToken
16
+ ];
17
+ const EmailEntities = [
16
18
  PendingRegistration
17
19
  ];
18
- export const CompanyEntities = [
20
+ const CompanyEntities = [
19
21
  Company,
20
22
  CompanyBranch,
21
23
  UserCompanyPermission
22
24
  ];
23
- export const AllEntities = [
24
- ...CoreEntities,
25
- ...CompanyEntities
26
- ];
27
- export function getEntitiesByConfig(enableCompanyFeature) {
28
- return enableCompanyFeature ? AllEntities : CoreEntities;
25
+ export function getEntitiesByConfig(config) {
26
+ const { enableCompanyFeature = false, enableEmailVerification = true } = config;
27
+ const entities = [
28
+ ...BaseEntities
29
+ ];
30
+ if (enableEmailVerification) {
31
+ entities.push(...EmailEntities);
32
+ }
33
+ if (enableCompanyFeature) {
34
+ entities.push(...CompanyEntities);
35
+ }
36
+ return entities;
29
37
  }
@@ -10,8 +10,8 @@ import { JwtModule } from '@nestjs/jwt';
10
10
  import { PassportModule } from '@nestjs/passport';
11
11
  import { JwtAuthGuard } from '@flusys/nestjs-shared/guards';
12
12
  import { AUTH_MODULE_OPTIONS } from '../config/auth.constants';
13
- import { AuthenticationController, BranchController, CompanyController, CompanySelectionController, UserController, UserPermissionController } from '../controllers';
14
- import { Company, CompanyBranch, User, UserCompanyPermission } from '../entities';
13
+ import { AuthenticationController, BranchController, CompanyController, CompanySelectionController, EmailVerificationController, UserController, UserPermissionController } from '../controllers';
14
+ import { getEntitiesByConfig } from '../entities';
15
15
  import { ClearToken } from '../interceptors/clear-token.interceptor';
16
16
  import { SetToken } from '../interceptors/set-token.interceptor';
17
17
  import { AuthEmailService, AuthenticationService, BranchService, CompanySelectionSessionService, CompanyService, UserPermissionService, UserService } from '../services';
@@ -36,9 +36,9 @@ export class AuthModule {
36
36
  ...options.providers ?? []
37
37
  ], options.imports);
38
38
  }
39
- /** Build the dynamic module with shared logic */ static buildModule(options, providers, externalImports = []) {
39
+ static buildModule(options, providers, externalImports = []) {
40
40
  const { global = false, includeController = true, bootstrapAppConfig } = options;
41
- const enableCompanyFeature = bootstrapAppConfig?.enableCompanyFeature ?? false;
41
+ const featureFlags = this.getFeatureFlags(bootstrapAppConfig);
42
42
  return {
43
43
  module: AuthModule,
44
44
  global,
@@ -46,15 +46,21 @@ export class AuthModule {
46
46
  ...externalImports,
47
47
  ...this.buildImports()
48
48
  ],
49
- controllers: this.buildControllers(includeController, enableCompanyFeature),
49
+ controllers: this.buildControllers(includeController, featureFlags),
50
50
  providers: [
51
51
  ...providers,
52
- ...this.buildProviders(enableCompanyFeature)
52
+ ...this.buildProviders(featureFlags)
53
53
  ],
54
- exports: this.buildExports(enableCompanyFeature)
54
+ exports: this.buildExports(featureFlags)
55
55
  };
56
56
  }
57
- /** Common module imports */ static buildImports() {
57
+ static getFeatureFlags(bootstrapAppConfig) {
58
+ return {
59
+ enableCompanyFeature: bootstrapAppConfig?.enableCompanyFeature ?? false,
60
+ enableEmailVerification: bootstrapAppConfig?.enableEmailVerification ?? true
61
+ };
62
+ }
63
+ static buildImports() {
58
64
  return [
59
65
  PassportModule.register({
60
66
  defaultStrategy: 'jwt'
@@ -64,35 +70,40 @@ export class AuthModule {
64
70
  UtilsModule
65
71
  ];
66
72
  }
67
- /** Build controllers based on feature flags */ static buildControllers(includeController, enableCompanyFeature) {
73
+ static buildControllers(includeController, flags) {
68
74
  if (!includeController) return [];
69
75
  const controllers = [
70
76
  AuthenticationController,
71
77
  UserController
72
78
  ];
73
- if (enableCompanyFeature) {
79
+ if (flags.enableEmailVerification) {
80
+ controllers.push(EmailVerificationController);
81
+ }
82
+ if (flags.enableCompanyFeature) {
74
83
  controllers.push(CompanySelectionController, CompanyController, BranchController, UserPermissionController);
75
84
  }
76
85
  return controllers;
77
86
  }
78
- /** Core providers (without AUTH_MODULE_OPTIONS - that's added separately) */ static buildProviders(enableCompanyFeature) {
87
+ static buildProviders(flags) {
79
88
  const providers = [
80
89
  AuthConfigService,
81
90
  AuthDataSourceProvider,
82
91
  JwtStrategy,
83
92
  JwtAuthGuard,
84
93
  AuthenticationService,
85
- AuthEmailService,
86
94
  SetToken,
87
95
  ClearToken,
88
96
  UserService
89
97
  ];
90
- if (enableCompanyFeature) {
98
+ if (flags.enableEmailVerification) {
99
+ providers.push(AuthEmailService);
100
+ }
101
+ if (flags.enableCompanyFeature) {
91
102
  providers.push(CompanySelectionSessionService, CompanyService, BranchService, UserPermissionService);
92
103
  }
93
104
  return providers;
94
105
  }
95
- /** Build module exports */ static buildExports(enableCompanyFeature) {
106
+ static buildExports(flags) {
96
107
  const exports = [
97
108
  PassportModule,
98
109
  AUTH_MODULE_OPTIONS,
@@ -101,15 +112,17 @@ export class AuthModule {
101
112
  JwtStrategy,
102
113
  JwtAuthGuard,
103
114
  AuthenticationService,
104
- AuthEmailService,
105
115
  UserService
106
116
  ];
107
- if (enableCompanyFeature) {
117
+ if (flags.enableEmailVerification) {
118
+ exports.push(AuthEmailService);
119
+ }
120
+ if (flags.enableCompanyFeature) {
108
121
  exports.push(CompanySelectionSessionService, CompanyService, BranchService, UserPermissionService);
109
122
  }
110
123
  return exports;
111
124
  }
112
- /** Create async providers for forRootAsync */ static createAsyncProviders(options) {
125
+ static createAsyncProviders(options) {
113
126
  const staticOptions = {
114
127
  global: options.global,
115
128
  includeController: options.includeController,
@@ -166,15 +179,11 @@ export class AuthModule {
166
179
  }
167
180
  ];
168
181
  }
169
- /** Get auth entities based on feature flags */ static getEntities(enableCompanyFeature = false) {
170
- return enableCompanyFeature ? [
171
- User,
172
- Company,
173
- CompanyBranch,
174
- UserCompanyPermission
175
- ] : [
176
- User
177
- ];
182
+ static getEntities(config) {
183
+ return getEntitiesByConfig({
184
+ enableCompanyFeature: config.enableCompanyFeature ?? false,
185
+ enableEmailVerification: config.enableEmailVerification ?? true
186
+ });
178
187
  }
179
188
  }
180
189
  AuthModule = _ts_decorate([
@@ -25,6 +25,7 @@ function _ts_param(paramIndex, decorator) {
25
25
  decorator(target, key, paramIndex);
26
26
  };
27
27
  }
28
+ import { envConfig } from '@flusys/nestjs-core/config';
28
29
  import { Inject, Injectable, InternalServerErrorException, Logger, Optional } from '@nestjs/common';
29
30
  import { AUTH_MODULE_OPTIONS } from '../config/auth.constants';
30
31
  import { AuthModuleOptions } from '../interfaces/auth-module-options.interface';
@@ -40,21 +41,24 @@ export class AuthConfigService {
40
41
  isCompanyFeatureEnabled() {
41
42
  return this.options.bootstrapAppConfig?.enableCompanyFeature ?? false;
42
43
  }
44
+ isEmailVerificationEnabled() {
45
+ return this.options.bootstrapAppConfig?.enableEmailVerification ?? true;
46
+ }
43
47
  // JWT Configuration
44
- /** Get JWT secret key */ getJwtSecret() {
48
+ getJwtSecret() {
45
49
  if (!this.config.jwtSecret) {
46
50
  throw new InternalServerErrorException('[AuthModule] JWT_SECRET is required - set via environment or module config');
47
51
  }
48
52
  return this.config.jwtSecret;
49
53
  }
50
- /** Get JWT expiration time */ getJwtExpiration() {
54
+ getJwtExpiration() {
51
55
  return this.config.jwtExpiration ?? '1h';
52
56
  }
53
- /** Get refresh token secret key */ getRefreshTokenSecret() {
57
+ getRefreshTokenSecret() {
54
58
  if (this.config.refreshTokenSecret) {
55
59
  return this.config.refreshTokenSecret;
56
60
  }
57
- if (process.env.NODE_ENV === 'production') {
61
+ if (envConfig.isProduction()) {
58
62
  throw new InternalServerErrorException('[AuthModule] REFRESH_TOKEN_SECRET is required in production - ' + 'using the same secret for access and refresh tokens is a security risk');
59
63
  }
60
64
  if (!this.refreshTokenSecretWarned) {
@@ -63,14 +67,14 @@ export class AuthConfigService {
63
67
  }
64
68
  return this.getJwtSecret();
65
69
  }
66
- /** Get refresh token expiration time */ getRefreshTokenExpiration() {
70
+ getRefreshTokenExpiration() {
67
71
  return this.config.refreshTokenExpiration ?? '7d';
68
72
  }
69
- /** Get refresh token cookie name */ getRefreshTokenCookieName() {
73
+ getRefreshTokenCookieName() {
70
74
  return this.config.refreshTokenCookieName ?? 'fsn_refresh_token';
71
75
  }
72
76
  // Frontend Configuration
73
- /** Get frontend URL for email links */ getFrontendUrl() {
77
+ getFrontendUrl() {
74
78
  return this.config.frontendUrl;
75
79
  }
76
80
  constructor(injectedOptions){