@flusys/nestjs-auth 0.1.0-beta.3 → 1.0.0-rc

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 (102) hide show
  1. package/README.md +274 -301
  2. package/cjs/config/auth.constants.js +22 -4
  3. package/cjs/controllers/authentication.controller.js +222 -38
  4. package/cjs/controllers/branch.controller.js +46 -4
  5. package/cjs/controllers/company-selection.controller.js +27 -20
  6. package/cjs/controllers/company.controller.js +46 -4
  7. package/cjs/controllers/user-permission.controller.js +40 -37
  8. package/cjs/controllers/user.controller.js +222 -23
  9. package/cjs/dtos/authentication.dto.js +119 -13
  10. package/cjs/dtos/user-permission.dto.js +28 -0
  11. package/cjs/dtos/user.dto.js +19 -4
  12. package/cjs/entities/index.js +5 -1
  13. package/cjs/entities/pending-registration.entity.js +125 -0
  14. package/cjs/entities/user-company-permission.entity.js +0 -6
  15. package/cjs/entities/user-token.entity.js +129 -0
  16. package/cjs/guards/auth-throttler.guard.js +53 -0
  17. package/cjs/interceptors/clear-token.interceptor.js +3 -6
  18. package/cjs/interceptors/set-token.interceptor.js +38 -31
  19. package/cjs/interfaces/auth-email-provider.interface.js +45 -0
  20. package/cjs/interfaces/authentication.interface.js +0 -3
  21. package/cjs/interfaces/index.js +2 -0
  22. package/cjs/interfaces/user-enricher.interface.js +4 -0
  23. package/cjs/modules/auth.module.js +8 -20
  24. package/cjs/services/auth-config.service.js +42 -47
  25. package/cjs/services/auth-datasource.provider.js +18 -34
  26. package/cjs/services/auth-email.service.js +471 -0
  27. package/cjs/services/authentication.service.js +240 -153
  28. package/cjs/services/branch.service.js +15 -48
  29. package/cjs/services/company-selection-session.service.js +1 -1
  30. package/cjs/services/company.service.js +7 -36
  31. package/cjs/services/index.js +1 -0
  32. package/cjs/services/user-permission.service.js +9 -29
  33. package/cjs/services/user.service.js +228 -107
  34. package/cjs/strategies/jwt.strategy.js +14 -1
  35. package/cjs/validators/password.validator.js +45 -0
  36. package/config/auth.constants.d.ts +5 -0
  37. package/controllers/authentication.controller.d.ts +13 -9
  38. package/controllers/company-selection.controller.d.ts +6 -2
  39. package/controllers/user.controller.d.ts +33 -0
  40. package/dtos/authentication.dto.d.ts +21 -3
  41. package/dtos/company-branch.dto.d.ts +0 -1
  42. package/dtos/company.dto.d.ts +0 -1
  43. package/dtos/user-permission.dto.d.ts +4 -0
  44. package/dtos/user.dto.d.ts +1 -2
  45. package/entities/index.d.ts +7 -3
  46. package/entities/pending-registration.entity.d.ts +17 -0
  47. package/entities/user-company-permission.entity.d.ts +0 -2
  48. package/entities/user-token.entity.d.ts +15 -0
  49. package/fesm/config/auth.constants.js +11 -8
  50. package/fesm/controllers/authentication.controller.js +224 -40
  51. package/fesm/controllers/branch.controller.js +49 -7
  52. package/fesm/controllers/company-selection.controller.js +28 -21
  53. package/fesm/controllers/company.controller.js +49 -7
  54. package/fesm/controllers/user-permission.controller.js +41 -38
  55. package/fesm/controllers/user.controller.js +225 -26
  56. package/fesm/dtos/authentication.dto.js +123 -111
  57. package/fesm/dtos/user-permission.dto.js +28 -0
  58. package/fesm/dtos/user.dto.js +20 -5
  59. package/fesm/entities/index.js +7 -1
  60. package/fesm/entities/pending-registration.entity.js +115 -0
  61. package/fesm/entities/user-company-permission.entity.js +0 -6
  62. package/fesm/entities/user-token.entity.js +113 -0
  63. package/fesm/guards/auth-throttler.guard.js +43 -0
  64. package/fesm/interceptors/clear-token.interceptor.js +2 -5
  65. package/fesm/interceptors/set-token.interceptor.js +37 -30
  66. package/fesm/interfaces/auth-email-provider.interface.js +38 -0
  67. package/fesm/interfaces/authentication.interface.js +1 -7
  68. package/fesm/interfaces/index.js +2 -0
  69. package/fesm/interfaces/user-enricher.interface.js +26 -0
  70. package/fesm/modules/auth.module.js +10 -22
  71. package/fesm/services/auth-config.service.js +42 -47
  72. package/fesm/services/auth-datasource.provider.js +19 -35
  73. package/fesm/services/auth-email.service.js +420 -0
  74. package/fesm/services/authentication.service.js +238 -151
  75. package/fesm/services/branch.service.js +16 -49
  76. package/fesm/services/company-selection-session.service.js +1 -1
  77. package/fesm/services/company.service.js +8 -37
  78. package/fesm/services/index.js +1 -0
  79. package/fesm/services/user-permission.service.js +10 -30
  80. package/fesm/services/user.service.js +229 -108
  81. package/fesm/strategies/jwt.strategy.js +14 -1
  82. package/fesm/validators/password.validator.js +48 -0
  83. package/guards/auth-throttler.guard.d.ts +7 -0
  84. package/interceptors/set-token.interceptor.d.ts +1 -0
  85. package/interfaces/auth-email-provider.interface.d.ts +6 -0
  86. package/interfaces/auth-module-options.interface.d.ts +4 -1
  87. package/interfaces/authentication.interface.d.ts +14 -0
  88. package/interfaces/index.d.ts +2 -0
  89. package/interfaces/user-enricher.interface.d.ts +64 -0
  90. package/interfaces/user.interface.d.ts +1 -0
  91. package/modules/auth.module.d.ts +0 -1
  92. package/package.json +4 -4
  93. package/services/auth-config.service.d.ts +5 -1
  94. package/services/auth-email.service.d.ts +51 -0
  95. package/services/authentication.service.d.ts +21 -12
  96. package/services/branch.service.d.ts +2 -5
  97. package/services/company-selection-session.service.d.ts +1 -1
  98. package/services/company.service.d.ts +1 -4
  99. package/services/index.d.ts +1 -0
  100. package/services/user-permission.service.d.ts +0 -1
  101. package/services/user.service.d.ts +20 -6
  102. package/validators/password.validator.d.ts +10 -0
