@flusys/nestjs-auth 1.0.0-beta → 1.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 (106) hide show
  1. package/README.md +590 -473
  2. package/cjs/config/auth.constants.js +12 -0
  3. package/cjs/controllers/authentication.controller.js +365 -24
  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/user-permission.controller.js +82 -154
  8. package/cjs/controllers/user.controller.js +211 -7
  9. package/cjs/docs/auth-swagger.config.js +14 -7
  10. package/cjs/dtos/authentication.dto.js +114 -38
  11. package/cjs/dtos/index.js +0 -1
  12. package/cjs/dtos/user-permission.dto.js +28 -0
  13. package/cjs/dtos/user.dto.js +19 -4
  14. package/cjs/entities/index.js +5 -1
  15. package/cjs/entities/pending-registration.entity.js +125 -0
  16. package/cjs/entities/user-company-permission.entity.js +3 -9
  17. package/cjs/entities/user-token.entity.js +129 -0
  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 +45 -0
  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 +65 -143
  24. package/cjs/services/auth-config.service.js +25 -27
  25. package/cjs/services/auth-datasource.provider.js +13 -23
  26. package/cjs/services/auth-email.service.js +456 -0
  27. package/cjs/services/authentication.service.js +297 -349
  28. package/cjs/services/branch.service.js +9 -4
  29. package/cjs/services/company-selection-session.service.js +1 -1
  30. package/cjs/services/index.js +1 -0
  31. package/cjs/services/user-permission.service.js +43 -73
  32. package/cjs/services/user.service.js +184 -34
  33. package/cjs/strategies/jwt.strategy.js +44 -44
  34. package/cjs/validators/password.validator.js +45 -0
  35. package/config/auth.constants.d.ts +3 -0
  36. package/controllers/authentication.controller.d.ts +16 -10
  37. package/controllers/company-selection.controller.d.ts +6 -2
  38. package/controllers/user-permission.controller.d.ts +5 -4
  39. package/controllers/user.controller.d.ts +33 -0
  40. package/dtos/authentication.dto.d.ts +20 -6
  41. package/dtos/company-branch.dto.d.ts +0 -1
  42. package/dtos/company.dto.d.ts +0 -1
  43. package/dtos/index.d.ts +0 -1
  44. package/dtos/user-permission.dto.d.ts +4 -0
  45. package/dtos/user.dto.d.ts +1 -2
  46. package/entities/index.d.ts +7 -3
  47. package/entities/pending-registration.entity.d.ts +17 -0
  48. package/entities/user-company-permission.entity.d.ts +1 -3
  49. package/entities/user-token.entity.d.ts +15 -0
  50. package/fesm/config/auth.constants.js +6 -2
  51. package/fesm/controllers/authentication.controller.js +368 -27
  52. package/fesm/controllers/branch.controller.js +45 -2
  53. package/fesm/controllers/company-selection.controller.js +28 -21
  54. package/fesm/controllers/company.controller.js +45 -2
  55. package/fesm/controllers/user-permission.controller.js +84 -156
  56. package/fesm/controllers/user.controller.js +214 -10
  57. package/fesm/docs/auth-swagger.config.js +14 -7
  58. package/fesm/dtos/authentication.dto.js +101 -39
  59. package/fesm/dtos/index.js +0 -1
  60. package/fesm/dtos/user-permission.dto.js +28 -0
  61. package/fesm/dtos/user.dto.js +20 -5
  62. package/fesm/entities/index.js +7 -1
  63. package/fesm/entities/pending-registration.entity.js +115 -0
  64. package/fesm/entities/user-company-permission.entity.js +3 -9
  65. package/fesm/entities/user-token.entity.js +113 -0
  66. package/fesm/interceptors/clear-token.interceptor.js +9 -22
  67. package/fesm/interceptors/set-token.interceptor.js +14 -54
  68. package/fesm/interfaces/auth-email-provider.interface.js +38 -0
  69. package/fesm/interfaces/authentication.interface.js +1 -1
  70. package/fesm/interfaces/index.js +2 -0
  71. package/fesm/interfaces/user-enricher.interface.js +26 -0
  72. package/fesm/modules/auth.module.js +67 -145
  73. package/fesm/services/auth-config.service.js +26 -28
  74. package/fesm/services/auth-datasource.provider.js +14 -24
  75. package/fesm/services/auth-email.service.js +405 -0
  76. package/fesm/services/authentication.service.js +297 -349
  77. package/fesm/services/branch.service.js +9 -4
  78. package/fesm/services/company-selection-session.service.js +1 -1
  79. package/fesm/services/index.js +1 -0
  80. package/fesm/services/user-permission.service.js +44 -74
  81. package/fesm/services/user.service.js +186 -36
  82. package/fesm/strategies/jwt.strategy.js +44 -44
  83. package/fesm/validators/password.validator.js +48 -0
  84. package/interceptors/clear-token.interceptor.d.ts +0 -1
  85. package/interceptors/set-token.interceptor.d.ts +1 -1
  86. package/interfaces/auth-email-provider.interface.d.ts +6 -0
  87. package/interfaces/auth-module-options.interface.d.ts +4 -1
  88. package/interfaces/authentication.interface.d.ts +13 -3
  89. package/interfaces/index.d.ts +2 -0
  90. package/interfaces/user-enricher.interface.d.ts +64 -0
  91. package/interfaces/user.interface.d.ts +1 -0
  92. package/modules/auth.module.d.ts +6 -3
  93. package/package.json +4 -4
  94. package/services/auth-config.service.d.ts +7 -8
  95. package/services/auth-datasource.provider.d.ts +2 -4
  96. package/services/auth-email.service.d.ts +54 -0
  97. package/services/authentication.service.d.ts +27 -16
  98. package/services/company-selection-session.service.d.ts +1 -1
  99. package/services/index.d.ts +1 -0
  100. package/services/user-permission.service.d.ts +6 -9
  101. package/services/user.service.d.ts +19 -3
  102. package/strategies/jwt.strategy.d.ts +4 -1
  103. package/validators/password.validator.d.ts +10 -0
  104. package/cjs/dtos/user-company-permission.dto.js +0 -110
  105. package/dtos/user-company-permission.dto.d.ts +0 -10
  106. package/fesm/dtos/user-company-permission.dto.js +0 -98
