@flusys/nestjs-auth 4.1.1 → 5.0.1

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 (51) hide show
  1. package/README.md +151 -719
  2. package/cjs/config/message-keys.js +6 -61
  3. package/cjs/controllers/authentication.controller.js +113 -87
  4. package/cjs/controllers/company-selection.controller.js +24 -4
  5. package/cjs/controllers/email-verification.controller.js +12 -13
  6. package/cjs/docs/auth-swagger.config.js +143 -106
  7. package/cjs/dtos/authentication.dto.js +0 -15
  8. package/cjs/entities/company-branch.entity.js +1 -1
  9. package/cjs/entities/company.entity.js +2 -2
  10. package/cjs/entities/pending-registration.entity.js +3 -2
  11. package/cjs/entities/user-company-permission.entity.js +0 -8
  12. package/cjs/entities/user-token.entity.js +0 -9
  13. package/cjs/interceptors/set-token.interceptor.js +15 -7
  14. package/cjs/services/auth-config.service.js +0 -4
  15. package/cjs/services/auth-email.service.js +8 -31
  16. package/cjs/services/authentication.service.js +99 -15
  17. package/cjs/services/user-permission.service.js +6 -8
  18. package/cjs/services/user.service.js +16 -13
  19. package/cjs/strategies/jwt.strategy.js +10 -3
  20. package/config/message-keys.d.ts +5 -153
  21. package/controllers/authentication.controller.d.ts +6 -7
  22. package/controllers/company-selection.controller.d.ts +3 -2
  23. package/controllers/email-verification.controller.d.ts +6 -2
  24. package/dtos/authentication.dto.d.ts +0 -2
  25. package/entities/user-company-permission.entity.d.ts +0 -1
  26. package/entities/user-token.entity.d.ts +0 -1
  27. package/fesm/config/message-keys.js +6 -53
  28. package/fesm/controllers/authentication.controller.js +115 -90
  29. package/fesm/controllers/company-selection.controller.js +25 -5
  30. package/fesm/controllers/email-verification.controller.js +13 -14
  31. package/fesm/docs/auth-swagger.config.js +146 -113
  32. package/fesm/dtos/authentication.dto.js +0 -15
  33. package/fesm/entities/company-branch.entity.js +2 -2
  34. package/fesm/entities/company.entity.js +3 -3
  35. package/fesm/entities/pending-registration.entity.js +3 -2
  36. package/fesm/entities/user-company-permission.entity.js +0 -8
  37. package/fesm/entities/user-token.entity.js +0 -9
  38. package/fesm/interceptors/set-token.interceptor.js +15 -7
  39. package/fesm/services/auth-config.service.js +0 -4
  40. package/fesm/services/auth-email.service.js +8 -32
  41. package/fesm/services/authentication.service.js +100 -17
  42. package/fesm/services/user-permission.service.js +6 -8
  43. package/fesm/services/user.service.js +16 -14
  44. package/fesm/strategies/jwt.strategy.js +10 -3
  45. package/interfaces/auth-module-options.interface.d.ts +0 -1
  46. package/package.json +4 -4
  47. package/services/auth-config.service.d.ts +0 -1
  48. package/services/auth-email.service.d.ts +0 -4
  49. package/services/authentication.service.d.ts +1 -1
  50. package/services/user-permission.service.d.ts +1 -1
  51. package/services/user.service.d.ts +5 -5
