@flusys/nestjs-auth 1.0.0-beta → 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.
Files changed (95) hide show
  1. package/README.md +274 -291
  2. package/cjs/config/auth.constants.js +12 -0
  3. package/cjs/controllers/authentication.controller.js +219 -10
  4. package/cjs/controllers/branch.controller.js +44 -1
  5. package/cjs/controllers/company-selection.controller.js +27 -20
  6. package/cjs/controllers/company.controller.js +44 -1
  7. package/cjs/controllers/user-permission.controller.js +40 -25
  8. package/cjs/controllers/user.controller.js +211 -7
  9. package/cjs/dtos/authentication.dto.js +119 -13
  10. package/cjs/dtos/user-permission.dto.js +28 -0
  11. package/cjs/dtos/user.dto.js +19 -4
  12. package/cjs/entities/index.js +5 -1
  13. package/cjs/entities/pending-registration.entity.js +125 -0
  14. package/cjs/entities/user-company-permission.entity.js +0 -6
  15. package/cjs/entities/user-token.entity.js +129 -0
  16. package/cjs/guards/auth-throttler.guard.js +53 -0
  17. package/cjs/interceptors/clear-token.interceptor.js +3 -6
  18. package/cjs/interceptors/set-token.interceptor.js +38 -31
  19. package/cjs/interfaces/auth-email-provider.interface.js +45 -0
  20. package/cjs/interfaces/index.js +2 -0
  21. package/cjs/interfaces/user-enricher.interface.js +4 -0
  22. package/cjs/modules/auth.module.js +8 -20
  23. package/cjs/services/auth-config.service.js +23 -2
  24. package/cjs/services/auth-datasource.provider.js +5 -3
  25. package/cjs/services/auth-email.service.js +471 -0
  26. package/cjs/services/authentication.service.js +169 -77
  27. package/cjs/services/branch.service.js +6 -5
  28. package/cjs/services/company-selection-session.service.js +1 -1
  29. package/cjs/services/index.js +1 -0
  30. package/cjs/services/user-permission.service.js +0 -2
  31. package/cjs/services/user.service.js +213 -34
  32. package/cjs/validators/password.validator.js +45 -0
  33. package/config/auth.constants.d.ts +3 -0
  34. package/controllers/authentication.controller.d.ts +13 -9
  35. package/controllers/company-selection.controller.d.ts +6 -2
  36. package/controllers/user.controller.d.ts +33 -0
  37. package/dtos/authentication.dto.d.ts +21 -3
  38. package/dtos/company-branch.dto.d.ts +0 -1
  39. package/dtos/company.dto.d.ts +0 -1
  40. package/dtos/user-permission.dto.d.ts +4 -0
  41. package/dtos/user.dto.d.ts +1 -2
  42. package/entities/index.d.ts +7 -3
  43. package/entities/pending-registration.entity.d.ts +17 -0
  44. package/entities/user-company-permission.entity.d.ts +0 -2
  45. package/entities/user-token.entity.d.ts +15 -0
  46. package/fesm/config/auth.constants.js +6 -2
  47. package/fesm/controllers/authentication.controller.js +221 -12
  48. package/fesm/controllers/branch.controller.js +45 -2
  49. package/fesm/controllers/company-selection.controller.js +28 -21
  50. package/fesm/controllers/company.controller.js +45 -2
  51. package/fesm/controllers/user-permission.controller.js +41 -26
  52. package/fesm/controllers/user.controller.js +214 -10
  53. package/fesm/dtos/authentication.dto.js +106 -14
  54. package/fesm/dtos/user-permission.dto.js +28 -0
  55. package/fesm/dtos/user.dto.js +20 -5
  56. package/fesm/entities/index.js +7 -1
  57. package/fesm/entities/pending-registration.entity.js +115 -0
  58. package/fesm/entities/user-company-permission.entity.js +0 -6
  59. package/fesm/entities/user-token.entity.js +113 -0
  60. package/fesm/guards/auth-throttler.guard.js +43 -0
  61. package/fesm/interceptors/clear-token.interceptor.js +2 -5
  62. package/fesm/interceptors/set-token.interceptor.js +37 -30
  63. package/fesm/interfaces/auth-email-provider.interface.js +38 -0
  64. package/fesm/interfaces/authentication.interface.js +1 -1
  65. package/fesm/interfaces/index.js +2 -0
  66. package/fesm/interfaces/user-enricher.interface.js +26 -0
  67. package/fesm/modules/auth.module.js +10 -22
  68. package/fesm/services/auth-config.service.js +24 -3
  69. package/fesm/services/auth-datasource.provider.js +6 -4
  70. package/fesm/services/auth-email.service.js +420 -0
  71. package/fesm/services/authentication.service.js +169 -77
  72. package/fesm/services/branch.service.js +6 -5
  73. package/fesm/services/company-selection-session.service.js +1 -1
  74. package/fesm/services/index.js +1 -0
  75. package/fesm/services/user-permission.service.js +1 -3
  76. package/fesm/services/user.service.js +215 -36
  77. package/fesm/validators/password.validator.js +48 -0
  78. package/guards/auth-throttler.guard.d.ts +7 -0
  79. package/interceptors/set-token.interceptor.d.ts +1 -0
  80. package/interfaces/auth-email-provider.interface.d.ts +6 -0
  81. package/interfaces/auth-module-options.interface.d.ts +4 -1
  82. package/interfaces/authentication.interface.d.ts +14 -0
  83. package/interfaces/index.d.ts +2 -0
  84. package/interfaces/user-enricher.interface.d.ts +64 -0
  85. package/interfaces/user.interface.d.ts +1 -0
  86. package/modules/auth.module.d.ts +0 -1
  87. package/package.json +4 -4
  88. package/services/auth-config.service.d.ts +5 -1
  89. package/services/auth-email.service.d.ts +51 -0
  90. package/services/authentication.service.d.ts +16 -11
  91. package/services/company-selection-session.service.d.ts +1 -1
  92. package/services/index.d.ts +1 -0
  93. package/services/user-permission.service.d.ts +0 -1
  94. package/services/user.service.d.ts +19 -3
  95. package/validators/password.validator.d.ts +10 -0