@@ -21,16 +21,10 @@ function _ts_metadata(k, v) {
21
21
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
22
22
  }
23
23
  import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
24
- import { IsEmail, IsNotEmpty, IsOptional, IsString, IsUUID, MaxLength, MinLength, ValidateIf } from 'class-validator';
25
- // =============================================================================
26
- // REQUEST DTOs (Following Controller Endpoint Order)
27
- // =============================================================================
28
- // -----------------------------------------------------------------------------
29
- // 1. LOGIN
30
- // -----------------------------------------------------------------------------
31
- /**
32
- * Login Request DTO
33
- */ export class LoginDto {
24
+ import { IsEmail, IsNotEmpty, IsOptional, IsString, IsUUID, MaxLength, ValidateIf } from 'class-validator';
25
+ import { IsStrongPassword } from '../validators/password.validator';
26
+ // Request DTOs
27
+ /** Login Request DTO */ export class LoginDto {
34
28
  constructor(){
35
29
  _define_property(this, "email", void 0);
36
30
  _define_property(this, "password", void 0);
@@ -47,21 +41,15 @@ _ts_decorate([
47
41
  ], LoginDto.prototype, "email", void 0);
48
42
  _ts_decorate([
49
43
  ApiProperty({
50
- example: '123456',
51
- description: 'User password (min 6 chars)'
44
+ example: 'SecureP@ss1',
45
+ description: 'User password'
52
46
  }),
53
47
  IsString(),
54
48
  IsNotEmpty(),
55
- MinLength(6),
49
+ MaxLength(128),
56
50
  _ts_metadata("design:type", String)
57
51
  ], LoginDto.prototype, "password", void 0);
58
- // -----------------------------------------------------------------------------
59
- // 2. REGISTER
60
- // -----------------------------------------------------------------------------
61
- /**
62
- * Registration Request DTO
63
- * Supports both simple registration and company-based registration
64
- */ export class RegistrationDto {
52
+ /** Registration Request DTO - Supports simple and company-based registration */ export class RegistrationDto {
65
53
  constructor(){
66
54
  _define_property(this, "name", void 0);
67
55
  _define_property(this, "email", void 0);
@@ -97,13 +85,13 @@ _ts_decorate([
97
85
  ], RegistrationDto.prototype, "email", void 0);
98
86
  _ts_decorate([
99
87
  ApiProperty({
100
- example: 'strongPassword123',
101
- description: 'Password (min 6 chars)'
88
+ example: 'StrongP@ss123',
89
+ description: 'Password (min 8 chars, requires uppercase, lowercase, number, special char)'
102
90
  }),
103
91
  IsNotEmpty(),
104
92
  IsString(),
105
- MinLength(6),
106
- MaxLength(60),
93
+ IsStrongPassword(),
94
+ MaxLength(128),
107
95
  _ts_metadata("design:type", String)
108
96
  ], RegistrationDto.prototype, "password", void 0);
109
97
  _ts_decorate([
@@ -164,15 +152,10 @@ _ts_decorate([
164
152
  }),
165
153
  IsOptional(),
166
154
  IsString(),
155
+ MaxLength(500),
167
156
  _ts_metadata("design:type", String)
168
157
  ], RegistrationDto.prototype, "newCompanyAddress", void 0);
169
- // -----------------------------------------------------------------------------
170
- // 3. REFRESH TOKEN
171
- // -----------------------------------------------------------------------------
172
- /**
173
- * Refresh Token Request DTO
174
- * Note: refreshToken is optional in body - browsers send it via HTTP-only cookie
175
- */ export class RefreshTokenDto {
158
+ /** Refresh Token Request DTO - refreshToken optional in body (browsers use HTTP-only cookie) */ export class RefreshTokenDto {
176
159
  constructor(){
177
160
  _define_property(this, "refreshToken", void 0);
178
161
  }
@@ -186,12 +169,7 @@ _ts_decorate([
186
169
  IsString(),
187
170
  _ts_metadata("design:type", String)
188
171
  ], RefreshTokenDto.prototype, "refreshToken", void 0);
189
- // -----------------------------------------------------------------------------
190
- // 4. CHANGE PASSWORD
191
- // -----------------------------------------------------------------------------
192
- /**
193
- * Change Password Request DTO
194
- */ export class ChangePasswordDto {
172
+ /** Change Password Request DTO */ export class ChangePasswordDto {
195
173
  constructor(){
196
174
  _define_property(this, "currentPassword", void 0);
197
175
  _define_property(this, "newPassword", void 0);
@@ -204,26 +182,20 @@ _ts_decorate([
204
182
  }),
205
183
  IsString(),
206
184
  IsNotEmpty(),
185
+ MaxLength(128),
207
186
  _ts_metadata("design:type", String)
208
187
  ], ChangePasswordDto.prototype, "currentPassword", void 0);
209
188
  _ts_decorate([
210
189
  ApiProperty({
211
- example: 'newPassword456',
212
- description: 'New password (min 6 chars)'
190
+ example: 'NewP@ssword456',
191
+ description: 'New password (min 8 chars, requires uppercase, lowercase, number, special char)'
213
192
  }),
214
193
  IsString(),
215
194
  IsNotEmpty(),
216
- MinLength(6),
195
+ IsStrongPassword(),
217
196
  _ts_metadata("design:type", String)
218
197
  ], ChangePasswordDto.prototype, "newPassword", void 0);
219
- // -----------------------------------------------------------------------------
220
- // 5. SELECT COMPANY & BRANCH (Step 2 - after login with multiple options)
221
- // -----------------------------------------------------------------------------
222
- /**
223
- * Select Company & Branch Request DTO
224
- * Used after login when user needs to select company and branch
225
- * Frontend receives all companies with their branches, user selects both
226
- */ export class SelectDto {
198
+ /** Select Company & Branch Request DTO - Used after login when user needs to select company and branch */ export class SelectDto {
227
199
  constructor(){
228
200
  _define_property(this, "sessionId", void 0);
229
201
  _define_property(this, "companyId", void 0);
@@ -257,13 +229,7 @@ _ts_decorate([
257
229
  IsNotEmpty(),
258
230
  _ts_metadata("design:type", String)
259
231
  ], SelectDto.prototype, "branchId", void 0);
260
- // -----------------------------------------------------------------------------
261
- // 7. SWITCH COMPANY/BRANCH (after already logged in)
262
- // -----------------------------------------------------------------------------
263
- /**
264
- * Switch Company Request DTO
265
- * Used to switch company/branch after login
266
- */ export class SwitchCompanyDto {
232
+ /** Switch Company Request DTO - Used to switch company/branch after login */ export class SwitchCompanyDto {
267
233
  constructor(){
268
234
  _define_property(this, "companyId", void 0);
269
235
  _define_property(this, "branchId", void 0);
@@ -287,15 +253,8 @@ _ts_decorate([
287
253
  IsNotEmpty(),
288
254
  _ts_metadata("design:type", String)
289
255
  ], SwitchCompanyDto.prototype, "branchId", void 0);
290
- // =============================================================================
291
- // RESPONSE DTOs
292
- // =============================================================================
293
- // -----------------------------------------------------------------------------
294
- // NESTED/HELPER DTOs (Used in Response DTOs)
295
- // -----------------------------------------------------------------------------
296
- /**
297
- * User Info DTO (used in responses)
298
- */ export class UserInfoDto {
256
+ // Response DTOs
257
+ /** User Info DTO (used in responses) */ export class UserInfoDto {
299
258
  constructor(){
300
259
  _define_property(this, "id", void 0);
301
260
  _define_property(this, "email", void 0);
@@ -329,9 +288,7 @@ _ts_decorate([
329
288
  }),
330
289
  _ts_metadata("design:type", Object)
331
290
  ], UserInfoDto.prototype, "profilePictureId", void 0);
332
- /**
333
- * Company Info DTO (used in responses)
334
- */ export class CompanyInfoDto {
291
+ /** Company Info DTO (used in responses) */ export class CompanyInfoDto {
335
292
  constructor(){
336
293
  _define_property(this, "id", void 0);
337
294
  _define_property(this, "name", void 0);
@@ -365,9 +322,7 @@ _ts_decorate([
365
322
  }),
366
323
  _ts_metadata("design:type", Object)
367
324
  ], CompanyInfoDto.prototype, "logoId", void 0);
368
- /**
369
- * Branch Info DTO (used in responses)
370
- */ export class BranchInfoDto {
325
+ /** Branch Info DTO (used in responses) */ export class BranchInfoDto {
371
326
  constructor(){
372
327
  _define_property(this, "id", void 0);
373
328
  _define_property(this, "name", void 0);
@@ -401,9 +356,7 @@ _ts_decorate([
401
356
  }),
402
357
  _ts_metadata("design:type", Object)
403
358
  ], BranchInfoDto.prototype, "logoId", void 0);
404
- /**
405
- * Branch Info for Selection (with additional fields)
406
- */ export class BranchSelectionInfoDto {
359
+ /** Branch Info for Selection (with additional fields) */ export class BranchSelectionInfoDto {
407
360
  constructor(){
408
361
  _define_property(this, "id", void 0);
409
362
  _define_property(this, "name", void 0);
@@ -444,9 +397,7 @@ _ts_decorate([
444
397
  }),
445
398
  _ts_metadata("design:type", Object)
446
399
  ], BranchSelectionInfoDto.prototype, "logoId", void 0);
447
- /**
448
- * Company with Branches DTO (for selection response)
449
- */ export class CompanyWithBranchesDto {
400
+ /** Company with Branches DTO (for selection response) */ export class CompanyWithBranchesDto {
450
401
  constructor(){
451
402
  _define_property(this, "id", void 0);
452
403
  _define_property(this, "name", void 0);
@@ -497,13 +448,7 @@ _ts_decorate([
497
448
  }),
498
449
  _ts_metadata("design:type", Array)
499
450
  ], CompanyWithBranchesDto.prototype, "branches", void 0);
500
- // -----------------------------------------------------------------------------
501
- // LOGIN RESPONSE
502
- // -----------------------------------------------------------------------------
503
- /**
504
- * Login Response DTO
505
- * Returned on successful login with tokens
506
- */ export class LoginResponseDto {
451
+ /** Login Response DTO - Returned on successful login with tokens */ export class LoginResponseDto {
507
452
  constructor(){
508
453
  _define_property(this, "accessToken", void 0);
509
454
  _define_property(this, "refreshToken", void 0);
@@ -553,13 +498,7 @@ _ts_decorate([
553
498
  }),
554
499
  _ts_metadata("design:type", Boolean)
555
500
  ], LoginResponseDto.prototype, "companyFeatureEnabled", void 0);
556
- // -----------------------------------------------------------------------------
557
- // REGISTRATION RESPONSE
558
- // -----------------------------------------------------------------------------
559
- /**
560
- * Registration Response DTO
561
- * Returned on successful registration
562
- */ export class RegistrationResponseDto {
501
+ /** Registration Response DTO - Returned on successful registration */ export class RegistrationResponseDto {
563
502
  constructor(){
564
503
  _define_property(this, "accessToken", void 0);
565
504
  _define_property(this, "refreshToken", void 0);
@@ -567,16 +506,17 @@ _ts_decorate([
567
506
  _define_property(this, "company", void 0);
568
507
  _define_property(this, "branch", void 0);
569
508
  _define_property(this, "companyFeatureEnabled", void 0);
509
+ _define_property(this, "requiresEmailVerification", void 0);
570
510
  }
571
511
  }
572
512
  _ts_decorate([
573
- ApiProperty({
513
+ ApiPropertyOptional({
574
514
  example: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...'
575
515
  }),
576
516
  _ts_metadata("design:type", String)
577
517
  ], RegistrationResponseDto.prototype, "accessToken", void 0);
578
518
  _ts_decorate([
579
- ApiProperty({
519
+ ApiPropertyOptional({
580
520
  example: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...'
581
521
  }),
582
522
  _ts_metadata("design:type", String)
@@ -603,22 +543,20 @@ _ts_decorate([
603
543
  _ts_metadata("design:type", typeof BranchInfoDto === "undefined" ? Object : BranchInfoDto)
604
544
  ], RegistrationResponseDto.prototype, "branch", void 0);
605
545
  _ts_decorate([
606
- ApiProperty({
546
+ ApiPropertyOptional({
607
547
  example: true,
608
548
  description: 'Whether company feature is enabled'
609
549
  }),
610
550
  _ts_metadata("design:type", Boolean)
611
551
  ], RegistrationResponseDto.prototype, "companyFeatureEnabled", void 0);
612
- // -----------------------------------------------------------------------------
613
- // ME (GET CURRENT USER INFO) RESPONSE
614
- // -----------------------------------------------------------------------------
615
- /**
616
- * Me Response DTO
617
- * Returned by GET /auth/me endpoint
618
- * Does NOT include accessToken or refreshToken - only user data
619
- * Company and branch are optional - only present when company feature is enabled
620
- * These fields are automatically hidden in Swagger when company feature is disabled
621
- */ export class MeResponseDto {
552
+ _ts_decorate([
553
+ ApiPropertyOptional({
554
+ example: true,
555
+ description: 'Whether email verification is required'
556
+ }),
557
+ _ts_metadata("design:type", Boolean)
558
+ ], RegistrationResponseDto.prototype, "requiresEmailVerification", void 0);
559
+ /** Me Response DTO - Returned by GET /auth/me (user data only, no tokens) */ export class MeResponseDto {
622
560
  constructor(){
623
561
  _define_property(this, "user", void 0);
624
562
  _define_property(this, "company", void 0);
@@ -646,14 +584,7 @@ _ts_decorate([
646
584
  }),
647
585
  _ts_metadata("design:type", typeof BranchInfoDto === "undefined" ? Object : BranchInfoDto)
648
586
  ], MeResponseDto.prototype, "branch", void 0);
649
- // -----------------------------------------------------------------------------
650
- // COMPANY/BRANCH SELECTION RESPONSE
651
- // -----------------------------------------------------------------------------
652
- /**
653
- * Company Selection Response DTO
654
- * Returned when user has multiple companies/branches to choose from
655
- * Frontend displays selection UI and calls /select with chosen company + branch
656
- */ export class CompanySelectionResponseDto {
587
+ /** Company Selection Response DTO - Returned when user has multiple companies/branches to choose from */ export class CompanySelectionResponseDto {
657
588
  constructor(){
658
589
  _define_property(this, "requiresSelection", void 0);
659
590
  _define_property(this, "sessionId", void 0);
@@ -699,3 +630,84 @@ _ts_decorate([
699
630
  }),
700
631
  _ts_metadata("design:type", Array)
701
632
  ], CompanySelectionResponseDto.prototype, "companies", void 0);
633
+ /** Login Response when email verification required */ export class LoginResponseRequiresEmailVerificationDto {
634
+ constructor(){
635
+ _define_property(this, "requiresEmailVerification", void 0);
636
+ _define_property(this, "email", void 0);
637
+ _define_property(this, "message", void 0);
638
+ }
639
+ }
640
+ _ts_decorate([
641
+ ApiProperty({
642
+ example: true
643
+ }),
644
+ _ts_metadata("design:type", Boolean)
645
+ ], LoginResponseRequiresEmailVerificationDto.prototype, "requiresEmailVerification", void 0);
646
+ _ts_decorate([
647
+ ApiProperty({
648
+ example: 'john@example.com'
649
+ }),
650
+ _ts_metadata("design:type", String)
651
+ ], LoginResponseRequiresEmailVerificationDto.prototype, "email", void 0);
652
+ _ts_decorate([
653
+ ApiProperty({
654
+ example: 'Please verify your email address before logging in.'
655
+ }),
656
+ _ts_metadata("design:type", String)
657
+ ], LoginResponseRequiresEmailVerificationDto.prototype, "message", void 0);
658
+ // Email Auth DTOs
659
+ /** Forgot Password Request DTO - Initiates password reset flow */ export class ForgotPasswordDto {
660
+ constructor(){
661
+ _define_property(this, "email", void 0);
662
+ }
663
+ }
664
+ _ts_decorate([
665
+ ApiProperty({
666
+ example: 'john@example.com',
667
+ description: 'Email address to send reset link to'
668
+ }),
669
+ IsEmail(),
670
+ IsNotEmpty(),
671
+ _ts_metadata("design:type", String)
672
+ ], ForgotPasswordDto.prototype, "email", void 0);
673
+ /** Reset Password Request DTO - Resets password using token */ export class ResetPasswordDto {
674
+ constructor(){
675
+ _define_property(this, "token", void 0);
676
+ _define_property(this, "newPassword", void 0);
677
+ }
678
+ }
679
+ _ts_decorate([
680
+ ApiProperty({
681
+ example: 'a1b2c3d4e5f6...',
682
+ description: 'Password reset token from email'
683
+ }),
684
+ IsString(),
685
+ IsNotEmpty(),
686
+ _ts_metadata("design:type", String)
687
+ ], ResetPasswordDto.prototype, "token", void 0);
688
+ _ts_decorate([
689
+ ApiProperty({
690
+ example: 'NewSecureP@ss123',
691
+ description: 'New password (min 8 chars, requires uppercase, lowercase, number, special char)'
692
+ }),
693
+ IsString(),
694
+ IsNotEmpty(),
695
+ IsStrongPassword(),
696
+ _ts_metadata("design:type", String)
697
+ ], ResetPasswordDto.prototype, "newPassword", void 0);
698
+ /** Verify Email Request DTO - Verifies email using token */ export class VerifyEmailDto {
699
+ constructor(){
700
+ _define_property(this, "token", void 0);
701
+ }
702
+ }
703
+ _ts_decorate([
704
+ ApiProperty({
705
+ example: 'a1b2c3d4e5f6...',
706
+ description: 'Email verification token from email'
707
+ }),
708
+ IsString(),
709
+ IsNotEmpty(),
710
+ _ts_metadata("design:type", String)
711
+ ], VerifyEmailDto.prototype, "token", void 0);
712
+ /** Resend Verification Email Request DTO - Same structure as ForgotPasswordDto */ export class ResendVerificationDto extends ForgotPasswordDto {
713
+ }
@@ -233,9 +233,23 @@ _ts_decorate([
233
233
  * User companies response
234
234
  */ export class UserCompaniesResponseDto {
235
235
  constructor(){
236
+ _define_property(this, "success", void 0);
237
+ _define_property(this, "message", void 0);
236
238
  _define_property(this, "data", void 0);
237
239
  }
238
240
  }
241
+ _ts_decorate([
242
+ ApiProperty({
243
+ example: true
244
+ }),
245
+ _ts_metadata("design:type", Boolean)
246
+ ], UserCompaniesResponseDto.prototype, "success", void 0);
247
+ _ts_decorate([
248
+ ApiProperty({
249
+ example: 'User companies retrieved successfully'
250
+ }),
251
+ _ts_metadata("design:type", String)
252
+ ], UserCompaniesResponseDto.prototype, "message", void 0);
239
253
  _ts_decorate([
240
254
  ApiProperty({
241
255
  description: 'List of companies the user has access to',
@@ -265,9 +279,23 @@ _ts_decorate([
265
279
  * User branches response
266
280
  */ export class UserBranchesResponseDto {
267
281
  constructor(){
282
+ _define_property(this, "success", void 0);
283
+ _define_property(this, "message", void 0);
268
284
  _define_property(this, "data", void 0);
269
285
  }
270
286
  }
287
+ _ts_decorate([
288
+ ApiProperty({
289
+ example: true
290
+ }),
291
+ _ts_metadata("design:type", Boolean)
292
+ ], UserBranchesResponseDto.prototype, "success", void 0);
293
+ _ts_decorate([
294
+ ApiProperty({
295
+ example: 'User branches retrieved successfully'
296
+ }),
297
+ _ts_metadata("design:type", String)
298
+ ], UserBranchesResponseDto.prototype, "message", void 0);
271
299
  _ts_decorate([
272
300
  ApiProperty({
273
301
  description: 'List of branches the user has access to',
@@ -21,7 +21,8 @@ function _ts_metadata(k, v) {
21
21
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
22
22
  }
23
23
  import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
24
- import { IsBoolean, IsEmail, IsObject, IsOptional, IsString } from 'class-validator';
24
+ import { IsBoolean, IsEmail, IsNotEmpty, IsObject, IsOptional, IsString, IsUUID, MaxLength } from 'class-validator';
25
+ import { IsStrongPassword } from '../validators/password.validator';
25
26
  export class CreateUserDto {
26
27
  constructor(){
27
28
  _define_property(this, "name", void 0);
@@ -62,10 +63,13 @@ _ts_decorate([
62
63
  ], CreateUserDto.prototype, "email", void 0);
63
64
  _ts_decorate([
64
65
  ApiProperty({
65
- example: 'password123',
66
- description: 'Password'
66
+ example: 'SecureP@ss123',
67
+ description: 'Password (must meet complexity requirements)'
67
68
  }),
68
69
  IsString(),
70
+ IsNotEmpty(),
71
+ IsStrongPassword(),
72
+ MaxLength(128),
69
73
  _ts_metadata("design:type", String)
70
74
  ], CreateUserDto.prototype, "password", void 0);
71
75
  _ts_decorate([
@@ -118,6 +122,7 @@ export class UpdateUserDto {
118
122
  _define_property(this, "phone", void 0);
119
123
  _define_property(this, "email", void 0);
120
124
  _define_property(this, "password", void 0);
125
+ _define_property(this, "oldPassword", void 0);
121
126
  _define_property(this, "profilePictureId", void 0);
122
127
  _define_property(this, "isActive", void 0);
123
128
  _define_property(this, "emailVerified", void 0);
@@ -129,7 +134,7 @@ _ts_decorate([
129
134
  ApiProperty({
130
135
  description: 'User ID'
131
136
  }),
132
- IsString(),
137
+ IsUUID(),
133
138
  _ts_metadata("design:type", String)
134
139
  ], UpdateUserDto.prototype, "id", void 0);
135
140
  _ts_decorate([
@@ -161,12 +166,22 @@ _ts_decorate([
161
166
  ], UpdateUserDto.prototype, "email", void 0);
162
167
  _ts_decorate([
163
168
  ApiPropertyOptional({
164
- description: 'New password'
169
+ description: 'New password (must meet complexity requirements)'
165
170
  }),
166
171
  IsOptional(),
167
172
  IsString(),
173
+ IsStrongPassword(),
174
+ MaxLength(128),
168
175
  _ts_metadata("design:type", String)
169
176
  ], UpdateUserDto.prototype, "password", void 0);
177
+ _ts_decorate([
178
+ ApiPropertyOptional({
179
+ description: 'Current password (required when changing password on own profile)'
180
+ }),
181
+ IsOptional(),
182
+ IsString(),
183
+ _ts_metadata("design:type", String)
184
+ ], UpdateUserDto.prototype, "oldPassword", void 0);
170
185
  _ts_decorate([
171
186
  ApiPropertyOptional({
172
187
  description: 'Profile picture file ID'
@@ -1,13 +1,19 @@
1
1
  export * from './company-branch.entity';
2
2
  export * from './company.entity';
3
+ export * from './pending-registration.entity';
3
4
  export { PermissionType, UserCompanyPermission } from './user-company-permission.entity';
4
5
  export * from './user.entity';
6
+ export * from './user-token.entity';
5
7
  import { CompanyBranch } from './company-branch.entity';
6
8
  import { Company } from './company.entity';
9
+ import { PendingRegistration } from './pending-registration.entity';
7
10
  import { UserCompanyPermission } from './user-company-permission.entity';
8
11
  import { User } from './user.entity';
12
+ import { UserToken } from './user-token.entity';
9
13
  export const CoreEntities = [
10
- User
14
+ User,
15
+ UserToken,
16
+ PendingRegistration
11
17
  ];
12
18
  export const CompanyEntities = [
13
19
  Company,
@@ -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);
@@ -27,12 +27,6 @@ import { Company } from './company.entity';
27
27
  import { User } from './user.entity';
28
28
  export { PermissionType };
29
29
  export class UserCompanyPermission {
30
- /* ---------- Helpers ---------- */ isCompanyPermission() {
31
- return this.permissionType === PermissionType.COMPANY;
32
- }
33
- isBranchPermission() {
34
- return this.permissionType === PermissionType.BRANCH;
35
- }
36
30
  constructor(){
37
31
  _define_property(this, "id", void 0);
38
32
  /* ---------- Ownership ---------- */ _define_property(this, "userId", void 0);