@flusys/nestjs-auth 3.0.0-rc → 3.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.
Files changed (40) hide show
  1. package/README.md +610 -95
  2. package/cjs/controllers/authentication.controller.js +2 -173
  3. package/cjs/controllers/email-verification.controller.js +220 -0
  4. package/cjs/controllers/index.js +1 -0
  5. package/cjs/dtos/authentication.dto.js +12 -2
  6. package/cjs/entities/index.js +16 -17
  7. package/cjs/entities/pending-registration.entity.js +9 -0
  8. package/cjs/modules/auth.module.js +33 -24
  9. package/cjs/services/auth-config.service.js +11 -7
  10. package/cjs/services/auth-datasource.provider.js +15 -27
  11. package/cjs/services/auth-email.service.js +8 -33
  12. package/cjs/services/authentication.service.js +123 -99
  13. package/cjs/services/user.service.js +28 -83
  14. package/controllers/authentication.controller.d.ts +2 -10
  15. package/controllers/email-verification.controller.d.ts +20 -0
  16. package/controllers/index.d.ts +1 -0
  17. package/dtos/authentication.dto.d.ts +1 -0
  18. package/entities/index.d.ts +5 -10
  19. package/entities/pending-registration.entity.d.ts +1 -0
  20. package/fesm/controllers/authentication.controller.js +3 -174
  21. package/fesm/controllers/email-verification.controller.js +210 -0
  22. package/fesm/controllers/index.js +1 -0
  23. package/fesm/dtos/authentication.dto.js +32 -25
  24. package/fesm/entities/index.js +17 -9
  25. package/fesm/entities/pending-registration.entity.js +9 -0
  26. package/fesm/interfaces/user-enricher.interface.js +2 -24
  27. package/fesm/modules/auth.module.js +35 -26
  28. package/fesm/services/auth-config.service.js +11 -7
  29. package/fesm/services/auth-datasource.provider.js +15 -27
  30. package/fesm/services/auth-email.service.js +8 -33
  31. package/fesm/services/authentication.service.js +124 -100
  32. package/fesm/services/user.service.js +28 -83
  33. package/interfaces/user-enricher.interface.d.ts +3 -2
  34. package/modules/auth.module.d.ts +3 -1
  35. package/package.json +3 -3
  36. package/services/auth-config.service.d.ts +1 -0
  37. package/services/auth-datasource.provider.d.ts +1 -0
  38. package/services/auth-email.service.d.ts +1 -0
  39. package/services/authentication.service.d.ts +4 -1
  40. package/services/user.service.d.ts +5 -0
