@flusys/nestjs-auth 0.1.0-beta.2 → 1.0.0-beta

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 (38) hide show
  1. package/README.md +1 -11
  2. package/cjs/config/auth.constants.js +10 -4
  3. package/cjs/controllers/authentication.controller.js +7 -32
  4. package/cjs/controllers/branch.controller.js +3 -4
  5. package/cjs/controllers/company.controller.js +3 -4
  6. package/cjs/controllers/user-permission.controller.js +6 -18
  7. package/cjs/controllers/user.controller.js +17 -22
  8. package/cjs/interfaces/authentication.interface.js +0 -3
  9. package/cjs/services/auth-config.service.js +18 -44
  10. package/cjs/services/auth-datasource.provider.js +13 -31
  11. package/cjs/services/authentication.service.js +80 -85
  12. package/cjs/services/branch.service.js +10 -44
  13. package/cjs/services/company.service.js +7 -36
  14. package/cjs/services/user-permission.service.js +9 -27
  15. package/cjs/services/user.service.js +33 -91
  16. package/cjs/strategies/jwt.strategy.js +14 -1
  17. package/config/auth.constants.d.ts +2 -0
  18. package/fesm/config/auth.constants.js +7 -8
  19. package/fesm/controllers/authentication.controller.js +7 -32
  20. package/fesm/controllers/branch.controller.js +5 -6
  21. package/fesm/controllers/company.controller.js +5 -6
  22. package/fesm/controllers/user-permission.controller.js +6 -18
  23. package/fesm/controllers/user.controller.js +17 -22
  24. package/fesm/dtos/authentication.dto.js +17 -97
  25. package/fesm/interfaces/authentication.interface.js +1 -7
  26. package/fesm/services/auth-config.service.js +18 -44
  27. package/fesm/services/auth-datasource.provider.js +13 -31
  28. package/fesm/services/authentication.service.js +78 -83
  29. package/fesm/services/branch.service.js +11 -45
  30. package/fesm/services/company.service.js +8 -37
  31. package/fesm/services/user-permission.service.js +9 -27
  32. package/fesm/services/user.service.js +34 -92
  33. package/fesm/strategies/jwt.strategy.js +14 -1
  34. package/package.json +4 -4
  35. package/services/authentication.service.d.ts +6 -2
  36. package/services/branch.service.d.ts +2 -5
  37. package/services/company.service.d.ts +1 -4
  38. package/services/user.service.d.ts +1 -3
@@ -17,6 +17,8 @@ const _utils = require("@flusys/nestjs-shared/utils");
17
17
  const _authconfigservice = require("./auth-config.service");
18
18
  const _authdatasourceprovider = require("./auth-datasource.provider");
19
19
  const _enums = require("../enums");
20
+ const _config = require("../config");
21
+ const _classes = require("@flusys/nestjs-shared/classes");
20
22
  const _companybranchentity = require("../entities/company-branch.entity");
21
23
  const _companyentity = require("../entities/company.entity");
22
24
  const _usercompanypermissionentity = require("../entities/user-company-permission.entity");
@@ -90,12 +92,8 @@ function _ts_param(paramIndex, decorator) {
90
92
  decorator(target, key, paramIndex);
91
93
  };
92
94
  }