@@ -1,33 +1,14 @@
1
- /** Tags used for company-related APIs (excluded when company feature is disabled) */ const COMPANY_RELATED_TAGS = [
1
+ // ============================================================================
2
+ // Company feature exclusions
3
+ // ============================================================================
4
+ const COMPANY_RELATED_TAGS = [
2
5
  'Companies',
3
6
  'Branches',
4
7
  'User Permissions',
5
8
  'Company Selection'
6
9
  ];
7
- /** Examples to exclude when company feature is disabled */ const COMPANY_EXAMPLE_EXCLUSIONS = [
8
- {
9
- pathPattern: '/auth/login',
10
- method: 'post',
11
- examples: [
12
- 'loginSuccessWithCompany',
13
- 'companySelection'
14
- ]
15
- }
16
- ];
17
- /**
18
- * Schema properties to exclude when company feature is disabled
19
- *
20
- * This list controls which DTO properties are hidden from Swagger documentation
21
- * when bootstrapConfig.enableCompanyFeature = false
22
- *
23
- * **Documentation:**
24
- * - Usage: See FLUSYS_NEST/docs/AUTH-GUIDE.md "Swagger Schema Behavior" section
25
- * - Mechanism: See FLUSYS_NEST/docs/CORE-GUIDE.md "excludeSchemaProperties" section
26
- *
27
- * @see setupSwaggerDocs in @flusys/nestjs-core/docs
28
- * @see ISchemaPropertyExclusion interface
29
- */ const COMPANY_SCHEMA_EXCLUSIONS = [
30
- // ===== Authentication Request DTOs =====
10
+ const COMPANY_SCHEMA_EXCLUSIONS = [
11
+ // Request DTOs
31
12
  {
32
13
  schemaName: 'RegistrationDto',
33
14
  properties: [
@@ -53,7 +34,7 @@
53
34
  'branchId'
54
35
  ]
55
36
  },
56
- // ===== Authentication Response DTOs =====
37
+ // Response DTOs
57
38
  {
58
39
  schemaName: 'RegistrationResponseDto',
59
40
  properties: [
@@ -75,7 +56,7 @@
75
56
  'branch'
76
57
  ]
77
58
  },
78
- // ===== Nested/Helper DTOs (completely excluded) =====
59
+ // Nested helper DTOs
79
60
  {
80
61
  schemaName: 'CompanyInfoDto',
81
62
  properties: [
@@ -123,7 +104,7 @@
123
104
  'companies'
124
105
  ]
125
106
  },
126
- // ===== Company Management DTOs =====
107
+ // Company management DTOs
127
108
  {
128
109
  schemaName: 'CreateCompanyDto',
129
110
  properties: [
@@ -177,7 +158,7 @@
177
158
  'updatedAt'
178
159
  ]
179
160
  },
180
- // ===== Branch Management DTOs =====
161
+ // Branch management DTOs
181
162
  {
182
163
  schemaName: 'CreateCompanyBranchDto',
183
164
  properties: [
@@ -231,7 +212,7 @@
231
212
  'updatedAt'
232
213
  ]
233
214
  },
234
- // ===== User Permission DTOs =====
215
+ // User permission DTOs
235
216
  {
236
217
  schemaName: 'UserCompanyPermissionDto',
237
218
  properties: [
@@ -287,127 +268,179 @@
287
268
  ]
288
269
  }
289
270
  ];
290
- /**
291
- * Auth Module Swagger Configuration
292
- * Use this with setupSwaggerDocs() from @flusys/nestjs-core
293
- * Note: modules not specified to include ALL controllers from the app
294
- *
295
- * @param bootstrapConfig - Bootstrap configuration to determine feature visibility
296
- * @returns Swagger configuration with appropriate excludeTags based on enableCompanyFeature
297
- */ export function authSwaggerConfig(bootstrapConfig) {
298
- const enableCompanyFeature = bootstrapConfig?.enableCompanyFeature ?? true;
299
- // Exclude company-related tags when company feature is disabled
300
- const excludeTags = enableCompanyFeature ? [] : COMPANY_RELATED_TAGS;
301
- return {
302
- title: 'Auth API',
303
- description: enableCompanyFeature ? `
304
- ## Authentication API
305
-
306
- Handles user authentication, registration, and company/branch management.
307
-
308
- ### Features
309
- - User registration (with optional company assignment)
310
- - Login with email/password
311
- - JWT token-based authentication
312
- - Company/Branch selection flow (when multi-company enabled)
313
- - Token refresh
314
- - Password change
315
-
271
+ const COMPANY_EXAMPLE_EXCLUSIONS = [
272
+ {
273
+ pathPattern: '/auth/login',
274
+ method: 'post',
275
+ examples: [
276
+ 'loginSuccessWithCompany',
277
+ 'companySelection'
278
+ ]
279
+ }
280
+ ];
281
+ // ============================================================================
282
+ // Email verification exclusions
283
+ // ============================================================================
284
+ const EMAIL_VERIFICATION_PATHS = [
285
+ '/auth/forgot-password',
286
+ '/auth/reset-password',
287
+ '/auth/resend-verification',
288
+ '/auth/verify-email'
289
+ ];
290
+ const EMAIL_VERIFICATION_SCHEMA_EXCLUSIONS = [
291
+ {
292
+ schemaName: 'RegistrationResponseDto',
293
+ properties: [
294
+ 'requiresEmailVerification'
295
+ ]
296
+ },
297
+ {
298
+ schemaName: 'LoginResponseRequiresEmailVerificationDto',
299
+ properties: [
300
+ 'requiresEmailVerification',
301
+ 'email'
302
+ ]
303
+ }
304
+ ];
305
+ const EMAIL_VERIFICATION_EXAMPLE_EXCLUSIONS = [
306
+ {
307
+ pathPattern: '/auth/login',
308
+ method: 'post',
309
+ examples: [
310
+ 'emailVerification'
311
+ ]
312
+ }
313
+ ];
314
+ // ============================================================================
315
+ // Description builder
316
+ // ============================================================================
317
+ function buildDescription(enableCompanyFeature, enableEmailVerification, isMultiTenant) {
318
+ const multiTenantNote = isMultiTenant ? `\n> **Multi-Tenant Mode**: Include \`x-tenant-id\` header to target a specific tenant database.\n` : '';
319
+ const features = [
320
+ '- User registration',
321
+ '- Login with email/password',
322
+ '- JWT token-based authentication',
323
+ ...enableEmailVerification ? [
324
+ '- Email verification',
325
+ '- Forgot/reset password'
326
+ ] : [],
327
+ ...enableCompanyFeature ? [
328
+ '- Company/Branch selection flow (multi-company enabled)'
329
+ ] : [],
330
+ '- Token refresh',
331
+ '- Password change'
332
+ ].join('\n');
333
+ const loginFlowSection = enableCompanyFeature ? `
316
334
  ### Authentication Flow
317
335
 
318
- #### Simple Login (Company feature disabled)
319
- \`\`\`
320
- POST /auth/login → { accessToken, refreshToken, user }
321
- \`\`\`
322
-
323
- #### Company-Based Login (Company feature enabled)
324
-
325
- **Case 1: Single company, single branch**
336
+ #### Simple Login (single company/branch)
326
337
  \`\`\`
327
338
  POST /auth/login → { accessToken, refreshToken, user, company, branch }
328
339
  \`\`\`
329
340
 
330
- **Case 2: Multiple companies or branches**
341
+ #### Multi-Company Login (multiple companies or branches)
331
342
  \`\`\`
332
343
  POST /auth/login → { requiresSelection: true, sessionId, companies }
333
344
  POST /auth/select → { accessToken, refreshToken, user, company, branch }
334
345
  \`\`\`
335
-
346
+ ${enableEmailVerification ? `
347
+ #### Email Verification Required
348
+ \`\`\`
349
+ POST /auth/login → { requiresEmailVerification: true, email }
350
+ POST /auth/verify-email → { accessToken, refreshToken, user }
351
+ \`\`\`
352
+ ` : ''}
336
353
  ### Company/Branch Selection Endpoints
337
354
  - \`POST /auth/select\` - Complete login by selecting company and branch
338
355
  - \`POST /auth/switch-company\` - Switch to different company/branch while logged in
339
- - \`GET /auth/companies\` - Get user's available companies
340
- - \`GET /auth/companies/:companyId/branches\` - Get branches for a company
341
-
356
+ ` : `
357
+ ### Authentication Flow
358
+ \`\`\`
359
+ POST /auth/login → { accessToken, refreshToken, user }
360
+ \`\`\`
361
+ ${enableEmailVerification ? `
362
+ #### Email Verification Required
363
+ \`\`\`
364
+ POST /auth/login → { requiresEmailVerification: true, email }
365
+ POST /auth/verify-email → { accessToken, refreshToken, user }
366
+ \`\`\`
367
+ ` : ''}`;
368
+ const emailVerificationSection = enableEmailVerification ? `
369
+ ### Email Verification Endpoints
370
+ - \`POST /auth/forgot-password\` - Request password reset email
371
+ - \`POST /auth/reset-password\` - Reset password using token
372
+ - \`POST /auth/resend-verification\` - Resend verification email
373
+ - \`POST /auth/verify-email\` - Verify email using token
374
+ ` : '';
375
+ const administrationSection = enableCompanyFeature ? `
342
376
  ### Administration Endpoints
343
377
  - \`POST /administration/users/*\` - User management
344
378
  - \`POST /administration/company/*\` - Company management
345
379
  - \`POST /administration/branch/*\` - Branch management
346
380
  - \`POST /administration/user-permissions/*\` - User permission management
347
-
381
+ ` : `
382
+ ### Administration Endpoints
383
+ - \`POST /administration/users/*\` - User management
384
+ `;
385
+ const registrationSection = enableCompanyFeature ? `
348
386
  ### Registration Flow
349
387
 
350
388
  **Simple registration:**
351
389
  \`\`\`json
352
- {
353
- "name": "John Doe",
354
- "email": "john@example.com",
355
- "password": "password123"
356
- }
390
+ { "name": "John Doe", "email": "john@example.com", "password": "password123" }
357
391
  \`\`\`
358
392
 
359
393
  **Join existing company:**
360
394
  \`\`\`json
361
- {
362
- "name": "John Doe",
363
- "email": "john@example.com",
364
- "password": "password123",
365
- "companySlug": "acme-corp",
366
- "branchSlug": "main-branch"
367
- }
395
+ { "name": "John Doe", "email": "john@example.com", "password": "password123", "companySlug": "acme-corp", "branchSlug": "main-branch" }
368
396
  \`\`\`
369
397
 
370
398
  **Create new company:**
371
399
  \`\`\`json
372
- {
373
- "name": "John Doe",
374
- "email": "john@example.com",
375
- "password": "password123",
376
- "newCompanyName": "My New Company",
377
- "newCompanyPhone": "+1234567890"
378
- }
400
+ { "name": "John Doe", "email": "john@example.com", "password": "password123", "newCompanyName": "My New Company" }
401
+ \`\`\`
402
+ ` : `
403
+ ### Registration Flow
404
+ \`\`\`json
405
+ { "name": "John Doe", "email": "john@example.com", "password": "password123" }
379
406
  \`\`\`
380
- ` : `
407
+ `;
408
+ return `
381
409
  ## Authentication API
382
-
383
- Handles user authentication and registration.
410
+ ${multiTenantNote}
411
+ Handles user authentication${enableCompanyFeature ? ', company/branch management' : ''}, and registration.
384
412
 
385
413
  ### Features
386
- - User registration
387
- - Login with email/password
388
- - JWT token-based authentication
389
- - Token refresh
390
- - Password change
391
-
392
- ### Authentication Flow
393
- \`\`\`
394
- POST /auth/login → { accessToken, refreshToken, user }
395
- \`\`\`
396
-
397
- ### Registration Flow
398
- \`\`\`json
399
- {
400
- "name": "John Doe",
401
- "email": "john@example.com",
402
- "password": "password123"
414
+ ${features}
415
+ ${loginFlowSection}${emailVerificationSection}${administrationSection}${registrationSection}`;
403
416
  }
404
- \`\`\`
405
- `,
417
+ // ============================================================================
418
+ // Config factory
419
+ // ============================================================================
420
+ export function authSwaggerConfig(bootstrapConfig) {
421
+ const enableCompanyFeature = bootstrapConfig?.enableCompanyFeature ?? true;
422
+ const enableEmailVerification = bootstrapConfig?.enableEmailVerification ?? true;
423
+ const isMultiTenant = bootstrapConfig?.databaseMode === 'multi-tenant';
424
+ const excludeTags = enableCompanyFeature ? [] : COMPANY_RELATED_TAGS;
425
+ const excludeSchemaProperties = [
426
+ ...enableCompanyFeature ? [] : COMPANY_SCHEMA_EXCLUSIONS,
427
+ ...enableEmailVerification ? [] : EMAIL_VERIFICATION_SCHEMA_EXCLUSIONS
428
+ ];
429
+ // Merge example exclusions — both may target /auth/login with different example names
430
+ const excludeExamples = [
431
+ ...enableCompanyFeature ? [] : COMPANY_EXAMPLE_EXCLUSIONS,
432
+ ...enableEmailVerification ? [] : EMAIL_VERIFICATION_EXAMPLE_EXCLUSIONS
433
+ ];
434
+ const excludePaths = enableEmailVerification ? undefined : EMAIL_VERIFICATION_PATHS;
435
+ return {
436
+ title: 'Auth API',
437
+ description: buildDescription(enableCompanyFeature, enableEmailVerification, isMultiTenant),
406
438
  version: '1.0',
407
439
  path: 'api/docs/auth',
408
440
  bearerAuth: true,
409
441
  excludeTags,
410
- excludeSchemaProperties: enableCompanyFeature ? undefined : COMPANY_SCHEMA_EXCLUSIONS,
411
- excludeExamples: enableCompanyFeature ? undefined : COMPANY_EXAMPLE_EXCLUSIONS
442
+ excludeSchemaProperties: excludeSchemaProperties.length ? excludeSchemaProperties : undefined,
443
+ excludeExamples: excludeExamples.length ? excludeExamples : undefined,
444
+ excludePaths
412
445
  };
413
446
  }
@@ -612,8 +612,6 @@ export class LoginResponseRequiresEmailVerificationDto {
612
612
  constructor(){
613
613
  _define_property(this, "requiresEmailVerification", void 0);
614
614
  _define_property(this, "email", void 0);
615
- _define_property(this, "message", void 0);
616
- _define_property(this, "messageKey", void 0);
617
615
  }
618
616
  }
619
617
  _ts_decorate([
@@ -628,19 +626,6 @@ _ts_decorate([
628
626
  }),
629
627
  _ts_metadata("design:type", String)
630
628
  ], LoginResponseRequiresEmailVerificationDto.prototype, "email", void 0);
631
- _ts_decorate([
632
- ApiProperty({
633
- example: 'Please verify your email address before logging in.'
634
- }),
635
- _ts_metadata("design:type", String)
636
- ], LoginResponseRequiresEmailVerificationDto.prototype, "message", void 0);
637
- _ts_decorate([
638
- ApiProperty({
639
- example: 'auth.login.email.not.verified',
640
- description: 'Translation key for localization'
641
- }),
642
- _ts_metadata("design:type", String)
643
- ], LoginResponseRequiresEmailVerificationDto.prototype, "messageKey", void 0);
644
629
  export class ForgotPasswordDto {
645
630
  constructor(){
646
631
  _define_property(this, "email", void 0);
@@ -20,7 +20,7 @@ function _ts_decorate(decorators, target, key, desc) {
20
20
  function _ts_metadata(k, v) {
21
21
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
22
22
  }
23
- import { Identity } from '@flusys/nestjs-shared';
23
+ import { getJsonColumnType, Identity } from '@flusys/nestjs-shared';
24
24
  import { Column, Entity, JoinColumn, ManyToOne, OneToMany, Unique } from 'typeorm';
25
25
  import { Company } from './company.entity';
26
26
  export class CompanyBranch extends Identity {
@@ -99,7 +99,7 @@ _ts_decorate([
99
99
  ], CompanyBranch.prototype, "isActive", void 0);
100
100
  _ts_decorate([
101
101
  Column({
102
- type: 'json',
102
+ type: getJsonColumnType(),
103
103
  nullable: true
104
104
  }),
105
105
  _ts_metadata("design:type", Object)
@@ -20,7 +20,7 @@ function _ts_decorate(decorators, target, key, desc) {
20
20
  function _ts_metadata(k, v) {
21
21
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
22
22
  }
23
- import { Identity } from '@flusys/nestjs-shared';
23
+ import { getJsonColumnType, Identity } from '@flusys/nestjs-shared';
24
24
  import { Column, Entity, OneToMany } from 'typeorm';
25
25
  import { CompanyBranch } from './company-branch.entity';
26
26
  export class Company extends Identity {
@@ -113,14 +113,14 @@ _ts_decorate([
113
113
  ], Company.prototype, "isActive", void 0);
114
114
  _ts_decorate([
115
115
  Column({
116
- type: 'json',
116
+ type: getJsonColumnType(),
117
117
  nullable: true
118
118
  }),
119
119
  _ts_metadata("design:type", Object)
120
120
  ], Company.prototype, "settings", void 0);
121
121
  _ts_decorate([
122
122
  Column({
123
- type: 'json',
123
+ type: getJsonColumnType(),
124
124
  nullable: true
125
125
  }),
126
126
  _ts_metadata("design:type", Object)
@@ -20,6 +20,7 @@ function _ts_decorate(decorators, target, key, desc) {
20
20
  function _ts_metadata(k, v) {
21
21
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
22
22
  }
23
+ import { getJsonColumnType } from '@flusys/nestjs-shared';
23
24
  import { Column, CreateDateColumn, Entity, Index, PrimaryGeneratedColumn } from 'typeorm';
24
25
  export class PendingRegistration {
25
26
  constructor(){
@@ -85,7 +86,7 @@ _ts_decorate([
85
86
  ], PendingRegistration.prototype, "expiresAt", void 0);
86
87
  _ts_decorate([
87
88
  Column({
88
- type: 'json',
89
+ type: getJsonColumnType(),
89
90
  nullable: true,
90
91
  name: 'company_data'
91
92
  }),
@@ -93,7 +94,7 @@ _ts_decorate([
93
94
  ], PendingRegistration.prototype, "companyData", void 0);
94
95
  _ts_decorate([
95
96
  Column({
96
- type: 'json',
97
+ type: getJsonColumnType(),
97
98
  nullable: true,
98
99
  name: 'additional_fields'
99
100
  }),
@@ -33,7 +33,6 @@ export class UserCompanyPermission {
33
33
  _define_property(this, "user", void 0);
34
34
  /* ---------- Polymorphic Target ---------- */ _define_property(this, "permissionType", void 0);
35
35
  _define_property(this, "targetId", void 0);
36
- _define_property(this, "metadata", void 0);
37
36
  _define_property(this, "isActive", void 0);
38
37
  /* ---------- Optional Relations (no FK - polymorphic) ---------- */ _define_property(this, "company", void 0);
39
38
  _define_property(this, "branch", void 0);
@@ -76,13 +75,6 @@ _ts_decorate([
76
75
  }),
77
76
  _ts_metadata("design:type", String)
78
77
  ], UserCompanyPermission.prototype, "targetId", void 0);
79
- _ts_decorate([
80
- Column({
81
- type: 'json',
82
- nullable: true
83
- }),
84
- _ts_metadata("design:type", typeof Record === "undefined" ? Object : Record)
85
- ], UserCompanyPermission.prototype, "metadata", void 0);
86
78
  _ts_decorate([
87
79
  Column({
88
80
  type: 'boolean',
@@ -37,7 +37,6 @@ export class UserToken {
37
37
  _define_property(this, "token", void 0);
38
38
  _define_property(this, "expiresAt", void 0);
39
39
  _define_property(this, "usedAt", void 0);
40
- _define_property(this, "metadata", void 0);
41
40
  _define_property(this, "createdAt", void 0);
42
41
  }
43
42
  }
@@ -81,14 +80,6 @@ _ts_decorate([
81
80
  }),
82
81
  _ts_metadata("design:type", Object)
83
82
  ], UserToken.prototype, "usedAt", void 0);
84
- _ts_decorate([
85
- Column({
86
- type: 'varchar',
87
- length: 255,
88
- nullable: true
89
- }),
90
- _ts_metadata("design:type", Object)
91
- ], UserToken.prototype, "metadata", void 0);
92
83
  _ts_decorate([
93
84
  CreateDateColumn({
94
85
  type: 'timestamp',
@@ -43,16 +43,24 @@ export class SetToken {
43
43
  const req = context.switchToHttp().getRequest();
44
44
  const res = context.switchToHttp().getResponse();
45
45
  return next.handle().pipe(map((value)=>{
46
- if (typeof value !== 'object' || value === null || !('refreshToken' in value)) {
46
+ if (typeof value !== 'object' || value === null) {
47
47
  return value;
48
48
  }
49
49
  const response = value;
50
- if (isBrowserRequest(req)) {
51
- this.setRefreshTokenCookie(req, res, String(response.refreshToken));
52
- const { refreshToken, ...responseWithoutToken } = response;
53
- return responseWithoutToken;
50
+ const data = typeof response['data'] === 'object' && response['data'] !== null ? response['data'] : null;
51
+ const tokenInData = data && typeof data['refreshToken'] === 'string';
52
+ if (!tokenInData) {
53
+ return value;
54
+ }
55
+ if (!isBrowserRequest(req)) {
56
+ return value;
54
57
  }
55
- return value;
58
+ this.setRefreshTokenCookie(req, res, data['refreshToken']);
59
+ const { refreshToken: _, ...dataWithoutToken } = data;
60
+ return {
61
+ ...response,
62
+ data: dataWithoutToken
63
+ };
56
64
  }), catchError((err)=>throwError(()=>err)));
57
65
  }
58
66
  setRefreshTokenCookie(req, res, tokenValue) {
@@ -62,7 +70,7 @@ export class SetToken {
62
70
  throw new PayloadTooLargeException({
63
71
  message: `Refresh token too large (≈${estimatedBytes} bytes)`,
64
72
  messageKey: AUTH_MESSAGES.TOKEN_TOO_LARGE,
65
- messageParams: {
73
+ messageVariables: {
66
74
  size: estimatedBytes
67
75
  }
68
76
  });
@@ -76,10 +76,6 @@ export class AuthConfigService {
76
76
  getRefreshTokenCookieName() {
77
77
  return this.config.refreshTokenCookieName ?? 'fsn_refresh_token';
78
78
  }
79
- // Frontend Configuration
80
- getFrontendUrl() {
81
- return this.config.frontendUrl;
82
- }
83
79
  constructor(injectedOptions){
84
80
  _define_property(this, "options", void 0);
85
81
  _define_property(this, "config", void 0);
@@ -25,14 +25,12 @@ function _ts_param(paramIndex, decorator) {
25
25
  decorator(target, key, paramIndex);
26
26
  };
27
27
  }
28
- import { SYSTEM_MESSAGES } from '@flusys/nestjs-shared/constants';
29
28
  import { LogAction } from '@flusys/nestjs-shared';
30
- import { AUTH_MESSAGES, EMAIL_VERIFICATION_MESSAGES, USER_MESSAGES } from '../config';
29
+ import { SYSTEM_MESSAGES } from '@flusys/nestjs-shared/constants';
31
30
  import { BadRequestException, Inject, Injectable, InternalServerErrorException, Optional, Scope } from '@nestjs/common';
32
31
  import * as bcrypt from 'bcrypt';
33
32
  import * as crypto from 'crypto';
34
- import { LessThan } from 'typeorm';
35
- import { BCRYPT_SALT_ROUNDS } from '../config';
33
+ import { AUTH_MESSAGES, BCRYPT_SALT_ROUNDS, EMAIL_VERIFICATION_MESSAGES, USER_MESSAGES } from '../config';
36
34
  import { PendingRegistration } from '../entities/pending-registration.entity';
37
35
  import { TokenType, UserToken } from '../entities/user-token.entity';
38
36
  import { User } from '../entities/user.entity';
@@ -47,7 +45,7 @@ export class AuthEmailService {
47
45
  throw new InternalServerErrorException({
48
46
  message: `${String(entity)} repository not available`,
49
47
  messageKey: SYSTEM_MESSAGES.REPOSITORY_NOT_AVAILABLE,
50
- messageParams: {
48
+ messageVariables: {
51
49
  entity: String(entity)
52
50
  }
53
51
  });
@@ -186,7 +184,11 @@ export class AuthEmailService {
186
184
  } catch {
187
185
  throw new BadRequestException({
188
186
  message: 'Failed to process request. Please try again later.',
189
- messageKey: SYSTEM_MESSAGES.INTERNAL_ERROR
187
+ messageKey: SYSTEM_MESSAGES.INTERNAL_ERROR,
188
+ messageVariables: {
189
+ provider: 'EmailProvider',
190
+ error: 'Send email failed'
191
+ }
190
192
  });
191
193
  }
192
194
  return {
@@ -377,23 +379,6 @@ export class AuthEmailService {
377
379
  messageKey: EMAIL_VERIFICATION_MESSAGES.RESEND_SUCCESS
378
380
  };
379
381
  }
380
- async cleanupExpired() {
381
- const tokenRepository = await this.getRepository(UserToken);
382
- const pendingRepository = await this.getRepository(PendingRegistration);
383
- const now = new Date();
384
- const tokenResult = await tokenRepository.delete({
385
- expiresAt: LessThan(now)
386
- });
387
- const pendingResult = await pendingRepository.delete({
388
- expiresAt: LessThan(now)
389
- });
390
- const deletedTokens = tokenResult.affected ?? 0;
391
- const deletedPending = pendingResult.affected ?? 0;
392
- return {
393
- deletedTokens,
394
- deletedPending
395
- };
396
- }
397
382
  constructor(dataSourceProvider, emailProvider){
398
383
  _define_property(this, "dataSourceProvider", void 0);
399
384
  _define_property(this, "emailProvider", void 0);
@@ -466,15 +451,6 @@ _ts_decorate([
466
451
  ]),
467
452
  _ts_metadata("design:returntype", Promise)
468
453
  ], AuthEmailService.prototype, "resendVerificationEmail", null);
469
- _ts_decorate([
470
- LogAction({
471
- action: 'auth.cleanupExpiredTokens',
472
- module: 'auth'
473
- }),
474
- _ts_metadata("design:type", Function),
475
- _ts_metadata("design:paramtypes", []),
476
- _ts_metadata("design:returntype", Promise)
477
- ], AuthEmailService.prototype, "cleanupExpired", null);
478
454
  AuthEmailService = _ts_decorate([
479
455
  Injectable({
480
456
  scope: Scope.REQUEST