@flusys/nestjs-auth 3.0.0 → 4.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 (63) hide show
  1. package/README.md +1 -1
  2. package/cjs/config/index.js +1 -0
  3. package/cjs/config/message-keys.js +150 -0
  4. package/cjs/controllers/authentication.controller.js +9 -4
  5. package/cjs/controllers/branch.controller.js +1 -0
  6. package/cjs/controllers/company-selection.controller.js +3 -0
  7. package/cjs/controllers/company.controller.js +1 -0
  8. package/cjs/controllers/email-verification.controller.js +7 -2
  9. package/cjs/controllers/user-permission.controller.js +9 -1
  10. package/cjs/controllers/user.controller.js +16 -4
  11. package/cjs/dtos/authentication.dto.js +8 -0
  12. package/cjs/dtos/user-permission.dto.js +14 -0
  13. package/cjs/interceptors/set-token.interceptor.js +14 -5
  14. package/cjs/services/auth-config.service.js +9 -8
  15. package/cjs/services/auth-datasource.provider.js +7 -4
  16. package/cjs/services/auth-email.service.js +155 -45
  17. package/cjs/services/authentication.service.js +306 -71
  18. package/cjs/services/branch.service.js +1 -1
  19. package/cjs/services/company-selection-session.service.js +25 -6
  20. package/cjs/services/company.service.js +1 -1
  21. package/cjs/services/user-permission.service.js +52 -4
  22. package/cjs/services/user.service.js +122 -26
  23. package/cjs/strategies/jwt.strategy.js +18 -4
  24. package/config/index.d.ts +1 -0
  25. package/config/message-keys.d.ts +218 -0
  26. package/controllers/company-selection.controller.d.ts +2 -0
  27. package/controllers/user-permission.controller.d.ts +4 -0
  28. package/controllers/user.controller.d.ts +10 -0
  29. package/dtos/authentication.dto.d.ts +1 -0
  30. package/dtos/user-permission.dto.d.ts +2 -0
  31. package/entities/index.d.ts +10 -1
  32. package/fesm/config/index.js +1 -0
  33. package/fesm/config/message-keys.js +118 -0
  34. package/fesm/controllers/authentication.controller.js +9 -3
  35. package/fesm/controllers/branch.controller.js +1 -0
  36. package/fesm/controllers/company-selection.controller.js +3 -0
  37. package/fesm/controllers/company.controller.js +1 -0
  38. package/fesm/controllers/email-verification.controller.js +7 -2
  39. package/fesm/controllers/user-permission.controller.js +9 -1
  40. package/fesm/controllers/user.controller.js +16 -4
  41. package/fesm/dtos/authentication.dto.js +8 -0
  42. package/fesm/dtos/user-permission.dto.js +14 -0
  43. package/fesm/interceptors/set-token.interceptor.js +14 -4
  44. package/fesm/services/auth-config.service.js +10 -9
  45. package/fesm/services/auth-datasource.provider.js +7 -4
  46. package/fesm/services/auth-email.service.js +156 -45
  47. package/fesm/services/authentication.service.js +297 -61
  48. package/fesm/services/branch.service.js +1 -1
  49. package/fesm/services/company-selection-session.service.js +25 -6
  50. package/fesm/services/company.service.js +1 -1
  51. package/fesm/services/user-permission.service.js +52 -4
  52. package/fesm/services/user.service.js +122 -25
  53. package/fesm/strategies/jwt.strategy.js +18 -4
  54. package/interfaces/auth-module-options.interface.d.ts +2 -2
  55. package/interfaces/authentication.interface.d.ts +1 -0
  56. package/modules/auth.module.d.ts +2 -1
  57. package/package.json +3 -3
  58. package/services/auth-config.service.d.ts +0 -2
  59. package/services/auth-datasource.provider.d.ts +1 -3
  60. package/services/auth-email.service.d.ts +6 -3
  61. package/services/authentication.service.d.ts +5 -2
  62. package/services/branch.service.d.ts +2 -1
  63. package/services/user.service.d.ts +7 -7
@@ -9,17 +9,23 @@ Object.defineProperty(exports, "AuthenticationService", {
9
9
  }
10
10
  });
11
11
  const _classes = require("@flusys/nestjs-shared/classes");
12
+ const _constants = require("@flusys/nestjs-shared/constants");
13
+ const _nestjsshared = require("@flusys/nestjs-shared");
14
+ const _config = require("../config");
15
+ const _interfaces = require("@flusys/nestjs-shared/interfaces");
16
+ const _enums = require("@flusys/nestjs-shared/enums");
12
17
  const _utils = require("@flusys/nestjs-shared/utils");
13
18
  const _common = require("@nestjs/common");
14
19
  const _jwt = require("@nestjs/jwt");
15
20
  const _bcrypt = /*#__PURE__*/ _interop_require_wildcard(require("bcrypt"));
16
- const _config = require("../config");
17
21
  const _userenricherinterface = require("../interfaces/user-enricher.interface");
22
+ const _authenticationdto = require("../dtos/authentication.dto");
18
23
  const _companybranchentity = require("../entities/company-branch.entity");
19
24
  const _companyentity = require("../entities/company.entity");
25
+ const _pendingregistrationentity = require("../entities/pending-registration.entity");
20
26
  const _usercompanypermissionentity = require("../entities/user-company-permission.entity");
21
27
  const _userentity = require("../entities/user.entity");
