@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.
- package/README.md +274 -301
- package/cjs/config/auth.constants.js +22 -4
- package/cjs/controllers/authentication.controller.js +222 -38
- package/cjs/controllers/branch.controller.js +46 -4
- package/cjs/controllers/company-selection.controller.js +27 -20
- package/cjs/controllers/company.controller.js +46 -4
- package/cjs/controllers/user-permission.controller.js +40 -37
- package/cjs/controllers/user.controller.js +222 -23
- package/cjs/dtos/authentication.dto.js +119 -13
- 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 +0 -6
- package/cjs/entities/user-token.entity.js +129 -0
- package/cjs/guards/auth-throttler.guard.js +53 -0
- package/cjs/interceptors/clear-token.interceptor.js +3 -6
- package/cjs/interceptors/set-token.interceptor.js +38 -31
- package/cjs/interfaces/auth-email-provider.interface.js +45 -0
- package/cjs/interfaces/authentication.interface.js +0 -3
- package/cjs/interfaces/index.js +2 -0
- package/cjs/interfaces/user-enricher.interface.js +4 -0
- package/cjs/modules/auth.module.js +8 -20
- package/cjs/services/auth-config.service.js +42 -47
- package/cjs/services/auth-datasource.provider.js +18 -34
- package/cjs/services/auth-email.service.js +471 -0
- package/cjs/services/authentication.service.js +240 -153
- package/cjs/services/branch.service.js +15 -48
- package/cjs/services/company-selection-session.service.js +1 -1
- package/cjs/services/company.service.js +7 -36
- package/cjs/services/index.js +1 -0
- package/cjs/services/user-permission.service.js +9 -29
- package/cjs/services/user.service.js +228 -107
- package/cjs/strategies/jwt.strategy.js +14 -1
- package/cjs/validators/password.validator.js +45 -0
- package/config/auth.constants.d.ts +5 -0
- package/controllers/authentication.controller.d.ts +13 -9
- package/controllers/company-selection.controller.d.ts +6 -2
- package/controllers/user.controller.d.ts +33 -0
- package/dtos/authentication.dto.d.ts +21 -3
- package/dtos/company-branch.dto.d.ts +0 -1
- package/dtos/company.dto.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 +0 -2
- package/entities/user-token.entity.d.ts +15 -0
- package/fesm/config/auth.constants.js +11 -8
- package/fesm/controllers/authentication.controller.js +224 -40
- package/fesm/controllers/branch.controller.js +49 -7
- package/fesm/controllers/company-selection.controller.js +28 -21
- package/fesm/controllers/company.controller.js +49 -7
- package/fesm/controllers/user-permission.controller.js +41 -38
- package/fesm/controllers/user.controller.js +225 -26
- package/fesm/dtos/authentication.dto.js +123 -111
- 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 +0 -6
- package/fesm/entities/user-token.entity.js +113 -0
- package/fesm/guards/auth-throttler.guard.js +43 -0
- package/fesm/interceptors/clear-token.interceptor.js +2 -5
- package/fesm/interceptors/set-token.interceptor.js +37 -30
- package/fesm/interfaces/auth-email-provider.interface.js +38 -0
- package/fesm/interfaces/authentication.interface.js +1 -7
- package/fesm/interfaces/index.js +2 -0
- package/fesm/interfaces/user-enricher.interface.js +26 -0
- package/fesm/modules/auth.module.js +10 -22
- package/fesm/services/auth-config.service.js +42 -47
- package/fesm/services/auth-datasource.provider.js +19 -35
- package/fesm/services/auth-email.service.js +420 -0
- package/fesm/services/authentication.service.js +238 -151
- package/fesm/services/branch.service.js +16 -49
- package/fesm/services/company-selection-session.service.js +1 -1
- package/fesm/services/company.service.js +8 -37
- package/fesm/services/index.js +1 -0
- package/fesm/services/user-permission.service.js +10 -30
- package/fesm/services/user.service.js +229 -108
- package/fesm/strategies/jwt.strategy.js +14 -1
- package/fesm/validators/password.validator.js +48 -0
- package/guards/auth-throttler.guard.d.ts +7 -0
- package/interceptors/set-token.interceptor.d.ts +1 -0
- 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 +14 -0
- 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 +0 -1
- package/package.json +4 -4
- package/services/auth-config.service.d.ts +5 -1
- package/services/auth-email.service.d.ts +51 -0
- package/services/authentication.service.d.ts +21 -12
- package/services/branch.service.d.ts +2 -5
- package/services/company-selection-session.service.d.ts +1 -1
- package/services/company.service.d.ts +1 -4
- package/services/index.d.ts +1 -0
- package/services/user-permission.service.d.ts +0 -1
- package/services/user.service.d.ts +20 -6
- package/validators/password.validator.d.ts +10 -0
|
@@ -27,12 +27,18 @@ _export(exports, {
|
|
|
27
27
|
get CompanyWithBranchesDto () {
|
|
28
28
|
return CompanyWithBranchesDto;
|
|
29
29
|
},
|
|
30
|
+
get ForgotPasswordDto () {
|
|
31
|
+
return ForgotPasswordDto;
|
|
32
|
+
},
|
|
30
33
|
get LoginDto () {
|
|
31
34
|
return LoginDto;
|
|
32
35
|
},
|
|
33
36
|
get LoginResponseDto () {
|
|
34
37
|
return LoginResponseDto;
|
|
35
38
|
},
|
|
39
|
+
get LoginResponseRequiresEmailVerificationDto () {
|
|
40
|
+
return LoginResponseRequiresEmailVerificationDto;
|
|
41
|
+
},
|
|
36
42
|
get MeResponseDto () {
|
|
37
43
|
return MeResponseDto;
|
|
38
44
|
},
|
|
@@ -45,6 +51,12 @@ _export(exports, {
|
|
|
45
51
|
get RegistrationResponseDto () {
|
|
46
52
|
return RegistrationResponseDto;
|
|
47
53
|
},
|
|
54
|
+
get ResendVerificationDto () {
|
|
55
|
+
return ResendVerificationDto;
|
|
56
|
+
},
|
|
57
|
+
get ResetPasswordDto () {
|
|
58
|
+
return ResetPasswordDto;
|
|
59
|
+
},
|
|
48
60
|
get SelectDto () {
|
|
49
61
|
return SelectDto;
|
|
50
62
|
},
|
|
@@ -53,10 +65,14 @@ _export(exports, {
|
|
|
53
65
|
},
|
|
54
66
|
get UserInfoDto () {
|
|
55
67
|
return UserInfoDto;
|
|
68
|
+
},
|
|
69
|
+
get VerifyEmailDto () {
|
|
70
|
+
return VerifyEmailDto;
|
|
56
71
|
}
|
|
57
72
|
});
|
|
58
73
|
const _swagger = require("@nestjs/swagger");
|
|
59
74
|
const _classvalidator = require("class-validator");
|
|
75
|
+
const _passwordvalidator = require("../validators/password.validator");
|
|
60
76
|
function _define_property(obj, key, value) {
|
|
61
77
|
if (key in obj) {
|
|
62
78
|
Object.defineProperty(obj, key, {
|
|
@@ -96,12 +112,12 @@ _ts_decorate([
|
|
|
96
112
|
], LoginDto.prototype, "email", void 0);
|
|
97
113
|
_ts_decorate([
|
|
98
114
|
(0, _swagger.ApiProperty)({
|
|
99
|
-
example: '
|
|
100
|
-
description: 'User password
|
|
115
|
+
example: 'SecureP@ss1',
|
|
116
|
+
description: 'User password'
|
|
101
117
|
}),
|
|
102
118
|
(0, _classvalidator.IsString)(),
|
|
103
119
|
(0, _classvalidator.IsNotEmpty)(),
|
|
104
|
-
(0, _classvalidator.
|
|
120
|
+
(0, _classvalidator.MaxLength)(128),
|
|
105
121
|
_ts_metadata("design:type", String)
|
|
106
122
|
], LoginDto.prototype, "password", void 0);
|
|
107
123
|
let RegistrationDto = class RegistrationDto {
|
|
@@ -140,13 +156,13 @@ _ts_decorate([
|
|
|
140
156
|
], RegistrationDto.prototype, "email", void 0);
|
|
141
157
|
_ts_decorate([
|
|
142
158
|
(0, _swagger.ApiProperty)({
|
|
143
|
-
example: '
|
|
144
|
-
description: 'Password (min
|
|
159
|
+
example: 'StrongP@ss123',
|
|
160
|
+
description: 'Password (min 8 chars, requires uppercase, lowercase, number, special char)'
|
|
145
161
|
}),
|
|
146
162
|
(0, _classvalidator.IsNotEmpty)(),
|
|
147
163
|
(0, _classvalidator.IsString)(),
|
|
148
|
-
(0,
|
|
149
|
-
(0, _classvalidator.MaxLength)(
|
|
164
|
+
(0, _passwordvalidator.IsStrongPassword)(),
|
|
165
|
+
(0, _classvalidator.MaxLength)(128),
|
|
150
166
|
_ts_metadata("design:type", String)
|
|
151
167
|
], RegistrationDto.prototype, "password", void 0);
|
|
152
168
|
_ts_decorate([
|
|
@@ -207,6 +223,7 @@ _ts_decorate([
|
|
|
207
223
|
}),
|
|
208
224
|
(0, _classvalidator.IsOptional)(),
|
|
209
225
|
(0, _classvalidator.IsString)(),
|
|
226
|
+
(0, _classvalidator.MaxLength)(500),
|
|
210
227
|
_ts_metadata("design:type", String)
|
|
211
228
|
], RegistrationDto.prototype, "newCompanyAddress", void 0);
|
|
212
229
|
let RefreshTokenDto = class RefreshTokenDto {
|
|
@@ -236,16 +253,17 @@ _ts_decorate([
|
|
|
236
253
|
}),
|
|
237
254
|
(0, _classvalidator.IsString)(),
|
|
238
255
|
(0, _classvalidator.IsNotEmpty)(),
|
|
256
|
+
(0, _classvalidator.MaxLength)(128),
|
|
239
257
|
_ts_metadata("design:type", String)
|
|
240
258
|
], ChangePasswordDto.prototype, "currentPassword", void 0);
|
|
241
259
|
_ts_decorate([
|
|
242
260
|
(0, _swagger.ApiProperty)({
|
|
243
|
-
example: '
|
|
244
|
-
description: 'New password (min
|
|
261
|
+
example: 'NewP@ssword456',
|
|
262
|
+
description: 'New password (min 8 chars, requires uppercase, lowercase, number, special char)'
|
|
245
263
|
}),
|
|
246
264
|
(0, _classvalidator.IsString)(),
|
|
247
265
|
(0, _classvalidator.IsNotEmpty)(),
|
|
248
|
-
(0,
|
|
266
|
+
(0, _passwordvalidator.IsStrongPassword)(),
|
|
249
267
|
_ts_metadata("design:type", String)
|
|
250
268
|
], ChangePasswordDto.prototype, "newPassword", void 0);
|
|
251
269
|
let SelectDto = class SelectDto {
|
|
@@ -558,16 +576,17 @@ let RegistrationResponseDto = class RegistrationResponseDto {
|
|
|
558
576
|
_define_property(this, "company", void 0);
|
|
559
577
|
_define_property(this, "branch", void 0);
|
|
560
578
|
_define_property(this, "companyFeatureEnabled", void 0);
|
|
579
|
+
_define_property(this, "requiresEmailVerification", void 0);
|
|
561
580
|
}
|
|
562
581
|
};
|
|
563
582
|
_ts_decorate([
|
|
564
|
-
(0, _swagger.
|
|
583
|
+
(0, _swagger.ApiPropertyOptional)({
|
|
565
584
|
example: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...'
|
|
566
585
|
}),
|
|
567
586
|
_ts_metadata("design:type", String)
|
|
568
587
|
], RegistrationResponseDto.prototype, "accessToken", void 0);
|
|
569
588
|
_ts_decorate([
|
|
570
|
-
(0, _swagger.
|
|
589
|
+
(0, _swagger.ApiPropertyOptional)({
|
|
571
590
|
example: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...'
|
|
572
591
|
}),
|
|
573
592
|
_ts_metadata("design:type", String)
|
|
@@ -594,12 +613,19 @@ _ts_decorate([
|
|
|
594
613
|
_ts_metadata("design:type", typeof BranchInfoDto === "undefined" ? Object : BranchInfoDto)
|
|
595
614
|
], RegistrationResponseDto.prototype, "branch", void 0);
|
|
596
615
|
_ts_decorate([
|
|
597
|
-
(0, _swagger.
|
|
616
|
+
(0, _swagger.ApiPropertyOptional)({
|
|
598
617
|
example: true,
|
|
599
618
|
description: 'Whether company feature is enabled'
|
|
600
619
|
}),
|
|
601
620
|
_ts_metadata("design:type", Boolean)
|
|
602
621
|
], RegistrationResponseDto.prototype, "companyFeatureEnabled", void 0);
|
|
622
|
+
_ts_decorate([
|
|
623
|
+
(0, _swagger.ApiPropertyOptional)({
|
|
624
|
+
example: true,
|
|
625
|
+
description: 'Whether email verification is required'
|
|
626
|
+
}),
|
|
627
|
+
_ts_metadata("design:type", Boolean)
|
|
628
|
+
], RegistrationResponseDto.prototype, "requiresEmailVerification", void 0);
|
|
603
629
|
let MeResponseDto = class MeResponseDto {
|
|
604
630
|
constructor(){
|
|
605
631
|
_define_property(this, "user", void 0);
|
|
@@ -674,3 +700,83 @@ _ts_decorate([
|
|
|
674
700
|
}),
|
|
675
701
|
_ts_metadata("design:type", Array)
|
|
676
702
|
], CompanySelectionResponseDto.prototype, "companies", void 0);
|
|
703
|
+
let LoginResponseRequiresEmailVerificationDto = class LoginResponseRequiresEmailVerificationDto {
|
|
704
|
+
constructor(){
|
|
705
|
+
_define_property(this, "requiresEmailVerification", void 0);
|
|
706
|
+
_define_property(this, "email", void 0);
|
|
707
|
+
_define_property(this, "message", void 0);
|
|
708
|
+
}
|
|
709
|
+
};
|
|
710
|
+
_ts_decorate([
|
|
711
|
+
(0, _swagger.ApiProperty)({
|
|
712
|
+
example: true
|
|
713
|
+
}),
|
|
714
|
+
_ts_metadata("design:type", Boolean)
|
|
715
|
+
], LoginResponseRequiresEmailVerificationDto.prototype, "requiresEmailVerification", void 0);
|
|
716
|
+
_ts_decorate([
|
|
717
|
+
(0, _swagger.ApiProperty)({
|
|
718
|
+
example: 'john@example.com'
|
|
719
|
+
}),
|
|
720
|
+
_ts_metadata("design:type", String)
|
|
721
|
+
], LoginResponseRequiresEmailVerificationDto.prototype, "email", void 0);
|
|
722
|
+
_ts_decorate([
|
|
723
|
+
(0, _swagger.ApiProperty)({
|
|
724
|
+
example: 'Please verify your email address before logging in.'
|
|
725
|
+
}),
|
|
726
|
+
_ts_metadata("design:type", String)
|
|
727
|
+
], LoginResponseRequiresEmailVerificationDto.prototype, "message", void 0);
|
|
728
|
+
let ForgotPasswordDto = class ForgotPasswordDto {
|
|
729
|
+
constructor(){
|
|
730
|
+
_define_property(this, "email", void 0);
|
|
731
|
+
}
|
|
732
|
+
};
|
|
733
|
+
_ts_decorate([
|
|
734
|
+
(0, _swagger.ApiProperty)({
|
|
735
|
+
example: 'john@example.com',
|
|
736
|
+
description: 'Email address to send reset link to'
|
|
737
|
+
}),
|
|
738
|
+
(0, _classvalidator.IsEmail)(),
|
|
739
|
+
(0, _classvalidator.IsNotEmpty)(),
|
|
740
|
+
_ts_metadata("design:type", String)
|
|
741
|
+
], ForgotPasswordDto.prototype, "email", void 0);
|
|
742
|
+
let ResetPasswordDto = class ResetPasswordDto {
|
|
743
|
+
constructor(){
|
|
744
|
+
_define_property(this, "token", void 0);
|
|
745
|
+
_define_property(this, "newPassword", void 0);
|
|
746
|
+
}
|
|
747
|
+
};
|
|
748
|
+
_ts_decorate([
|
|
749
|
+
(0, _swagger.ApiProperty)({
|
|
750
|
+
example: 'a1b2c3d4e5f6...',
|
|
751
|
+
description: 'Password reset token from email'
|
|
752
|
+
}),
|
|
753
|
+
(0, _classvalidator.IsString)(),
|
|
754
|
+
(0, _classvalidator.IsNotEmpty)(),
|
|
755
|
+
_ts_metadata("design:type", String)
|
|
756
|
+
], ResetPasswordDto.prototype, "token", void 0);
|
|
757
|
+
_ts_decorate([
|
|
758
|
+
(0, _swagger.ApiProperty)({
|
|
759
|
+
example: 'NewSecureP@ss123',
|
|
760
|
+
description: 'New password (min 8 chars, requires uppercase, lowercase, number, special char)'
|
|
761
|
+
}),
|
|
762
|
+
(0, _classvalidator.IsString)(),
|
|
763
|
+
(0, _classvalidator.IsNotEmpty)(),
|
|
764
|
+
(0, _passwordvalidator.IsStrongPassword)(),
|
|
765
|
+
_ts_metadata("design:type", String)
|
|
766
|
+
], ResetPasswordDto.prototype, "newPassword", void 0);
|
|
767
|
+
let VerifyEmailDto = class VerifyEmailDto {
|
|
768
|
+
constructor(){
|
|
769
|
+
_define_property(this, "token", void 0);
|
|
770
|
+
}
|
|
771
|
+
};
|
|
772
|
+
_ts_decorate([
|
|
773
|
+
(0, _swagger.ApiProperty)({
|
|
774
|
+
example: 'a1b2c3d4e5f6...',
|
|
775
|
+
description: 'Email verification token from email'
|
|
776
|
+
}),
|
|
777
|
+
(0, _classvalidator.IsString)(),
|
|
778
|
+
(0, _classvalidator.IsNotEmpty)(),
|
|
779
|
+
_ts_metadata("design:type", String)
|
|
780
|
+
], VerifyEmailDto.prototype, "token", void 0);
|
|
781
|
+
let ResendVerificationDto = class ResendVerificationDto extends ForgotPasswordDto {
|
|
782
|
+
};
|
|
@@ -254,9 +254,23 @@ _ts_decorate([
|
|
|
254
254
|
], UserBranchPermissionDto.prototype, "companyId", void 0);
|
|
255
255
|
let UserCompaniesResponseDto = class UserCompaniesResponseDto {
|
|
256
256
|
constructor(){
|
|
257
|
+
_define_property(this, "success", void 0);
|
|
258
|
+
_define_property(this, "message", void 0);
|
|
257
259
|
_define_property(this, "data", void 0);
|
|
258
260
|
}
|
|
259
261
|
};
|
|
262
|
+
_ts_decorate([
|
|
263
|
+
(0, _swagger.ApiProperty)({
|
|
264
|
+
example: true
|
|
265
|
+
}),
|
|
266
|
+
_ts_metadata("design:type", Boolean)
|
|
267
|
+
], UserCompaniesResponseDto.prototype, "success", void 0);
|
|
268
|
+
_ts_decorate([
|
|
269
|
+
(0, _swagger.ApiProperty)({
|
|
270
|
+
example: 'User companies retrieved successfully'
|
|
271
|
+
}),
|
|
272
|
+
_ts_metadata("design:type", String)
|
|
273
|
+
], UserCompaniesResponseDto.prototype, "message", void 0);
|
|
260
274
|
_ts_decorate([
|
|
261
275
|
(0, _swagger.ApiProperty)({
|
|
262
276
|
description: 'List of companies the user has access to',
|
|
@@ -284,9 +298,23 @@ _ts_decorate([
|
|
|
284
298
|
], UserCompaniesResponseDto.prototype, "data", void 0);
|
|
285
299
|
let UserBranchesResponseDto = class UserBranchesResponseDto {
|
|
286
300
|
constructor(){
|
|
301
|
+
_define_property(this, "success", void 0);
|
|
302
|
+
_define_property(this, "message", void 0);
|
|
287
303
|
_define_property(this, "data", void 0);
|
|
288
304
|
}
|
|
289
305
|
};
|
|
306
|
+
_ts_decorate([
|
|
307
|
+
(0, _swagger.ApiProperty)({
|
|
308
|
+
example: true
|
|
309
|
+
}),
|
|
310
|
+
_ts_metadata("design:type", Boolean)
|
|
311
|
+
], UserBranchesResponseDto.prototype, "success", void 0);
|
|
312
|
+
_ts_decorate([
|
|
313
|
+
(0, _swagger.ApiProperty)({
|
|
314
|
+
example: 'User branches retrieved successfully'
|
|
315
|
+
}),
|
|
316
|
+
_ts_metadata("design:type", String)
|
|
317
|
+
], UserBranchesResponseDto.prototype, "message", void 0);
|
|
290
318
|
_ts_decorate([
|
|
291
319
|
(0, _swagger.ApiProperty)({
|
|
292
320
|
description: 'List of branches the user has access to',
|
package/cjs/dtos/user.dto.js
CHANGED
|
@@ -21,6 +21,7 @@ _export(exports, {
|
|
|
21
21
|
});
|
|
22
22
|
const _swagger = require("@nestjs/swagger");
|
|
23
23
|
const _classvalidator = require("class-validator");
|
|
24
|
+
const _passwordvalidator = require("../validators/password.validator");
|
|
24
25
|
function _define_property(obj, key, value) {
|
|
25
26
|
if (key in obj) {
|
|
26
27
|
Object.defineProperty(obj, key, {
|
|
@@ -83,10 +84,13 @@ _ts_decorate([
|
|
|
83
84
|
], CreateUserDto.prototype, "email", void 0);
|
|
84
85
|
_ts_decorate([
|
|
85
86
|
(0, _swagger.ApiProperty)({
|
|
86
|
-
example: '
|
|
87
|
-
description: 'Password'
|
|
87
|
+
example: 'SecureP@ss123',
|
|
88
|
+
description: 'Password (must meet complexity requirements)'
|
|
88
89
|
}),
|
|
89
90
|
(0, _classvalidator.IsString)(),
|
|
91
|
+
(0, _classvalidator.IsNotEmpty)(),
|
|
92
|
+
(0, _passwordvalidator.IsStrongPassword)(),
|
|
93
|
+
(0, _classvalidator.MaxLength)(128),
|
|
90
94
|
_ts_metadata("design:type", String)
|
|
91
95
|
], CreateUserDto.prototype, "password", void 0);
|
|
92
96
|
_ts_decorate([
|
|
@@ -139,6 +143,7 @@ let UpdateUserDto = class UpdateUserDto {
|
|
|
139
143
|
_define_property(this, "phone", void 0);
|
|
140
144
|
_define_property(this, "email", void 0);
|
|
141
145
|
_define_property(this, "password", void 0);
|
|
146
|
+
_define_property(this, "oldPassword", void 0);
|
|
142
147
|
_define_property(this, "profilePictureId", void 0);
|
|
143
148
|
_define_property(this, "isActive", void 0);
|
|
144
149
|
_define_property(this, "emailVerified", void 0);
|
|
@@ -150,7 +155,7 @@ _ts_decorate([
|
|
|
150
155
|
(0, _swagger.ApiProperty)({
|
|
151
156
|
description: 'User ID'
|
|
152
157
|
}),
|
|
153
|
-
(0, _classvalidator.
|
|
158
|
+
(0, _classvalidator.IsUUID)(),
|
|
154
159
|
_ts_metadata("design:type", String)
|
|
155
160
|
], UpdateUserDto.prototype, "id", void 0);
|
|
156
161
|
_ts_decorate([
|
|
@@ -182,12 +187,22 @@ _ts_decorate([
|
|
|
182
187
|
], UpdateUserDto.prototype, "email", void 0);
|
|
183
188
|
_ts_decorate([
|
|
184
189
|
(0, _swagger.ApiPropertyOptional)({
|
|
185
|
-
description: 'New password'
|
|
190
|
+
description: 'New password (must meet complexity requirements)'
|
|
186
191
|
}),
|
|
187
192
|
(0, _classvalidator.IsOptional)(),
|
|
188
193
|
(0, _classvalidator.IsString)(),
|
|
194
|
+
(0, _passwordvalidator.IsStrongPassword)(),
|
|
195
|
+
(0, _classvalidator.MaxLength)(128),
|
|
189
196
|
_ts_metadata("design:type", String)
|
|
190
197
|
], UpdateUserDto.prototype, "password", void 0);
|
|
198
|
+
_ts_decorate([
|
|
199
|
+
(0, _swagger.ApiPropertyOptional)({
|
|
200
|
+
description: 'Current password (required when changing password on own profile)'
|
|
201
|
+
}),
|
|
202
|
+
(0, _classvalidator.IsOptional)(),
|
|
203
|
+
(0, _classvalidator.IsString)(),
|
|
204
|
+
_ts_metadata("design:type", String)
|
|
205
|
+
], UpdateUserDto.prototype, "oldPassword", void 0);
|
|
191
206
|
_ts_decorate([
|
|
192
207
|
(0, _swagger.ApiPropertyOptional)({
|
|
193
208
|
description: 'Profile picture file ID'
|
package/cjs/entities/index.js
CHANGED
|
@@ -30,8 +30,10 @@ _export(exports, {
|
|
|
30
30
|
});
|
|
31
31
|
const _companybranchentity = _export_star(require("./company-branch.entity"), exports);
|
|
32
32
|
const _companyentity = _export_star(require("./company.entity"), exports);
|
|
33
|
+
const _pendingregistrationentity = _export_star(require("./pending-registration.entity"), exports);
|
|
33
34
|
const _usercompanypermissionentity = require("./user-company-permission.entity");
|
|
34
35
|
const _userentity = _export_star(require("./user.entity"), exports);
|
|
36
|
+
const _usertokenentity = _export_star(require("./user-token.entity"), exports);
|
|
35
37
|
function _export_star(from, to) {
|
|
36
38
|
Object.keys(from).forEach(function(k) {
|
|
37
39
|
if (k !== "default" && !Object.prototype.hasOwnProperty.call(to, k)) {
|
|
@@ -46,7 +48,9 @@ function _export_star(from, to) {
|
|
|
46
48
|
return from;
|
|
47
49
|
}
|
|
48
50
|
const CoreEntities = [
|
|
49
|
-
_userentity.User
|
|
51
|
+
_userentity.User,
|
|
52
|
+
_usertokenentity.UserToken,
|
|
53
|
+
_pendingregistrationentity.PendingRegistration
|
|
50
54
|
];
|
|
51
55
|
const CompanyEntities = [
|
|
52
56
|
_companyentity.Company,
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
Object.defineProperty(exports, "PendingRegistration", {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: function() {
|
|
8
|
+
return PendingRegistration;
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
const _typeorm = require("typeorm");
|
|
12
|
+
function _define_property(obj, key, value) {
|
|
13
|
+
if (key in obj) {
|
|
14
|
+
Object.defineProperty(obj, key, {
|
|
15
|
+
value: value,
|
|
16
|
+
enumerable: true,
|
|
17
|
+
configurable: true,
|
|
18
|
+
writable: true
|
|
19
|
+
});
|
|
20
|
+
} else {
|
|
21
|
+
obj[key] = value;
|
|
22
|
+
}
|
|
23
|
+
return obj;
|
|
24
|
+
}
|
|
25
|
+
function _ts_decorate(decorators, target, key, desc) {
|
|
26
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
27
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
28
|
+
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;
|
|
29
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
30
|
+
}
|
|
31
|
+
function _ts_metadata(k, v) {
|
|
32
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
33
|
+
}
|
|
34
|
+
let PendingRegistration = class PendingRegistration {
|
|
35
|
+
constructor(){
|
|
36
|
+
_define_property(this, "id", void 0);
|
|
37
|
+
_define_property(this, "email", void 0);
|
|
38
|
+
_define_property(this, "name", void 0);
|
|
39
|
+
_define_property(this, "phone", void 0);
|
|
40
|
+
_define_property(this, "passwordHash", void 0);
|
|
41
|
+
_define_property(this, "token", void 0);
|
|
42
|
+
_define_property(this, "expiresAt", void 0);
|
|
43
|
+
_define_property(this, "companyData", void 0);
|
|
44
|
+
_define_property(this, "createdAt", void 0);
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
_ts_decorate([
|
|
48
|
+
(0, _typeorm.PrimaryGeneratedColumn)('uuid'),
|
|
49
|
+
_ts_metadata("design:type", String)
|
|
50
|
+
], PendingRegistration.prototype, "id", void 0);
|
|
51
|
+
_ts_decorate([
|
|
52
|
+
(0, _typeorm.Column)({
|
|
53
|
+
type: 'varchar',
|
|
54
|
+
length: 255
|
|
55
|
+
}),
|
|
56
|
+
_ts_metadata("design:type", String)
|
|
57
|
+
], PendingRegistration.prototype, "email", void 0);
|
|
58
|
+
_ts_decorate([
|
|
59
|
+
(0, _typeorm.Column)({
|
|
60
|
+
type: 'varchar',
|
|
61
|
+
length: 255,
|
|
62
|
+
nullable: true
|
|
63
|
+
}),
|
|
64
|
+
_ts_metadata("design:type", Object)
|
|
65
|
+
], PendingRegistration.prototype, "name", void 0);
|
|
66
|
+
_ts_decorate([
|
|
67
|
+
(0, _typeorm.Column)({
|
|
68
|
+
type: 'varchar',
|
|
69
|
+
length: 255,
|
|
70
|
+
nullable: true
|
|
71
|
+
}),
|
|
72
|
+
_ts_metadata("design:type", Object)
|
|
73
|
+
], PendingRegistration.prototype, "phone", void 0);
|
|
74
|
+
_ts_decorate([
|
|
75
|
+
(0, _typeorm.Column)({
|
|
76
|
+
type: 'text',
|
|
77
|
+
name: 'passwordHash'
|
|
78
|
+
}),
|
|
79
|
+
_ts_metadata("design:type", String)
|
|
80
|
+
], PendingRegistration.prototype, "passwordHash", void 0);
|
|
81
|
+
_ts_decorate([
|
|
82
|
+
(0, _typeorm.Column)({
|
|
83
|
+
type: 'varchar',
|
|
84
|
+
length: 64
|
|
85
|
+
}),
|
|
86
|
+
_ts_metadata("design:type", String)
|
|
87
|
+
], PendingRegistration.prototype, "token", void 0);
|
|
88
|
+
_ts_decorate([
|
|
89
|
+
(0, _typeorm.Column)({
|
|
90
|
+
type: 'timestamp',
|
|
91
|
+
name: 'expires_at'
|
|
92
|
+
}),
|
|
93
|
+
_ts_metadata("design:type", typeof Date === "undefined" ? Object : Date)
|
|
94
|
+
], PendingRegistration.prototype, "expiresAt", void 0);
|
|
95
|
+
_ts_decorate([
|
|
96
|
+
(0, _typeorm.Column)({
|
|
97
|
+
type: 'json',
|
|
98
|
+
nullable: true,
|
|
99
|
+
name: 'company_data'
|
|
100
|
+
}),
|
|
101
|
+
_ts_metadata("design:type", Object)
|
|
102
|
+
], PendingRegistration.prototype, "companyData", void 0);
|
|
103
|
+
_ts_decorate([
|
|
104
|
+
(0, _typeorm.CreateDateColumn)({
|
|
105
|
+
type: 'timestamp',
|
|
106
|
+
name: 'created_at'
|
|
107
|
+
}),
|
|
108
|
+
_ts_metadata("design:type", typeof Date === "undefined" ? Object : Date)
|
|
109
|
+
], PendingRegistration.prototype, "createdAt", void 0);
|
|
110
|
+
PendingRegistration = _ts_decorate([
|
|
111
|
+
(0, _typeorm.Entity)('pending_registrations'),
|
|
112
|
+
(0, _typeorm.Index)('IDX_pending_reg_email', [
|
|
113
|
+
'email'
|
|
114
|
+
], {
|
|
115
|
+
unique: true
|
|
116
|
+
}),
|
|
117
|
+
(0, _typeorm.Index)('IDX_pending_reg_token', [
|
|
118
|
+
'token'
|
|
119
|
+
], {
|
|
120
|
+
unique: true
|
|
121
|
+
}),
|
|
122
|
+
(0, _typeorm.Index)('IDX_pending_reg_expires', [
|
|
123
|
+
'expiresAt'
|
|
124
|
+
])
|
|
125
|
+
], PendingRegistration);
|
|
@@ -44,12 +44,6 @@ function _ts_metadata(k, v) {
|
|
|
44
44
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
45
45
|
}
|
|
46
46
|
let UserCompanyPermission = class UserCompanyPermission {
|
|
47
|
-
/* ---------- Helpers ---------- */ isCompanyPermission() {
|
|
48
|
-
return this.permissionType === _enums.PermissionType.COMPANY;
|
|
49
|
-
}
|
|
50
|
-
isBranchPermission() {
|
|
51
|
-
return this.permissionType === _enums.PermissionType.BRANCH;
|
|
52
|
-
}
|
|
53
47
|
constructor(){
|
|
54
48
|
_define_property(this, "id", void 0);
|
|
55
49
|
/* ---------- Ownership ---------- */ _define_property(this, "userId", void 0);
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
function _export(target, all) {
|
|
6
|
+
for(var name in all)Object.defineProperty(target, name, {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: Object.getOwnPropertyDescriptor(all, name).get
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
_export(exports, {
|
|
12
|
+
get TokenType () {
|
|
13
|
+
return TokenType;
|
|
14
|
+
},
|
|
15
|
+
get UserToken () {
|
|
16
|
+
return UserToken;
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
const _typeorm = require("typeorm");
|
|
20
|
+
function _define_property(obj, key, value) {
|
|
21
|
+
if (key in obj) {
|
|
22
|
+
Object.defineProperty(obj, key, {
|
|
23
|
+
value: value,
|
|
24
|
+
enumerable: true,
|
|
25
|
+
configurable: true,
|
|
26
|
+
writable: true
|
|
27
|
+
});
|
|
28
|
+
} else {
|
|
29
|
+
obj[key] = value;
|
|
30
|
+
}
|
|
31
|
+
return obj;
|
|
32
|
+
}
|
|
33
|
+
function _ts_decorate(decorators, target, key, desc) {
|
|
34
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
35
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
36
|
+
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;
|
|
37
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
38
|
+
}
|
|
39
|
+
function _ts_metadata(k, v) {
|
|
40
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
41
|
+
}
|
|
42
|
+
var TokenType = /*#__PURE__*/ function(TokenType) {
|
|
43
|
+
TokenType["PASSWORD_RESET"] = "password_reset";
|
|
44
|
+
TokenType["EMAIL_VERIFICATION"] = "email_verification";
|
|
45
|
+
TokenType["EMAIL_CHANGE"] = "email_change";
|
|
46
|
+
return TokenType;
|
|
47
|
+
}({});
|
|
48
|
+
let UserToken = class UserToken {
|
|
49
|
+
constructor(){
|
|
50
|
+
_define_property(this, "id", void 0);
|
|
51
|
+
_define_property(this, "userId", void 0);
|
|
52
|
+
_define_property(this, "type", void 0);
|
|
53
|
+
_define_property(this, "token", void 0);
|
|
54
|
+
_define_property(this, "expiresAt", void 0);
|
|
55
|
+
_define_property(this, "usedAt", void 0);
|
|
56
|
+
_define_property(this, "metadata", void 0);
|
|
57
|
+
_define_property(this, "createdAt", void 0);
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
_ts_decorate([
|
|
61
|
+
(0, _typeorm.PrimaryGeneratedColumn)('uuid'),
|
|
62
|
+
_ts_metadata("design:type", String)
|
|
63
|
+
], UserToken.prototype, "id", void 0);
|
|
64
|
+
_ts_decorate([
|
|
65
|
+
(0, _typeorm.Column)({
|
|
66
|
+
type: 'uuid',
|
|
67
|
+
name: 'user_id'
|
|
68
|
+
}),
|
|
69
|
+
_ts_metadata("design:type", String)
|
|
70
|
+
], UserToken.prototype, "userId", void 0);
|
|
71
|
+
_ts_decorate([
|
|
72
|
+
(0, _typeorm.Column)({
|
|
73
|
+
type: 'varchar',
|
|
74
|
+
length: 32
|
|
75
|
+
}),
|
|
76
|
+
_ts_metadata("design:type", String)
|
|
77
|
+
], UserToken.prototype, "type", void 0);
|
|
78
|
+
_ts_decorate([
|
|
79
|
+
(0, _typeorm.Column)({
|
|
80
|
+
type: 'varchar',
|
|
81
|
+
length: 64
|
|
82
|
+
}),
|
|
83
|
+
_ts_metadata("design:type", String)
|
|
84
|
+
], UserToken.prototype, "token", void 0);
|
|
85
|
+
_ts_decorate([
|
|
86
|
+
(0, _typeorm.Column)({
|
|
87
|
+
type: 'timestamp',
|
|
88
|
+
name: 'expires_at'
|
|
89
|
+
}),
|
|
90
|
+
_ts_metadata("design:type", typeof Date === "undefined" ? Object : Date)
|
|
91
|
+
], UserToken.prototype, "expiresAt", void 0);
|
|
92
|
+
_ts_decorate([
|
|
93
|
+
(0, _typeorm.Column)({
|
|
94
|
+
type: 'timestamp',
|
|
95
|
+
name: 'used_at',
|
|
96
|
+
nullable: true
|
|
97
|
+
}),
|
|
98
|
+
_ts_metadata("design:type", Object)
|
|
99
|
+
], UserToken.prototype, "usedAt", void 0);
|
|
100
|
+
_ts_decorate([
|
|
101
|
+
(0, _typeorm.Column)({
|
|
102
|
+
type: 'varchar',
|
|
103
|
+
length: 255,
|
|
104
|
+
nullable: true
|
|
105
|
+
}),
|
|
106
|
+
_ts_metadata("design:type", Object)
|
|
107
|
+
], UserToken.prototype, "metadata", void 0);
|
|
108
|
+
_ts_decorate([
|
|
109
|
+
(0, _typeorm.CreateDateColumn)({
|
|
110
|
+
type: 'timestamp',
|
|
111
|
+
name: 'created_at'
|
|
112
|
+
}),
|
|
113
|
+
_ts_metadata("design:type", typeof Date === "undefined" ? Object : Date)
|
|
114
|
+
], UserToken.prototype, "createdAt", void 0);
|
|
115
|
+
UserToken = _ts_decorate([
|
|
116
|
+
(0, _typeorm.Entity)('user_tokens'),
|
|
117
|
+
(0, _typeorm.Index)('IDX_user_token_token', [
|
|
118
|
+
'token'
|
|
119
|
+
], {
|
|
120
|
+
unique: true
|
|
121
|
+
}),
|
|
122
|
+
(0, _typeorm.Index)('IDX_user_token_user_type', [
|
|
123
|
+
'userId',
|
|
124
|
+
'type'
|
|
125
|
+
]),
|
|
126
|
+
(0, _typeorm.Index)('IDX_user_token_expires', [
|
|
127
|
+
'expiresAt'
|
|
128
|
+
])
|
|
129
|
+
], UserToken);
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
Object.defineProperty(exports, "AuthThrottlerGuard", {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: function() {
|
|
8
|
+
return AuthThrottlerGuard;
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
const _common = require("@nestjs/common");
|
|
12
|
+
const _throttler = require("@nestjs/throttler");
|
|
13
|
+
function _ts_decorate(decorators, target, key, desc) {
|
|
14
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
15
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
16
|
+
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;
|
|
17
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
18
|
+
}
|
|
19
|
+
let AuthThrottlerGuard = class AuthThrottlerGuard extends _throttler.ThrottlerGuard {
|
|
20
|
+
/**
|
|
21
|
+
* Generate tracker key combining IP and email for login attempts.
|
|
22
|
+
* This prevents attackers from brute-forcing multiple accounts from the same IP.
|
|
23
|
+
*/ async getTracker(req) {
|
|
24
|
+
const ip = req.ip || req.headers?.['x-forwarded-for'] || 'unknown';
|
|
25
|
+
const body = req.body;
|
|
26
|
+
const email = body?.email || '';
|
|
27
|
+
return `auth:${ip}:${email}`;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Custom error message for rate limit exceeded.
|
|
31
|
+
*/ throwThrottlingException() {
|
|
32
|
+
throw new _throttler.ThrottlerException('Too many authentication attempts. Please try again later.');
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Skip rate limiting for authenticated users on certain endpoints.
|
|
36
|
+
*/ async shouldSkip(context) {
|
|
37
|
+
const request = context.switchToHttp().getRequest();
|
|
38
|
+
const path = request.path || request.url || '';
|
|
39
|
+
// Remove query string for comparison
|
|
40
|
+
const pathOnly = path.split('?')[0];
|
|
41
|
+
// Skip rate limiting for authenticated endpoints (they have their own protection)
|
|
42
|
+
// Use exact match or prefix match to prevent bypass via path manipulation
|
|
43
|
+
const authenticatedEndpoints = [
|
|
44
|
+
'/auth/me',
|
|
45
|
+
'/auth/logout',
|
|
46
|
+
'/auth/change-password'
|
|
47
|
+
];
|
|
48
|
+
return authenticatedEndpoints.some((endpoint)=>pathOnly === endpoint || pathOnly.startsWith(`${endpoint}/`));
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
AuthThrottlerGuard = _ts_decorate([
|
|
52
|
+
(0, _common.Injectable)()
|
|
53
|
+
], AuthThrottlerGuard);
|