@@ -25,14 +25,13 @@ function _ts_param(paramIndex, decorator) {
25
25
  decorator(target, key, paramIndex);
26
26
  };
27
27
  }
28
- import { Body, Controller, Get, Inject, Post, Query, UseGuards } from '@nestjs/common';
29
- import { ApiBearerAuth, ApiBody, ApiOperation, ApiQuery, ApiResponse, ApiTags } from '@nestjs/swagger';
30
- import { JwtAuthGuard } from '@flusys/nestjs-shared/guards';
28
+ import { Body, Controller, Inject, Post, UseGuards } from '@nestjs/common';
29
+ import { ApiBearerAuth, ApiBody, ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
30
+ import { JwtAuthGuard, RequirePermission, USER_PERMISSIONS } from '@flusys/nestjs-shared';
31
31
  import { AssignUserCompanyDto, AssignUserBranchDto, UserCompaniesResponseDto, UserBranchesResponseDto } from '../dtos/user-permission.dto';
32
32
  import { UserPermissionService } from '../services/user-permission.service';
33
33
  export class UserPermissionController {
34
- // User-Company Permissions
35
- /** Batch assign/revoke user-company permissions */ async assignUserCompany(dto) {
34
+ async assignUserCompany(dto) {
36
35
  let addedCount = 0;
37
36
  let removedCount = 0;
38
37
  for (const item of dto.items){
@@ -52,9 +51,8 @@ export class UserPermissionController {
52
51
  message: `Processed ${addedCount} additions and ${removedCount} removals`
53
52
  };
54
53
  }
55
- /** Get user's companies */ async getUserCompanies(userId) {
54
+ async getUserCompanies(userId) {
56
55
  const permissions = await this.userPermissionService.findUserCompanies(userId);
57
- // Map to DTO format with populated company details
58
56
  const data = permissions.map((permission)=>({
59
57
  id: permission.id,
60
58
  userId: permission.userId,
@@ -63,11 +61,12 @@ export class UserPermissionController {
63
61
  companySlug: permission.company?.slug || ''
64
62
  }));
65
63
  return {
64
+ success: true,
65
+ message: 'User companies retrieved successfully',
66
66
  data
67
67
  };
68
68
  }
69
- // User-Branch Permissions
70
- /** Batch assign/revoke user-branch permissions */ async assignUserBranch(dto) {
69
+ async assignUserBranch(dto) {
71
70
  let addedCount = 0;
72
71
  let removedCount = 0;
73
72
  for (const item of dto.items){
@@ -87,9 +86,8 @@ export class UserPermissionController {
87
86
  message: `Processed ${addedCount} additions and ${removedCount} removals`
88
87
  };
89
88
  }
90
- /** Get user's branches */ async getUserBranches(userId) {
89
+ async getUserBranches(userId) {
91
90
  const permissions = await this.userPermissionService.findUserBranches(userId);
92
- // Map to DTO format with populated branch details
93
91
  const data = permissions.map((permission)=>({
94
92
  id: permission.id,
95
93
  userId: permission.userId,
@@ -99,10 +97,11 @@ export class UserPermissionController {
99
97
  companyId: permission.branch?.companyId || ''
100
98
  }));
101
99
  return {
100
+ success: true,
101
+ message: 'User branches retrieved successfully',
102
102
  data
103
103
  };
104
104
  }
105
- // NOTE: @Inject() required for bundled code - type metadata may be lost during esbuild
106
105
  constructor(userPermissionService){
107
106
  _define_property(this, "userPermissionService", void 0);
108
107
  this.userPermissionService = userPermissionService;
@@ -110,6 +109,7 @@ export class UserPermissionController {
110
109
  }
111
110
  _ts_decorate([
112
111
  Post('user-company/assign'),
112
+ RequirePermission(USER_PERMISSIONS.UPDATE),
113
113
  ApiOperation({
114
114
  summary: 'Batch assign/revoke user-company permissions',
115
115
  description: `
@@ -164,22 +164,29 @@ Batch operation to assign or revoke user permissions to companies.
164
164
  _ts_metadata("design:returntype", Promise)
165
165
  ], UserPermissionController.prototype, "assignUserCompany", null);
166
166
  _ts_decorate([
167
- Get('user-company'),
167
+ Post('get-user-company'),
168
+ RequirePermission(USER_PERMISSIONS.READ),
168
169
  ApiOperation({
169
170
  summary: 'Get user companies',
170
171
  description: 'Returns all companies the user has access to.'
171
172
  }),
172
- ApiQuery({
173
- name: 'userId',
174
- required: true,
175
- description: 'User ID to get companies for',
176
- example: '550e8400-e29b-41d4-a716-446655440000'
173
+ ApiBody({
174
+ schema: {
175
+ properties: {
176
+ userId: {
177
+ type: 'string'
178
+ }
179
+ },
180
+ required: [
181
+ 'userId'
182
+ ]
183
+ }
177
184
  }),
178
185
  ApiResponse({
179
186
  status: 200,
180
187
  type: UserCompaniesResponseDto
181
188
  }),
182
- _ts_param(0, Query('userId')),
189
+ _ts_param(0, Body('userId')),
183
190
  _ts_metadata("design:type", Function),
184
191
  _ts_metadata("design:paramtypes", [
185
192
  String
@@ -188,6 +195,7 @@ _ts_decorate([
188
195
  ], UserPermissionController.prototype, "getUserCompanies", null);
189
196
  _ts_decorate([
190
197
  Post('user-branch/assign'),
198
+ RequirePermission(USER_PERMISSIONS.UPDATE),
191
199
  ApiOperation({
192
200
  summary: 'Batch assign/revoke user-branch permissions',
193
201
  description: `
@@ -242,22 +250,29 @@ Batch operation to assign or revoke user permissions to branches.
242
250
  _ts_metadata("design:returntype", Promise)
243
251
  ], UserPermissionController.prototype, "assignUserBranch", null);
244
252
  _ts_decorate([
245
- Get('user-branch'),
253
+ Post('get-user-branch'),
254
+ RequirePermission(USER_PERMISSIONS.READ),
246
255
  ApiOperation({
247
256
  summary: 'Get user branches',
248
257
  description: 'Returns all branches the user has access to.'
249
258
  }),
250
- ApiQuery({
251
- name: 'userId',
252
- required: true,
253
- description: 'User ID to get branches for',
254
- example: '550e8400-e29b-41d4-a716-446655440000'
259
+ ApiBody({
260
+ schema: {
261
+ properties: {
262
+ userId: {
263
+ type: 'string'
264
+ }
265
+ },
266
+ required: [
267
+ 'userId'
268
+ ]
269
+ }
255
270
  }),
256
271
  ApiResponse({
257
272
  status: 200,
258
273
  type: UserBranchesResponseDto
259
274
  }),
260
- _ts_param(0, Query('userId')),
275
+ _ts_param(0, Body('userId')),
261
276
  _ts_metadata("design:type", Function),
262
277
  _ts_metadata("design:paramtypes", [
263
278
  String
@@ -25,51 +25,160 @@ function _ts_param(paramIndex, decorator) {
25
25
  decorator(target, key, paramIndex);
26
26
  };
27
27
  }
28
- import { createApiController } from '@flusys/nestjs-shared/classes';
29
- import { CurrentUser } from '@flusys/nestjs-shared/decorators';
28
+ import { createApiController, USER_PERMISSIONS } from '@flusys/nestjs-shared/classes';
29
+ import { CurrentUser, RequirePermission } from '@flusys/nestjs-shared/decorators';
30
30
  import { JwtAuthGuard } from '@flusys/nestjs-shared/guards';
31
31
  import { ILoggedUserInfo } from '@flusys/nestjs-shared/interfaces';
32
- import { Body, Controller, Inject, Param, Post, Put, UseGuards } from '@nestjs/common';
32
+ import { Body, Controller, Inject, Param, Post, UseGuards } from '@nestjs/common';
33
33
  import { ApiBearerAuth, ApiBody, ApiOperation, ApiParam, ApiTags } from '@nestjs/swagger';
34
34
  import { CreateUserDto, UpdateUserDto, UserResponseDto } from '../dtos/user.dto';
35
35
  import { UserService } from '../services/user.service';
36
36
  export class UserController extends createApiController(CreateUserDto, UpdateUserDto, UserResponseDto, {
37
- security: 'jwt'
37
+ security: {
38
+ insert: {
39
+ level: 'permission',
40
+ permissions: [
41
+ USER_PERMISSIONS.CREATE
42
+ ]
43
+ },
44
+ insertMany: {
45
+ level: 'permission',
46
+ permissions: [
47
+ USER_PERMISSIONS.CREATE
48
+ ]
49
+ },
50
+ getById: {
51
+ level: 'permission',
52
+ permissions: [
53
+ USER_PERMISSIONS.READ
54
+ ]
55
+ },
56
+ getAll: {
57
+ level: 'permission',
58
+ permissions: [
59
+ USER_PERMISSIONS.READ
60
+ ]
61
+ },
62
+ update: {
63
+ level: 'permission',
64
+ permissions: [
65
+ USER_PERMISSIONS.UPDATE
66
+ ]
67
+ },
68
+ updateMany: {
69
+ level: 'permission',
70
+ permissions: [
71
+ USER_PERMISSIONS.UPDATE
72
+ ]
73
+ },
74
+ delete: {
75
+ level: 'permission',
76
+ permissions: [
77
+ USER_PERMISSIONS.DELETE
78
+ ]
79
+ }
80
+ }
38
81
  }) {
39
- // Custom Endpoints
40
- /** Verify user email */ async verifyEmail(id) {
82
+ async getProfileWithExtras(id, user) {
83
+ const data = await this.service.getProfileWithExtras(id, user);
84
+ return {
85
+ success: true,
86
+ data
87
+ };
88
+ }
89
+ async verifyEmail(id) {
41
90
  await this.service.verifyEmail(id);
42
91
  return {
92
+ success: true,
43
93
  message: 'Email verified successfully'
44
94
  };
45
95
  }
46
- /** Verify user phone */ async verifyPhone(id) {
96
+ async verifyPhone(id) {
47
97
  await this.service.verifyPhone(id);
48
98
  return {
99
+ success: true,
49
100
  message: 'Phone verified successfully'
50
101
  };
51
102
  }
52
- /** Update user active status. When company feature enabled, updates permission isActive for logged user's company. */ async updateStatus(id, isActive, user) {
103
+ async updateStatus(id, isActive, user) {
53
104
  await this.service.updateStatus(id, isActive, user);
54
105
  return {
106
+ success: true,
55
107
  message: 'Status updated successfully'
56
108
  };
57
109
  }
58
- /** Update user profile */ async profile(dto, user) {
110
+ async profile(dto, user) {
59
111
  const data = await this.service.profile(dto, user);
60
112
  return {
113
+ success: true,
61
114
  message: 'Profile updated successfully',
62
115
  data
63
116
  };
64
117
  }
118
+ async getProfileSections() {
119
+ const sections = await this.service.getProfileSections();
120
+ return {
121
+ success: true,
122
+ message: 'Profile sections retrieved successfully',
123
+ data: sections
124
+ };
125
+ }
126
+ async getProfileSectionData(id, sectionId, user) {
127
+ const data = await this.service.getProfileSectionData(id, sectionId, user);
128
+ return {
129
+ success: true,
130
+ message: 'Profile section data retrieved successfully',
131
+ data
132
+ };
133
+ }
134
+ async updateProfileSection(id, sectionId, data, user) {
135
+ await this.service.updateProfileSection(id, sectionId, data, user);
136
+ return {
137
+ success: true,
138
+ message: 'Section updated successfully'
139
+ };
140
+ }
141
+ async getProfileCompletion(id, user) {
142
+ const percentage = await this.service.getProfileCompletion(id, user);
143
+ return {
144
+ success: true,
145
+ message: 'Profile completion retrieved successfully',
146
+ data: {
147
+ completionPercentage: percentage
148
+ }
149
+ };
150
+ }
65
151
  constructor(service){
66
152
  super(service), _define_property(this, "service", void 0), this.service = service;
67
153
  }
68
154
  }
155
+ _ts_decorate([
156
+ Post(':id/profile-extras'),
157
+ UseGuards(JwtAuthGuard),
158
+ ApiBearerAuth(),
159
+ RequirePermission(USER_PERMISSIONS.READ),
160
+ ApiOperation({
161
+ summary: 'Get user profile with extras',
162
+ description: 'Returns user profile along with extra data (roles, permissions, etc.) if UserEnricher is provided.'
163
+ }),
164
+ ApiParam({
165
+ name: 'id',
166
+ description: 'User ID'
167
+ }),
168
+ _ts_param(0, Param('id')),
169
+ _ts_param(1, CurrentUser()),
170
+ _ts_metadata("design:type", Function),
171
+ _ts_metadata("design:paramtypes", [
172
+ String,
173
+ typeof ILoggedUserInfo === "undefined" ? Object : ILoggedUserInfo
174
+ ]),
175
+ _ts_metadata("design:returntype", Promise)
176
+ ], UserController.prototype, "getProfileWithExtras", null);
69
177
  _ts_decorate([
70
178
  Post(':id/verify-email'),
71
179
  UseGuards(JwtAuthGuard),
72
180
  ApiBearerAuth(),
181
+ RequirePermission(USER_PERMISSIONS.UPDATE),
73
182
  ApiOperation({
74
183
  summary: 'Verify user email'
75
184
  }),
@@ -88,6 +197,7 @@ _ts_decorate([
88
197
  Post(':id/verify-phone'),
89
198
  UseGuards(JwtAuthGuard),
90
199
  ApiBearerAuth(),
200
+ RequirePermission(USER_PERMISSIONS.UPDATE),
91
201
  ApiOperation({
92
202
  summary: 'Verify user phone'
93
203
  }),
@@ -103,9 +213,10 @@ _ts_decorate([
103
213
  _ts_metadata("design:returntype", Promise)
104
214
  ], UserController.prototype, "verifyPhone", null);
105
215
  _ts_decorate([
106
- Put(':id/status'),
216
+ Post(':id/status'),
107
217
  UseGuards(JwtAuthGuard),
108
218
  ApiBearerAuth(),
219
+ RequirePermission(USER_PERMISSIONS.UPDATE),
109
220
  ApiOperation({
110
221
  summary: 'Update user active status',
111
222
  description: 'Updates user active status. When company feature is enabled, updates the status for the current company context.'
@@ -151,6 +262,99 @@ _ts_decorate([
151
262
  ]),
152
263
  _ts_metadata("design:returntype", Promise)
153
264
  ], UserController.prototype, "profile", null);
265
+ _ts_decorate([
266
+ Post('profile-sections'),
267
+ UseGuards(JwtAuthGuard),
268
+ ApiBearerAuth(),
269
+ RequirePermission(USER_PERMISSIONS.READ),
270
+ ApiOperation({
271
+ summary: 'Get profile section definitions',
272
+ description: 'Returns available profile sections for multi-step profile (if enricher configured).'
273
+ }),
274
+ _ts_metadata("design:type", Function),
275
+ _ts_metadata("design:paramtypes", []),
276
+ _ts_metadata("design:returntype", Promise)
277
+ ], UserController.prototype, "getProfileSections", null);
278
+ _ts_decorate([
279
+ Post(':id/profile-section/:sectionId'),
280
+ UseGuards(JwtAuthGuard),
281
+ ApiBearerAuth(),
282
+ RequirePermission(USER_PERMISSIONS.READ),
283
+ ApiOperation({
284
+ summary: 'Get profile section data',
285
+ description: 'Returns data for a specific profile section.'
286
+ }),
287
+ ApiParam({
288
+ name: 'id',
289
+ description: 'User ID'
290
+ }),
291
+ ApiParam({
292
+ name: 'sectionId',
293
+ description: 'Section identifier'
294
+ }),
295
+ _ts_param(0, Param('id')),
296
+ _ts_param(1, Param('sectionId')),
297
+ _ts_param(2, CurrentUser()),
298
+ _ts_metadata("design:type", Function),
299
+ _ts_metadata("design:paramtypes", [
300
+ String,
301
+ String,
302
+ typeof ILoggedUserInfo === "undefined" ? Object : ILoggedUserInfo
303
+ ]),
304
+ _ts_metadata("design:returntype", Promise)
305
+ ], UserController.prototype, "getProfileSectionData", null);
306
+ _ts_decorate([
307
+ Post(':id/profile-section/:sectionId/update'),
308
+ UseGuards(JwtAuthGuard),
309
+ ApiBearerAuth(),
310
+ RequirePermission(USER_PERMISSIONS.UPDATE),
311
+ ApiOperation({
312
+ summary: 'Update profile section',
313
+ description: 'Updates a specific profile section data.'
314
+ }),
315
+ ApiParam({
316
+ name: 'id',
317
+ description: 'User ID'
318
+ }),
319
+ ApiParam({
320
+ name: 'sectionId',
321
+ description: 'Section identifier'
322
+ }),
323
+ _ts_param(0, Param('id')),
324
+ _ts_param(1, Param('sectionId')),
325
+ _ts_param(2, Body()),
326
+ _ts_param(3, CurrentUser()),
327
+ _ts_metadata("design:type", Function),
328
+ _ts_metadata("design:paramtypes", [
329
+ String,
330
+ String,
331
+ typeof Record === "undefined" ? Object : Record,
332
+ typeof ILoggedUserInfo === "undefined" ? Object : ILoggedUserInfo
333
+ ]),
334
+ _ts_metadata("design:returntype", Promise)
335
+ ], UserController.prototype, "updateProfileSection", null);
336
+ _ts_decorate([
337
+ Post(':id/profile-completion'),
338
+ UseGuards(JwtAuthGuard),
339
+ ApiBearerAuth(),
340
+ RequirePermission(USER_PERMISSIONS.READ),
341
+ ApiOperation({
342
+ summary: 'Get profile completion percentage',
343
+ description: 'Returns overall profile completion percentage.'
344
+ }),
345
+ ApiParam({
346
+ name: 'id',
347
+ description: 'User ID'
348
+ }),
349
+ _ts_param(0, Param('id')),
350
+ _ts_param(1, CurrentUser()),
351
+ _ts_metadata("design:type", Function),
352
+ _ts_metadata("design:paramtypes", [
353
+ String,
354
+ typeof ILoggedUserInfo === "undefined" ? Object : ILoggedUserInfo
355
+ ]),
356
+ _ts_metadata("design:returntype", Promise)
357
+ ], UserController.prototype, "getProfileCompletion", null);
154
358
  UserController = _ts_decorate([
155
359
  ApiTags('Users'),
156
360
  Controller('administration/users'),
@@ -21,7 +21,8 @@ function _ts_metadata(k, v) {
21
21
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
22
22
  }
23
23
  import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
24
- import { IsEmail, IsNotEmpty, IsOptional, IsString, IsUUID, MaxLength, MinLength, ValidateIf } from 'class-validator';
24
+ import { IsEmail, IsNotEmpty, IsOptional, IsString, IsUUID, MaxLength, ValidateIf } from 'class-validator';
25
+ import { IsStrongPassword } from '../validators/password.validator';
25
26
  // Request DTOs
26
27
  /** Login Request DTO */ export class LoginDto {
27
28
  constructor(){
@@ -40,12 +41,12 @@ _ts_decorate([
40
41
  ], LoginDto.prototype, "email", void 0);
41
42
  _ts_decorate([
42
43
  ApiProperty({
43
- example: '123456',
44
- description: 'User password (min 6 chars)'
44
+ example: 'SecureP@ss1',
45
+ description: 'User password'
45
46
  }),
46
47
  IsString(),
47
48
  IsNotEmpty(),
48
- MinLength(6),
49
+ MaxLength(128),
49
50
  _ts_metadata("design:type", String)
50
51
  ], LoginDto.prototype, "password", void 0);
51
52
  /** Registration Request DTO - Supports simple and company-based registration */ export class RegistrationDto {
@@ -84,13 +85,13 @@ _ts_decorate([
84
85
  ], RegistrationDto.prototype, "email", void 0);
85
86
  _ts_decorate([
86
87
  ApiProperty({
87
- example: 'strongPassword123',
88
- description: 'Password (min 6 chars)'
88
+ example: 'StrongP@ss123',
89
+ description: 'Password (min 8 chars, requires uppercase, lowercase, number, special char)'
89
90
  }),
90
91
  IsNotEmpty(),
91
92
  IsString(),
92
- MinLength(6),
93
- MaxLength(60),
93
+ IsStrongPassword(),
94
+ MaxLength(128),
94
95
  _ts_metadata("design:type", String)
95
96
  ], RegistrationDto.prototype, "password", void 0);
96
97
  _ts_decorate([
@@ -151,6 +152,7 @@ _ts_decorate([
151
152
  }),
152
153
  IsOptional(),
153
154
  IsString(),
155
+ MaxLength(500),
154
156
  _ts_metadata("design:type", String)
155
157
  ], RegistrationDto.prototype, "newCompanyAddress", void 0);
156
158
  /** Refresh Token Request DTO - refreshToken optional in body (browsers use HTTP-only cookie) */ export class RefreshTokenDto {
@@ -180,16 +182,17 @@ _ts_decorate([
180
182
  }),
181
183
  IsString(),
182
184
  IsNotEmpty(),
185
+ MaxLength(128),
183
186
  _ts_metadata("design:type", String)
184
187
  ], ChangePasswordDto.prototype, "currentPassword", void 0);
185
188
  _ts_decorate([
186
189
  ApiProperty({
187
- example: 'newPassword456',
188
- description: 'New password (min 6 chars)'
190
+ example: 'NewP@ssword456',
191
+ description: 'New password (min 8 chars, requires uppercase, lowercase, number, special char)'
189
192
  }),
190
193
  IsString(),
191
194
  IsNotEmpty(),
192
- MinLength(6),
195
+ IsStrongPassword(),
193
196
  _ts_metadata("design:type", String)
194
197
  ], ChangePasswordDto.prototype, "newPassword", void 0);
195
198
  /** Select Company & Branch Request DTO - Used after login when user needs to select company and branch */ export class SelectDto {
@@ -503,16 +506,17 @@ _ts_decorate([
503
506
  _define_property(this, "company", void 0);
504
507
  _define_property(this, "branch", void 0);
505
508
  _define_property(this, "companyFeatureEnabled", void 0);
509
+ _define_property(this, "requiresEmailVerification", void 0);
506
510
  }
507
511
  }
508
512
  _ts_decorate([
509
- ApiProperty({
513
+ ApiPropertyOptional({
510
514
  example: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...'
511
515
  }),
512
516
  _ts_metadata("design:type", String)
513
517
  ], RegistrationResponseDto.prototype, "accessToken", void 0);
514
518
  _ts_decorate([
515
- ApiProperty({
519
+ ApiPropertyOptional({
516
520
  example: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...'
517
521
  }),
518
522
  _ts_metadata("design:type", String)
@@ -539,12 +543,19 @@ _ts_decorate([
539
543
  _ts_metadata("design:type", typeof BranchInfoDto === "undefined" ? Object : BranchInfoDto)
540
544
  ], RegistrationResponseDto.prototype, "branch", void 0);
541
545
  _ts_decorate([
542
- ApiProperty({
546
+ ApiPropertyOptional({
543
547
  example: true,
544
548
  description: 'Whether company feature is enabled'
545
549
  }),
546
550
  _ts_metadata("design:type", Boolean)
547
551
  ], RegistrationResponseDto.prototype, "companyFeatureEnabled", void 0);
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);
548
559
  /** Me Response DTO - Returned by GET /auth/me (user data only, no tokens) */ export class MeResponseDto {
549
560
  constructor(){
550
561
  _define_property(this, "user", void 0);
@@ -619,3 +630,84 @@ _ts_decorate([
619
630
  }),
620
631
  _ts_metadata("design:type", Array)
621
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',