22
- const _enums = require("../enums");
28
+ const _enums1 = require("../enums");
23
29
  const _authconfigservice = require("./auth-config.service");
24
30
  const _authdatasourceprovider = require("./auth-datasource.provider");
25
31
  const _authemailservice = require("./auth-email.service");
@@ -103,7 +109,10 @@ let AuthenticationService = class AuthenticationService {
103
109
  }
104
110
  async getUserRepository() {
105
111
  if (!this.dataSourceProvider) {
106
- throw new Error('User repository not available');
112
+ throw new _common.InternalServerErrorException({
113
+ message: 'User repository not available',
114
+ messageKey: _constants.SYSTEM_MESSAGES.REPOSITORY_NOT_AVAILABLE
115
+ });
107
116
  }
108
117
  return this.dataSourceProvider.getRepository(_userentity.User);
109
118
  }
@@ -124,24 +133,29 @@ let AuthenticationService = class AuthenticationService {
124
133
  return {
125
134
  requiresEmailVerification: true,
126
135
  email,
127
- message: 'Please verify your email address to complete registration.'
136
+ message: 'Please verify your email address to complete registration.',
137
+ messageKey: _config.EMAIL_VERIFICATION_MESSAGES.VERIFICATION_SENT
128
138
  };
129
139
  }
130
140
  const user = await this.validateUser(email, password);
131
141
  if (!user.isActive) {
132
- throw new _common.UnauthorizedException('User account is deactivated');
142
+ throw new _common.UnauthorizedException({
143
+ message: 'User account is deactivated',
144
+ messageKey: _config.AUTH_MESSAGES.LOGIN_ACCOUNT_DEACTIVATED
145
+ });
133
146
  }
134
147
  if (this.isEmailVerificationEnabled() && !user.emailVerified) {
135
148
  return {
136
149
  requiresEmailVerification: true,
137
150
  email: user.email,
138
- message: 'Please verify your email address before logging in.'
151
+ message: 'Please verify your email address before logging in.',
152
+ messageKey: _config.AUTH_MESSAGES.LOGIN_EMAIL_NOT_VERIFIED
139
153
  };
140
154
  }
141
155
  if (!this.isCompanyFeatureEnabled()) {
142
156
  return this.generateLoginResponse(user);
143
157
  }
144
- return this.handleCompanyBasedLogin(user);
158
+ return await this.handleCompanyBasedLogin(user);
145
159
  }
146
160
  async handleCompanyBasedLogin(user) {
147
161
  const permissionRepository = await this.getPermissionRepository();
@@ -152,7 +166,7 @@ let AuthenticationService = class AuthenticationService {
152
166
  const companyPermissions = await permissionRepository.find({
153
167
  where: {
154
168
  userId: user.id,
155
- permissionType: _enums.PermissionType.COMPANY
169
+ permissionType: _enums1.PermissionType.COMPANY
156
170
  }
157
171
  });
158
172
  const companyRepository = await this.getCompanyRepository();
@@ -171,7 +185,7 @@ let AuthenticationService = class AuthenticationService {
171
185
  const branchPermissions = await permissionRepository.find({
172
186
  where: {
173
187
  userId: user.id,
174
- permissionType: _enums.PermissionType.BRANCH
188
+ permissionType: _enums1.PermissionType.BRANCH
175
189
  }
176
190
  });
177
191
  const branchIds = branchPermissions.map((p)=>p.targetId);
@@ -193,10 +207,13 @@ let AuthenticationService = class AuthenticationService {
193
207
  }
194
208
  });
195
209
  if (existingUser && this.isCompanyFeatureEnabled()) {
196
- return this.handleExistingUserCompanyRegistration(existingUser, dto);
210
+ return await this.handleExistingUserCompanyRegistration(existingUser, dto);
197
211
  }
198
212
  if (existingUser) {
199
- throw new _common.BadRequestException('Registration failed due to email exists. Please try again or contact support.');
213
+ throw new _common.BadRequestException({
214
+ message: 'Registration failed due to email exists. Please try again or contact support.',
215
+ messageKey: _config.AUTH_MESSAGES.REGISTER_EMAIL_EXISTS
216
+ });
200
217
  }
201
218
  if (this.isEmailVerificationEnabled() && verifyUrlBase) {
202
219
  const companyData = this.isCompanyFeatureEnabled() ? {
@@ -217,19 +234,26 @@ let AuthenticationService = class AuthenticationService {
217
234
  });
218
235
  return {
219
236
  requiresEmailVerification: true,
220
- message: result.message
237
+ message: result.message,
238
+ messageKey: _config.EMAIL_VERIFICATION_MESSAGES.VERIFICATION_SENT
221
239
  };
222
240
  }
223
- return this.createUserDirectly(dto);
241
+ return await this.createUserDirectly(dto);
224
242
  }
