@flusys/nestjs-auth 2.0.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/README.md +610 -95
  2. package/cjs/controllers/authentication.controller.js +2 -173
  3. package/cjs/controllers/email-verification.controller.js +220 -0
  4. package/cjs/controllers/index.js +1 -0
  5. package/cjs/dtos/authentication.dto.js +12 -2
  6. package/cjs/entities/index.js +16 -17
  7. package/cjs/entities/pending-registration.entity.js +9 -0
  8. package/cjs/entities/user-company-permission.entity.js +3 -3
  9. package/cjs/modules/auth.module.js +33 -24
  10. package/cjs/services/auth-config.service.js +11 -7
  11. package/cjs/services/auth-datasource.provider.js +15 -27
  12. package/cjs/services/auth-email.service.js +8 -33
  13. package/cjs/services/authentication.service.js +123 -99
  14. package/cjs/services/user.service.js +28 -83
  15. package/controllers/authentication.controller.d.ts +2 -10
  16. package/controllers/email-verification.controller.d.ts +20 -0
  17. package/controllers/index.d.ts +1 -0
  18. package/dtos/authentication.dto.d.ts +1 -0
  19. package/entities/index.d.ts +5 -10
  20. package/entities/pending-registration.entity.d.ts +1 -0
  21. package/entities/user-company-permission.entity.d.ts +1 -1
  22. package/fesm/controllers/authentication.controller.js +3 -174
  23. package/fesm/controllers/email-verification.controller.js +210 -0
  24. package/fesm/controllers/index.js +1 -0
  25. package/fesm/dtos/authentication.dto.js +32 -25
  26. package/fesm/entities/index.js +17 -9
  27. package/fesm/entities/pending-registration.entity.js +9 -0
  28. package/fesm/entities/user-company-permission.entity.js +3 -3
  29. package/fesm/interfaces/user-enricher.interface.js +2 -24
  30. package/fesm/modules/auth.module.js +35 -26
  31. package/fesm/services/auth-config.service.js +11 -7
  32. package/fesm/services/auth-datasource.provider.js +15 -27
  33. package/fesm/services/auth-email.service.js +8 -33
  34. package/fesm/services/authentication.service.js +124 -100
  35. package/fesm/services/user.service.js +28 -83
  36. package/interfaces/user-enricher.interface.d.ts +3 -2
  37. package/modules/auth.module.d.ts +3 -1
  38. package/package.json +3 -3
  39. package/services/auth-config.service.d.ts +1 -0
  40. package/services/auth-datasource.provider.d.ts +1 -0
  41. package/services/auth-email.service.d.ts +1 -0
  42. package/services/authentication.service.d.ts +4 -1
  43. package/services/user.service.d.ts +5 -0
@@ -14,6 +14,7 @@ const _common = require("@nestjs/common");
14
14
  const _jwt = require("@nestjs/jwt");
15
15
  const _bcrypt = /*#__PURE__*/ _interop_require_wildcard(require("bcrypt"));
16
16
  const _config = require("../config");
17
+ const _userenricherinterface = require("../interfaces/user-enricher.interface");
17
18
  const _companybranchentity = require("../entities/company-branch.entity");
18
19
  const _companyentity = require("../entities/company.entity");
19
20
  const _usercompanypermissionentity = require("../entities/user-company-permission.entity");
@@ -92,11 +93,14 @@ function _ts_param(paramIndex, decorator) {
92
93
  };
93
94
  }
