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