225
243
  async handleExistingUserCompanyRegistration(existingUser, dto) {
226
244
  if (!dto.companySlug && !dto.newCompanyName) {
227
- throw new _common.BadRequestException('Email already registered. Please login or provide a company to join/create.');
245
+ throw new _common.BadRequestException({
246
+ message: 'Email already registered. Please login or provide a company to join/create.',
247
+ messageKey: _config.AUTH_MESSAGES.REGISTER_EMAIL_EXISTS
248
+ });
228
249
  }
229
250
  const permissionRepository = await this.getPermissionRepository();
230
251
  const companyRepository = await this.getCompanyRepository();
231
252
  if (!permissionRepository || !companyRepository) {
232
- throw new _common.BadRequestException('Company feature repositories not available');
253
+ throw new _common.BadRequestException({
254
+ message: 'Company feature repositories not available',
255
+ messageKey: _constants.SYSTEM_MESSAGES.REPOSITORY_NOT_AVAILABLE
256
+ });
233
257
  }
234
258
  if (dto.companySlug) {
235
259
  const company = await companyRepository.findOne({
@@ -242,20 +266,26 @@ let AuthenticationService = class AuthenticationService {
242
266
  const existingPermission = await permissionRepository.findOne({
243
267
  where: {
244
268
  userId: existingUser.id,
245
- permissionType: _enums.PermissionType.COMPANY,
269
+ permissionType: _enums1.PermissionType.COMPANY,
246
270
  targetId: company.id
247
271
  }
248
272
  });
249
273
  if (existingPermission) {
250
- throw new _common.BadRequestException('You are already assigned to this company. Please login.');
274
+ throw new _common.BadRequestException({
275
+ message: 'You are already assigned to this company. Please login.',
276
+ messageKey: _config.AUTH_MESSAGES.REGISTER_COMPANY_ALREADY_ASSIGNED
277
+ });
251
278
  }
252
279
  }
253
280
  }
254
- return this.processCompanyRegistration(existingUser, dto, true);
281
+ return await this.processCompanyRegistration(existingUser, dto, true);
255
282
  }
256
283
  async createUserDirectly(dto) {
257
284
  if (!this.dataSourceProvider) {
258
- throw new _common.BadRequestException('Data source not available');
285
+ throw new _common.BadRequestException({
286
+ message: 'Data source not available',
287
+ messageKey: _constants.SYSTEM_MESSAGES.DATASOURCE_NOT_AVAILABLE
288
+ });
259
289
  }
260
290
  const dataSource = await this.dataSourceProvider.getDataSource();
261
291
  const queryRunner = dataSource.createQueryRunner();
@@ -280,21 +310,26 @@ let AuthenticationService = class AuthenticationService {
280
310
  if (!this.isCompanyFeatureEnabled()) {
281
311
  return this.generateRegistrationResponse(user);
282
312
  }
283
- return this.processCompanyRegistration(user, dto);
313
+ return await this.processCompanyRegistration(user, dto);
284
314
  } catch (error) {
285
315
  await queryRunner.rollbackTransaction();
286
316
  if (error instanceof _common.BadRequestException) {
287
317
  throw error;
288
318
  }
289
- _utils.ErrorHandler.logError(this.logger, error, 'createUserDirectly');
290
- throw new _common.BadRequestException('Registration failed. Please try again.');
319
+ throw new _common.BadRequestException({
320
+ message: 'Registration failed. Please try again.',
321
+ messageKey: _config.AUTH_MESSAGES.REGISTER_FAILED
322
+ });
291
323
  } finally{
292
324
  await queryRunner.release();
293
325
  }
294
326
  }
295
327
  async createUserFromPendingRegistration(pending) {
296
328
  if (!this.dataSourceProvider) {
297
- throw new _common.BadRequestException('Data source not available');
329
+ throw new _common.BadRequestException({
330
+ message: 'Data source not available',
331
+ messageKey: _constants.SYSTEM_MESSAGES.DATASOURCE_NOT_AVAILABLE
332
+ });
298
333
  }
299
334
  const dataSource = await this.dataSourceProvider.getDataSource();
300
335
  const queryRunner = dataSource.createQueryRunner();
@@ -307,7 +342,10 @@ let AuthenticationService = class AuthenticationService {
307
342
  }
308
343
  });
309
344
  if (existingUser) {
310
- throw new _common.BadRequestException('This email has already been registered.');
345
+ throw new _common.BadRequestException({
346
+ message: 'This email has already been registered.',
347
+ messageKey: _config.AUTH_MESSAGES.REGISTER_EMAIL_EXISTS
348
+ });
311
349
  }
312
350
  const user = queryRunner.manager.create(_userentity.User, {
313
351
  name: pending.name,
@@ -324,7 +362,7 @@ let AuthenticationService = class AuthenticationService {
324
362
  }
325
363
  await queryRunner.commitTransaction();
326
364
  if (this.isCompanyFeatureEnabled() && pending.companyData) {
327
- return this.processCompanyRegistration(user, pending.companyData);
365
+ return await this.processCompanyRegistration(user, pending.companyData);
328
366
  }
329
367
  return this.generateRegistrationResponse(user);
330
368
  } catch (error) {
@@ -332,8 +370,10 @@ let AuthenticationService = class AuthenticationService {
332
370
  if (error instanceof _common.BadRequestException) {
333
371
  throw error;
334
372
  }
335
- _utils.ErrorHandler.logError(this.logger, error, 'createUserFromPendingRegistration');
336
- throw new _common.BadRequestException('Registration failed. Please try again.');
373
+ throw new _common.BadRequestException({
374
+ message: 'Registration failed. Please try again.',
375
+ messageKey: _config.AUTH_MESSAGES.REGISTER_FAILED
376
+ });
337
377
  } finally{
338
378
  await queryRunner.release();
339
379
  }
@@ -343,7 +383,10 @@ let AuthenticationService = class AuthenticationService {
343
383
  const branchRepository = await this.getBranchRepository();
344
384
  const permissionRepository = await this.getPermissionRepository();
345
385
  if (!companyRepository || !branchRepository || !permissionRepository) {
346
- if (throwOnUnavailable) throw new _common.BadRequestException('Company feature repositories not available');
386
+ if (throwOnUnavailable) throw new _common.BadRequestException({
387
+ message: 'Company feature repositories not available',
388
+ messageKey: _constants.SYSTEM_MESSAGES.REPOSITORY_NOT_AVAILABLE
389
+ });
347
390
  return this.generateRegistrationResponse(user);
348
391
  }
349
392
  const { company, branch } = await this.findOrCreateCompanyAndBranch(data, companyRepository, branchRepository);
@@ -361,7 +404,10 @@ let AuthenticationService = class AuthenticationService {
361
404
  isActive: true
362
405
  }
363
406
  });
364
- if (!company) throw new _common.BadRequestException('Company not found or inactive');
407
+ if (!company) throw new _common.BadRequestException({
408
+ message: 'Company not found or inactive',
409
+ messageKey: _config.AUTH_MESSAGES.COMPANY_NOT_FOUND
410
+ });
365
411
  const branch = data.branchSlug ? await branchRepo.findOne({
366
412
  where: {
367
413
  slug: data.branchSlug,
@@ -378,7 +424,10 @@ let AuthenticationService = class AuthenticationService {
378
424
  createdAt: 'ASC'
379
425
  }
380
426
  });
381
- if (data.branchSlug && !branch) throw new _common.BadRequestException('Branch not found or inactive');
427
+ if (data.branchSlug && !branch) throw new _common.BadRequestException({
428
+ message: 'Branch not found or inactive',
429
+ messageKey: _config.AUTH_MESSAGES.BRANCH_NOT_FOUND
430
+ });
382
431
  return {
383
432
  company,
384
433
  branch
@@ -420,13 +469,13 @@ let AuthenticationService = class AuthenticationService {
420
469
  async assignUserPermissions(userId, companyId, branchId, permissionRepo) {
421
470
  await permissionRepo.save(permissionRepo.create({
422
471
  userId,
423
- permissionType: _enums.PermissionType.COMPANY,
472
+ permissionType: _enums1.PermissionType.COMPANY,
424
473
  targetId: companyId
425
474
  }));
426
475
  if (branchId) {
427
476
  await permissionRepo.save(permissionRepo.create({
428
477
  userId,
429
- permissionType: _enums.PermissionType.BRANCH,
478
+ permissionType: _enums1.PermissionType.BRANCH,
430
479
  targetId: branchId
431
480
  }));
432
481
  }
@@ -434,17 +483,23 @@ let AuthenticationService = class AuthenticationService {
434
483
  async select(sessionId, companyId, branchId) {
435
484
  this.ensureCompanyFeatureEnabled();
436
485
  if (!this.sessionService) {
437
- throw new _common.BadRequestException('Session service not available');
486
+ throw new _common.BadRequestException({
487
+ message: 'Session service not available',
488
+ messageKey: _config.AUTH_MESSAGES.SESSION_NOT_AVAILABLE
489
+ });
438
490
  }
439
491
  const session = await this.sessionService.consumeSession(sessionId);
440
492
  if (!session) {
441
- throw new _common.UnauthorizedException('Invalid or expired session');
493
+ throw new _common.UnauthorizedException({
494
+ message: 'Invalid or expired session',
495
+ messageKey: _config.AUTH_MESSAGES.SESSION_INVALID
496
+ });
442
497
  }
443
- return this.validateAndLoginWithCompany(session.userId, companyId, branchId);
498
+ return await this.validateAndLoginWithCompany(session.userId, companyId, branchId);
444
499
  }
445
500
  async switchCompany(userId, companyId, branchId) {
446
501
  this.ensureCompanyFeatureEnabled();
447
- return this.validateAndLoginWithCompany(userId, companyId, branchId);
502
+ return await this.validateAndLoginWithCompany(userId, companyId, branchId);
448
503
  }
449
504
  async validateAndLoginWithCompany(userId, companyId, branchId) {
450
505
  const userRepository = await this.getUserRepository();
@@ -454,23 +509,32 @@ let AuthenticationService = class AuthenticationService {
454
509
  }
455
510
  });
456
511
  if (!user) {
457
- throw new _common.NotFoundException('User not found');
512
+ throw new _common.NotFoundException({
513
+ message: 'User not found',
514
+ messageKey: _config.USER_MESSAGES.NOT_FOUND
515
+ });
458
516
  }
459
517
  const permissionRepository = await this.getPermissionRepository();
460
518
  const companyRepository = await this.getCompanyRepository();
461
519
  const branchRepository = await this.getBranchRepository();
462
520
  if (!permissionRepository || !companyRepository || !branchRepository) {
463
- throw new _common.BadRequestException('Repositories not available');
521
+ throw new _common.BadRequestException({
522
+ message: 'Repositories not available',
523
+ messageKey: _constants.SYSTEM_MESSAGES.REPOSITORY_NOT_AVAILABLE
524
+ });
464
525
  }
465
526
  const hasCompanyAccess = await permissionRepository.findOne({
466
527
  where: {
467
528
  userId,
468
- permissionType: _enums.PermissionType.COMPANY,
529
+ permissionType: _enums1.PermissionType.COMPANY,
469
530
  targetId: companyId
470
531
  }
471
532
  });
472
533
  if (!hasCompanyAccess) {
473
- throw new _common.UnauthorizedException('No access to this company');
534
+ throw new _common.UnauthorizedException({
535
+ message: 'No access to this company',
536
+ messageKey: _config.AUTH_MESSAGES.COMPANY_NO_ACCESS
537
+ });
474
538
  }
475
539
  const company = await companyRepository.findOne({
476
540
  where: {
@@ -479,17 +543,23 @@ let AuthenticationService = class AuthenticationService {
479
543
  }
480
544
  });
481
545
  if (!company) {
482
- throw new _common.UnauthorizedException('Company not found or inactive');
546
+ throw new _common.UnauthorizedException({
547
+ message: 'Company not found or inactive',
548
+ messageKey: _config.AUTH_MESSAGES.COMPANY_NOT_FOUND
549
+ });
483
550
  }
484
551
  const hasBranchAccess = await permissionRepository.findOne({
485
552
  where: {
486
553
  userId,
487
- permissionType: _enums.PermissionType.BRANCH,
554
+ permissionType: _enums1.PermissionType.BRANCH,
488
555
  targetId: branchId
489
556
  }
490
557
  });
491
558
  if (!hasBranchAccess) {
492
- throw new _common.UnauthorizedException('No access to this branch');
559
+ throw new _common.UnauthorizedException({
560
+ message: 'No access to this branch',
561
+ messageKey: _config.AUTH_MESSAGES.BRANCH_NO_ACCESS
562
+ });
493
563
  }
494
564
  const branch = await branchRepository.findOne({
495
565
  where: {
@@ -499,7 +569,10 @@ let AuthenticationService = class AuthenticationService {
499
569
  }
500
570
  });
501
571
  if (!branch) {
502
- throw new _common.UnauthorizedException('Branch not found or inactive');
572
+ throw new _common.UnauthorizedException({
573
+ message: 'Branch not found or inactive',
574
+ messageKey: _config.AUTH_MESSAGES.BRANCH_NOT_FOUND
575
+ });
503
576
  }
504
577
  return this.generateLoginResponseWithCompany(user, company, branch);
505
578
  }
@@ -509,7 +582,10 @@ let AuthenticationService = class AuthenticationService {
509
582
  secret: this.authConfig.getRefreshTokenSecret()
510
583
  });
511
584
  if (await this.isTokenRevoked(payload.id, payload.iat)) {
512
- throw new _common.UnauthorizedException('Token has been revoked');
585
+ throw new _common.UnauthorizedException({
586
+ message: 'Token has been revoked',
587
+ messageKey: _config.AUTH_MESSAGES.TOKEN_REVOKED
588
+ });
513
589
  }
514
590
  const userRepository = await this.getUserRepository();
515
591
  const user = await userRepository.findOne({
@@ -518,7 +594,10 @@ let AuthenticationService = class AuthenticationService {
518
594
  }
519
595
  });
520
596
  if (!user || !user.isActive) {
521
- throw new _common.UnauthorizedException('Invalid refresh token');
597
+ throw new _common.UnauthorizedException({
598
+ message: 'Invalid refresh token',
599
+ messageKey: _config.AUTH_MESSAGES.TOKEN_INVALID
600
+ });
522
601
  }
523
602
  return this.generateTokens({
524
603
  id: user.id,
@@ -532,9 +611,11 @@ let AuthenticationService = class AuthenticationService {
532
611
  branchId: payload.branchId
533
612
  }
534
613
  });
535
- } catch (error) {
536
- _utils.ErrorHandler.logError(this.logger, error, 'refreshToken');
537
- throw new _common.UnauthorizedException('Invalid or expired refresh token');
614
+ } catch {
615
+ throw new _common.UnauthorizedException({
616
+ message: 'Invalid or expired refresh token',
617
+ messageKey: _config.AUTH_MESSAGES.TOKEN_EXPIRED
618
+ });
538
619
  }
539
620
  }
540
621
  async changePassword(userId, currentPassword, newPassword) {
@@ -544,24 +625,31 @@ let AuthenticationService = class AuthenticationService {
544
625
  id: userId
545
626
  }
546
627
  });
547
- if (!user) throw new _common.UnauthorizedException('User not found');
628
+ if (!user) throw new _common.UnauthorizedException({
629
+ message: 'User not found',
630
+ messageKey: _config.USER_MESSAGES.NOT_FOUND
631
+ });
548
632
  if (!await _bcrypt.compare(currentPassword, user.password || '')) {
549
- throw new _common.UnauthorizedException('Current password is incorrect');
633
+ throw new _common.UnauthorizedException({
634
+ message: 'Current password is incorrect',
635
+ messageKey: _config.AUTH_MESSAGES.PASSWORD_CHANGE_INVALID_CURRENT
636
+ });
550
637
  }
551
638
  user.password = await _bcrypt.hash(newPassword, _config.BCRYPT_SALT_ROUNDS);
552
639
  await userRepository.save(user);
553
640
  }
554
641
  async logout(userId) {
555
642
  if (!this.cacheManager) {
556
- this.logger.error(`SECURITY: Cache not available for logout (userId: ${userId}). ` + 'Token revocation failed - tokens will remain valid until expiry. ' + 'Configure cache (Redis) to enable proper token revocation.');
557
- throw new _common.BadRequestException('Logout service temporarily unavailable. Please try again later.');
643
+ throw new _common.BadRequestException({
644
+ message: 'Logout service temporarily unavailable. Please try again later.',
645
+ messageKey: _config.AUTH_MESSAGES.LOGOUT_SERVICE_UNAVAILABLE
646
+ });
558
647
  }
559
648
  const revokedAt = Math.floor(Date.now() / 1000);
560
649
  const cacheKey = `${_config.TOKEN_REVOKED_PREFIX}:${userId}`;
561
650
  const refreshTokenExpiry = this.authConfig.getRefreshTokenExpiration();
562
651
  const ttlMs = this.parseExpiryToMs(refreshTokenExpiry);
563
652
  await this.cacheManager.set(cacheKey, revokedAt, ttlMs);
564
- this.logger.log(`User ${userId} logged out - all tokens revoked`);
565
653
  }
566
654
  async isTokenRevoked(userId, tokenIssuedAt) {
567
655
  if (!this.cacheManager || !tokenIssuedAt) {
@@ -597,12 +685,15 @@ let AuthenticationService = class AuthenticationService {
597
685
  const permissionRepository = await this.getPermissionRepository();
598
686
  const companyRepository = await this.getCompanyRepository();
599
687
  if (!permissionRepository || !companyRepository) {
600
- throw new _common.BadRequestException('Repositories not available');
688
+ throw new _common.BadRequestException({
689
+ message: 'Repositories not available',
690
+ messageKey: _constants.SYSTEM_MESSAGES.REPOSITORY_NOT_AVAILABLE
691
+ });
601
692
  }
602
693
  const permissions = await permissionRepository.find({
603
694
  where: {
604
695
  userId,
605
- permissionType: _enums.PermissionType.COMPANY
696
+ permissionType: _enums1.PermissionType.COMPANY
606
697
  }
607
698
  });
608
699
  const companyIds = permissions.map((p)=>p.targetId);
@@ -618,22 +709,28 @@ let AuthenticationService = class AuthenticationService {
618
709
  const permissionRepository = await this.getPermissionRepository();
619
710
  const branchRepository = await this.getBranchRepository();
620
711
  if (!permissionRepository || !branchRepository) {
621
- throw new _common.BadRequestException('Repositories not available');
712
+ throw new _common.BadRequestException({
713
+ message: 'Repositories not available',
714
+ messageKey: _constants.SYSTEM_MESSAGES.REPOSITORY_NOT_AVAILABLE
715
+ });
622
716
  }
623
717
  const companyPermission = await permissionRepository.findOne({
624
718
  where: {
625
719
  userId,
626
- permissionType: _enums.PermissionType.COMPANY,
720
+ permissionType: _enums1.PermissionType.COMPANY,
627
721
  targetId: companyId
628
722
  }
629
723
  });
630
724
  if (!companyPermission) {
631
- throw new _common.UnauthorizedException('No access to this company');
725
+ throw new _common.UnauthorizedException({
726
+ message: 'No access to this company',
727
+ messageKey: _config.AUTH_MESSAGES.COMPANY_NO_ACCESS
728
+ });
632
729
  }
633
730
  const branchPermissions = await permissionRepository.find({
634
731
  where: {
635
732
  userId,
636
- permissionType: _enums.PermissionType.BRANCH
733
+ permissionType: _enums1.PermissionType.BRANCH
637
734
  }
638
735
  });
639
736
  const branchIds = branchPermissions.map((p)=>p.targetId);
@@ -675,20 +772,32 @@ let AuthenticationService = class AuthenticationService {
675
772
  id: userId
676
773
  }
677
774
  });
678
- if (!user) throw new _common.UnauthorizedException('User not found');
775
+ if (!user) throw new _common.UnauthorizedException({
776
+ message: 'User not found',
777
+ messageKey: _config.USER_MESSAGES.NOT_FOUND
778
+ });
679
779
  const response = {
680
780
  user: this.toUserInfo(user)
681
781
  };
682
782
  if (this.isCompanyFeatureEnabled()) {
683
783
  if (!companyId) {
684
- throw new _common.UnauthorizedException('Company feature is enabled but user has no company assigned.');
784
+ throw new _common.UnauthorizedException({
785
+ message: 'Company feature is enabled but user has no company assigned.',
786
+ messageKey: _config.AUTH_MESSAGES.COMPANY_REQUIRED
787
+ });
685
788
  }
686
789
  const company = await this.getCompanyById(companyId);
687
- if (!company) throw new _common.UnauthorizedException('Company not found.');
790
+ if (!company) throw new _common.UnauthorizedException({
791
+ message: 'Company not found.',
792
+ messageKey: _config.AUTH_MESSAGES.COMPANY_NOT_FOUND
793
+ });
688
794
  response.company = this.toCompanyInfo(company);
689
795
  if (branchId) {
690
796
  const branch = await this.getBranchById(branchId);
691
- if (!branch) throw new _common.UnauthorizedException('Branch not found.');
797
+ if (!branch) throw new _common.UnauthorizedException({
798
+ message: 'Branch not found.',
799
+ messageKey: _config.AUTH_MESSAGES.BRANCH_NOT_FOUND
800
+ });
692
801
  response.branch = this.toBranchInfo(branch);
693
802
  }
694
803
  }
@@ -696,7 +805,10 @@ let AuthenticationService = class AuthenticationService {
696
805
  }
697
806
  ensureCompanyFeatureEnabled() {
698
807
  if (!this.isCompanyFeatureEnabled()) {
699
- throw new _common.BadRequestException('Company feature is not enabled');
808
+ throw new _common.BadRequestException({
809
+ message: 'Company feature is not enabled',
810
+ messageKey: _config.AUTH_MESSAGES.COMPANY_FEATURE_NOT_ENABLED
811
+ });
700
812
  }
701
813
  }
702
814
  async validateUser(email, password) {
@@ -707,7 +819,10 @@ let AuthenticationService = class AuthenticationService {
707
819
  }
708
820
  });
709
821
  if (!user || !await _bcrypt.compare(password, user.password || '')) {
710
- throw new _common.UnauthorizedException('Invalid credentials');
822
+ throw new _common.UnauthorizedException({
823
+ message: 'Invalid credentials',
824
+ messageKey: _config.AUTH_MESSAGES.LOGIN_INVALID_CREDENTIALS
825
+ });
711
826
  }
712
827
  user.lastLoginAt = new Date();
713
828
  await userRepository.save(user);
@@ -764,6 +879,7 @@ let AuthenticationService = class AuthenticationService {
764
879
  email: user.email,
765
880
  type: 'access'
766
881
  });
882
+ this.sendLoginNotification(user.id);
767
883
  return {
768
884
  accessToken,
769
885
  refreshToken,
@@ -778,6 +894,7 @@ let AuthenticationService = class AuthenticationService {
778
894
  companyId: company.id,
779
895
  branchId: branch?.id
780
896
  });
897
+ this.sendLoginNotification(user.id, company.id);
781
898
  return {
782
899
  accessToken,
783
900
  refreshToken,
@@ -786,9 +903,24 @@ let AuthenticationService = class AuthenticationService {
786
903
  branch: branch ? this.toBranchInfo(branch) : undefined
787
904
  };
788
905
  }
906
+ sendLoginNotification(userId, companyId) {
907
+ if (!this.notificationAdapter) return;
908
+ this.notificationAdapter.send({
909
+ userId,
910
+ title: 'Login successful',
911
+ message: 'You have successfully logged in to your account.',
912
+ type: _enums.NotificationType.INFO,
913
+ companyId
914
+ }).catch(()=>{
915
+ // Silent failure - notification is non-critical
916
+ });
917
+ }
789
918
  async generateCompanySelectionResponse(user, companies, branches) {
790
919
  if (!this.sessionService) {
791
- throw new _common.BadRequestException('Session service not available');
920
+ throw new _common.BadRequestException({
921
+ message: 'Session service not available',
922
+ messageKey: _config.AUTH_MESSAGES.SESSION_NOT_AVAILABLE
923
+ });
792
924
  }
793
925
  const sessionId = await this.sessionService.createSession(user.id);
794
926
  const companiesWithBranches = companies.map((company)=>({
@@ -820,7 +952,7 @@ let AuthenticationService = class AuthenticationService {
820
952
  };
821
953
  }
822
954
  // NOTE: @Inject() required for bundled code - type metadata may be lost during esbuild
823
- constructor(jwtService, authConfig, cacheManager, dataSourceProvider, sessionService, authEmailService, userEnricher){
955
+ constructor(jwtService, authConfig, cacheManager, dataSourceProvider, sessionService, authEmailService, userEnricher, notificationAdapter){
824
956
  _define_property(this, "jwtService", void 0);
825
957
  _define_property(this, "authConfig", void 0);
826
958
  _define_property(this, "cacheManager", void 0);
@@ -828,7 +960,7 @@ let AuthenticationService = class AuthenticationService {
828
960
  _define_property(this, "sessionService", void 0);
829
961
  _define_property(this, "authEmailService", void 0);
830
962
  _define_property(this, "userEnricher", void 0);
831
- _define_property(this, "logger", void 0);
963
+ _define_property(this, "notificationAdapter", void 0);
832
964
  this.jwtService = jwtService;
833
965
  this.authConfig = authConfig;
834
966
  this.cacheManager = cacheManager;
@@ -836,9 +968,109 @@ let AuthenticationService = class AuthenticationService {
836
968
  this.sessionService = sessionService;
837
969
  this.authEmailService = authEmailService;
838
970
  this.userEnricher = userEnricher;
839
- this.logger = new _common.Logger(AuthenticationService.name);
971
+ this.notificationAdapter = notificationAdapter;
840
972
  }
841
973
  };
974
+ _ts_decorate([
975
+ (0, _nestjsshared.LogAction)({
976
+ action: 'auth.login',
977
+ module: 'auth',
978
+ includeParams: false
979
+ }),
980
+ _ts_metadata("design:type", Function),
981
+ _ts_metadata("design:paramtypes", [
982
+ String,
983
+ String
984
+ ]),
985
+ _ts_metadata("design:returntype", Promise)
986
+ ], AuthenticationService.prototype, "login", null);
987
+ _ts_decorate([
988
+ (0, _nestjsshared.LogAction)({
989
+ action: 'auth.register',
990
+ module: 'auth',
991
+ includeParams: false
992
+ }),
993
+ _ts_metadata("design:type", Function),
994
+ _ts_metadata("design:paramtypes", [
995
+ typeof _authenticationdto.RegistrationDto === "undefined" ? Object : _authenticationdto.RegistrationDto,
996
+ String
997
+ ]),
998
+ _ts_metadata("design:returntype", Promise)
999
+ ], AuthenticationService.prototype, "register", null);
1000
+ _ts_decorate([
1001
+ (0, _nestjsshared.LogAction)({
1002
+ action: 'auth.createUser',
1003
+ module: 'auth',
1004
+ includeParams: false
1005
+ }),
1006
+ _ts_metadata("design:type", Function),
1007
+ _ts_metadata("design:paramtypes", [
1008
+ typeof _authenticationdto.RegistrationDto === "undefined" ? Object : _authenticationdto.RegistrationDto
1009
+ ]),
1010
+ _ts_metadata("design:returntype", Promise)
1011
+ ], AuthenticationService.prototype, "createUserDirectly", null);
1012
+ _ts_decorate([
1013
+ (0, _nestjsshared.LogAction)({
1014
+ action: 'auth.createUserFromPending',
1015
+ module: 'auth',
1016
+ includeParams: false
1017
+ }),
1018
+ _ts_metadata("design:type", Function),
1019
+ _ts_metadata("design:paramtypes", [
1020
+ typeof _pendingregistrationentity.PendingRegistration === "undefined" ? Object : _pendingregistrationentity.PendingRegistration
1021
+ ]),
1022
+ _ts_metadata("design:returntype", Promise)
1023
+ ], AuthenticationService.prototype, "createUserFromPendingRegistration", null);
1024
+ _ts_decorate([
1025
+ (0, _nestjsshared.LogAction)({
1026
+ action: 'auth.companySwitch',
1027
+ module: 'auth'
1028
+ }),
1029
+ _ts_metadata("design:type", Function),
1030
+ _ts_metadata("design:paramtypes", [
1031
+ String,
1032
+ String,
1033
+ String
1034
+ ]),
1035
+ _ts_metadata("design:returntype", Promise)
1036
+ ], AuthenticationService.prototype, "validateAndLoginWithCompany", null);
1037
+ _ts_decorate([
1038
+ (0, _nestjsshared.LogAction)({
1039
+ action: 'auth.refreshToken',
1040
+ module: 'auth',
1041
+ includeParams: false
1042
+ }),
1043
+ _ts_metadata("design:type", Function),
1044
+ _ts_metadata("design:paramtypes", [
1045
+ String
1046
+ ]),
1047
+ _ts_metadata("design:returntype", Promise)
1048
+ ], AuthenticationService.prototype, "refreshToken", null);
1049
+ _ts_decorate([
1050
+ (0, _nestjsshared.LogAction)({
1051
+ action: 'auth.changePassword',
1052
+ module: 'auth',
1053
+ includeParams: false
1054
+ }),
1055
+ _ts_metadata("design:type", Function),
1056
+ _ts_metadata("design:paramtypes", [
1057
+ String,
1058
+ String,
1059
+ String
1060
+ ]),
1061
+ _ts_metadata("design:returntype", Promise)
1062
+ ], AuthenticationService.prototype, "changePassword", null);
1063
+ _ts_decorate([
1064
+ (0, _nestjsshared.LogAction)({
1065
+ action: 'auth.logout',
1066
+ module: 'auth'
1067
+ }),
1068
+ _ts_metadata("design:type", Function),
1069
+ _ts_metadata("design:paramtypes", [
1070
+ String
1071
+ ]),
1072
+ _ts_metadata("design:returntype", Promise)
1073
+ ], AuthenticationService.prototype, "logout", null);
842
1074
  AuthenticationService = _ts_decorate([
843
1075
  (0, _common.Injectable)({
844
1076
  scope: _common.Scope.REQUEST
@@ -855,6 +1087,8 @@ AuthenticationService = _ts_decorate([
855
1087
  _ts_param(5, (0, _common.Inject)(_authemailservice.AuthEmailService)),
856
1088
  _ts_param(6, (0, _common.Optional)()),
857
1089
  _ts_param(6, (0, _common.Inject)(_config.USER_ENRICHER)),
1090
+ _ts_param(7, (0, _common.Optional)()),
1091
+ _ts_param(7, (0, _common.Inject)(_interfaces.NOTIFICATION_ADAPTER)),
858
1092
  _ts_metadata("design:type", Function),
859
1093
  _ts_metadata("design:paramtypes", [
860
1094
  typeof _jwt.JwtService === "undefined" ? Object : _jwt.JwtService,
@@ -863,6 +1097,7 @@ AuthenticationService = _ts_decorate([
863
1097
  typeof _authdatasourceprovider.AuthDataSourceProvider === "undefined" ? Object : _authdatasourceprovider.AuthDataSourceProvider,
864
1098
  typeof _companyselectionsessionservice.CompanySelectionSessionService === "undefined" ? Object : _companyselectionsessionservice.CompanySelectionSessionService,
865
1099
  typeof _authemailservice.AuthEmailService === "undefined" ? Object : _authemailservice.AuthEmailService,
866
- typeof _userenricherinterface.IUserEnricher === "undefined" ? Object : _userenricherinterface.IUserEnricher
1100
+ typeof _userenricherinterface.IUserEnricher === "undefined" ? Object : _userenricherinterface.IUserEnricher,
1101
+ typeof _interfaces.INotificationAdapter === "undefined" ? Object : _interfaces.INotificationAdapter
867
1102
  ])
868
1103
  ], AuthenticationService);