94
95
  let AuthenticationService = class AuthenticationService {
95
- // Feature Flags
96
- /** Check if company feature is enabled (tenant-aware with global fallback) */ isCompanyFeatureEnabled() {
96
+ isCompanyFeatureEnabled() {
97
97
  return this.dataSourceProvider?.isCompanyFeatureEnabled() ?? this.authConfig.isCompanyFeatureEnabled();
98
98
  }
99
- // Repository Getters
99
+ isEmailVerificationEnabled() {
100
+ const featureEnabled = this.dataSourceProvider?.isEmailVerificationEnabled() ?? this.authConfig.isEmailVerificationEnabled();
101
+ const providerAvailable = this.authEmailService?.isEmailEnabled() ?? false;
102
+ return featureEnabled && providerAvailable;
103
+ }
100
104
  async getUserRepository() {
101
105
  if (!this.dataSourceProvider) {
102
106
  throw new Error('User repository not available');
@@ -115,10 +119,8 @@ let AuthenticationService = class AuthenticationService {
115
119
  if (!this.isCompanyFeatureEnabled() || !this.dataSourceProvider) return null;
116
120
  return this.dataSourceProvider.getRepository(_companybranchentity.CompanyBranch);
117
121
  }
118
- // Login
119
122
  async login(email, password) {
120
- // Check for pending registration first (user registered but hasn't verified email yet)
121
- if (await this.authEmailService?.hasPendingRegistration(email)) {
123
+ if (this.isEmailVerificationEnabled() && await this.authEmailService.hasPendingRegistration(email)) {
122
124
  return {
123
125
  requiresEmailVerification: true,
124
126
  email,
@@ -129,7 +131,7 @@ let AuthenticationService = class AuthenticationService {
129
131
  if (!user.isActive) {
130
132
  throw new _common.UnauthorizedException('User account is deactivated');
131
133
  }
132
- if (this.authEmailService?.isEmailEnabled() && !user.emailVerified) {
134
+ if (this.isEmailVerificationEnabled() && !user.emailVerified) {
133
135
  return {
134
136
  requiresEmailVerification: true,
135
137
  email: user.email,
@@ -141,20 +143,18 @@ let AuthenticationService = class AuthenticationService {
141
143
  }
142
144
  return this.handleCompanyBasedLogin(user);
143
145
  }
144
- /** Handle login when company feature is enabled */ async handleCompanyBasedLogin(user) {
146
+ async handleCompanyBasedLogin(user) {
145
147
  const permissionRepository = await this.getPermissionRepository();
146
148
  const branchRepository = await this.getBranchRepository();
147
149
  if (!permissionRepository || !branchRepository) {
148
150
  return this.generateLoginResponse(user);
149
151
  }
150
- // Get company permissions
151
152
  const companyPermissions = await permissionRepository.find({
152
153
  where: {
153
154
  userId: user.id,
154
155
  permissionType: _enums.PermissionType.COMPANY
155
156
  }
156
157
  });
157
- // Load companies
158
158
  const companyRepository = await this.getCompanyRepository();
159
159
  if (!companyRepository) {
160
160
  return this.generateLoginResponse(user);
@@ -165,12 +165,9 @@ let AuthenticationService = class AuthenticationService {
165
165
  }).andWhere('c.is_active = :active', {
166
166
  active: true
167
167
  }).getMany() : [];
168
- // If user has no company assignments yet, return simple login response
169
- // This allows users to login and be assigned to companies later
170
168
  if (companies.length === 0) {
171
169
  return this.generateLoginResponse(user);
172
170
  }
173
- // Get branch permissions
174
171
  const branchPermissions = await permissionRepository.find({
175
172
  where: {
176
173
  userId: user.id,
@@ -183,32 +180,25 @@ let AuthenticationService = class AuthenticationService {
183
180
  }).andWhere('b.is_active = :active', {
184
181
  active: true
185
182
  }).getMany() : [];
186
- // Case 1: Single company, single branch → Direct login
187
183
  if (companies.length === 1 && branches.length === 1) {
188
184
  return this.generateLoginResponseWithCompany(user, companies[0], branches[0]);
189
185
  }
190
- // Case 2: Multiple options → Selection required (frontend handles UI)
191
- // Returns all companies with their branches for frontend to display
192
186
  return await this.generateCompanySelectionResponse(user, companies, branches);
193
187
  }
194
- // Registration
195
- /** Register a new user. If email enabled, creates pending registration. Otherwise creates user directly. */ async register(dto, verifyUrlBase) {
188
+ async register(dto, verifyUrlBase) {
196
189
  const userRepository = await this.getUserRepository();
197
190
  const existingUser = await userRepository.findOne({
198
191
  where: {
199
192
  email: dto.email
200
193
  }
201
194
  });
202
- // When company feature is enabled and user exists, allow joining/creating company
203
195
  if (existingUser && this.isCompanyFeatureEnabled()) {
204
196
  return this.handleExistingUserCompanyRegistration(existingUser, dto);
205
197
  }
206
- // User exists but company feature is off - email must be unique
207
198
  if (existingUser) {
208
199
  throw new _common.BadRequestException('Registration failed due to email exists. Please try again or contact support.');
209
200
  }
210
- // If email verification is enabled, create pending registration instead of user
211
- if (this.authEmailService?.isEmailEnabled() && verifyUrlBase) {
201
+ if (this.isEmailVerificationEnabled() && verifyUrlBase) {
212
202
  const companyData = this.isCompanyFeatureEnabled() ? {
213
203
  companySlug: dto.companySlug,
214
204
  branchSlug: dto.branchSlug,
@@ -222,6 +212,7 @@ let AuthenticationService = class AuthenticationService {
222
212
  phone: dto.phone,
223
213
  password: dto.password,
224
214
  companyData,
215
+ additionalFields: dto.additionalFields,
225
216
  verifyUrlBase
226
217
  });
227
218
  return {
@@ -229,10 +220,9 @@ let AuthenticationService = class AuthenticationService {
229
220
  message: result.message
230
221
  };
231
222
  }
232
- // No email verification - create user directly
233
223
  return this.createUserDirectly(dto);
234
224
  }
235
- /** Handle registration for existing user when company feature is enabled */ async handleExistingUserCompanyRegistration(existingUser, dto) {
225
+ async handleExistingUserCompanyRegistration(existingUser, dto) {
236
226
  if (!dto.companySlug && !dto.newCompanyName) {
237
227
  throw new _common.BadRequestException('Email already registered. Please login or provide a company to join/create.');
238
228
  }
@@ -241,7 +231,6 @@ let AuthenticationService = class AuthenticationService {
241
231
  if (!permissionRepository || !companyRepository) {
242
232
  throw new _common.BadRequestException('Company feature repositories not available');
243
233
  }
244
- // For existing users joining a company, check if already assigned
245
234
  if (dto.companySlug) {
246
235
  const company = await companyRepository.findOne({
247
236
  where: {
@@ -264,50 +253,92 @@ let AuthenticationService = class AuthenticationService {
264
253
  }
265
254
  return this.processCompanyRegistration(existingUser, dto, true);
266
255
  }
267
- /** Create user directly (no email verification) */ async createUserDirectly(dto) {
268
- const userRepository = await this.getUserRepository();
269
- const hashedPassword = await _bcrypt.hash(dto.password, _config.BCRYPT_SALT_ROUNDS);
270
- const user = userRepository.create({
271
- name: dto.name,
272
- email: dto.email,
273
- phone: dto.phone,
274
- password: hashedPassword,
275
- isActive: true,
276
- emailVerified: false,
277
- phoneVerified: false
278
- });
279
- await userRepository.save(user);
280
- if (!this.isCompanyFeatureEnabled()) {
281
- return this.generateRegistrationResponse(user);
256
+ async createUserDirectly(dto) {
257
+ if (!this.dataSourceProvider) {
258
+ throw new _common.BadRequestException('Data source not available');
259
+ }
260
+ const dataSource = await this.dataSourceProvider.getDataSource();
261
+ const queryRunner = dataSource.createQueryRunner();
262
+ await queryRunner.connect();
263
+ await queryRunner.startTransaction();
264
+ try {
265
+ const hashedPassword = await _bcrypt.hash(dto.password, _config.BCRYPT_SALT_ROUNDS);
266
+ const user = queryRunner.manager.create(_userentity.User, {
267
+ name: dto.name,
268
+ email: dto.email,
269
+ phone: dto.phone,
270
+ password: hashedPassword,
271
+ isActive: true,
272
+ emailVerified: false,
273
+ phoneVerified: false
274
+ });
275
+ await queryRunner.manager.save(_userentity.User, user);
276
+ if (this.userEnricher?.onUserCreated) {
277
+ await this.userEnricher.onUserCreated(user.id, dto.additionalFields ?? null, queryRunner);
278
+ }
279
+ await queryRunner.commitTransaction();
280
+ if (!this.isCompanyFeatureEnabled()) {
281
+ return this.generateRegistrationResponse(user);
282
+ }
283
+ return this.processCompanyRegistration(user, dto);
284
+ } catch (error) {
285
+ await queryRunner.rollbackTransaction();
286
+ if (error instanceof _common.BadRequestException) {
287
+ throw error;
288
+ }
289
+ _utils.ErrorHandler.logError(this.logger, error, 'createUserDirectly');
290
+ throw new _common.BadRequestException('Registration failed. Please try again.');
291
+ } finally{
292
+ await queryRunner.release();
282
293
  }
283
- return this.processCompanyRegistration(user, dto);
284
294
  }
285
- /** Create user from pending registration (after email verification) */ async createUserFromPendingRegistration(pending) {
286
- const userRepository = await this.getUserRepository();
287
- const existingUser = await userRepository.findOne({
288
- where: {
289
- email: pending.email
295
+ async createUserFromPendingRegistration(pending) {
296
+ if (!this.dataSourceProvider) {
297
+ throw new _common.BadRequestException('Data source not available');
298
+ }
299
+ const dataSource = await this.dataSourceProvider.getDataSource();
300
+ const queryRunner = dataSource.createQueryRunner();
301
+ await queryRunner.connect();
302
+ await queryRunner.startTransaction();
303
+ try {
304
+ const existingUser = await queryRunner.manager.findOne(_userentity.User, {
305
+ where: {
306
+ email: pending.email
307
+ }
308
+ });
309
+ if (existingUser) {
310
+ throw new _common.BadRequestException('This email has already been registered.');
290
311
  }
291
- });
292
- if (existingUser) {
293
- throw new _common.BadRequestException('This email has already been registered.');
294
- }
295
- const user = userRepository.create({
296
- name: pending.name,
297
- email: pending.email,
298
- phone: pending.phone,
299
- password: pending.passwordHash,
300
- isActive: true,
301
- emailVerified: true,
302
- phoneVerified: false
303
- });
304
- await userRepository.save(user);
305
- if (this.isCompanyFeatureEnabled() && pending.companyData) {
306
- return this.processCompanyRegistration(user, pending.companyData);
312
+ const user = queryRunner.manager.create(_userentity.User, {
313
+ name: pending.name,
314
+ email: pending.email,
315
+ phone: pending.phone,
316
+ password: pending.passwordHash,
317
+ isActive: true,
318
+ emailVerified: true,
319
+ phoneVerified: false
320
+ });
321
+ await queryRunner.manager.save(_userentity.User, user);
322
+ if (this.userEnricher?.onUserCreated) {
323
+ await this.userEnricher.onUserCreated(user.id, pending.additionalFields ?? null, queryRunner);
324
+ }
325
+ await queryRunner.commitTransaction();
326
+ if (this.isCompanyFeatureEnabled() && pending.companyData) {
327
+ return this.processCompanyRegistration(user, pending.companyData);
328
+ }
329
+ return this.generateRegistrationResponse(user);
330
+ } catch (error) {
331
+ await queryRunner.rollbackTransaction();
332
+ if (error instanceof _common.BadRequestException) {
333
+ throw error;
334
+ }
335
+ _utils.ErrorHandler.logError(this.logger, error, 'createUserFromPendingRegistration');
336
+ throw new _common.BadRequestException('Registration failed. Please try again.');
337
+ } finally{
338
+ await queryRunner.release();
307
339
  }
308
- return this.generateRegistrationResponse(user);
309
340
  }
310
- /** Process company registration (join existing or create new) */ async processCompanyRegistration(user, data, throwOnUnavailable = false) {
341
+ async processCompanyRegistration(user, data, throwOnUnavailable = false) {
311
342
  const companyRepository = await this.getCompanyRepository();
312
343
  const branchRepository = await this.getBranchRepository();
313
344
  const permissionRepository = await this.getPermissionRepository();
@@ -322,7 +353,7 @@ let AuthenticationService = class AuthenticationService {
322
353
  }
323
354
  return this.generateRegistrationResponse(user);
324
355
  }
325
- /** Find existing company/branch or create new ones */ async findOrCreateCompanyAndBranch(data, companyRepo, branchRepo) {
356
+ async findOrCreateCompanyAndBranch(data, companyRepo, branchRepo) {
326
357
  if (data.companySlug) {
327
358
  const company = await companyRepo.findOne({
328
359
  where: {
@@ -386,7 +417,7 @@ let AuthenticationService = class AuthenticationService {
386
417
  branch: null
387
418
  };
388
419
  }
389
- /** Assign user to company and optionally branch */ async assignUserPermissions(userId, companyId, branchId, permissionRepo) {
420
+ async assignUserPermissions(userId, companyId, branchId, permissionRepo) {
390
421
  await permissionRepo.save(permissionRepo.create({
391
422
  userId,
392
423
  permissionType: _enums.PermissionType.COMPANY,
@@ -400,8 +431,7 @@ let AuthenticationService = class AuthenticationService {
400
431
  }));
401
432
  }
402
433
  }
403
- // Company/Branch Selection
404
- /** Select company and branch (step 2 of login). Frontend receives all options and user selects both. */ async select(sessionId, companyId, branchId) {
434
+ async select(sessionId, companyId, branchId) {
405
435
  this.ensureCompanyFeatureEnabled();
406
436
  if (!this.sessionService) {
407
437
  throw new _common.BadRequestException('Session service not available');
@@ -412,11 +442,11 @@ let AuthenticationService = class AuthenticationService {
412
442
  }
413
443
  return this.validateAndLoginWithCompany(session.userId, companyId, branchId);
414
444
  }
415
- /** Switch company/branch after login */ async switchCompany(userId, companyId, branchId) {
445
+ async switchCompany(userId, companyId, branchId) {
416
446
  this.ensureCompanyFeatureEnabled();
417
447
  return this.validateAndLoginWithCompany(userId, companyId, branchId);
418
448
  }
419
- /** Shared: Validate user access to company/branch and generate login response */ async validateAndLoginWithCompany(userId, companyId, branchId) {
449
+ async validateAndLoginWithCompany(userId, companyId, branchId) {
420
450
  const userRepository = await this.getUserRepository();
421
451
  const user = await userRepository.findOne({
422
452
  where: {
@@ -432,7 +462,6 @@ let AuthenticationService = class AuthenticationService {
432
462
  if (!permissionRepository || !companyRepository || !branchRepository) {
433
463
  throw new _common.BadRequestException('Repositories not available');
434
464
  }
435
- // Validate company access
436
465
  const hasCompanyAccess = await permissionRepository.findOne({
437
466
  where: {
438
467
  userId,
@@ -452,7 +481,6 @@ let AuthenticationService = class AuthenticationService {
452
481
  if (!company) {
453
482
  throw new _common.UnauthorizedException('Company not found or inactive');
454
483
  }
455
- // Validate branch access
456
484
  const hasBranchAccess = await permissionRepository.findOne({
457
485
  where: {
458
486
  userId,
@@ -475,8 +503,7 @@ let AuthenticationService = class AuthenticationService {
475
503
  }
476
504
  return this.generateLoginResponseWithCompany(user, company, branch);
477
505
  }
478
- // Token Management
479
- /** Refresh access token (with token rotation). Returns new access token and new refresh token. */ async refreshToken(refreshToken) {
506
+ async refreshToken(refreshToken) {
480
507
  try {
481
508
  const payload = this.jwtService.verify(refreshToken, {
482
509
  secret: this.authConfig.getRefreshTokenSecret()
@@ -510,7 +537,7 @@ let AuthenticationService = class AuthenticationService {
510
537
  throw new _common.UnauthorizedException('Invalid or expired refresh token');
511
538
  }
512
539
  }
513
- /** Change password */ async changePassword(userId, currentPassword, newPassword) {
540
+ async changePassword(userId, currentPassword, newPassword) {
514
541
  const userRepository = await this.getUserRepository();
515
542
  const user = await userRepository.findOne({
516
543
  where: {
@@ -524,21 +551,19 @@ let AuthenticationService = class AuthenticationService {
524
551
  user.password = await _bcrypt.hash(newPassword, _config.BCRYPT_SALT_ROUNDS);
525
552
  await userRepository.save(user);
526
553
  }
527
- /** Logout - Revokes all tokens. Stores revocation timestamp in cache. */ async logout(userId) {
554
+ async logout(userId) {
528
555
  if (!this.cacheManager) {
529
- // Cache is required for secure logout - tokens cannot be revoked without it
530
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.');
531
557
  throw new _common.BadRequestException('Logout service temporarily unavailable. Please try again later.');
532
558
  }
533
- const revokedAt = Math.floor(Date.now() / 1000); // Unix timestamp in seconds
559
+ const revokedAt = Math.floor(Date.now() / 1000);
534
560
  const cacheKey = `${_config.TOKEN_REVOKED_PREFIX}:${userId}`;
535
- // TTL matches refresh token expiry (tokens older than this are already expired)
536
561
  const refreshTokenExpiry = this.authConfig.getRefreshTokenExpiration();
537
562
  const ttlMs = this.parseExpiryToMs(refreshTokenExpiry);
538
563
  await this.cacheManager.set(cacheKey, revokedAt, ttlMs);
539
564
  this.logger.log(`User ${userId} logged out - all tokens revoked`);
540
565
  }
541
- /** Check if a token is revoked (issued before user's revocation timestamp) */ async isTokenRevoked(userId, tokenIssuedAt) {
566
+ async isTokenRevoked(userId, tokenIssuedAt) {
542
567
  if (!this.cacheManager || !tokenIssuedAt) {
543
568
  return false;
544
569
  }
@@ -547,12 +572,11 @@ let AuthenticationService = class AuthenticationService {
547
572
  if (!revokedAt) {
548
573
  return false;
549
574
  }
550
- // Token is revoked if it was issued before the revocation timestamp
551
575
  return tokenIssuedAt < revokedAt;
552
576
  }
553
- /** Parse JWT expiry string to milliseconds */ parseExpiryToMs(expiry) {
577
+ parseExpiryToMs(expiry) {
554
578
  const match = expiry.match(/^(\d+)([smhd])$/);
555
- if (!match) return 7 * 24 * 60 * 60 * 1000; // Default 7 days
579
+ if (!match) return 7 * 24 * 60 * 60 * 1000;
556
580
  const value = parseInt(match[1], 10);
557
581
  const unit = match[2];
558
582
  switch(unit){
@@ -568,8 +592,7 @@ let AuthenticationService = class AuthenticationService {
568
592
  return 7 * 24 * 60 * 60 * 1000;
569
593
  }
570
594
  }
571
- // Query Methods
572
- /** Get user's companies */ async getUserCompanies(userId) {
595
+ async getUserCompanies(userId) {
573
596
  this.ensureCompanyFeatureEnabled();
574
597
  const permissionRepository = await this.getPermissionRepository();
575
598
  const companyRepository = await this.getCompanyRepository();
@@ -590,14 +613,13 @@ let AuthenticationService = class AuthenticationService {
590
613
  active: true
591
614
  }).orderBy('c.name', 'ASC').getMany();
592
615
  }
593
- /** Get branches for a company that user has access to */ async getUserBranches(userId, companyId) {
616
+ async getUserBranches(userId, companyId) {
594
617
  this.ensureCompanyFeatureEnabled();
595
618
  const permissionRepository = await this.getPermissionRepository();
596
619
  const branchRepository = await this.getBranchRepository();
597
620
  if (!permissionRepository || !branchRepository) {
598
621
  throw new _common.BadRequestException('Repositories not available');
599
622
  }
600
- // Verify company access
601
623
  const companyPermission = await permissionRepository.findOne({
602
624
  where: {
603
625
  userId,
@@ -608,7 +630,6 @@ let AuthenticationService = class AuthenticationService {
608
630
  if (!companyPermission) {
609
631
  throw new _common.UnauthorizedException('No access to this company');
610
632
  }
611
- // Get branch permissions
612
633
  const branchPermissions = await permissionRepository.find({
613
634
  where: {
614
635
  userId,
@@ -625,7 +646,7 @@ let AuthenticationService = class AuthenticationService {
625
646
  active: true
626
647
  }).orderBy('b.serial', 'ASC').addOrderBy('b.name', 'ASC').getMany();
627
648
  }
628
- /** Get company by ID */ async getCompanyById(companyId) {
649
+ async getCompanyById(companyId) {
629
650
  const companyRepository = await this.getCompanyRepository();
630
651
  if (!companyRepository) {
631
652
  return null;
@@ -636,7 +657,7 @@ let AuthenticationService = class AuthenticationService {
636
657
  }
637
658
  });
638
659
  }
639
- /** Get branch by ID */ async getBranchById(branchId) {
660
+ async getBranchById(branchId) {
640
661
  const branchRepository = await this.getBranchRepository();
641
662
  if (!branchRepository) {
642
663
  return null;
@@ -647,7 +668,7 @@ let AuthenticationService = class AuthenticationService {
647
668
  }
648
669
  });
649
670
  }
650
- /** Get user info for /auth/me endpoint. Returns user, company, and branch info (no tokens). */ async getUserInfo(userId, companyId, branchId) {
671
+ async getUserInfo(userId, companyId, branchId) {
651
672
  const userRepository = await this.getUserRepository();
652
673
  const user = await userRepository.findOne({
653
674
  where: {
@@ -673,7 +694,6 @@ let AuthenticationService = class AuthenticationService {
673
694
  }
674
695
  return response;
675
696
  }
676
- // Helper Methods
677
697
  ensureCompanyFeatureEnabled() {
678
698
  if (!this.isCompanyFeatureEnabled()) {
679
699
  throw new _common.BadRequestException('Company feature is not enabled');
@@ -693,8 +713,7 @@ let AuthenticationService = class AuthenticationService {
693
713
  await userRepository.save(user);
694
714
  return user;
695
715
  }
696
- // Response Generators
697
- /** Create user info object */ toUserInfo(user) {
716
+ toUserInfo(user) {
698
717
  return {
699
718
  id: user.id,
700
719
  email: user.email,
@@ -703,7 +722,7 @@ let AuthenticationService = class AuthenticationService {
703
722
  profilePictureId: user.profilePictureId ?? null
704
723
  };
705
724
  }
706
- /** Create company info object */ toCompanyInfo(company) {
725
+ toCompanyInfo(company) {
707
726
  return {
708
727
  id: company.id,
709
728
  name: company.name,
@@ -711,7 +730,7 @@ let AuthenticationService = class AuthenticationService {
711
730
  logoId: company.logoId ?? null
712
731
  };
713
732
  }
714
- /** Create branch info object */ toBranchInfo(branch) {
733
+ toBranchInfo(branch) {
715
734
  return {
716
735
  id: branch.id,
717
736
  name: branch.name,
@@ -719,7 +738,7 @@ let AuthenticationService = class AuthenticationService {
719
738
  logoId: branch.logoId ?? null
720
739
  };
721
740
  }
722
- /** Generate JWT tokens */ generateTokens(payload) {
741
+ generateTokens(payload) {
723
742
  const accessToken = this.jwtService.sign({
724
743
  ...payload,
725
744
  type: 'access'
@@ -801,13 +820,14 @@ let AuthenticationService = class AuthenticationService {
801
820
  };
802
821
  }
803
822
  // NOTE: @Inject() required for bundled code - type metadata may be lost during esbuild
804
- constructor(jwtService, authConfig, cacheManager, dataSourceProvider, sessionService, authEmailService){
823
+ constructor(jwtService, authConfig, cacheManager, dataSourceProvider, sessionService, authEmailService, userEnricher){
805
824
  _define_property(this, "jwtService", void 0);
806
825
  _define_property(this, "authConfig", void 0);
807
826
  _define_property(this, "cacheManager", void 0);
808
827
  _define_property(this, "dataSourceProvider", void 0);
809
828
  _define_property(this, "sessionService", void 0);
810
829
  _define_property(this, "authEmailService", void 0);
830
+ _define_property(this, "userEnricher", void 0);
811
831
  _define_property(this, "logger", void 0);
812
832
  this.jwtService = jwtService;
813
833
  this.authConfig = authConfig;
@@ -815,6 +835,7 @@ let AuthenticationService = class AuthenticationService {
815
835
  this.dataSourceProvider = dataSourceProvider;
816
836
  this.sessionService = sessionService;
817
837
  this.authEmailService = authEmailService;
838
+ this.userEnricher = userEnricher;
818
839
  this.logger = new _common.Logger(AuthenticationService.name);
819
840
  }
820
841
  };
@@ -832,6 +853,8 @@ AuthenticationService = _ts_decorate([
832
853
  _ts_param(4, (0, _common.Inject)(_companyselectionsessionservice.CompanySelectionSessionService)),
833
854
  _ts_param(5, (0, _common.Optional)()),
834
855
  _ts_param(5, (0, _common.Inject)(_authemailservice.AuthEmailService)),
856
+ _ts_param(6, (0, _common.Optional)()),
857
+ _ts_param(6, (0, _common.Inject)(_config.USER_ENRICHER)),
835
858
  _ts_metadata("design:type", Function),
836
859
  _ts_metadata("design:paramtypes", [
837
860
  typeof _jwt.JwtService === "undefined" ? Object : _jwt.JwtService,
@@ -839,6 +862,7 @@ AuthenticationService = _ts_decorate([
839
862
  typeof _classes.HybridCache === "undefined" ? Object : _classes.HybridCache,
840
863
  typeof _authdatasourceprovider.AuthDataSourceProvider === "undefined" ? Object : _authdatasourceprovider.AuthDataSourceProvider,
841
864
  typeof _companyselectionsessionservice.CompanySelectionSessionService === "undefined" ? Object : _companyselectionsessionservice.CompanySelectionSessionService,
842
- typeof _authemailservice.AuthEmailService === "undefined" ? Object : _authemailservice.AuthEmailService
865
+ typeof _authemailservice.AuthEmailService === "undefined" ? Object : _authemailservice.AuthEmailService,
866
+ typeof _userenricherinterface.IUserEnricher === "undefined" ? Object : _userenricherinterface.IUserEnricher
843
867
  ])
844
868
  ], AuthenticationService);