@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.
- package/README.md +590 -473
- package/cjs/config/auth.constants.js +12 -0
- package/cjs/controllers/authentication.controller.js +365 -24
- package/cjs/controllers/branch.controller.js +44 -1
- package/cjs/controllers/company-selection.controller.js +27 -20
- package/cjs/controllers/company.controller.js +44 -1
- package/cjs/controllers/user-permission.controller.js +82 -154
- package/cjs/controllers/user.controller.js +211 -7
- package/cjs/docs/auth-swagger.config.js +14 -7
- package/cjs/dtos/authentication.dto.js +114 -38
- package/cjs/dtos/index.js +0 -1
- package/cjs/dtos/user-permission.dto.js +28 -0
- package/cjs/dtos/user.dto.js +19 -4
- package/cjs/entities/index.js +5 -1
- package/cjs/entities/pending-registration.entity.js +125 -0
- package/cjs/entities/user-company-permission.entity.js +3 -9
- package/cjs/entities/user-token.entity.js +129 -0
- package/cjs/interceptors/clear-token.interceptor.js +10 -23
- package/cjs/interceptors/set-token.interceptor.js +15 -55
- package/cjs/interfaces/auth-email-provider.interface.js +45 -0
- package/cjs/interfaces/index.js +2 -0
- package/cjs/interfaces/user-enricher.interface.js +4 -0
- package/cjs/modules/auth.module.js +65 -143
- package/cjs/services/auth-config.service.js +25 -27
- package/cjs/services/auth-datasource.provider.js +13 -23
- package/cjs/services/auth-email.service.js +456 -0
- package/cjs/services/authentication.service.js +297 -349
- package/cjs/services/branch.service.js +9 -4
- package/cjs/services/company-selection-session.service.js +1 -1
- package/cjs/services/index.js +1 -0
- package/cjs/services/user-permission.service.js +43 -73
- package/cjs/services/user.service.js +184 -34
- package/cjs/strategies/jwt.strategy.js +44 -44
- package/cjs/validators/password.validator.js +45 -0
- package/config/auth.constants.d.ts +3 -0
- package/controllers/authentication.controller.d.ts +16 -10
- package/controllers/company-selection.controller.d.ts +6 -2
- package/controllers/user-permission.controller.d.ts +5 -4
- package/controllers/user.controller.d.ts +33 -0
- package/dtos/authentication.dto.d.ts +20 -6
- package/dtos/company-branch.dto.d.ts +0 -1
- package/dtos/company.dto.d.ts +0 -1
- package/dtos/index.d.ts +0 -1
- package/dtos/user-permission.dto.d.ts +4 -0
- package/dtos/user.dto.d.ts +1 -2
- package/entities/index.d.ts +7 -3
- package/entities/pending-registration.entity.d.ts +17 -0
- package/entities/user-company-permission.entity.d.ts +1 -3
- package/entities/user-token.entity.d.ts +15 -0
- package/fesm/config/auth.constants.js +6 -2
- package/fesm/controllers/authentication.controller.js +368 -27
- package/fesm/controllers/branch.controller.js +45 -2
- package/fesm/controllers/company-selection.controller.js +28 -21
- package/fesm/controllers/company.controller.js +45 -2
- package/fesm/controllers/user-permission.controller.js +84 -156
- package/fesm/controllers/user.controller.js +214 -10
- package/fesm/docs/auth-swagger.config.js +14 -7
- package/fesm/dtos/authentication.dto.js +101 -39
- package/fesm/dtos/index.js +0 -1
- package/fesm/dtos/user-permission.dto.js +28 -0
- package/fesm/dtos/user.dto.js +20 -5
- package/fesm/entities/index.js +7 -1
- package/fesm/entities/pending-registration.entity.js +115 -0
- package/fesm/entities/user-company-permission.entity.js +3 -9
- package/fesm/entities/user-token.entity.js +113 -0
- package/fesm/interceptors/clear-token.interceptor.js +9 -22
- package/fesm/interceptors/set-token.interceptor.js +14 -54
- package/fesm/interfaces/auth-email-provider.interface.js +38 -0
- package/fesm/interfaces/authentication.interface.js +1 -1
- package/fesm/interfaces/index.js +2 -0
- package/fesm/interfaces/user-enricher.interface.js +26 -0
- package/fesm/modules/auth.module.js +67 -145
- package/fesm/services/auth-config.service.js +26 -28
- package/fesm/services/auth-datasource.provider.js +14 -24
- package/fesm/services/auth-email.service.js +405 -0
- package/fesm/services/authentication.service.js +297 -349
- package/fesm/services/branch.service.js +9 -4
- package/fesm/services/company-selection-session.service.js +1 -1
- package/fesm/services/index.js +1 -0
- package/fesm/services/user-permission.service.js +44 -74
- package/fesm/services/user.service.js +186 -36
- package/fesm/strategies/jwt.strategy.js +44 -44
- package/fesm/validators/password.validator.js +48 -0
- package/interceptors/clear-token.interceptor.d.ts +0 -1
- package/interceptors/set-token.interceptor.d.ts +1 -1
- package/interfaces/auth-email-provider.interface.d.ts +6 -0
- package/interfaces/auth-module-options.interface.d.ts +4 -1
- package/interfaces/authentication.interface.d.ts +13 -3
- package/interfaces/index.d.ts +2 -0
- package/interfaces/user-enricher.interface.d.ts +64 -0
- package/interfaces/user.interface.d.ts +1 -0
- package/modules/auth.module.d.ts +6 -3
- package/package.json +4 -4
- package/services/auth-config.service.d.ts +7 -8
- package/services/auth-datasource.provider.d.ts +2 -4
- package/services/auth-email.service.d.ts +54 -0
- package/services/authentication.service.d.ts +27 -16
- package/services/company-selection-session.service.d.ts +1 -1
- package/services/index.d.ts +1 -0
- package/services/user-permission.service.d.ts +6 -9
- package/services/user.service.d.ts +19 -3
- package/strategies/jwt.strategy.d.ts +4 -1
- package/validators/password.validator.d.ts +10 -0
- package/cjs/dtos/user-company-permission.dto.js +0 -110
- package/dtos/user-company-permission.dto.d.ts +0 -10
- 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,
|
|
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: '
|
|
44
|
-
description: 'User password
|
|
44
|
+
example: 'SecureP@ss1',
|
|
45
|
+
description: 'User password'
|
|
45
46
|
}),
|
|
46
47
|
IsString(),
|
|
47
48
|
IsNotEmpty(),
|
|
48
|
-
|
|
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: '
|
|
88
|
-
description: 'Password (min
|
|
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
|
-
|
|
93
|
-
MaxLength(
|
|
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: '
|
|
188
|
-
description: 'New password (min
|
|
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
|
-
|
|
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, "
|
|
486
|
+
_define_property(this, "requiresEmailVerification", void 0);
|
|
506
487
|
}
|
|
507
488
|
}
|
|
508
489
|
_ts_decorate([
|
|
509
|
-
|
|
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
|
-
|
|
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
|
-
|
|
523
|
+
ApiPropertyOptional({
|
|
543
524
|
example: true,
|
|
544
|
-
description: 'Whether
|
|
525
|
+
description: 'Whether email verification is required'
|
|
545
526
|
}),
|
|
546
527
|
_ts_metadata("design:type", Boolean)
|
|
547
|
-
], RegistrationResponseDto.prototype, "
|
|
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
|
+
}
|
package/fesm/dtos/index.js
CHANGED
|
@@ -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',
|
package/fesm/dtos/user.dto.js
CHANGED
|
@@ -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: '
|
|
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
|
-
|
|
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'
|
package/fesm/entities/index.js
CHANGED
|
@@ -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: '
|
|
73
|
-
|
|
66
|
+
type: 'varchar',
|
|
67
|
+
length: 50,
|
|
74
68
|
name: 'permission_type'
|
|
75
69
|
}),
|
|
76
|
-
_ts_metadata("design:type",
|
|
70
|
+
_ts_metadata("design:type", String)
|
|
77
71
|
], UserCompanyPermission.prototype, "permissionType", void 0);
|
|
78
72
|
_ts_decorate([
|
|
79
73
|
Column({
|