@flusys/nestjs-auth 3.0.0-rc → 3.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 +610 -95
- package/cjs/controllers/authentication.controller.js +2 -173
- package/cjs/controllers/email-verification.controller.js +220 -0
- package/cjs/controllers/index.js +1 -0
- package/cjs/dtos/authentication.dto.js +12 -2
- package/cjs/entities/index.js +16 -17
- package/cjs/entities/pending-registration.entity.js +9 -0
- package/cjs/modules/auth.module.js +33 -24
- package/cjs/services/auth-config.service.js +11 -7
- package/cjs/services/auth-datasource.provider.js +15 -27
- package/cjs/services/auth-email.service.js +8 -33
- package/cjs/services/authentication.service.js +123 -99
- package/cjs/services/user.service.js +28 -83
- package/controllers/authentication.controller.d.ts +2 -10
- package/controllers/email-verification.controller.d.ts +20 -0
- package/controllers/index.d.ts +1 -0
- package/dtos/authentication.dto.d.ts +1 -0
- package/entities/index.d.ts +5 -10
- package/entities/pending-registration.entity.d.ts +1 -0
- package/fesm/controllers/authentication.controller.js +3 -174
- package/fesm/controllers/email-verification.controller.js +210 -0
- package/fesm/controllers/index.js +1 -0
- package/fesm/dtos/authentication.dto.js +32 -25
- package/fesm/entities/index.js +17 -9
- package/fesm/entities/pending-registration.entity.js +9 -0
- package/fesm/interfaces/user-enricher.interface.js +2 -24
- package/fesm/modules/auth.module.js +35 -26
- package/fesm/services/auth-config.service.js +11 -7
- package/fesm/services/auth-datasource.provider.js +15 -27
- package/fesm/services/auth-email.service.js +8 -33
- package/fesm/services/authentication.service.js +124 -100
- package/fesm/services/user.service.js +28 -83
- package/interfaces/user-enricher.interface.d.ts +3 -2
- package/modules/auth.module.d.ts +3 -1
- package/package.json +3 -3
- package/services/auth-config.service.d.ts +1 -0
- package/services/auth-datasource.provider.d.ts +1 -0
- package/services/auth-email.service.d.ts +1 -0
- package/services/authentication.service.d.ts +4 -1
- package/services/user.service.d.ts +5 -0
|
@@ -0,0 +1,210 @@
|
|
|
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
|
+
function _ts_param(paramIndex, decorator) {
|
|
24
|
+
return function(target, key) {
|
|
25
|
+
decorator(target, key, paramIndex);
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
import { MessageResponseDto } from '@flusys/nestjs-shared/dtos';
|
|
29
|
+
import { BadRequestException, Body, Controller, HttpCode, HttpStatus, Inject, Post, Req, UseInterceptors } from '@nestjs/common';
|
|
30
|
+
import { ApiBody, ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
|
|
31
|
+
import { Throttle } from '@nestjs/throttler';
|
|
32
|
+
import { Request } from 'express';
|
|
33
|
+
import { ForgotPasswordDto, RegistrationResponseDto, ResendVerificationDto, ResetPasswordDto, VerifyEmailDto } from '../dtos/authentication.dto';
|
|
34
|
+
import { SetToken } from '../interceptors/set-token.interceptor';
|
|
35
|
+
import { AuthConfigService } from '../services/auth-config.service';
|
|
36
|
+
import { AuthDataSourceProvider } from '../services/auth-datasource.provider';
|
|
37
|
+
import { AuthEmailService } from '../services/auth-email.service';
|
|
38
|
+
import { AuthenticationService } from '../services/authentication.service';
|
|
39
|
+
export class EmailVerificationController {
|
|
40
|
+
ensureEmailVerificationEnabled() {
|
|
41
|
+
if (!this.dataSourceProvider.isEmailVerificationEnabled()) {
|
|
42
|
+
throw new BadRequestException('Email verification is not enabled for this tenant');
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
buildAuthUrl(req, path) {
|
|
46
|
+
const frontendUrl = this.authConfig.getFrontendUrl();
|
|
47
|
+
return frontendUrl ? `${frontendUrl}${path}` : `${req.protocol}://${req.get('host')}${path}`;
|
|
48
|
+
}
|
|
49
|
+
async forgotPassword(req, dto) {
|
|
50
|
+
this.ensureEmailVerificationEnabled();
|
|
51
|
+
return this.authEmailService.forgotPassword(dto.email, this.buildAuthUrl(req, '/auth/reset-password'));
|
|
52
|
+
}
|
|
53
|
+
async resetPassword(dto) {
|
|
54
|
+
this.ensureEmailVerificationEnabled();
|
|
55
|
+
return this.authEmailService.resetPassword(dto.token, dto.newPassword);
|
|
56
|
+
}
|
|
57
|
+
async resendVerification(req, dto) {
|
|
58
|
+
this.ensureEmailVerificationEnabled();
|
|
59
|
+
return this.authEmailService.resendVerificationEmail(dto.email, this.buildAuthUrl(req, '/auth/verify-email'));
|
|
60
|
+
}
|
|
61
|
+
async verifyEmail(dto) {
|
|
62
|
+
this.ensureEmailVerificationEnabled();
|
|
63
|
+
const result = await this.authEmailService.verifyEmail(dto.token);
|
|
64
|
+
if (result.type === 'pending') {
|
|
65
|
+
return this.authService.createUserFromPendingRegistration(result.pending);
|
|
66
|
+
}
|
|
67
|
+
return {
|
|
68
|
+
success: true,
|
|
69
|
+
message: result.message
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
constructor(authService, authEmailService, authConfig, dataSourceProvider){
|
|
73
|
+
_define_property(this, "authService", void 0);
|
|
74
|
+
_define_property(this, "authEmailService", void 0);
|
|
75
|
+
_define_property(this, "authConfig", void 0);
|
|
76
|
+
_define_property(this, "dataSourceProvider", void 0);
|
|
77
|
+
this.authService = authService;
|
|
78
|
+
this.authEmailService = authEmailService;
|
|
79
|
+
this.authConfig = authConfig;
|
|
80
|
+
this.dataSourceProvider = dataSourceProvider;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
_ts_decorate([
|
|
84
|
+
Post('forgot-password'),
|
|
85
|
+
HttpCode(HttpStatus.OK),
|
|
86
|
+
Throttle({
|
|
87
|
+
default: {
|
|
88
|
+
limit: 3,
|
|
89
|
+
ttl: 300000
|
|
90
|
+
}
|
|
91
|
+
}),
|
|
92
|
+
ApiOperation({
|
|
93
|
+
summary: 'Request password reset email'
|
|
94
|
+
}),
|
|
95
|
+
ApiBody({
|
|
96
|
+
type: ForgotPasswordDto
|
|
97
|
+
}),
|
|
98
|
+
ApiResponse({
|
|
99
|
+
status: 200,
|
|
100
|
+
type: MessageResponseDto
|
|
101
|
+
}),
|
|
102
|
+
_ts_param(0, Req()),
|
|
103
|
+
_ts_param(1, Body()),
|
|
104
|
+
_ts_metadata("design:type", Function),
|
|
105
|
+
_ts_metadata("design:paramtypes", [
|
|
106
|
+
typeof Request === "undefined" ? Object : Request,
|
|
107
|
+
typeof ForgotPasswordDto === "undefined" ? Object : ForgotPasswordDto
|
|
108
|
+
]),
|
|
109
|
+
_ts_metadata("design:returntype", Promise)
|
|
110
|
+
], EmailVerificationController.prototype, "forgotPassword", null);
|
|
111
|
+
_ts_decorate([
|
|
112
|
+
Post('reset-password'),
|
|
113
|
+
HttpCode(HttpStatus.OK),
|
|
114
|
+
Throttle({
|
|
115
|
+
default: {
|
|
116
|
+
limit: 5,
|
|
117
|
+
ttl: 900000
|
|
118
|
+
}
|
|
119
|
+
}),
|
|
120
|
+
ApiOperation({
|
|
121
|
+
summary: 'Reset password using token'
|
|
122
|
+
}),
|
|
123
|
+
ApiBody({
|
|
124
|
+
type: ResetPasswordDto
|
|
125
|
+
}),
|
|
126
|
+
ApiResponse({
|
|
127
|
+
status: 200,
|
|
128
|
+
type: MessageResponseDto
|
|
129
|
+
}),
|
|
130
|
+
_ts_param(0, Body()),
|
|
131
|
+
_ts_metadata("design:type", Function),
|
|
132
|
+
_ts_metadata("design:paramtypes", [
|
|
133
|
+
typeof ResetPasswordDto === "undefined" ? Object : ResetPasswordDto
|
|
134
|
+
]),
|
|
135
|
+
_ts_metadata("design:returntype", Promise)
|
|
136
|
+
], EmailVerificationController.prototype, "resetPassword", null);
|
|
137
|
+
_ts_decorate([
|
|
138
|
+
Post('resend-verification'),
|
|
139
|
+
HttpCode(HttpStatus.OK),
|
|
140
|
+
Throttle({
|
|
141
|
+
default: {
|
|
142
|
+
limit: 3,
|
|
143
|
+
ttl: 300000
|
|
144
|
+
}
|
|
145
|
+
}),
|
|
146
|
+
ApiOperation({
|
|
147
|
+
summary: 'Resend email verification link'
|
|
148
|
+
}),
|
|
149
|
+
ApiBody({
|
|
150
|
+
type: ResendVerificationDto
|
|
151
|
+
}),
|
|
152
|
+
ApiResponse({
|
|
153
|
+
status: 200,
|
|
154
|
+
type: MessageResponseDto
|
|
155
|
+
}),
|
|
156
|
+
_ts_param(0, Req()),
|
|
157
|
+
_ts_param(1, Body()),
|
|
158
|
+
_ts_metadata("design:type", Function),
|
|
159
|
+
_ts_metadata("design:paramtypes", [
|
|
160
|
+
typeof Request === "undefined" ? Object : Request,
|
|
161
|
+
typeof ResendVerificationDto === "undefined" ? Object : ResendVerificationDto
|
|
162
|
+
]),
|
|
163
|
+
_ts_metadata("design:returntype", Promise)
|
|
164
|
+
], EmailVerificationController.prototype, "resendVerification", null);
|
|
165
|
+
_ts_decorate([
|
|
166
|
+
Post('verify-email'),
|
|
167
|
+
HttpCode(HttpStatus.OK),
|
|
168
|
+
Throttle({
|
|
169
|
+
default: {
|
|
170
|
+
limit: 10,
|
|
171
|
+
ttl: 60000
|
|
172
|
+
}
|
|
173
|
+
}),
|
|
174
|
+
UseInterceptors(SetToken),
|
|
175
|
+
ApiOperation({
|
|
176
|
+
summary: 'Verify email using token'
|
|
177
|
+
}),
|
|
178
|
+
ApiBody({
|
|
179
|
+
type: VerifyEmailDto
|
|
180
|
+
}),
|
|
181
|
+
ApiResponse({
|
|
182
|
+
status: 200,
|
|
183
|
+
type: MessageResponseDto
|
|
184
|
+
}),
|
|
185
|
+
ApiResponse({
|
|
186
|
+
status: 200,
|
|
187
|
+
type: RegistrationResponseDto
|
|
188
|
+
}),
|
|
189
|
+
_ts_param(0, Body()),
|
|
190
|
+
_ts_metadata("design:type", Function),
|
|
191
|
+
_ts_metadata("design:paramtypes", [
|
|
192
|
+
typeof VerifyEmailDto === "undefined" ? Object : VerifyEmailDto
|
|
193
|
+
]),
|
|
194
|
+
_ts_metadata("design:returntype", Promise)
|
|
195
|
+
], EmailVerificationController.prototype, "verifyEmail", null);
|
|
196
|
+
EmailVerificationController = _ts_decorate([
|
|
197
|
+
ApiTags('Authentication'),
|
|
198
|
+
Controller('auth'),
|
|
199
|
+
_ts_param(0, Inject(AuthenticationService)),
|
|
200
|
+
_ts_param(1, Inject(AuthEmailService)),
|
|
201
|
+
_ts_param(2, Inject(AuthConfigService)),
|
|
202
|
+
_ts_param(3, Inject(AuthDataSourceProvider)),
|
|
203
|
+
_ts_metadata("design:type", Function),
|
|
204
|
+
_ts_metadata("design:paramtypes", [
|
|
205
|
+
typeof AuthenticationService === "undefined" ? Object : AuthenticationService,
|
|
206
|
+
typeof AuthEmailService === "undefined" ? Object : AuthEmailService,
|
|
207
|
+
typeof AuthConfigService === "undefined" ? Object : AuthConfigService,
|
|
208
|
+
typeof AuthDataSourceProvider === "undefined" ? Object : AuthDataSourceProvider
|
|
209
|
+
])
|
|
210
|
+
], EmailVerificationController);
|
|
@@ -23,8 +23,7 @@ function _ts_metadata(k, v) {
|
|
|
23
23
|
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
|
|
24
24
|
import { IsEmail, IsNotEmpty, IsOptional, IsString, IsUUID, MaxLength, ValidateIf } from 'class-validator';
|
|
25
25
|
import { IsStrongPassword } from '../validators/password.validator';
|
|
26
|
-
|
|
27
|
-
/** Login Request DTO */ export class LoginDto {
|
|
26
|
+
export class LoginDto {
|
|
28
27
|
constructor(){
|
|
29
28
|
_define_property(this, "email", void 0);
|
|
30
29
|
_define_property(this, "password", void 0);
|
|
@@ -49,19 +48,18 @@ _ts_decorate([
|
|
|
49
48
|
MaxLength(128),
|
|
50
49
|
_ts_metadata("design:type", String)
|
|
51
50
|
], LoginDto.prototype, "password", void 0);
|
|
52
|
-
|
|
51
|
+
export class RegistrationDto {
|
|
53
52
|
constructor(){
|
|
54
53
|
_define_property(this, "name", void 0);
|
|
55
54
|
_define_property(this, "email", void 0);
|
|
56
55
|
_define_property(this, "password", void 0);
|
|
57
56
|
_define_property(this, "phone", void 0);
|
|
58
|
-
// Company Feature Fields (Optional - only used when company feature is enabled)
|
|
59
57
|
_define_property(this, "companySlug", void 0);
|
|
60
58
|
_define_property(this, "branchSlug", void 0);
|
|
61
|
-
// New Company Creation Fields (Optional - for creating new company)
|
|
62
59
|
_define_property(this, "newCompanyName", void 0);
|
|
63
60
|
_define_property(this, "newCompanyPhone", void 0);
|
|
64
61
|
_define_property(this, "newCompanyAddress", void 0);
|
|
62
|
+
_define_property(this, "additionalFields", void 0);
|
|
65
63
|
}
|
|
66
64
|
}
|
|
67
65
|
_ts_decorate([
|
|
@@ -155,7 +153,18 @@ _ts_decorate([
|
|
|
155
153
|
MaxLength(500),
|
|
156
154
|
_ts_metadata("design:type", String)
|
|
157
155
|
], RegistrationDto.prototype, "newCompanyAddress", void 0);
|
|
158
|
-
|
|
156
|
+
_ts_decorate([
|
|
157
|
+
ApiPropertyOptional({
|
|
158
|
+
example: {
|
|
159
|
+
prevCompanyName: 'Acme Corp',
|
|
160
|
+
employeeId: 'EMP001'
|
|
161
|
+
},
|
|
162
|
+
description: 'Additional fields for profile extension (handled by USER_ENRICHER)'
|
|
163
|
+
}),
|
|
164
|
+
IsOptional(),
|
|
165
|
+
_ts_metadata("design:type", typeof Record === "undefined" ? Object : Record)
|
|
166
|
+
], RegistrationDto.prototype, "additionalFields", void 0);
|
|
167
|
+
export class RefreshTokenDto {
|
|
159
168
|
constructor(){
|
|
160
169
|
_define_property(this, "refreshToken", void 0);
|
|
161
170
|
}
|
|
@@ -169,7 +178,7 @@ _ts_decorate([
|
|
|
169
178
|
IsString(),
|
|
170
179
|
_ts_metadata("design:type", String)
|
|
171
180
|
], RefreshTokenDto.prototype, "refreshToken", void 0);
|
|
172
|
-
|
|
181
|
+
export class ChangePasswordDto {
|
|
173
182
|
constructor(){
|
|
174
183
|
_define_property(this, "currentPassword", void 0);
|
|
175
184
|
_define_property(this, "newPassword", void 0);
|
|
@@ -195,7 +204,7 @@ _ts_decorate([
|
|
|
195
204
|
IsStrongPassword(),
|
|
196
205
|
_ts_metadata("design:type", String)
|
|
197
206
|
], ChangePasswordDto.prototype, "newPassword", void 0);
|
|
198
|
-
|
|
207
|
+
export class SelectDto {
|
|
199
208
|
constructor(){
|
|
200
209
|
_define_property(this, "sessionId", void 0);
|
|
201
210
|
_define_property(this, "companyId", void 0);
|
|
@@ -229,7 +238,7 @@ _ts_decorate([
|
|
|
229
238
|
IsNotEmpty(),
|
|
230
239
|
_ts_metadata("design:type", String)
|
|
231
240
|
], SelectDto.prototype, "branchId", void 0);
|
|
232
|
-
|
|
241
|
+
export class SwitchCompanyDto {
|
|
233
242
|
constructor(){
|
|
234
243
|
_define_property(this, "companyId", void 0);
|
|
235
244
|
_define_property(this, "branchId", void 0);
|
|
@@ -253,8 +262,7 @@ _ts_decorate([
|
|
|
253
262
|
IsNotEmpty(),
|
|
254
263
|
_ts_metadata("design:type", String)
|
|
255
264
|
], SwitchCompanyDto.prototype, "branchId", void 0);
|
|
256
|
-
|
|
257
|
-
/** User Info DTO (used in responses) */ export class UserInfoDto {
|
|
265
|
+
export class UserInfoDto {
|
|
258
266
|
constructor(){
|
|
259
267
|
_define_property(this, "id", void 0);
|
|
260
268
|
_define_property(this, "email", void 0);
|
|
@@ -288,7 +296,7 @@ _ts_decorate([
|
|
|
288
296
|
}),
|
|
289
297
|
_ts_metadata("design:type", Object)
|
|
290
298
|
], UserInfoDto.prototype, "profilePictureId", void 0);
|
|
291
|
-
|
|
299
|
+
export class CompanyInfoDto {
|
|
292
300
|
constructor(){
|
|
293
301
|
_define_property(this, "id", void 0);
|
|
294
302
|
_define_property(this, "name", void 0);
|
|
@@ -322,7 +330,7 @@ _ts_decorate([
|
|
|
322
330
|
}),
|
|
323
331
|
_ts_metadata("design:type", Object)
|
|
324
332
|
], CompanyInfoDto.prototype, "logoId", void 0);
|
|
325
|
-
|
|
333
|
+
export class BranchInfoDto {
|
|
326
334
|
constructor(){
|
|
327
335
|
_define_property(this, "id", void 0);
|
|
328
336
|
_define_property(this, "name", void 0);
|
|
@@ -356,7 +364,7 @@ _ts_decorate([
|
|
|
356
364
|
}),
|
|
357
365
|
_ts_metadata("design:type", Object)
|
|
358
366
|
], BranchInfoDto.prototype, "logoId", void 0);
|
|
359
|
-
|
|
367
|
+
export class BranchSelectionInfoDto {
|
|
360
368
|
constructor(){
|
|
361
369
|
_define_property(this, "id", void 0);
|
|
362
370
|
_define_property(this, "name", void 0);
|
|
@@ -390,7 +398,7 @@ _ts_decorate([
|
|
|
390
398
|
}),
|
|
391
399
|
_ts_metadata("design:type", Object)
|
|
392
400
|
], BranchSelectionInfoDto.prototype, "logoId", void 0);
|
|
393
|
-
|
|
401
|
+
export class CompanyWithBranchesDto {
|
|
394
402
|
constructor(){
|
|
395
403
|
_define_property(this, "id", void 0);
|
|
396
404
|
_define_property(this, "name", void 0);
|
|
@@ -434,7 +442,7 @@ _ts_decorate([
|
|
|
434
442
|
}),
|
|
435
443
|
_ts_metadata("design:type", Array)
|
|
436
444
|
], CompanyWithBranchesDto.prototype, "branches", void 0);
|
|
437
|
-
|
|
445
|
+
export class LoginResponseDto {
|
|
438
446
|
constructor(){
|
|
439
447
|
_define_property(this, "accessToken", void 0);
|
|
440
448
|
_define_property(this, "refreshToken", void 0);
|
|
@@ -476,7 +484,7 @@ _ts_decorate([
|
|
|
476
484
|
}),
|
|
477
485
|
_ts_metadata("design:type", typeof BranchInfoDto === "undefined" ? Object : BranchInfoDto)
|
|
478
486
|
], LoginResponseDto.prototype, "branch", void 0);
|
|
479
|
-
|
|
487
|
+
export class RegistrationResponseDto {
|
|
480
488
|
constructor(){
|
|
481
489
|
_define_property(this, "accessToken", void 0);
|
|
482
490
|
_define_property(this, "refreshToken", void 0);
|
|
@@ -526,7 +534,7 @@ _ts_decorate([
|
|
|
526
534
|
}),
|
|
527
535
|
_ts_metadata("design:type", Boolean)
|
|
528
536
|
], RegistrationResponseDto.prototype, "requiresEmailVerification", void 0);
|
|
529
|
-
|
|
537
|
+
export class MeResponseDto {
|
|
530
538
|
constructor(){
|
|
531
539
|
_define_property(this, "user", void 0);
|
|
532
540
|
_define_property(this, "company", void 0);
|
|
@@ -554,7 +562,7 @@ _ts_decorate([
|
|
|
554
562
|
}),
|
|
555
563
|
_ts_metadata("design:type", typeof BranchInfoDto === "undefined" ? Object : BranchInfoDto)
|
|
556
564
|
], MeResponseDto.prototype, "branch", void 0);
|
|
557
|
-
|
|
565
|
+
export class CompanySelectionResponseDto {
|
|
558
566
|
constructor(){
|
|
559
567
|
_define_property(this, "requiresSelection", void 0);
|
|
560
568
|
_define_property(this, "sessionId", void 0);
|
|
@@ -600,7 +608,7 @@ _ts_decorate([
|
|
|
600
608
|
}),
|
|
601
609
|
_ts_metadata("design:type", Array)
|
|
602
610
|
], CompanySelectionResponseDto.prototype, "companies", void 0);
|
|
603
|
-
|
|
611
|
+
export class LoginResponseRequiresEmailVerificationDto {
|
|
604
612
|
constructor(){
|
|
605
613
|
_define_property(this, "requiresEmailVerification", void 0);
|
|
606
614
|
_define_property(this, "email", void 0);
|
|
@@ -625,8 +633,7 @@ _ts_decorate([
|
|
|
625
633
|
}),
|
|
626
634
|
_ts_metadata("design:type", String)
|
|
627
635
|
], LoginResponseRequiresEmailVerificationDto.prototype, "message", void 0);
|
|
628
|
-
|
|
629
|
-
/** Forgot Password Request DTO - Initiates password reset flow */ export class ForgotPasswordDto {
|
|
636
|
+
export class ForgotPasswordDto {
|
|
630
637
|
constructor(){
|
|
631
638
|
_define_property(this, "email", void 0);
|
|
632
639
|
}
|
|
@@ -640,7 +647,7 @@ _ts_decorate([
|
|
|
640
647
|
IsNotEmpty(),
|
|
641
648
|
_ts_metadata("design:type", String)
|
|
642
649
|
], ForgotPasswordDto.prototype, "email", void 0);
|
|
643
|
-
|
|
650
|
+
export class ResetPasswordDto {
|
|
644
651
|
constructor(){
|
|
645
652
|
_define_property(this, "token", void 0);
|
|
646
653
|
_define_property(this, "newPassword", void 0);
|
|
@@ -665,7 +672,7 @@ _ts_decorate([
|
|
|
665
672
|
IsStrongPassword(),
|
|
666
673
|
_ts_metadata("design:type", String)
|
|
667
674
|
], ResetPasswordDto.prototype, "newPassword", void 0);
|
|
668
|
-
|
|
675
|
+
export class VerifyEmailDto {
|
|
669
676
|
constructor(){
|
|
670
677
|
_define_property(this, "token", void 0);
|
|
671
678
|
}
|
|
@@ -679,5 +686,5 @@ _ts_decorate([
|
|
|
679
686
|
IsNotEmpty(),
|
|
680
687
|
_ts_metadata("design:type", String)
|
|
681
688
|
], VerifyEmailDto.prototype, "token", void 0);
|
|
682
|
-
|
|
689
|
+
export class ResendVerificationDto extends ForgotPasswordDto {
|
|
683
690
|
}
|
package/fesm/entities/index.js
CHANGED
|
@@ -10,20 +10,28 @@ import { PendingRegistration } from './pending-registration.entity';
|
|
|
10
10
|
import { UserCompanyPermission } from './user-company-permission.entity';
|
|
11
11
|
import { User } from './user.entity';
|
|
12
12
|
import { UserToken } from './user-token.entity';
|
|
13
|
-
|
|
13
|
+
const BaseEntities = [
|
|
14
14
|
User,
|
|
15
|
-
UserToken
|
|
15
|
+
UserToken
|
|
16
|
+
];
|
|
17
|
+
const EmailEntities = [
|
|
16
18
|
PendingRegistration
|
|
17
19
|
];
|
|
18
|
-
|
|
20
|
+
const CompanyEntities = [
|
|
19
21
|
Company,
|
|
20
22
|
CompanyBranch,
|
|
21
23
|
UserCompanyPermission
|
|
22
24
|
];
|
|
23
|
-
export
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
25
|
+
export function getEntitiesByConfig(config) {
|
|
26
|
+
const { enableCompanyFeature = false, enableEmailVerification = true } = config;
|
|
27
|
+
const entities = [
|
|
28
|
+
...BaseEntities
|
|
29
|
+
];
|
|
30
|
+
if (enableEmailVerification) {
|
|
31
|
+
entities.push(...EmailEntities);
|
|
32
|
+
}
|
|
33
|
+
if (enableCompanyFeature) {
|
|
34
|
+
entities.push(...CompanyEntities);
|
|
35
|
+
}
|
|
36
|
+
return entities;
|
|
29
37
|
}
|
|
@@ -31,6 +31,7 @@ export class PendingRegistration {
|
|
|
31
31
|
_define_property(this, "token", void 0);
|
|
32
32
|
_define_property(this, "expiresAt", void 0);
|
|
33
33
|
_define_property(this, "companyData", void 0);
|
|
34
|
+
_define_property(this, "additionalFields", void 0);
|
|
34
35
|
_define_property(this, "createdAt", void 0);
|
|
35
36
|
}
|
|
36
37
|
}
|
|
@@ -90,6 +91,14 @@ _ts_decorate([
|
|
|
90
91
|
}),
|
|
91
92
|
_ts_metadata("design:type", Object)
|
|
92
93
|
], PendingRegistration.prototype, "companyData", void 0);
|
|
94
|
+
_ts_decorate([
|
|
95
|
+
Column({
|
|
96
|
+
type: 'json',
|
|
97
|
+
nullable: true,
|
|
98
|
+
name: 'additional_fields'
|
|
99
|
+
}),
|
|
100
|
+
_ts_metadata("design:type", Object)
|
|
101
|
+
], PendingRegistration.prototype, "additionalFields", void 0);
|
|
93
102
|
_ts_decorate([
|
|
94
103
|
CreateDateColumn({
|
|
95
104
|
type: 'timestamp',
|
|
@@ -1,26 +1,4 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* User Enricher Provider Interface
|
|
3
|
-
*
|
|
4
|
-
* Allows consuming applications to extend user list and profile
|
|
5
|
-
* without modifying the base nestjs-auth package.
|
|
6
|
-
*
|
|
7
|
-
* This follows the Provider Interface Pattern:
|
|
8
|
-
* - nestjs-auth defines the interface (this file)
|
|
9
|
-
* - Consuming apps implement the interface
|
|
10
|
-
* - nestjs-auth optionally injects the implementation
|
|
11
|
-
*
|
|
12
|
-
* @example
|
|
13
|
-
* // In your app module
|
|
14
|
-
* providers: [
|
|
15
|
-
* { provide: USER_ENRICHER, useClass: MyUserEnricher },
|
|
16
|
-
* ]
|
|
17
|
-
*
|
|
18
|
-
* // Your enricher implementation
|
|
19
|
-
* @Injectable()
|
|
20
|
-
* export class MyUserEnricher implements IUserEnricher {
|
|
21
|
-
* async enrichListQuery(query, user) {
|
|
22
|
-
* query.leftJoinAndSelect('user.department', 'department');
|
|
23
|
-
* return { extraFields: ['department.name'] };
|
|
24
|
-
* }
|
|
25
|
-
* }
|
|
2
|
+
* User Enricher Provider Interface - allows apps to extend user list/profile
|
|
3
|
+
* without modifying nestjs-auth. Provide via: { provide: USER_ENRICHER, useClass: MyEnricher }
|
|
26
4
|
*/ export { };
|
|
@@ -10,8 +10,8 @@ import { JwtModule } from '@nestjs/jwt';
|
|
|
10
10
|
import { PassportModule } from '@nestjs/passport';
|
|
11
11
|
import { JwtAuthGuard } from '@flusys/nestjs-shared/guards';
|
|
12
12
|
import { AUTH_MODULE_OPTIONS } from '../config/auth.constants';
|
|
13
|
-
import { AuthenticationController, BranchController, CompanyController, CompanySelectionController, UserController, UserPermissionController } from '../controllers';
|
|
14
|
-
import {
|
|
13
|
+
import { AuthenticationController, BranchController, CompanyController, CompanySelectionController, EmailVerificationController, UserController, UserPermissionController } from '../controllers';
|
|
14
|
+
import { getEntitiesByConfig } from '../entities';
|
|
15
15
|
import { ClearToken } from '../interceptors/clear-token.interceptor';
|
|
16
16
|
import { SetToken } from '../interceptors/set-token.interceptor';
|
|
17
17
|
import { AuthEmailService, AuthenticationService, BranchService, CompanySelectionSessionService, CompanyService, UserPermissionService, UserService } from '../services';
|
|
@@ -36,9 +36,9 @@ export class AuthModule {
|
|
|
36
36
|
...options.providers ?? []
|
|
37
37
|
], options.imports);
|
|
38
38
|
}
|
|
39
|
-
|
|
39
|
+
static buildModule(options, providers, externalImports = []) {
|
|
40
40
|
const { global = false, includeController = true, bootstrapAppConfig } = options;
|
|
41
|
-
const
|
|
41
|
+
const featureFlags = this.getFeatureFlags(bootstrapAppConfig);
|
|
42
42
|
return {
|
|
43
43
|
module: AuthModule,
|
|
44
44
|
global,
|
|
@@ -46,15 +46,21 @@ export class AuthModule {
|
|
|
46
46
|
...externalImports,
|
|
47
47
|
...this.buildImports()
|
|
48
48
|
],
|
|
49
|
-
controllers: this.buildControllers(includeController,
|
|
49
|
+
controllers: this.buildControllers(includeController, featureFlags),
|
|
50
50
|
providers: [
|
|
51
51
|
...providers,
|
|
52
|
-
...this.buildProviders(
|
|
52
|
+
...this.buildProviders(featureFlags)
|
|
53
53
|
],
|
|
54
|
-
exports: this.buildExports(
|
|
54
|
+
exports: this.buildExports(featureFlags)
|
|
55
55
|
};
|
|
56
56
|
}
|
|
57
|
-
|
|
57
|
+
static getFeatureFlags(bootstrapAppConfig) {
|
|
58
|
+
return {
|
|
59
|
+
enableCompanyFeature: bootstrapAppConfig?.enableCompanyFeature ?? false,
|
|
60
|
+
enableEmailVerification: bootstrapAppConfig?.enableEmailVerification ?? true
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
static buildImports() {
|
|
58
64
|
return [
|
|
59
65
|
PassportModule.register({
|
|
60
66
|
defaultStrategy: 'jwt'
|
|
@@ -64,35 +70,40 @@ export class AuthModule {
|
|
|
64
70
|
UtilsModule
|
|
65
71
|
];
|
|
66
72
|
}
|
|
67
|
-
|
|
73
|
+
static buildControllers(includeController, flags) {
|
|
68
74
|
if (!includeController) return [];
|
|
69
75
|
const controllers = [
|
|
70
76
|
AuthenticationController,
|
|
71
77
|
UserController
|
|
72
78
|
];
|
|
73
|
-
if (
|
|
79
|
+
if (flags.enableEmailVerification) {
|
|
80
|
+
controllers.push(EmailVerificationController);
|
|
81
|
+
}
|
|
82
|
+
if (flags.enableCompanyFeature) {
|
|
74
83
|
controllers.push(CompanySelectionController, CompanyController, BranchController, UserPermissionController);
|
|
75
84
|
}
|
|
76
85
|
return controllers;
|
|
77
86
|
}
|
|
78
|
-
|
|
87
|
+
static buildProviders(flags) {
|
|
79
88
|
const providers = [
|
|
80
89
|
AuthConfigService,
|
|
81
90
|
AuthDataSourceProvider,
|
|
82
91
|
JwtStrategy,
|
|
83
92
|
JwtAuthGuard,
|
|
84
93
|
AuthenticationService,
|
|
85
|
-
AuthEmailService,
|
|
86
94
|
SetToken,
|
|
87
95
|
ClearToken,
|
|
88
96
|
UserService
|
|
89
97
|
];
|
|
90
|
-
if (
|
|
98
|
+
if (flags.enableEmailVerification) {
|
|
99
|
+
providers.push(AuthEmailService);
|
|
100
|
+
}
|
|
101
|
+
if (flags.enableCompanyFeature) {
|
|
91
102
|
providers.push(CompanySelectionSessionService, CompanyService, BranchService, UserPermissionService);
|
|
92
103
|
}
|
|
93
104
|
return providers;
|
|
94
105
|
}
|
|
95
|
-
|
|
106
|
+
static buildExports(flags) {
|
|
96
107
|
const exports = [
|
|
97
108
|
PassportModule,
|
|
98
109
|
AUTH_MODULE_OPTIONS,
|
|
@@ -101,15 +112,17 @@ export class AuthModule {
|
|
|
101
112
|
JwtStrategy,
|
|
102
113
|
JwtAuthGuard,
|
|
103
114
|
AuthenticationService,
|
|
104
|
-
AuthEmailService,
|
|
105
115
|
UserService
|
|
106
116
|
];
|
|
107
|
-
if (
|
|
117
|
+
if (flags.enableEmailVerification) {
|
|
118
|
+
exports.push(AuthEmailService);
|
|
119
|
+
}
|
|
120
|
+
if (flags.enableCompanyFeature) {
|
|
108
121
|
exports.push(CompanySelectionSessionService, CompanyService, BranchService, UserPermissionService);
|
|
109
122
|
}
|
|
110
123
|
return exports;
|
|
111
124
|
}
|
|
112
|
-
|
|
125
|
+
static createAsyncProviders(options) {
|
|
113
126
|
const staticOptions = {
|
|
114
127
|
global: options.global,
|
|
115
128
|
includeController: options.includeController,
|
|
@@ -166,15 +179,11 @@ export class AuthModule {
|
|
|
166
179
|
}
|
|
167
180
|
];
|
|
168
181
|
}
|
|
169
|
-
|
|
170
|
-
return
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
UserCompanyPermission
|
|
175
|
-
] : [
|
|
176
|
-
User
|
|
177
|
-
];
|
|
182
|
+
static getEntities(config) {
|
|
183
|
+
return getEntitiesByConfig({
|
|
184
|
+
enableCompanyFeature: config.enableCompanyFeature ?? false,
|
|
185
|
+
enableEmailVerification: config.enableEmailVerification ?? true
|
|
186
|
+
});
|
|
178
187
|
}
|
|
179
188
|
}
|
|
180
189
|
AuthModule = _ts_decorate([
|