93
- // Password hashing configuration
94
- const BCRYPT_SALT_ROUNDS = 12; // Increased from 10 for better security
95
95
  let AuthenticationService = class AuthenticationService {
96
- // ==========================================================================
97
- // REPOSITORY GETTERS
98
- // ==========================================================================
96
+ // Repository Getters
99
97
  async getUserRepository() {
100
98
  if (this.dataSourceProvider) {
101
99
  return this.dataSourceProvider.getRepository(_userentity.User);
@@ -126,13 +124,8 @@ let AuthenticationService = class AuthenticationService {
126
124
  }
127
125
  return this.injectedBranchRepository ?? null;
128
126
  }
129
- // ==========================================================================
130
- // LOGIN
131
- // ==========================================================================
132
- /**
133
- * Login with email and password
134
- * Returns either tokens directly or requires company/branch selection
135
- */ async login(email, password) {
127
+ // Login
128
+ /** Login with email and password. Returns tokens or requires company/branch selection. */ async login(email, password) {
136
129
  const user = await this.validateUser(email, password);
137
130
  if (!user.isActive) {
138
131
  throw new _common.UnauthorizedException('User account is deactivated');
@@ -143,9 +136,7 @@ let AuthenticationService = class AuthenticationService {
143
136
  }
144
137
  return this.handleCompanyBasedLogin(user);
145
138
  }
146
- /**
147
- * Handle login when company feature is enabled
148
- */ async handleCompanyBasedLogin(user) {
139
+ /** Handle login when company feature is enabled */ async handleCompanyBasedLogin(user) {
149
140
  const permissionRepository = await this.getPermissionRepository();
150
141
  const branchRepository = await this.getBranchRepository();
151
142
  if (!permissionRepository || !branchRepository) {
@@ -195,13 +186,8 @@ let AuthenticationService = class AuthenticationService {
195
186
  // Returns all companies with their branches for frontend to display
196
187
  return await this.generateCompanySelectionResponse(user, companies, branches);
197
188
  }
198
- // ==========================================================================
199
- // REGISTRATION
200
- // ==========================================================================
201
- /**
202
- * Register a new user
203
- * If company feature enabled, optionally join/create company
204
- */ async register(dto) {
189
+ // Registration
190
+ /** Register a new user. If company feature enabled, optionally join/create company. */ async register(dto) {
205
191
  const userRepository = await this.getUserRepository();
206
192
  // Check if user exists
207
193
  // Note: Generic error message to prevent email enumeration attacks
@@ -214,7 +200,7 @@ let AuthenticationService = class AuthenticationService {
214
200
  throw new _common.BadRequestException('Registration failed. Please try again or contact support.');
215
201
  }
216
202
  // Create user
217
- const hashedPassword = await _bcrypt.hash(dto.password, BCRYPT_SALT_ROUNDS);
203
+ const hashedPassword = await _bcrypt.hash(dto.password, _config.BCRYPT_SALT_ROUNDS);
218
204
  const user = userRepository.create({
219
205
  name: dto.name,
220
206
  email: dto.email,
@@ -232,9 +218,7 @@ let AuthenticationService = class AuthenticationService {
232
218
  // Handle company feature
233
219
  return this.handleCompanyRegistration(user, dto);
234
220
  }
235
- /**
236
- * Handle company-related registration logic
237
- */ async handleCompanyRegistration(user, dto) {
221
+ /** Handle company-related registration logic */ async handleCompanyRegistration(user, dto) {
238
222
  const companyRepository = await this.getCompanyRepository();
239
223
  const branchRepository = await this.getBranchRepository();
240
224
  const permissionRepository = await this.getPermissionRepository();
@@ -331,18 +315,11 @@ let AuthenticationService = class AuthenticationService {
331
315
  // No company assigned
332
316
  return this.generateLoginResponse(user, true);
333
317
  }
334
- /**
335
- * Generate URL-friendly slug from name
336
- */ generateSlug(name) {
318
+ /** Generate URL-friendly slug from name */ generateSlug(name) {
337
319
  return name.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, '').substring(0, 100);
338
320
  }
339
- // ==========================================================================
340
- // COMPANY/BRANCH SELECTION
341
- // ==========================================================================
342
- /**
343
- * Select company and branch (step 2 of login)
344
- * Frontend receives all options and user selects both together
345
- */ async select(sessionId, companyId, branchId) {
321
+ // Company/Branch Selection
322
+ /** Select company and branch (step 2 of login). Frontend receives all options and user selects both. */ async select(sessionId, companyId, branchId) {
346
323
  this.ensureCompanyFeatureEnabled();
347
324
  if (!this.sessionService) {
348
325
  throw new _common.BadRequestException('Session service not available');
@@ -409,9 +386,7 @@ let AuthenticationService = class AuthenticationService {
409
386
  }
410
387
  return this.generateLoginResponseWithCompany(user, company, branch);
411
388
  }
412
- /**
413
- * Switch company/branch after login
414
- */ async switchCompany(userId, companyId, branchId) {
389
+ /** Switch company/branch after login */ async switchCompany(userId, companyId, branchId) {
415
390
  this.ensureCompanyFeatureEnabled();
416
391
  const userRepository = await this.getUserRepository();
417
392
  const user = await userRepository.findOne({
@@ -470,13 +445,8 @@ let AuthenticationService = class AuthenticationService {
470
445
  }
471
446
  return this.generateLoginResponseWithCompany(user, company, branch);
472
447
  }
473
- // ==========================================================================
474
- // TOKEN MANAGEMENT
475
- // ==========================================================================
476
- /**
477
- * Refresh access token (with token rotation)
478
- * Returns new access token and new refresh token
479
- */ async refreshToken(refreshToken) {
448
+ // Token Management
449
+ /** Refresh access token (with token rotation). Returns new access token and new refresh token. */ async refreshToken(refreshToken) {
480
450
  try {
481
451
  const payload = this.jwtService.verify(refreshToken, {
482
452
  secret: this.authConfig.getRefreshTokenSecret()
@@ -542,9 +512,7 @@ let AuthenticationService = class AuthenticationService {
542
512
  throw new _common.UnauthorizedException('Invalid or expired refresh token');
543
513
  }
544
514
  }
545
- /**
546
- * Change password
547
- */ async changePassword(userId, currentPassword, newPassword) {
515
+ /** Change password */ async changePassword(userId, currentPassword, newPassword) {
548
516
  const userRepository = await this.getUserRepository();
549
517
  const user = await userRepository.findOne({
550
518
  where: {
@@ -558,18 +526,53 @@ let AuthenticationService = class AuthenticationService {
558
526
  if (!isPasswordValid) {
559
527
  throw new _common.UnauthorizedException('Current password is incorrect');
560
528
  }
561
- user.password = await _bcrypt.hash(newPassword, BCRYPT_SALT_ROUNDS);
529
+ user.password = await _bcrypt.hash(newPassword, _config.BCRYPT_SALT_ROUNDS);
562
530
  await userRepository.save(user);
563
531
  }
564
- /**
565
- * Logout (placeholder for token blacklisting if needed)
566
- */ async logout(_userId) {}
567
- // ==========================================================================
568
- // QUERY METHODS
569
- // ==========================================================================
570
- /**
571
- * Get user's companies
572
- */ async getUserCompanies(userId) {
532
+ /** Logout - Revokes all tokens. Stores revocation timestamp in cache. */ async logout(userId) {
533
+ if (!this.cacheManager) {
534
+ // Cache not available - graceful degradation (client-side logout only)
535
+ return;
536
+ }
537
+ const revokedAt = Math.floor(Date.now() / 1000); // Unix timestamp in seconds
538
+ const cacheKey = `${_config.TOKEN_REVOKED_PREFIX}:${userId}`;
539
+ // TTL matches refresh token expiry (tokens older than this are already expired)
540
+ const refreshTokenExpiry = this.authConfig.getRefreshTokenExpiration();
541
+ const ttlMs = this.parseExpiryToMs(refreshTokenExpiry);
542
+ await this.cacheManager.set(cacheKey, revokedAt, ttlMs);
543
+ }
544
+ /** Check if a token is revoked (issued before user's revocation timestamp) */ async isTokenRevoked(userId, tokenIssuedAt) {
545
+ if (!this.cacheManager || !tokenIssuedAt) {
546
+ return false;
547
+ }
548
+ const cacheKey = `${_config.TOKEN_REVOKED_PREFIX}:${userId}`;
549
+ const revokedAt = await this.cacheManager.get(cacheKey);
550
+ if (!revokedAt) {
551
+ return false;
552
+ }
553
+ // Token is revoked if it was issued before the revocation timestamp
554
+ return tokenIssuedAt < revokedAt;
555
+ }
556
+ /** Parse JWT expiry string to milliseconds */ parseExpiryToMs(expiry) {
557
+ const match = expiry.match(/^(\d+)([smhd])$/);
558
+ if (!match) return 7 * 24 * 60 * 60 * 1000; // Default 7 days
559
+ const value = parseInt(match[1], 10);
560
+ const unit = match[2];
561
+ switch(unit){
562
+ case 's':
563
+ return value * 1000;
564
+ case 'm':
565
+ return value * 60 * 1000;
566
+ case 'h':
567
+ return value * 60 * 60 * 1000;
568
+ case 'd':
569
+ return value * 24 * 60 * 60 * 1000;
570
+ default:
571
+ return 7 * 24 * 60 * 60 * 1000;
572
+ }
573
+ }
574
+ // Query Methods
575
+ /** Get user's companies */ async getUserCompanies(userId) {
573
576
  this.ensureCompanyFeatureEnabled();
574
577
  const permissionRepository = await this.getPermissionRepository();
575
578
  const companyRepository = await this.getCompanyRepository();
@@ -590,9 +593,7 @@ let AuthenticationService = class AuthenticationService {
590
593
  active: true
591
594
  }).orderBy('c.name', 'ASC').getMany();
592
595
  }
593
- /**
594
- * Get branches for a company that user has access to
595
- */ async getUserBranches(userId, companyId) {
596
+ /** Get branches for a company that user has access to */ async getUserBranches(userId, companyId) {
596
597
  this.ensureCompanyFeatureEnabled();
597
598
  const permissionRepository = await this.getPermissionRepository();
598
599
  const branchRepository = await this.getBranchRepository();
@@ -627,9 +628,7 @@ let AuthenticationService = class AuthenticationService {
627
628
  active: true
628
629
  }).orderBy('b.serial', 'ASC').addOrderBy('b.name', 'ASC').getMany();
629
630
  }
630
- /**
631
- * Get company by ID
632
- */ async getCompanyById(companyId) {
631
+ /** Get company by ID */ async getCompanyById(companyId) {
633
632
  const companyRepository = await this.getCompanyRepository();
634
633
  if (!companyRepository) {
635
634
  return null;
@@ -640,9 +639,7 @@ let AuthenticationService = class AuthenticationService {
640
639
  }
641
640
  });
642
641
  }
643
- /**
644
- * Get branch by ID
645
- */ async getBranchById(branchId) {
642
+ /** Get branch by ID */ async getBranchById(branchId) {
646
643
  const branchRepository = await this.getBranchRepository();
647
644
  if (!branchRepository) {
648
645
  return null;
@@ -653,10 +650,7 @@ let AuthenticationService = class AuthenticationService {
653
650
  }
654
651
  });
655
652
  }
656
- /**
657
- * Get user info for /auth/me endpoint
658
- * Returns only user, company, and branch information (no tokens)
659
- */ async getUserInfo(userId, companyId, branchId) {
653
+ /** Get user info for /auth/me endpoint. Returns user, company, and branch info (no tokens). */ async getUserInfo(userId, companyId, branchId) {
660
654
  const userRepository = await this.getUserRepository();
661
655
  const user = await userRepository.findOne({
662
656
  where: {
@@ -707,9 +701,7 @@ let AuthenticationService = class AuthenticationService {
707
701
  }
708
702
  return response;
709
703
  }
710
- // ==========================================================================
711
- // HELPER METHODS
712
- // ==========================================================================
704
+ // Helper Methods
713
705
  ensureCompanyFeatureEnabled() {
714
706
  if (!this.authConfig.isCompanyFeatureEnabled()) {
715
707
  throw new _common.BadRequestException('Company feature is not enabled');
@@ -733,9 +725,7 @@ let AuthenticationService = class AuthenticationService {
733
725
  await userRepository.save(user);
734
726
  return user;
735
727
  }
736
- // ==========================================================================
737
- // RESPONSE GENERATORS
738
- // ==========================================================================
728
+ // Response Generators
739
729
  generateLoginResponse(user, companyFeatureEnabled = false) {
740
730
  const payload = {
741
731
  id: user.id,
@@ -848,9 +838,10 @@ let AuthenticationService = class AuthenticationService {
848
838
  };
849
839
  }
850
840
  // NOTE: @Inject() required for bundled code - type metadata may be lost during esbuild
851
- constructor(jwtService, authConfig, dataSourceProvider, sessionService, injectedUserRepository, injectedPermissionRepository, injectedCompanyRepository, injectedBranchRepository){
841
+ constructor(jwtService, authConfig, cacheManager, dataSourceProvider, sessionService, injectedUserRepository, injectedPermissionRepository, injectedCompanyRepository, injectedBranchRepository){
852
842
  _define_property(this, "jwtService", void 0);
853
843
  _define_property(this, "authConfig", void 0);
844
+ _define_property(this, "cacheManager", void 0);
854
845
  _define_property(this, "dataSourceProvider", void 0);
855
846
  _define_property(this, "sessionService", void 0);
856
847
  _define_property(this, "injectedUserRepository", void 0);
@@ -860,6 +851,7 @@ let AuthenticationService = class AuthenticationService {
860
851
  _define_property(this, "logger", void 0);
861
852
  this.jwtService = jwtService;
862
853
  this.authConfig = authConfig;
854
+ this.cacheManager = cacheManager;
863
855
  this.dataSourceProvider = dataSourceProvider;
864
856
  this.sessionService = sessionService;
865
857
  this.injectedUserRepository = injectedUserRepository;
@@ -876,21 +868,24 @@ AuthenticationService = _ts_decorate([
876
868
  _ts_param(0, (0, _common.Inject)(_jwt.JwtService)),
877
869
  _ts_param(1, (0, _common.Inject)(_authconfigservice.AuthConfigService)),
878
870
  _ts_param(2, (0, _common.Optional)()),
879
- _ts_param(2, (0, _common.Inject)(_authdatasourceprovider.AuthDataSourceProvider)),
871
+ _ts_param(2, (0, _common.Inject)('CACHE_INSTANCE')),
880
872
  _ts_param(3, (0, _common.Optional)()),
881
- _ts_param(3, (0, _common.Inject)(_companyselectionsessionservice.CompanySelectionSessionService)),
873
+ _ts_param(3, (0, _common.Inject)(_authdatasourceprovider.AuthDataSourceProvider)),
882
874
  _ts_param(4, (0, _common.Optional)()),
883
- _ts_param(4, (0, _typeorm.InjectRepository)(_userentity.User)),
875
+ _ts_param(4, (0, _common.Inject)(_companyselectionsessionservice.CompanySelectionSessionService)),
884
876
  _ts_param(5, (0, _common.Optional)()),
885
- _ts_param(5, (0, _typeorm.InjectRepository)(_usercompanypermissionentity.UserCompanyPermission)),
877
+ _ts_param(5, (0, _typeorm.InjectRepository)(_userentity.User)),
886
878
  _ts_param(6, (0, _common.Optional)()),
887
- _ts_param(6, (0, _typeorm.InjectRepository)(_companyentity.Company)),
879
+ _ts_param(6, (0, _typeorm.InjectRepository)(_usercompanypermissionentity.UserCompanyPermission)),
888
880
  _ts_param(7, (0, _common.Optional)()),
889
- _ts_param(7, (0, _typeorm.InjectRepository)(_companybranchentity.CompanyBranch)),
881
+ _ts_param(7, (0, _typeorm.InjectRepository)(_companyentity.Company)),
882
+ _ts_param(8, (0, _common.Optional)()),
883
+ _ts_param(8, (0, _typeorm.InjectRepository)(_companybranchentity.CompanyBranch)),
890
884
  _ts_metadata("design:type", Function),
891
885
  _ts_metadata("design:paramtypes", [
892
886
  typeof _jwt.JwtService === "undefined" ? Object : _jwt.JwtService,
893
887
  typeof _authconfigservice.AuthConfigService === "undefined" ? Object : _authconfigservice.AuthConfigService,
888
+ typeof _classes.HybridCache === "undefined" ? Object : _classes.HybridCache,
894
889
  typeof _authdatasourceprovider.AuthDataSourceProvider === "undefined" ? Object : _authdatasourceprovider.AuthDataSourceProvider,
895
890
  typeof _companyselectionsessionservice.CompanySelectionSessionService === "undefined" ? Object : _companyselectionsessionservice.CompanySelectionSessionService,
896
891
  typeof _typeorm1.Repository === "undefined" ? Object : _typeorm1.Repository,
@@ -42,41 +42,15 @@ function _ts_param(paramIndex, decorator) {
42
42
  };
43
43
  }
44
44
  let BranchService = class BranchService extends _classes.RequestScopedApiService {
45
- /**
46
- * Resolve entity class for this service
47
- * @returns CompanyBranch entity class
48
- */ resolveEntity() {
45
+ resolveEntity() {
49
46
  return _companybranchentity.CompanyBranch;
50
47
  }
51
- /**
52
- * Get DataSource provider for this service
53
- * @returns AuthDataSourceProvider instance
54
- */ getDataSourceProvider() {
48
+ getDataSourceProvider() {
55
49
  return this.dataSourceProvider;
56
50
  }
57
- // ==================== Entity Conversion ====================
58
- async convertSingleDtoToEntity(dto, _user) {
59
- // Repository initialization is handled automatically by RequestScopedApiService
60
- let branch = new _companybranchentity.CompanyBranch();
61
- if ('id' in dto && dto.id && typeof dto.id === 'string') {
62
- const dbData = await this.repository.findOne({
63
- where: {
64
- id: dto.id
65
- }
66
- });
67
- if (!dbData) {
68
- throw new _common.NotFoundException('Branch not found');
69
- }
70
- branch = dbData;
71
- }
72
- return {
73
- ...branch,
74
- ...dto
75
- };
76
- }
51
+ // Query Customization
77
52
  async getSelectQuery(query, _user, select) {
78
- // Repository initialization is handled automatically by RequestScopedApiService
79
- if (!select || !select.length) {
53
+ if (!select?.length) {
80
54
  select = [
81
55
  'id',
82
56
  'name',
@@ -85,14 +59,13 @@ let BranchService = class BranchService extends _classes.RequestScopedApiService
85
59
  'createdAt'
86
60
  ];
87
61
  }
88
- const selectFields = select.map((field)=>`${this.entityName}.${field}`);
89
- query.select(selectFields);
62
+ query.select(select.map((f)=>`${this.entityName}.${f}`));
90
63
  return {
91
64
  query,
92
65
  isRaw: false
93
66
  };
94
67
  }
95
- async getGlobalSearchQuery(query, search, _user) {
68
+ async getGlobalSearchQuery(query, search) {
96
69
  query.andWhere('(company_branch.name LIKE :search OR company_branch.slug LIKE :search OR company_branch.email LIKE :search)', {
97
70
  search: `%${search}%`
98
71
  });
@@ -101,24 +74,17 @@ let BranchService = class BranchService extends _classes.RequestScopedApiService
101
74
  isRaw: false
102
75
  };
103
76
  }
104
- /**
105
- * Override: Filter branches by user's company
106
- * Ensures users can only see branches belonging to their company
107
- */ async getExtraManipulateQuery(query, _filterAndPaginationDto, user) {
108
- const result = await super.getExtraManipulateQuery(query, _filterAndPaginationDto, user);
109
- // Only apply company filtering if company feature is enabled and user has company context
110
- const isCompanyFeatureEnabled = this.authConfig.isCompanyFeatureEnabled();
111
- if (isCompanyFeatureEnabled && user?.companyId) {
77
+ async getExtraManipulateQuery(query, filterDto, user) {
78
+ const result = await super.getExtraManipulateQuery(query, filterDto, user);
79
+ if (this.authConfig.isCompanyFeatureEnabled() && user?.companyId) {
112
80
  query.andWhere('company_branch.company_id = :companyId', {
113
81
  companyId: user.companyId
114
82
  });
115
83
  }
116
84
  return result;
117
85
  }
118
- // NOTE: @Inject() required for bundled code - type metadata may be lost during esbuild
119
86
  constructor(cacheManager, utilsService, dataSourceProvider, authConfig){
120
- // Repository will be set asynchronously by RequestScopedApiService
121
- super('company_branch', null, cacheManager, utilsService, BranchService.name, true), _define_property(this, "cacheManager", void 0), _define_property(this, "utilsService", void 0), _define_property(this, "dataSourceProvider", void 0), _define_property(this, "authConfig", void 0), _define_property(this, "logger", void 0), this.cacheManager = cacheManager, this.utilsService = utilsService, this.dataSourceProvider = dataSourceProvider, this.authConfig = authConfig, this.logger = new _common.Logger(BranchService.name);
87
+ super('company_branch', null, cacheManager, utilsService, BranchService.name, true), _define_property(this, "cacheManager", void 0), _define_property(this, "utilsService", void 0), _define_property(this, "dataSourceProvider", void 0), _define_property(this, "authConfig", void 0), this.cacheManager = cacheManager, this.utilsService = utilsService, this.dataSourceProvider = dataSourceProvider, this.authConfig = authConfig;
122
88
  }
123
89
  };
124
90
  BranchService = _ts_decorate([
@@ -41,41 +41,15 @@ function _ts_param(paramIndex, decorator) {
41
41
  };
42
42
  }
43
43
  let CompanyService = class CompanyService extends _classes.RequestScopedApiService {
44
- /**
45
- * Resolve entity class for this service
46
- * @returns Company entity class
47
- */ resolveEntity() {
44
+ resolveEntity() {
48
45
  return _companyentity.Company;
49
46
  }
50
- /**
51
- * Get DataSource provider for this service
52
- * @returns AuthDataSourceProvider instance
53
- */ getDataSourceProvider() {
47
+ getDataSourceProvider() {
54
48
  return this.dataSourceProvider;
55
49
  }
56
- // ==================== Entity Conversion ====================
57
- async convertSingleDtoToEntity(dto, _user) {
58
- // Repository initialization is handled automatically by RequestScopedApiService
59
- let company = new _companyentity.Company();
60
- if ('id' in dto && dto.id && typeof dto.id === 'string') {
61
- const dbData = await this.repository.findOne({
62
- where: {
63
- id: dto.id
64
- }
65
- });
66
- if (!dbData) {
67
- throw new _common.NotFoundException('Company not found');
68
- }
69
- company = dbData;
70
- }
71
- return {
72
- ...company,
73
- ...dto
74
- };
75
- }
50
+ // Query Customization
76
51
  async getSelectQuery(query, _user, select) {
77
- // Repository initialization is handled automatically by RequestScopedApiService
78
- if (!select || !select.length) {
52
+ if (!select?.length) {
79
53
  select = [
80
54
  'id',
81
55
  'name',
@@ -84,14 +58,13 @@ let CompanyService = class CompanyService extends _classes.RequestScopedApiServi
84
58
  'createdAt'
85
59
  ];
86
60
  }
87
- const selectFields = select.map((field)=>`${this.entityName}.${field}`);
88
- query.select(selectFields);
61
+ query.select(select.map((f)=>`${this.entityName}.${f}`));
89
62
  return {
90
63
  query,
91
64
  isRaw: false
92
65
  };
93
66
  }
94
- async getGlobalSearchQuery(query, search, _user) {
67
+ async getGlobalSearchQuery(query, search) {
95
68
  query.andWhere('(company.name LIKE :search OR company.slug LIKE :search OR company.email LIKE :search)', {
96
69
  search: `%${search}%`
97
70
  });
@@ -100,10 +73,8 @@ let CompanyService = class CompanyService extends _classes.RequestScopedApiServi
100
73
  isRaw: false
101
74
  };
102
75
  }
103
- // NOTE: @Inject() required for bundled code - type metadata may be lost during esbuild
104
76
  constructor(cacheManager, utilsService, dataSourceProvider){
105
- // Repository will be set asynchronously by RequestScopedApiService
106
- super('company', null, cacheManager, utilsService, CompanyService.name, true), _define_property(this, "cacheManager", void 0), _define_property(this, "utilsService", void 0), _define_property(this, "dataSourceProvider", void 0), _define_property(this, "logger", void 0), this.cacheManager = cacheManager, this.utilsService = utilsService, this.dataSourceProvider = dataSourceProvider, this.logger = new _common.Logger(CompanyService.name);
77
+ super('company', null, cacheManager, utilsService, CompanyService.name, true), _define_property(this, "cacheManager", void 0), _define_property(this, "utilsService", void 0), _define_property(this, "dataSourceProvider", void 0), this.cacheManager = cacheManager, this.utilsService = utilsService, this.dataSourceProvider = dataSourceProvider;
107
78
  }
108
79
  };
109
80
  CompanyService = _ts_decorate([
@@ -39,20 +39,14 @@ function _ts_param(paramIndex, decorator) {
39
39
  };
40
40
  }
41
41
  let UserPermissionService = class UserPermissionService {
42
- /**
43
- * Get repository lazily - initialized on first access
44
- */ async getRepository() {
42
+ /** Get repository lazily - initialized on first access */ async getRepository() {
45
43
  if (!this._repository) {
46
44
  this._repository = await this.dataSourceProvider.getRepository(_usercompanypermissionentity.UserCompanyPermission);
47
45
  }
48
46
  return this._repository;
49
47
  }
50
- // ==========================================================================
51
- // COMPANY PERMISSIONS
52
- // ==========================================================================
53
- /**
54
- * Find all companies a user has access to
55
- */ async findUserCompanies(userId) {
48
+ // Company Permissions
49
+ /** Find all companies a user has access to */ async findUserCompanies(userId) {
56
50
  const repository = await this.getRepository();
57
51
  return repository.find({
58
52
  where: {
@@ -67,9 +61,7 @@ let UserPermissionService = class UserPermissionService {
67
61
  }
68
62
  });
69
63
  }
70
- /**
71
- * Assign user to a company
72
- */ async assignUserToCompany(dto) {
64
+ /** Assign user to a company */ async assignUserToCompany(dto) {
73
65
  const repository = await this.getRepository();
74
66
  // Check if already exists
75
67
  const existing = await repository.findOne({
@@ -90,9 +82,7 @@ let UserPermissionService = class UserPermissionService {
90
82
  });
91
83
  await repository.save(permission);
92
84
  }
93
- /**
94
- * Revoke user access to a company
95
- */ async revokeCompanyAccess(userId, companyId) {
85
+ /** Revoke user access to a company */ async revokeCompanyAccess(userId, companyId) {
96
86
  const repository = await this.getRepository();
97
87
  const permission = await repository.findOne({
98
88
  where: {
@@ -106,12 +96,8 @@ let UserPermissionService = class UserPermissionService {
106
96
  }
107
97
  await repository.remove(permission);
108
98
  }
109
- // ==========================================================================
110
- // BRANCH PERMISSIONS
111
- // ==========================================================================
112
- /**
113
- * Find all branches a user has access to
114
- */ async findUserBranches(userId) {
99
+ // Branch Permissions
100
+ /** Find all branches a user has access to */ async findUserBranches(userId) {
115
101
  const repository = await this.getRepository();
116
102
  return repository.find({
117
103
  where: {
@@ -126,9 +112,7 @@ let UserPermissionService = class UserPermissionService {
126
112
  }
127
113
  });
128
114
  }
129
- /**
130
- * Assign user to a branch
131
- */ async assignUserToBranch(dto) {
115
+ /** Assign user to a branch */ async assignUserToBranch(dto) {
132
116
  const repository = await this.getRepository();
133
117
  // Check if already exists
134
118
  const existing = await repository.findOne({
@@ -149,9 +133,7 @@ let UserPermissionService = class UserPermissionService {
149
133
  });
150
134
  await repository.save(permission);
151
135
  }
152
- /**
153
- * Revoke user access to a branch
154
- */ async revokeBranchAccess(userId, branchId) {
136
+ /** Revoke user access to a branch */ async revokeBranchAccess(userId, branchId) {
155
137
  const repository = await this.getRepository();
156
138
  const permission = await repository.findOne({
157
139
  where: {