@@ -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';
@@ -23,8 +23,7 @@ function _ts_metadata(k, v) {
23
23
  import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
24
24
  import { IsEmail, IsNotEmpty, IsOptional, IsString, IsUUID, MaxLength, ValidateIf } from 'class-validator';
25
25
  import { IsStrongPassword } from '../validators/password.validator';
26
- // Request DTOs
27
- /** Login Request DTO */ export class LoginDto {
26
+ export class LoginDto {
28
27
  constructor(){
29
28
  _define_property(this, "email", void 0);
30
29
  _define_property(this, "password", void 0);
@@ -49,19 +48,18 @@ _ts_decorate([
49
48
  MaxLength(128),
50
49
  _ts_metadata("design:type", String)
51
50
  ], LoginDto.prototype, "password", void 0);
52
- /** Registration Request DTO - Supports simple and company-based registration */ export class RegistrationDto {
51
+ export class RegistrationDto {
53
52
  constructor(){
54
53
  _define_property(this, "name", void 0);
55
54
  _define_property(this, "email", void 0);
56
55
  _define_property(this, "password", void 0);
57
56
  _define_property(this, "phone", void 0);
58
- // Company Feature Fields (Optional - only used when company feature is enabled)
59
57
  _define_property(this, "companySlug", void 0);
60
58
  _define_property(this, "branchSlug", void 0);
61
- // New Company Creation Fields (Optional - for creating new company)
62
59
  _define_property(this, "newCompanyName", void 0);
63
60
  _define_property(this, "newCompanyPhone", void 0);
64
61
  _define_property(this, "newCompanyAddress", void 0);
62
+ _define_property(this, "additionalFields", void 0);
65
63
  }
66
64
  }
67
65
  _ts_decorate([
@@ -155,7 +153,18 @@ _ts_decorate([
155
153
  MaxLength(500),
156
154
  _ts_metadata("design:type", String)
157
155
  ], RegistrationDto.prototype, "newCompanyAddress", void 0);
158
- /** Refresh Token Request DTO - refreshToken optional in body (browsers use HTTP-only cookie) */ export class RefreshTokenDto {
156
+ _ts_decorate([
157
+ ApiPropertyOptional({
158
+ example: {
159
+ prevCompanyName: 'Acme Corp',
160
+ employeeId: 'EMP001'
161
+ },
162
+ description: 'Additional fields for profile extension (handled by USER_ENRICHER)'
163
+ }),
164
+ IsOptional(),
165
+ _ts_metadata("design:type", typeof Record === "undefined" ? Object : Record)
166
+ ], RegistrationDto.prototype, "additionalFields", void 0);
167
+ export class RefreshTokenDto {
159
168
  constructor(){
160
169
  _define_property(this, "refreshToken", void 0);
161
170
  }
@@ -169,7 +178,7 @@ _ts_decorate([
169
178
  IsString(),
170
179
  _ts_metadata("design:type", String)
171
180
  ], RefreshTokenDto.prototype, "refreshToken", void 0);
172
- /** Change Password Request DTO */ export class ChangePasswordDto {
181
+ export class ChangePasswordDto {
173
182
  constructor(){
174
183
  _define_property(this, "currentPassword", void 0);
175
184
  _define_property(this, "newPassword", void 0);
@@ -195,7 +204,7 @@ _ts_decorate([
195
204
  IsStrongPassword(),
196
205
  _ts_metadata("design:type", String)
197
206
  ], ChangePasswordDto.prototype, "newPassword", void 0);
198
- /** Select Company & Branch Request DTO - Used after login when user needs to select company and branch */ export class SelectDto {
207
+ export class SelectDto {
199
208
  constructor(){
200
209
  _define_property(this, "sessionId", void 0);
201
210
  _define_property(this, "companyId", void 0);
@@ -229,7 +238,7 @@ _ts_decorate([
229
238
  IsNotEmpty(),
230
239
  _ts_metadata("design:type", String)
231
240
  ], SelectDto.prototype, "branchId", void 0);
232
- /** Switch Company Request DTO - Used to switch company/branch after login */ export class SwitchCompanyDto {
241
+ export class SwitchCompanyDto {
233
242
  constructor(){
234
243
  _define_property(this, "companyId", void 0);
235
244
  _define_property(this, "branchId", void 0);
@@ -253,8 +262,7 @@ _ts_decorate([
253
262
  IsNotEmpty(),
254
263
  _ts_metadata("design:type", String)
255
264
  ], SwitchCompanyDto.prototype, "branchId", void 0);
256
- // Response DTOs
257
- /** User Info DTO (used in responses) */ export class UserInfoDto {
265
+ export class UserInfoDto {
258
266
  constructor(){
259
267
  _define_property(this, "id", void 0);
260
268
  _define_property(this, "email", void 0);
@@ -288,7 +296,7 @@ _ts_decorate([
288
296
  }),
289
297
  _ts_metadata("design:type", Object)
290
298
  ], UserInfoDto.prototype, "profilePictureId", void 0);
291
- /** Company Info DTO (used in responses) */ export class CompanyInfoDto {
299
+ export class CompanyInfoDto {
292
300
  constructor(){
293
301
  _define_property(this, "id", void 0);
294
302
  _define_property(this, "name", void 0);
@@ -322,7 +330,7 @@ _ts_decorate([
322
330
  }),
323
331
  _ts_metadata("design:type", Object)
324
332
  ], CompanyInfoDto.prototype, "logoId", void 0);
325
- /** Branch Info DTO (used in responses) */ export class BranchInfoDto {
333
+ export class BranchInfoDto {
326
334
  constructor(){
327
335
  _define_property(this, "id", void 0);
328
336
  _define_property(this, "name", void 0);
@@ -356,7 +364,7 @@ _ts_decorate([
356
364
  }),
357
365
  _ts_metadata("design:type", Object)
358
366
  ], BranchInfoDto.prototype, "logoId", void 0);
359
- /** Branch Info for Selection (with additional fields) */ export class BranchSelectionInfoDto {
367
+ export class BranchSelectionInfoDto {
360
368
  constructor(){
361
369
  _define_property(this, "id", void 0);
362
370
  _define_property(this, "name", void 0);
@@ -390,7 +398,7 @@ _ts_decorate([
390
398
  }),
391
399
  _ts_metadata("design:type", Object)
392
400
  ], BranchSelectionInfoDto.prototype, "logoId", void 0);
393
- /** Company with Branches DTO (for selection response) */ export class CompanyWithBranchesDto {
401
+ export class CompanyWithBranchesDto {
394
402
  constructor(){
395
403
  _define_property(this, "id", void 0);
396
404
  _define_property(this, "name", void 0);
@@ -434,7 +442,7 @@ _ts_decorate([
434
442
  }),
435
443
  _ts_metadata("design:type", Array)
436
444
  ], CompanyWithBranchesDto.prototype, "branches", void 0);
437
- /** Login Response DTO - Returned on successful login with tokens */ export class LoginResponseDto {
445
+ export class LoginResponseDto {
438
446
  constructor(){
439
447
  _define_property(this, "accessToken", void 0);
440
448
  _define_property(this, "refreshToken", void 0);
@@ -476,7 +484,7 @@ _ts_decorate([
476
484
  }),
477
485
  _ts_metadata("design:type", typeof BranchInfoDto === "undefined" ? Object : BranchInfoDto)
478
486
  ], LoginResponseDto.prototype, "branch", void 0);
479
- /** Registration Response DTO - Returned on successful registration */ export class RegistrationResponseDto {
487
+ export class RegistrationResponseDto {
480
488
  constructor(){
481
489
  _define_property(this, "accessToken", void 0);
482
490
  _define_property(this, "refreshToken", void 0);
@@ -526,7 +534,7 @@ _ts_decorate([
526
534
  }),
527
535
  _ts_metadata("design:type", Boolean)
528
536
  ], RegistrationResponseDto.prototype, "requiresEmailVerification", void 0);
529
- /** Me Response DTO - Returned by GET /auth/me (user data only, no tokens) */ export class MeResponseDto {
537
+ export class MeResponseDto {
530
538
  constructor(){
531
539
  _define_property(this, "user", void 0);
532
540
  _define_property(this, "company", void 0);
@@ -554,7 +562,7 @@ _ts_decorate([
554
562
  }),
555
563
  _ts_metadata("design:type", typeof BranchInfoDto === "undefined" ? Object : BranchInfoDto)
556
564
  ], MeResponseDto.prototype, "branch", void 0);
557
- /** Company Selection Response DTO - Returned when user has multiple companies/branches to choose from */ export class CompanySelectionResponseDto {
565
+ export class CompanySelectionResponseDto {
558
566
  constructor(){
559
567
  _define_property(this, "requiresSelection", void 0);
560
568
  _define_property(this, "sessionId", void 0);
@@ -600,7 +608,7 @@ _ts_decorate([
600
608
  }),
601
609
  _ts_metadata("design:type", Array)
602
610
  ], CompanySelectionResponseDto.prototype, "companies", void 0);
603
- /** Login Response when email verification required */ export class LoginResponseRequiresEmailVerificationDto {
611
+ export class LoginResponseRequiresEmailVerificationDto {
604
612
  constructor(){
605
613
  _define_property(this, "requiresEmailVerification", void 0);
606
614
  _define_property(this, "email", void 0);
@@ -625,8 +633,7 @@ _ts_decorate([
625
633
  }),
626
634
  _ts_metadata("design:type", String)
627
635
  ], LoginResponseRequiresEmailVerificationDto.prototype, "message", void 0);
628
- // Email Auth DTOs
629
- /** Forgot Password Request DTO - Initiates password reset flow */ export class ForgotPasswordDto {
636
+ export class ForgotPasswordDto {
630
637
  constructor(){
631
638
  _define_property(this, "email", void 0);
632
639
  }
@@ -640,7 +647,7 @@ _ts_decorate([
640
647
  IsNotEmpty(),
641
648
  _ts_metadata("design:type", String)
642
649
  ], ForgotPasswordDto.prototype, "email", void 0);
643
- /** Reset Password Request DTO - Resets password using token */ export class ResetPasswordDto {
650
+ export class ResetPasswordDto {
644
651
  constructor(){
645
652
  _define_property(this, "token", void 0);
646
653
  _define_property(this, "newPassword", void 0);
@@ -665,7 +672,7 @@ _ts_decorate([
665
672
  IsStrongPassword(),
666
673
  _ts_metadata("design:type", String)
667
674
  ], ResetPasswordDto.prototype, "newPassword", void 0);
668
- /** Verify Email Request DTO - Verifies email using token */ export class VerifyEmailDto {
675
+ export class VerifyEmailDto {
669
676
  constructor(){
670
677
  _define_property(this, "token", void 0);
671
678
  }
@@ -679,5 +686,5 @@ _ts_decorate([
679
686
  IsNotEmpty(),
680
687
  _ts_metadata("design:type", String)
681
688
  ], VerifyEmailDto.prototype, "token", void 0);
682
- /** Resend Verification Email Request DTO - Same structure as ForgotPasswordDto */ export class ResendVerificationDto extends ForgotPasswordDto {
689
+ export class ResendVerificationDto extends ForgotPasswordDto {
683
690
  }
@@ -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
  }
@@ -31,6 +31,7 @@ export class PendingRegistration {
31
31
  _define_property(this, "token", void 0);
32
32
  _define_property(this, "expiresAt", void 0);
33
33
  _define_property(this, "companyData", void 0);
34
+ _define_property(this, "additionalFields", void 0);
34
35
  _define_property(this, "createdAt", void 0);
35
36
  }
36
37
  }
@@ -90,6 +91,14 @@ _ts_decorate([
90
91
  }),
91
92
  _ts_metadata("design:type", Object)
92
93
  ], PendingRegistration.prototype, "companyData", void 0);
94
+ _ts_decorate([
95
+ Column({
96
+ type: 'json',
97
+ nullable: true,
98
+ name: 'additional_fields'
99
+ }),
100
+ _ts_metadata("design:type", Object)
101
+ ], PendingRegistration.prototype, "additionalFields", void 0);
93
102
  _ts_decorate([
94
103
  CreateDateColumn({
95
104
  type: 'timestamp',
@@ -1,26 +1,4 @@
1
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
- * }
2
+ * User Enricher Provider Interface - allows apps to extend user list/profile
3
+ * without modifying nestjs-auth. Provide via: { provide: USER_ENRICHER, useClass: MyEnricher }
26
4
  */ export { };
@@ -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([