@flusys/nestjs-auth 1.1.0-beta → 2.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 +8 -0
- package/cjs/controllers/authentication.controller.js +218 -39
- 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 +68 -15
- package/cjs/docs/auth-swagger.config.js +14 -7
- package/cjs/dtos/authentication.dto.js +16 -43
- 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/user-company-permission.entity.js +0 -6
- 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 +1 -1
- package/cjs/modules/auth.module.js +63 -147
- package/cjs/services/auth-config.service.js +22 -28
- package/cjs/services/auth-datasource.provider.js +9 -21
- package/cjs/services/auth-email.service.js +89 -85
- package/cjs/services/authentication.service.js +225 -396
- package/cjs/services/branch.service.js +9 -4
- package/cjs/services/company-selection-session.service.js +1 -1
- package/cjs/services/user-permission.service.js +43 -73
- package/cjs/services/user.service.js +78 -64
- package/cjs/strategies/jwt.strategy.js +44 -44
- package/cjs/validators/password.validator.js +45 -0
- package/config/auth.constants.d.ts +2 -0
- package/controllers/authentication.controller.d.ts +5 -3
- package/controllers/company-selection.controller.d.ts +6 -2
- package/controllers/user-permission.controller.d.ts +5 -4
- package/controllers/user.controller.d.ts +6 -0
- package/dtos/authentication.dto.d.ts +0 -4
- 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 -3
- package/entities/index.d.ts +3 -3
- package/entities/user-company-permission.entity.d.ts +0 -2
- package/fesm/config/auth.constants.js +6 -13
- package/fesm/controllers/authentication.controller.js +221 -42
- 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 +71 -18
- package/fesm/docs/auth-swagger.config.js +14 -7
- package/fesm/dtos/authentication.dto.js +17 -44
- 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/user-company-permission.entity.js +0 -6
- 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 +1 -1
- package/fesm/modules/auth.module.js +64 -148
- package/fesm/services/auth-config.service.js +23 -29
- package/fesm/services/auth-datasource.provider.js +10 -22
- package/fesm/services/auth-email.service.js +90 -86
- package/fesm/services/authentication.service.js +225 -396
- package/fesm/services/branch.service.js +9 -4
- package/fesm/services/company-selection-session.service.js +1 -1
- package/fesm/services/user-permission.service.js +44 -74
- package/fesm/services/user.service.js +79 -65
- 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/authentication.interface.d.ts +0 -4
- package/interfaces/user-enricher.interface.d.ts +1 -4
- package/modules/auth.module.d.ts +6 -3
- package/package.json +4 -4
- package/services/auth-config.service.d.ts +6 -8
- package/services/auth-datasource.provider.d.ts +2 -4
- package/services/auth-email.service.d.ts +8 -4
- package/services/authentication.service.d.ts +15 -16
- package/services/company-selection-session.service.d.ts +1 -1
- package/services/user-permission.service.d.ts +6 -9
- package/services/user.service.d.ts +3 -0
- 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
|
@@ -72,6 +72,7 @@ _export(exports, {
|
|
|
72
72
|
});
|
|
73
73
|
const _swagger = require("@nestjs/swagger");
|
|
74
74
|
const _classvalidator = require("class-validator");
|
|
75
|
+
const _passwordvalidator = require("../validators/password.validator");
|
|
75
76
|
function _define_property(obj, key, value) {
|
|
76
77
|
if (key in obj) {
|
|
77
78
|
Object.defineProperty(obj, key, {
|
|
@@ -111,12 +112,12 @@ _ts_decorate([
|
|
|
111
112
|
], LoginDto.prototype, "email", void 0);
|
|
112
113
|
_ts_decorate([
|
|
113
114
|
(0, _swagger.ApiProperty)({
|
|
114
|
-
example: '
|
|
115
|
-
description: 'User password
|
|
115
|
+
example: 'SecureP@ss1',
|
|
116
|
+
description: 'User password'
|
|
116
117
|
}),
|
|
117
118
|
(0, _classvalidator.IsString)(),
|
|
118
119
|
(0, _classvalidator.IsNotEmpty)(),
|
|
119
|
-
(0, _classvalidator.
|
|
120
|
+
(0, _classvalidator.MaxLength)(128),
|
|
120
121
|
_ts_metadata("design:type", String)
|
|
121
122
|
], LoginDto.prototype, "password", void 0);
|
|
122
123
|
let RegistrationDto = class RegistrationDto {
|
|
@@ -155,13 +156,13 @@ _ts_decorate([
|
|
|
155
156
|
], RegistrationDto.prototype, "email", void 0);
|
|
156
157
|
_ts_decorate([
|
|
157
158
|
(0, _swagger.ApiProperty)({
|
|
158
|
-
example: '
|
|
159
|
-
description: 'Password (min
|
|
159
|
+
example: 'StrongP@ss123',
|
|
160
|
+
description: 'Password (min 8 chars, requires uppercase, lowercase, number, special char)'
|
|
160
161
|
}),
|
|
161
162
|
(0, _classvalidator.IsNotEmpty)(),
|
|
162
163
|
(0, _classvalidator.IsString)(),
|
|
163
|
-
(0,
|
|
164
|
-
(0, _classvalidator.MaxLength)(
|
|
164
|
+
(0, _passwordvalidator.IsStrongPassword)(),
|
|
165
|
+
(0, _classvalidator.MaxLength)(128),
|
|
165
166
|
_ts_metadata("design:type", String)
|
|
166
167
|
], RegistrationDto.prototype, "password", void 0);
|
|
167
168
|
_ts_decorate([
|
|
@@ -222,6 +223,7 @@ _ts_decorate([
|
|
|
222
223
|
}),
|
|
223
224
|
(0, _classvalidator.IsOptional)(),
|
|
224
225
|
(0, _classvalidator.IsString)(),
|
|
226
|
+
(0, _classvalidator.MaxLength)(500),
|
|
225
227
|
_ts_metadata("design:type", String)
|
|
226
228
|
], RegistrationDto.prototype, "newCompanyAddress", void 0);
|
|
227
229
|
let RefreshTokenDto = class RefreshTokenDto {
|
|
@@ -251,16 +253,17 @@ _ts_decorate([
|
|
|
251
253
|
}),
|
|
252
254
|
(0, _classvalidator.IsString)(),
|
|
253
255
|
(0, _classvalidator.IsNotEmpty)(),
|
|
256
|
+
(0, _classvalidator.MaxLength)(128),
|
|
254
257
|
_ts_metadata("design:type", String)
|
|
255
258
|
], ChangePasswordDto.prototype, "currentPassword", void 0);
|
|
256
259
|
_ts_decorate([
|
|
257
260
|
(0, _swagger.ApiProperty)({
|
|
258
|
-
example: '
|
|
259
|
-
description: 'New password (min
|
|
261
|
+
example: 'NewP@ssword456',
|
|
262
|
+
description: 'New password (min 8 chars, requires uppercase, lowercase, number, special char)'
|
|
260
263
|
}),
|
|
261
264
|
(0, _classvalidator.IsString)(),
|
|
262
265
|
(0, _classvalidator.IsNotEmpty)(),
|
|
263
|
-
(0,
|
|
266
|
+
(0, _passwordvalidator.IsStrongPassword)(),
|
|
264
267
|
_ts_metadata("design:type", String)
|
|
265
268
|
], ChangePasswordDto.prototype, "newPassword", void 0);
|
|
266
269
|
let SelectDto = class SelectDto {
|
|
@@ -428,7 +431,6 @@ let BranchSelectionInfoDto = class BranchSelectionInfoDto {
|
|
|
428
431
|
_define_property(this, "id", void 0);
|
|
429
432
|
_define_property(this, "name", void 0);
|
|
430
433
|
_define_property(this, "slug", void 0);
|
|
431
|
-
_define_property(this, "isActive", void 0);
|
|
432
434
|
_define_property(this, "logoId", void 0);
|
|
433
435
|
}
|
|
434
436
|
};
|
|
@@ -450,12 +452,6 @@ _ts_decorate([
|
|
|
450
452
|
}),
|
|
451
453
|
_ts_metadata("design:type", String)
|
|
452
454
|
], BranchSelectionInfoDto.prototype, "slug", void 0);
|
|
453
|
-
_ts_decorate([
|
|
454
|
-
(0, _swagger.ApiProperty)({
|
|
455
|
-
example: true
|
|
456
|
-
}),
|
|
457
|
-
_ts_metadata("design:type", Boolean)
|
|
458
|
-
], BranchSelectionInfoDto.prototype, "isActive", void 0);
|
|
459
455
|
_ts_decorate([
|
|
460
456
|
(0, _swagger.ApiPropertyOptional)({
|
|
461
457
|
example: '550e8400-e29b-41d4-a716-446655440077',
|
|
@@ -469,7 +465,6 @@ let CompanyWithBranchesDto = class CompanyWithBranchesDto {
|
|
|
469
465
|
_define_property(this, "id", void 0);
|
|
470
466
|
_define_property(this, "name", void 0);
|
|
471
467
|
_define_property(this, "slug", void 0);
|
|
472
|
-
_define_property(this, "isActive", void 0);
|
|
473
468
|
_define_property(this, "logoId", void 0);
|
|
474
469
|
_define_property(this, "branches", void 0);
|
|
475
470
|
}
|
|
@@ -492,12 +487,6 @@ _ts_decorate([
|
|
|
492
487
|
}),
|
|
493
488
|
_ts_metadata("design:type", String)
|
|
494
489
|
], CompanyWithBranchesDto.prototype, "slug", void 0);
|
|
495
|
-
_ts_decorate([
|
|
496
|
-
(0, _swagger.ApiProperty)({
|
|
497
|
-
example: true
|
|
498
|
-
}),
|
|
499
|
-
_ts_metadata("design:type", Boolean)
|
|
500
|
-
], CompanyWithBranchesDto.prototype, "isActive", void 0);
|
|
501
490
|
_ts_decorate([
|
|
502
491
|
(0, _swagger.ApiPropertyOptional)({
|
|
503
492
|
example: '550e8400-e29b-41d4-a716-446655440088',
|
|
@@ -522,7 +511,6 @@ let LoginResponseDto = class LoginResponseDto {
|
|
|
522
511
|
_define_property(this, "user", void 0);
|
|
523
512
|
_define_property(this, "company", void 0);
|
|
524
513
|
_define_property(this, "branch", void 0);
|
|
525
|
-
_define_property(this, "companyFeatureEnabled", void 0);
|
|
526
514
|
}
|
|
527
515
|
};
|
|
528
516
|
_ts_decorate([
|
|
@@ -558,13 +546,6 @@ _ts_decorate([
|
|
|
558
546
|
}),
|
|
559
547
|
_ts_metadata("design:type", typeof BranchInfoDto === "undefined" ? Object : BranchInfoDto)
|
|
560
548
|
], LoginResponseDto.prototype, "branch", void 0);
|
|
561
|
-
_ts_decorate([
|
|
562
|
-
(0, _swagger.ApiPropertyOptional)({
|
|
563
|
-
example: true,
|
|
564
|
-
description: 'Whether company feature is enabled'
|
|
565
|
-
}),
|
|
566
|
-
_ts_metadata("design:type", Boolean)
|
|
567
|
-
], LoginResponseDto.prototype, "companyFeatureEnabled", void 0);
|
|
568
549
|
let RegistrationResponseDto = class RegistrationResponseDto {
|
|
569
550
|
constructor(){
|
|
570
551
|
_define_property(this, "accessToken", void 0);
|
|
@@ -572,7 +553,6 @@ let RegistrationResponseDto = class RegistrationResponseDto {
|
|
|
572
553
|
_define_property(this, "user", void 0);
|
|
573
554
|
_define_property(this, "company", void 0);
|
|
574
555
|
_define_property(this, "branch", void 0);
|
|
575
|
-
_define_property(this, "companyFeatureEnabled", void 0);
|
|
576
556
|
_define_property(this, "requiresEmailVerification", void 0);
|
|
577
557
|
}
|
|
578
558
|
};
|
|
@@ -609,13 +589,6 @@ _ts_decorate([
|
|
|
609
589
|
}),
|
|
610
590
|
_ts_metadata("design:type", typeof BranchInfoDto === "undefined" ? Object : BranchInfoDto)
|
|
611
591
|
], RegistrationResponseDto.prototype, "branch", void 0);
|
|
612
|
-
_ts_decorate([
|
|
613
|
-
(0, _swagger.ApiPropertyOptional)({
|
|
614
|
-
example: true,
|
|
615
|
-
description: 'Whether company feature is enabled'
|
|
616
|
-
}),
|
|
617
|
-
_ts_metadata("design:type", Boolean)
|
|
618
|
-
], RegistrationResponseDto.prototype, "companyFeatureEnabled", void 0);
|
|
619
592
|
_ts_decorate([
|
|
620
593
|
(0, _swagger.ApiPropertyOptional)({
|
|
621
594
|
example: true,
|
|
@@ -753,12 +726,12 @@ _ts_decorate([
|
|
|
753
726
|
], ResetPasswordDto.prototype, "token", void 0);
|
|
754
727
|
_ts_decorate([
|
|
755
728
|
(0, _swagger.ApiProperty)({
|
|
756
|
-
example: '
|
|
757
|
-
description: 'New password (min
|
|
729
|
+
example: 'NewSecureP@ss123',
|
|
730
|
+
description: 'New password (min 8 chars, requires uppercase, lowercase, number, special char)'
|
|
758
731
|
}),
|
|
759
732
|
(0, _classvalidator.IsString)(),
|
|
760
733
|
(0, _classvalidator.IsNotEmpty)(),
|
|
761
|
-
(0,
|
|
734
|
+
(0, _passwordvalidator.IsStrongPassword)(),
|
|
762
735
|
_ts_metadata("design:type", String)
|
|
763
736
|
], ResetPasswordDto.prototype, "newPassword", void 0);
|
|
764
737
|
let VerifyEmailDto = class VerifyEmailDto {
|
package/cjs/dtos/index.js
CHANGED
|
@@ -5,7 +5,6 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
_export_star(require("./authentication.dto"), exports);
|
|
6
6
|
_export_star(require("./company-branch.dto"), exports);
|
|
7
7
|
_export_star(require("./company.dto"), exports);
|
|
8
|
-
_export_star(require("./user-company-permission.dto"), exports);
|
|
9
8
|
_export_star(require("./user.dto"), exports);
|
|
10
9
|
_export_star(require("./user-permission.dto"), exports);
|
|
11
10
|
function _export_star(from, to) {
|
|
@@ -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'
|
|
@@ -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);
|
|
@@ -8,8 +8,10 @@ Object.defineProperty(exports, "ClearToken", {
|
|
|
8
8
|
return ClearToken;
|
|
9
9
|
}
|
|
10
10
|
});
|
|
11
|
+
const _utils = require("@flusys/nestjs-shared/utils");
|
|
11
12
|
const _common = require("@nestjs/common");
|
|
12
13
|
const _rxjs = require("rxjs");
|
|
14
|
+
const _config = require("../config");
|
|
13
15
|
const _authconfigservice = require("../services/auth-config.service");
|
|
14
16
|
function _define_property(obj, key, value) {
|
|
15
17
|
if (key in obj) {
|
|
@@ -38,39 +40,24 @@ function _ts_param(paramIndex, decorator) {
|
|
|
38
40
|
decorator(target, key, paramIndex);
|
|
39
41
|
};
|
|
40
42
|
}
|
|
41
|
-
const DEFAULT_COOKIE_NAME = 'fsn_refresh_token';
|
|
42
43
|
let ClearToken = class ClearToken {
|
|
43
44
|
get cookieName() {
|
|
44
|
-
return this.authConfig?.getRefreshTokenCookieName() ?? DEFAULT_COOKIE_NAME;
|
|
45
|
+
return this.authConfig?.getRefreshTokenCookieName() ?? _config.DEFAULT_COOKIE_NAME;
|
|
45
46
|
}
|
|
46
47
|
intercept(context, next) {
|
|
47
48
|
const req = context.switchToHttp().getRequest();
|
|
48
49
|
const res = context.switchToHttp().getResponse();
|
|
49
50
|
return next.handle().pipe((0, _rxjs.map)((value)=>{
|
|
50
|
-
|
|
51
|
-
|
|
51
|
+
if ((0, _utils.isBrowserRequest)(req)) {
|
|
52
|
+
res.clearCookie(this.cookieName, {
|
|
53
|
+
httpOnly: true,
|
|
54
|
+
path: '/',
|
|
55
|
+
...(0, _utils.buildCookieOptions)(req)
|
|
56
|
+
});
|
|
57
|
+
}
|
|
52
58
|
return value;
|
|
53
59
|
}));
|
|
54
60
|
}
|
|
55
|
-
/**
|
|
56
|
-
* Clear refresh token cookie
|
|
57
|
-
*/ clearRefreshTokenCookie(req, res) {
|
|
58
|
-
const origin = req.headers.origin || '';
|
|
59
|
-
const hostname = req.hostname || '';
|
|
60
|
-
const isHttps = origin.startsWith('https://') || req.secure;
|
|
61
|
-
let cookieDomain = hostname;
|
|
62
|
-
const domainParts = hostname.split('.');
|
|
63
|
-
if (domainParts.length > 2) {
|
|
64
|
-
cookieDomain = '.' + domainParts.slice(-2).join('.');
|
|
65
|
-
}
|
|
66
|
-
res.clearCookie(this.cookieName, {
|
|
67
|
-
httpOnly: true,
|
|
68
|
-
secure: isHttps,
|
|
69
|
-
sameSite: isHttps ? 'strict' : 'lax',
|
|
70
|
-
domain: cookieDomain,
|
|
71
|
-
path: '/'
|
|
72
|
-
});
|
|
73
|
-
}
|
|
74
61
|
constructor(authConfig){
|
|
75
62
|
_define_property(this, "authConfig", void 0);
|
|
76
63
|
this.authConfig = authConfig;
|
|
@@ -8,9 +8,11 @@ Object.defineProperty(exports, "SetToken", {
|
|
|
8
8
|
return SetToken;
|
|
9
9
|
}
|
|
10
10
|
});
|
|
11
|
+
const _utils = require("@flusys/nestjs-shared/utils");
|
|
11
12
|
const _common = require("@nestjs/common");
|
|
12
13
|
const _buffer = require("buffer");
|
|
13
14
|
const _rxjs = require("rxjs");
|
|
15
|
+
const _config = require("../config");
|
|
14
16
|
const _authconfigservice = require("../services/auth-config.service");
|
|
15
17
|
function _define_property(obj, key, value) {
|
|
16
18
|
if (key in obj) {
|
|
@@ -39,80 +41,37 @@ function _ts_param(paramIndex, decorator) {
|
|
|
39
41
|
decorator(target, key, paramIndex);
|
|
40
42
|
};
|
|
41
43
|
}
|
|
42
|
-
const DEFAULT_COOKIE_NAME = 'fsn_refresh_token';
|
|
43
|
-
const MAX_COOKIE_BYTES = 3500;
|
|
44
44
|
let SetToken = class SetToken {
|
|
45
45
|
get cookieName() {
|
|
46
|
-
return this.authConfig?.getRefreshTokenCookieName() ?? DEFAULT_COOKIE_NAME;
|
|
46
|
+
return this.authConfig?.getRefreshTokenCookieName() ?? _config.DEFAULT_COOKIE_NAME;
|
|
47
|
+
}
|
|
48
|
+
get maxAgeMs() {
|
|
49
|
+
return (0, _utils.parseDurationToMs)(this.authConfig?.getRefreshTokenExpiration() ?? '7d');
|
|
47
50
|
}
|
|
48
51
|
intercept(context, next) {
|
|
49
52
|
const req = context.switchToHttp().getRequest();
|
|
50
53
|
const res = context.switchToHttp().getResponse();
|
|
51
54
|
return next.handle().pipe((0, _rxjs.map)((value)=>{
|
|
52
|
-
|
|
53
|
-
if (
|
|
54
|
-
|
|
55
|
-
}
|
|
56
|
-
const isBrowser = this.isBrowserRequest(req);
|
|
57
|
-
const tokenValue = value.refreshToken;
|
|
58
|
-
if (isBrowser) {
|
|
59
|
-
// Browser: Set cookie and remove from response body
|
|
60
|
-
this.setRefreshTokenCookie(req, res, tokenValue);
|
|
61
|
-
// Return response without refreshToken for browsers
|
|
55
|
+
if (!value?.refreshToken) return value;
|
|
56
|
+
if ((0, _utils.isBrowserRequest)(req)) {
|
|
57
|
+
this.setRefreshTokenCookie(req, res, value.refreshToken);
|
|
62
58
|
const { refreshToken, ...responseWithoutToken } = value;
|
|
63
59
|
return responseWithoutToken;
|
|
64
60
|
}
|
|
65
|
-
// API/Mobile: Keep refreshToken in response body
|
|
66
61
|
return value;
|
|
67
62
|
}), (0, _rxjs.catchError)((err)=>(0, _rxjs.throwError)(()=>err)));
|
|
68
63
|
}
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
* Checks Accept header and custom X-Client-Type header
|
|
72
|
-
*/ isBrowserRequest(req) {
|
|
73
|
-
// Check custom header first (allows explicit client identification)
|
|
74
|
-
const clientType = req.headers['x-client-type'];
|
|
75
|
-
if (clientType) {
|
|
76
|
-
return clientType.toLowerCase() === 'browser' || clientType.toLowerCase() === 'web';
|
|
77
|
-
}
|
|
78
|
-
// Check Accept header - browsers typically include text/html
|
|
79
|
-
const accept = req.headers['accept'] || '';
|
|
80
|
-
if (accept.includes('text/html')) {
|
|
81
|
-
return true;
|
|
82
|
-
}
|
|
83
|
-
// Check User-Agent for common browsers
|
|
84
|
-
const userAgent = req.headers['user-agent'] || '';
|
|
85
|
-
const browserPatterns = /mozilla|chrome|safari|firefox|edge|opera|msie/i;
|
|
86
|
-
if (browserPatterns.test(userAgent) && !userAgent.includes('Postman')) {
|
|
87
|
-
return true;
|
|
88
|
-
}
|
|
89
|
-
return false;
|
|
90
|
-
}
|
|
91
|
-
/**
|
|
92
|
-
* Set refresh token in HTTP-only cookie
|
|
93
|
-
*/ setRefreshTokenCookie(req, res, tokenValue) {
|
|
94
|
-
const origin = req.headers.origin || '';
|
|
95
|
-
const hostname = req.hostname || '';
|
|
96
|
-
const isHttps = origin.startsWith('https://') || req.secure;
|
|
97
|
-
let cookieDomain = hostname;
|
|
98
|
-
const domainParts = hostname.split('.');
|
|
99
|
-
if (domainParts.length > 2) {
|
|
100
|
-
cookieDomain = '.' + domainParts.slice(-2).join('.');
|
|
101
|
-
}
|
|
102
|
-
// Check cookie size
|
|
103
|
-
const rawCookieString = `${this.cookieName}=${tokenValue}; HttpOnly; Domain=${cookieDomain}`;
|
|
64
|
+
setRefreshTokenCookie(req, res, tokenValue) {
|
|
65
|
+
const rawCookieString = `${this.cookieName}=${tokenValue}; HttpOnly`;
|
|
104
66
|
const estimatedBytes = _buffer.Buffer.byteLength(rawCookieString, 'utf8');
|
|
105
|
-
if (estimatedBytes > MAX_COOKIE_BYTES) {
|
|
67
|
+
if (estimatedBytes > _config.MAX_COOKIE_BYTES) {
|
|
106
68
|
throw new _common.PayloadTooLargeException(`Refresh token too large (≈${estimatedBytes} bytes)`);
|
|
107
69
|
}
|
|
108
|
-
// Set HTTP-only secure cookie
|
|
109
70
|
res.cookie(this.cookieName, tokenValue, {
|
|
110
71
|
httpOnly: true,
|
|
111
|
-
secure: isHttps,
|
|
112
|
-
sameSite: isHttps ? 'strict' : 'lax',
|
|
113
|
-
domain: cookieDomain,
|
|
114
72
|
path: '/',
|
|
115
|
-
maxAge:
|
|
73
|
+
maxAge: this.maxAgeMs,
|
|
74
|
+
...(0, _utils.buildCookieOptions)(req)
|
|
116
75
|
});
|
|
117
76
|
}
|
|
118
77
|
constructor(authConfig){
|
|
@@ -123,6 +82,7 @@ let SetToken = class SetToken {
|
|
|
123
82
|
SetToken = _ts_decorate([
|
|
124
83
|
(0, _common.Injectable)(),
|
|
125
84
|
_ts_param(0, (0, _common.Optional)()),
|
|
85
|
+
_ts_param(0, (0, _common.Inject)(_authconfigservice.AuthConfigService)),
|
|
126
86
|
_ts_metadata("design:type", Function),
|
|
127
87
|
_ts_metadata("design:paramtypes", [
|
|
128
88
|
typeof _authconfigservice.AuthConfigService === "undefined" ? Object : _authconfigservice.AuthConfigService
|