@@ -4,6 +4,16 @@
4
4
  'User Permissions',
5
5
  'Company Selection'
6
6
  ];
7
+ /** Examples to exclude when company feature is disabled */ const COMPANY_EXAMPLE_EXCLUSIONS = [
8
+ {
9
+ pathPattern: '/auth/login',
10
+ method: 'post',
11
+ examples: [
12
+ 'loginSuccessWithCompany',
13
+ 'companySelection'
14
+ ]
15
+ }
16
+ ];
7
17
  /**
8
18
  * Schema properties to exclude when company feature is disabled
9
19
  *
@@ -48,16 +58,14 @@
48
58
  schemaName: 'RegistrationResponseDto',
49
59
  properties: [
50
60
  'company',
51
- 'branch',
52
- 'companyFeatureEnabled'
61
+ 'branch'
53
62
  ]
54
63
  },
55
64
  {
56
65
  schemaName: 'LoginResponseDto',
57
66
  properties: [
58
67
  'company',
59
- 'branch',
60
- 'companyFeatureEnabled'
68
+ 'branch'
61
69
  ]
62
70
  },
63
71
  {
@@ -92,7 +100,6 @@
92
100
  'id',
93
101
  'name',
94
102
  'slug',
95
- 'isActive',
96
103
  'logoId'
97
104
  ]
98
105
  },
@@ -102,7 +109,6 @@
102
109
  'id',
103
110
  'name',
104
111
  'slug',
105
- 'isActive',
106
112
  'logoId',
107
113
  'branches'
108
114
  ]
@@ -401,6 +407,7 @@ POST /auth/login → { accessToken, refreshToken, user }
401
407
  path: 'api/docs/auth',
402
408
  bearerAuth: true,
403
409
  excludeTags,
404
- excludeSchemaProperties: enableCompanyFeature ? undefined : COMPANY_SCHEMA_EXCLUSIONS
410
+ excludeSchemaProperties: enableCompanyFeature ? undefined : COMPANY_SCHEMA_EXCLUSIONS,
411
+ excludeExamples: enableCompanyFeature ? undefined : COMPANY_EXAMPLE_EXCLUSIONS
405
412
  };
406
413
  }
@@ -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 { IsEmail, IsNotEmpty, IsOptional, IsString, IsUUID, MaxLength, MinLength, ValidateIf } from 'class-validator';
24
+ import { IsEmail, IsNotEmpty, IsOptional, IsString, IsUUID, MaxLength, ValidateIf } from 'class-validator';
25
+ import { IsStrongPassword } from '../validators/password.validator';
25
26
  // Request DTOs
26
27
  /** Login Request DTO */ export class LoginDto {
27
28
  constructor(){
@@ -40,12 +41,12 @@ _ts_decorate([
40
41
  ], LoginDto.prototype, "email", void 0);
41
42
  _ts_decorate([
42
43
  ApiProperty({
43
- example: '123456',
44
- description: 'User password (min 6 chars)'
44
+ example: 'SecureP@ss1',
45
+ description: 'User password'
45
46
  }),
46
47
  IsString(),
47
48
  IsNotEmpty(),
48
- MinLength(6),
49
+ MaxLength(128),
49
50
  _ts_metadata("design:type", String)
50
51
  ], LoginDto.prototype, "password", void 0);
51
52
  /** Registration Request DTO - Supports simple and company-based registration */ export class RegistrationDto {
@@ -84,13 +85,13 @@ _ts_decorate([
84
85
  ], RegistrationDto.prototype, "email", void 0);
85
86
  _ts_decorate([
86
87
  ApiProperty({
87
- example: 'strongPassword123',
88
- description: 'Password (min 6 chars)'
88
+ example: 'StrongP@ss123',
89
+ description: 'Password (min 8 chars, requires uppercase, lowercase, number, special char)'
89
90
  }),
90
91
  IsNotEmpty(),
91
92
  IsString(),
92
- MinLength(6),
93
- MaxLength(60),
93
+ IsStrongPassword(),
94
+ MaxLength(128),
94
95
  _ts_metadata("design:type", String)
95
96
  ], RegistrationDto.prototype, "password", void 0);
96
97
  _ts_decorate([
@@ -151,6 +152,7 @@ _ts_decorate([
151
152
  }),
152
153
  IsOptional(),
153
154
  IsString(),
155
+ MaxLength(500),
154
156
  _ts_metadata("design:type", String)
155
157
  ], RegistrationDto.prototype, "newCompanyAddress", void 0);
156
158
  /** Refresh Token Request DTO - refreshToken optional in body (browsers use HTTP-only cookie) */ export class RefreshTokenDto {
@@ -180,16 +182,17 @@ _ts_decorate([
180
182
  }),
181
183
  IsString(),
182
184
  IsNotEmpty(),
185
+ MaxLength(128),
183
186
  _ts_metadata("design:type", String)
184
187
  ], ChangePasswordDto.prototype, "currentPassword", void 0);
185
188
  _ts_decorate([
186
189
  ApiProperty({
187
- example: 'newPassword456',
188
- description: 'New password (min 6 chars)'
190
+ example: 'NewP@ssword456',
191
+ description: 'New password (min 8 chars, requires uppercase, lowercase, number, special char)'
189
192
  }),
190
193
  IsString(),
191
194
  IsNotEmpty(),
192
- MinLength(6),
195
+ IsStrongPassword(),
193
196
  _ts_metadata("design:type", String)
194
197
  ], ChangePasswordDto.prototype, "newPassword", void 0);
195
198
  /** Select Company & Branch Request DTO - Used after login when user needs to select company and branch */ export class SelectDto {
@@ -358,7 +361,6 @@ _ts_decorate([
358
361
  _define_property(this, "id", void 0);
359
362
  _define_property(this, "name", void 0);
360
363
  _define_property(this, "slug", void 0);
361
- _define_property(this, "isActive", void 0);
362
364
  _define_property(this, "logoId", void 0);
363
365
  }
364
366
  }
@@ -380,12 +382,6 @@ _ts_decorate([
380
382
  }),
381
383
  _ts_metadata("design:type", String)
382
384
  ], BranchSelectionInfoDto.prototype, "slug", void 0);
383
- _ts_decorate([
384
- ApiProperty({
385
- example: true
386
- }),
387
- _ts_metadata("design:type", Boolean)
388
- ], BranchSelectionInfoDto.prototype, "isActive", void 0);
389
385
  _ts_decorate([
390
386
  ApiPropertyOptional({
391
387
  example: '550e8400-e29b-41d4-a716-446655440077',
@@ -399,7 +395,6 @@ _ts_decorate([
399
395
  _define_property(this, "id", void 0);
400
396
  _define_property(this, "name", void 0);
401
397
  _define_property(this, "slug", void 0);
402
- _define_property(this, "isActive", void 0);
403
398
  _define_property(this, "logoId", void 0);
404
399
  _define_property(this, "branches", void 0);
405
400
  }
@@ -422,12 +417,6 @@ _ts_decorate([
422
417
  }),
423
418
  _ts_metadata("design:type", String)
424
419
  ], CompanyWithBranchesDto.prototype, "slug", void 0);
425
- _ts_decorate([
426
- ApiProperty({
427
- example: true
428
- }),
429
- _ts_metadata("design:type", Boolean)
430
- ], CompanyWithBranchesDto.prototype, "isActive", void 0);
431
420
  _ts_decorate([
432
421
  ApiPropertyOptional({
433
422
  example: '550e8400-e29b-41d4-a716-446655440088',
@@ -452,7 +441,6 @@ _ts_decorate([
452
441
  _define_property(this, "user", void 0);
453
442
  _define_property(this, "company", void 0);
454
443
  _define_property(this, "branch", void 0);
455
- _define_property(this, "companyFeatureEnabled", void 0);
456
444
  }
457
445
  }
458
446
  _ts_decorate([
@@ -488,13 +476,6 @@ _ts_decorate([
488
476
  }),
489
477
  _ts_metadata("design:type", typeof BranchInfoDto === "undefined" ? Object : BranchInfoDto)
490
478
  ], LoginResponseDto.prototype, "branch", void 0);
491
- _ts_decorate([
492
- ApiPropertyOptional({
493
- example: true,
494
- description: 'Whether company feature is enabled'
495
- }),
496
- _ts_metadata("design:type", Boolean)
497
- ], LoginResponseDto.prototype, "companyFeatureEnabled", void 0);
498
479
  /** Registration Response DTO - Returned on successful registration */ export class RegistrationResponseDto {
499
480
  constructor(){
500
481
  _define_property(this, "accessToken", void 0);
@@ -502,17 +483,17 @@ _ts_decorate([
502
483
  _define_property(this, "user", void 0);
503
484
  _define_property(this, "company", void 0);
504
485
  _define_property(this, "branch", void 0);
505
- _define_property(this, "companyFeatureEnabled", void 0);
486
+ _define_property(this, "requiresEmailVerification", void 0);
506
487
  }
507
488
  }
508
489
  _ts_decorate([
509
- ApiProperty({
490
+ ApiPropertyOptional({
510
491
  example: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...'
511
492
  }),
512
493
  _ts_metadata("design:type", String)
513
494
  ], RegistrationResponseDto.prototype, "accessToken", void 0);
514
495
  _ts_decorate([
515
- ApiProperty({
496
+ ApiPropertyOptional({
516
497
  example: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...'
517
498
  }),
518
499
  _ts_metadata("design:type", String)
@@ -539,12 +520,12 @@ _ts_decorate([
539
520
  _ts_metadata("design:type", typeof BranchInfoDto === "undefined" ? Object : BranchInfoDto)
540
521
  ], RegistrationResponseDto.prototype, "branch", void 0);
541
522
  _ts_decorate([
542
- ApiProperty({
523
+ ApiPropertyOptional({
543
524
  example: true,
544
- description: 'Whether company feature is enabled'
525
+ description: 'Whether email verification is required'
545
526
  }),
546
527
  _ts_metadata("design:type", Boolean)
547
- ], RegistrationResponseDto.prototype, "companyFeatureEnabled", void 0);
528
+ ], RegistrationResponseDto.prototype, "requiresEmailVerification", void 0);
548
529
  /** Me Response DTO - Returned by GET /auth/me (user data only, no tokens) */ export class MeResponseDto {
549
530
  constructor(){
550
531
  _define_property(this, "user", void 0);
@@ -619,3 +600,84 @@ _ts_decorate([
619
600
  }),
620
601
  _ts_metadata("design:type", Array)
621
602
  ], CompanySelectionResponseDto.prototype, "companies", void 0);
603
+ /** Login Response when email verification required */ export class LoginResponseRequiresEmailVerificationDto {
604
+ constructor(){
605
+ _define_property(this, "requiresEmailVerification", void 0);
606
+ _define_property(this, "email", void 0);
607
+ _define_property(this, "message", void 0);
608
+ }
609
+ }
610
+ _ts_decorate([
611
+ ApiProperty({
612
+ example: true
613
+ }),
614
+ _ts_metadata("design:type", Boolean)
615
+ ], LoginResponseRequiresEmailVerificationDto.prototype, "requiresEmailVerification", void 0);
616
+ _ts_decorate([
617
+ ApiProperty({
618
+ example: 'john@example.com'
619
+ }),
620
+ _ts_metadata("design:type", String)
621
+ ], LoginResponseRequiresEmailVerificationDto.prototype, "email", void 0);
622
+ _ts_decorate([
623
+ ApiProperty({
624
+ example: 'Please verify your email address before logging in.'
625
+ }),
626
+ _ts_metadata("design:type", String)
627
+ ], LoginResponseRequiresEmailVerificationDto.prototype, "message", void 0);
628
+ // Email Auth DTOs
629
+ /** Forgot Password Request DTO - Initiates password reset flow */ export class ForgotPasswordDto {
630
+ constructor(){
631
+ _define_property(this, "email", void 0);
632
+ }
633
+ }
634
+ _ts_decorate([
635
+ ApiProperty({
636
+ example: 'john@example.com',
637
+ description: 'Email address to send reset link to'
638
+ }),
639
+ IsEmail(),
640
+ IsNotEmpty(),
641
+ _ts_metadata("design:type", String)
642
+ ], ForgotPasswordDto.prototype, "email", void 0);
643
+ /** Reset Password Request DTO - Resets password using token */ export class ResetPasswordDto {
644
+ constructor(){
645
+ _define_property(this, "token", void 0);
646
+ _define_property(this, "newPassword", void 0);
647
+ }
648
+ }
649
+ _ts_decorate([
650
+ ApiProperty({
651
+ example: 'a1b2c3d4e5f6...',
652
+ description: 'Password reset token from email'
653
+ }),
654
+ IsString(),
655
+ IsNotEmpty(),
656
+ _ts_metadata("design:type", String)
657
+ ], ResetPasswordDto.prototype, "token", void 0);
658
+ _ts_decorate([
659
+ ApiProperty({
660
+ example: 'NewSecureP@ss123',
661
+ description: 'New password (min 8 chars, requires uppercase, lowercase, number, special char)'
662
+ }),
663
+ IsString(),
664
+ IsNotEmpty(),
665
+ IsStrongPassword(),
666
+ _ts_metadata("design:type", String)
667
+ ], ResetPasswordDto.prototype, "newPassword", void 0);
668
+ /** Verify Email Request DTO - Verifies email using token */ export class VerifyEmailDto {
669
+ constructor(){
670
+ _define_property(this, "token", void 0);
671
+ }
672
+ }
673
+ _ts_decorate([
674
+ ApiProperty({
675
+ example: 'a1b2c3d4e5f6...',
676
+ description: 'Email verification token from email'
677
+ }),
678
+ IsString(),
679
+ IsNotEmpty(),
680
+ _ts_metadata("design:type", String)
681
+ ], VerifyEmailDto.prototype, "token", void 0);
682
+ /** Resend Verification Email Request DTO - Same structure as ForgotPasswordDto */ export class ResendVerificationDto extends ForgotPasswordDto {
683
+ }
@@ -1,6 +1,5 @@
1
1
  export * from './authentication.dto';
2
2
  export * from './company-branch.dto';
3
3
  export * from './company.dto';
4
- export * from './user-company-permission.dto';
5
4
  export * from './user.dto';
6
5
  export * from './user-permission.dto';
@@ -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);
@@ -69,11 +63,11 @@ _ts_decorate([
69
63
  ], UserCompanyPermission.prototype, "user", void 0);
70
64
  _ts_decorate([
71
65
  Column({
72
- type: 'enum',
73
- enum: PermissionType,
66
+ type: 'varchar',
67
+ length: 50,
74
68
  name: 'permission_type'
75
69
  }),
76
- _ts_metadata("design:type", typeof PermissionType === "undefined" ? Object : PermissionType)
70
+ _ts_metadata("design:type", String)
77
71
  ], UserCompanyPermission.prototype, "permissionType", void 0);
78
72
  _ts_decorate([
79
73
  Column({