@flusys/nestjs-auth 5.0.1 → 5.0.4

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 (32) hide show
  1. package/README.md +13 -14
  2. package/cjs/controllers/user-permission.controller.js +2 -2
  3. package/cjs/controllers/user.controller.js +5 -8
  4. package/cjs/entities/{user.entity.js → app-user.entity.js} +6 -6
  5. package/cjs/entities/index.js +2 -2
  6. package/cjs/entities/user-company-permission.entity.js +3 -3
  7. package/cjs/services/auth-config.service.js +3 -0
  8. package/cjs/services/auth-email.service.js +6 -6
  9. package/cjs/services/authentication.service.js +8 -8
  10. package/cjs/services/user.service.js +117 -54
  11. package/cjs/strategies/jwt.strategy.js +2 -2
  12. package/entities/{user.entity.d.ts → app-user.entity.d.ts} +1 -1
  13. package/entities/index.d.ts +4 -4
  14. package/entities/user-company-permission.entity.d.ts +2 -2
  15. package/fesm/controllers/user-permission.controller.js +3 -3
  16. package/fesm/controllers/user.controller.js +6 -9
  17. package/fesm/entities/{user.entity.js → app-user.entity.js} +4 -4
  18. package/fesm/entities/index.js +3 -3
  19. package/fesm/entities/user-company-permission.entity.js +3 -3
  20. package/fesm/services/auth-config.service.js +3 -0
  21. package/fesm/services/auth-email.service.js +6 -6
  22. package/fesm/services/authentication.service.js +8 -8
  23. package/fesm/services/branch.service.js +1 -1
  24. package/fesm/services/company.service.js +1 -1
  25. package/fesm/services/user.service.js +118 -55
  26. package/fesm/strategies/jwt.strategy.js +2 -2
  27. package/interfaces/user-enricher.interface.d.ts +1 -5
  28. package/package.json +3 -3
  29. package/services/auth-config.service.d.ts +1 -0
  30. package/services/branch.service.d.ts +4 -4
  31. package/services/company.service.d.ts +3 -3
  32. package/services/user.service.d.ts +16 -11
package/README.md CHANGED
@@ -228,20 +228,19 @@ When `AUTH_EMAIL_PROVIDER` is not provided, registration still works but emails
228
228
 
229
229
  Extend user list and profile responses without creating circular imports. All methods are optional — implement only what you need.
230
230
 
231
- | Method | When called | Purpose |
232
- | --- | --- | --- |
233
- | `enrichListQuery` | User list query build | Add extra joins/selects to the query |
234
- | `enrichListItems` | After user list fetch | Attach computed data to list items |
235
- | `getProfileExtras` | `POST /users/get/:id` | Add roles, actions, sections to profile |
236
- | `updateProfileExtras` | Profile update (in tx) | Persist extra profile fields |
237
- | `validateProfileExtras` | Before profile update | Validate extra fields |
238
- | `getProfileSections` | Profile form init | Return multi-step section definitions |
239
- | `getProfileSectionData` | Section fetch | Return section-specific data |
240
- | `updateProfileSection` | Section save (in tx) | Persist section data |
241
- | `handleSectionFileUpload` | File upload (in tx) | Handle file attach to section |
242
- | `handleSectionFileDelete` | File delete (in tx) | Handle file removal from section |
243
- | `calculateProfileCompletion` | Profile fetch | Return 0–100 completion score |
244
- | `onUserCreated` | Registration (in tx) | Hook after user row created; throw to rollback |
231
+ | Method | When called | Purpose |
232
+ | ---------------------------- | ---------------------- | ---------------------------------------------- |
233
+ | `enrichListItems` | After user list fetch | Attach computed data to list items |
234
+ | `getProfileExtras` | `POST /users/get/:id` | Add roles, actions, sections to profile |
235
+ | `updateProfileExtras` | Profile update (in tx) | Persist extra profile fields |
236
+ | `validateProfileExtras` | Before profile update | Validate extra fields |
237
+ | `getProfileSections` | Profile form init | Return multi-step section definitions |
238
+ | `getProfileSectionData` | Section fetch | Return section-specific data |
239
+ | `updateProfileSection` | Section save (in tx) | Persist section data |
240
+ | `handleSectionFileUpload` | File upload (in tx) | Handle file attach to section |
241
+ | `handleSectionFileDelete` | File delete (in tx) | Handle file removal from section |
242
+ | `calculateProfileCompletion` | Profile fetch | Return 0–100 completion score |
243
+ | `onUserCreated` | Registration (in tx) | Hook after user row created; throw to rollback |
245
244
 
246
245
  ```typescript
247
246
  import { USER_ENRICHER, IUserEnricher, IProfileExtras } from '@flusys/nestjs-auth';
@@ -9,9 +9,9 @@ Object.defineProperty(exports, "UserPermissionController", {
9
9
  }
10
10
  });
11
11
  const _nestjsshared = require("@flusys/nestjs-shared");
12
- const _config = require("../config");
13
12
  const _common = require("@nestjs/common");
14
13
  const _swagger = require("@nestjs/swagger");
14
+ const _config = require("../config");
15
15
  const _userpermissiondto = require("../dtos/user-permission.dto");
16
16
  const _usercompanypermissionentity = require("../entities/user-company-permission.entity");
17
17
  const _userpermissionservice = require("../services/user-permission.service");
@@ -214,7 +214,7 @@ UserPermissionController = _ts_decorate([
214
214
  (0, _swagger.ApiTags)('User Permissions'),
215
215
  (0, _swagger.ApiBearerAuth)(),
216
216
  (0, _common.Controller)('administration/permissions'),
217
- (0, _common.UseGuards)(_nestjsshared.JwtAuthGuard),
217
+ (0, _common.UseGuards)(_nestjsshared.JwtAuthGuard, _nestjsshared.PermissionGuard),
218
218
  _ts_param(0, (0, _common.Inject)(_userpermissionservice.UserPermissionService)),
219
219
  _ts_metadata("design:type", Function),
220
220
  _ts_metadata("design:paramtypes", [
@@ -9,12 +9,12 @@ Object.defineProperty(exports, "UserController", {
9
9
  }
10
10
  });
11
11
  const _classes = require("@flusys/nestjs-shared/classes");
12
- const _config = require("../config");
13
12
  const _decorators = require("@flusys/nestjs-shared/decorators");
14
13
  const _guards = require("@flusys/nestjs-shared/guards");
15
14
  const _interfaces = require("@flusys/nestjs-shared/interfaces");
16
15
  const _common = require("@nestjs/common");
17
16
  const _swagger = require("@nestjs/swagger");
17
+ const _config = require("../config");
18
18
  const _userdto = require("../dtos/user.dto");
19
19
  const _userservice = require("../services/user.service");
20
20
  function _define_property(obj, key, value) {
@@ -176,7 +176,7 @@ let UserController = class UserController extends (0, _classes.createApiControll
176
176
  };
177
177
  _ts_decorate([
178
178
  (0, _common.Post)(':id/profile-extras'),
179
- (0, _common.UseGuards)(_guards.JwtAuthGuard),
179
+ (0, _common.UseGuards)(_guards.JwtAuthGuard, _guards.PermissionGuard),
180
180
  (0, _swagger.ApiBearerAuth)(),
181
181
  (0, _decorators.RequirePermission)(_classes.USER_PERMISSIONS.READ),
182
182
  (0, _swagger.ApiOperation)({
@@ -198,7 +198,7 @@ _ts_decorate([
198
198
  ], UserController.prototype, "getProfileWithExtras", null);
199
199
  _ts_decorate([
200
200
  (0, _common.Post)(':id/verify-email'),
201
- (0, _common.UseGuards)(_guards.JwtAuthGuard),
201
+ (0, _common.UseGuards)(_guards.JwtAuthGuard, _guards.PermissionGuard),
202
202
  (0, _swagger.ApiBearerAuth)(),
203
203
  (0, _decorators.RequirePermission)(_classes.USER_PERMISSIONS.UPDATE),
204
204
  (0, _swagger.ApiOperation)({
@@ -217,7 +217,7 @@ _ts_decorate([
217
217
  ], UserController.prototype, "verifyEmail", null);
218
218
  _ts_decorate([
219
219
  (0, _common.Post)(':id/verify-phone'),
220
- (0, _common.UseGuards)(_guards.JwtAuthGuard),
220
+ (0, _common.UseGuards)(_guards.JwtAuthGuard, _guards.PermissionGuard),
221
221
  (0, _swagger.ApiBearerAuth)(),
222
222
  (0, _decorators.RequirePermission)(_classes.USER_PERMISSIONS.UPDATE),
223
223
  (0, _swagger.ApiOperation)({
@@ -236,7 +236,7 @@ _ts_decorate([
236
236
  ], UserController.prototype, "verifyPhone", null);
237
237
  _ts_decorate([
238
238
  (0, _common.Post)(':id/status'),
239
- (0, _common.UseGuards)(_guards.JwtAuthGuard),
239
+ (0, _common.UseGuards)(_guards.JwtAuthGuard, _guards.PermissionGuard),
240
240
  (0, _swagger.ApiBearerAuth)(),
241
241
  (0, _decorators.RequirePermission)(_classes.USER_PERMISSIONS.UPDATE),
242
242
  (0, _swagger.ApiOperation)({
@@ -301,7 +301,6 @@ _ts_decorate([
301
301
  (0, _common.Post)(':id/profile-section/:sectionId'),
302
302
  (0, _common.UseGuards)(_guards.JwtAuthGuard),
303
303
  (0, _swagger.ApiBearerAuth)(),
304
- (0, _decorators.RequirePermission)(_classes.USER_PERMISSIONS.READ),
305
304
  (0, _swagger.ApiOperation)({
306
305
  summary: 'Get profile section data',
307
306
  description: 'Returns data for a specific profile section.'
@@ -329,7 +328,6 @@ _ts_decorate([
329
328
  (0, _common.Post)(':id/profile-section/:sectionId/update'),
330
329
  (0, _common.UseGuards)(_guards.JwtAuthGuard),
331
330
  (0, _swagger.ApiBearerAuth)(),
332
- (0, _decorators.RequirePermission)(_classes.USER_PERMISSIONS.UPDATE),
333
331
  (0, _swagger.ApiOperation)({
334
332
  summary: 'Update profile section',
335
333
  description: 'Updates a specific profile section data.'
@@ -359,7 +357,6 @@ _ts_decorate([
359
357
  (0, _common.Post)(':id/profile-completion'),
360
358
  (0, _common.UseGuards)(_guards.JwtAuthGuard),
361
359
  (0, _swagger.ApiBearerAuth)(),
362
- (0, _decorators.RequirePermission)(_classes.USER_PERMISSIONS.READ),
363
360
  (0, _swagger.ApiOperation)({
364
361
  summary: 'Get profile completion percentage',
365
362
  description: 'Returns overall profile completion percentage.'
@@ -2,10 +2,10 @@
2
2
  Object.defineProperty(exports, "__esModule", {
3
3
  value: true
4
4
  });
5
- Object.defineProperty(exports, "User", {
5
+ Object.defineProperty(exports, "AppUser", {
6
6
  enumerable: true,
7
7
  get: function() {
8
- return User;
8
+ return AppUser;
9
9
  }
10
10
  });
11
11
  const _nestjsshared = require("@flusys/nestjs-shared");
@@ -16,10 +16,10 @@ function _ts_decorate(decorators, target, key, desc) {
16
16
  else for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
17
17
  return c > 3 && r && Object.defineProperty(target, key, r), r;
18
18
  }
19
- let User = class User extends _nestjsshared.UserRoot {
19
+ let AppUser = class AppUser extends _nestjsshared.UserRoot {
20
20
  };
21
- User = _ts_decorate([
21
+ AppUser = _ts_decorate([
22
22
  (0, _typeorm.Entity)({
23
- name: 'user'
23
+ name: 'app_user'
24
24
  })
25
- ], User);
25
+ ], AppUser);
@@ -19,11 +19,11 @@ _export(exports, {
19
19
  return getEntitiesByConfig;
20
20
  }
21
21
  });
22
+ const _appuserentity = _export_star(require("./app-user.entity"), exports);
22
23
  const _companybranchentity = _export_star(require("./company-branch.entity"), exports);
23
24
  const _companyentity = _export_star(require("./company.entity"), exports);
24
25
  const _pendingregistrationentity = _export_star(require("./pending-registration.entity"), exports);
25
26
  const _usercompanypermissionentity = require("./user-company-permission.entity");
26
- const _userentity = _export_star(require("./user.entity"), exports);
27
27
  const _usertokenentity = _export_star(require("./user-token.entity"), exports);
28
28
  function _export_star(from, to) {
29
29
  Object.keys(from).forEach(function(k) {
@@ -39,7 +39,7 @@ function _export_star(from, to) {
39
39
  return from;
40
40
  }
41
41
  const BaseEntities = [
42
- _userentity.User,
42
+ _appuserentity.AppUser,
43
43
  _usertokenentity.UserToken
44
44
  ];
45
45
  const EmailEntities = [
@@ -18,9 +18,9 @@ _export(exports, {
18
18
  });
19
19
  const _typeorm = require("typeorm");
20
20
  const _enums = require("../enums");
21
+ const _appuserentity = require("./app-user.entity");
21
22
  const _companybranchentity = require("./company-branch.entity");
22
23
  const _companyentity = require("./company.entity");
23
- const _userentity = require("./user.entity");
24
24
  function _define_property(obj, key, value) {
25
25
  if (key in obj) {
26
26
  Object.defineProperty(obj, key, {
@@ -69,13 +69,13 @@ _ts_decorate([
69
69
  _ts_metadata("design:type", String)
70
70
  ], UserCompanyPermission.prototype, "userId", void 0);
71
71
  _ts_decorate([
72
- (0, _typeorm.ManyToOne)(()=>_userentity.User, {
72
+ (0, _typeorm.ManyToOne)(()=>_appuserentity.AppUser, {
73
73
  onDelete: 'CASCADE'
74
74
  }),
75
75
  (0, _typeorm.JoinColumn)({
76
76
  name: 'user_id'
77
77
  }),
78
- _ts_metadata("design:type", typeof _userentity.User === "undefined" ? Object : _userentity.User)
78
+ _ts_metadata("design:type", typeof _appuserentity.AppUser === "undefined" ? Object : _appuserentity.AppUser)
79
79
  ], UserCompanyPermission.prototype, "user", void 0);
80
80
  _ts_decorate([
81
81
  (0, _typeorm.Column)({
@@ -55,6 +55,9 @@ let AuthConfigService = class AuthConfigService {
55
55
  isEmailVerificationEnabled() {
56
56
  return this.options.bootstrapAppConfig?.enableEmailVerification ?? true;
57
57
  }
58
+ isPermissionModeFound() {
59
+ return this.options.bootstrapAppConfig?.permissionMode !== undefined;
60
+ }
58
61
  // JWT Configuration
59
62
  getJwtSecret() {
60
63
  if (!this.config.jwtSecret) {
@@ -14,9 +14,9 @@ const _common = require("@nestjs/common");
14
14
  const _bcrypt = /*#__PURE__*/ _interop_require_wildcard(require("bcrypt"));
15
15
  const _crypto = /*#__PURE__*/ _interop_require_wildcard(require("crypto"));
16
16
  const _config = require("../config");
17
+ const _appuserentity = require("../entities/app-user.entity");
17
18
  const _pendingregistrationentity = require("../entities/pending-registration.entity");
18
19
  const _usertokenentity = require("../entities/user-token.entity");
19
- const _userentity = require("../entities/user.entity");
20
20
  const _interfaces = require("../interfaces");
21
21
  const _authdatasourceprovider = require("./auth-datasource.provider");
22
22
  function _define_property(obj, key, value) {
@@ -153,7 +153,7 @@ let AuthEmailService = class AuthEmailService {
153
153
  }
154
154
  async createPendingRegistration(data) {
155
155
  this.assertEmailEnabled();
156
- const userRepository = await this.getRepository(_userentity.User);
156
+ const userRepository = await this.getRepository(_appuserentity.AppUser);
157
157
  const pendingRepository = await this.getRepository(_pendingregistrationentity.PendingRegistration);
158
158
  // Check if user already exists
159
159
  const existingUser = await userRepository.findOne({
@@ -198,7 +198,7 @@ let AuthEmailService = class AuthEmailService {
198
198
  }
199
199
  async forgotPassword(email, resetUrlBase) {
200
200
  this.assertEmailEnabled();
201
- const userRepository = await this.getRepository(_userentity.User);
201
+ const userRepository = await this.getRepository(_appuserentity.AppUser);
202
202
  const tokenRepository = await this.getRepository(_usertokenentity.UserToken);
203
203
  const user = await userRepository.findOne({
204
204
  where: {
@@ -249,7 +249,7 @@ let AuthEmailService = class AuthEmailService {
249
249
  };
250
250
  }
251
251
  async resetPassword(token, newPassword) {
252
- const userRepository = await this.getRepository(_userentity.User);
252
+ const userRepository = await this.getRepository(_appuserentity.AppUser);
253
253
  const tokenRepository = await this.getRepository(_usertokenentity.UserToken);
254
254
  // Hash the incoming token to compare with stored hash
255
255
  const tokenHash = this.hashToken(token);
@@ -291,7 +291,7 @@ let AuthEmailService = class AuthEmailService {
291
291
  }
292
292
  async verifyEmail(token) {
293
293
  const pendingRepository = await this.getRepository(_pendingregistrationentity.PendingRegistration);
294
- const userRepository = await this.getRepository(_userentity.User);
294
+ const userRepository = await this.getRepository(_appuserentity.AppUser);
295
295
  const tokenRepository = await this.getRepository(_usertokenentity.UserToken);
296
296
  // Hash the incoming token to compare with stored hash
297
297
  const tokenHash = this.hashToken(token);
@@ -375,7 +375,7 @@ let AuthEmailService = class AuthEmailService {
375
375
  async resendVerificationEmail(email, verifyUrlBase) {
376
376
  this.assertEmailEnabled();
377
377
  const pendingRepository = await this.getRepository(_pendingregistrationentity.PendingRegistration);
378
- const userRepository = await this.getRepository(_userentity.User);
378
+ const userRepository = await this.getRepository(_appuserentity.AppUser);
379
379
  const tokenRepository = await this.getRepository(_usertokenentity.UserToken);
380
380
  // Check pending registration first
381
381
  const pending = await pendingRepository.findOne({
@@ -19,11 +19,11 @@ const _jwt = require("@nestjs/jwt");
19
19
  const _bcrypt = /*#__PURE__*/ _interop_require_wildcard(require("bcrypt"));
20
20
  const _config = require("../config");
21
21
  const _authenticationdto = require("../dtos/authentication.dto");
22
+ const _appuserentity = require("../entities/app-user.entity");
22
23
  const _companybranchentity = require("../entities/company-branch.entity");
23
24
  const _companyentity = require("../entities/company.entity");
24
25
  const _pendingregistrationentity = require("../entities/pending-registration.entity");
25
26
  const _usercompanypermissionentity = require("../entities/user-company-permission.entity");
26
- const _userentity = require("../entities/user.entity");
27
27
  const _enums1 = require("../enums");
28
28
  const _userenricherinterface = require("../interfaces/user-enricher.interface");
29
29
  const _authconfigservice = require("./auth-config.service");
@@ -113,11 +113,11 @@ let AuthenticationService = class AuthenticationService {
113
113
  message: 'User repository not available',
114
114
  messageKey: _constants.SYSTEM_MESSAGES.REPOSITORY_NOT_AVAILABLE,
115
115
  messageVariables: {
116
- entity: 'User'
116
+ entity: 'AppUser'
117
117
  }
118
118
  });
119
119
  }
120
- return this.dataSourceProvider.getRepository(_userentity.User);
120
+ return this.dataSourceProvider.getRepository(_appuserentity.AppUser);
121
121
  }
122
122
  async getPermissionRepository() {
123
123
  if (!this.isCompanyFeatureEnabled() || !this.dataSourceProvider) return null;
@@ -299,7 +299,7 @@ let AuthenticationService = class AuthenticationService {
299
299
  await queryRunner.startTransaction();
300
300
  try {
301
301
  const hashedPassword = await _bcrypt.hash(dto.password, _config.BCRYPT_SALT_ROUNDS);
302
- const user = queryRunner.manager.create(_userentity.User, {
302
+ const user = queryRunner.manager.create(_appuserentity.AppUser, {
303
303
  name: dto.name,
304
304
  email: dto.email,
305
305
  phone: dto.phone,
@@ -308,7 +308,7 @@ let AuthenticationService = class AuthenticationService {
308
308
  emailVerified: false,
309
309
  phoneVerified: false
310
310
  });
311
- await queryRunner.manager.save(_userentity.User, user);
311
+ await queryRunner.manager.save(_appuserentity.AppUser, user);
312
312
  if (this.userEnricher?.onUserCreated) {
313
313
  await this.userEnricher.onUserCreated(user.id, dto.additionalFields ?? null, queryRunner);
314
314
  }
@@ -342,7 +342,7 @@ let AuthenticationService = class AuthenticationService {
342
342
  await queryRunner.connect();
343
343
  await queryRunner.startTransaction();
344
344
  try {
345
- const existingUser = await queryRunner.manager.findOne(_userentity.User, {
345
+ const existingUser = await queryRunner.manager.findOne(_appuserentity.AppUser, {
346
346
  where: {
347
347
  email: pending.email
348
348
  }
@@ -353,7 +353,7 @@ let AuthenticationService = class AuthenticationService {
353
353
  messageKey: _config.AUTH_MESSAGES.REGISTER_EMAIL_EXISTS
354
354
  });
355
355
  }
356
- const user = queryRunner.manager.create(_userentity.User, {
356
+ const user = queryRunner.manager.create(_appuserentity.AppUser, {
357
357
  name: pending.name,
358
358
  email: pending.email,
359
359
  phone: pending.phone,
@@ -362,7 +362,7 @@ let AuthenticationService = class AuthenticationService {
362
362
  emailVerified: true,
363
363
  phoneVerified: false
364
364
  });
365
- await queryRunner.manager.save(_userentity.User, user);
365
+ await queryRunner.manager.save(_appuserentity.AppUser, user);
366
366
  if (this.userEnricher?.onUserCreated) {
367
367
  await this.userEnricher.onUserCreated(user.id, pending.additionalFields ?? null, queryRunner);
368
368
  }
@@ -17,8 +17,8 @@ const _common = require("@nestjs/common");
17
17
  const _bcrypt = /*#__PURE__*/ _interop_require_wildcard(require("bcrypt"));
18
18
  const _config = require("../config");
19
19
  const _userdto = require("../dtos/user.dto");
20
+ const _appuserentity = require("../entities/app-user.entity");
20
21
  const _usercompanypermissionentity = require("../entities/user-company-permission.entity");
21
- const _userentity = require("../entities/user.entity");
22
22
  const _enums = require("../enums");
23
23
  const _userenricherinterface = require("../interfaces/user-enricher.interface");
24
24
  const _authconfigservice = require("./auth-config.service");
@@ -93,7 +93,7 @@ function _ts_param(paramIndex, decorator) {
93
93
  }
94
94
  let UserService = class UserService extends _classes.RequestScopedApiService {
95
95
  resolveEntity() {
96
- return _userentity.User;
96
+ return _appuserentity.AppUser;
97
97
  }
98
98
  getDataSourceProvider() {
99
99
  return this.dataSourceProvider;
@@ -200,24 +200,24 @@ let UserService = class UserService extends _classes.RequestScopedApiService {
200
200
  return this.convertEntityToDto(entity);
201
201
  }
202
202
  convertRawToResponseDto(raw) {
203
- const isActive = raw.user_companyIsActive !== undefined ? Boolean(raw.user_companyIsActive) : raw.user_is_active;
203
+ const isActive = raw.appuser_companyIsActive !== undefined ? Boolean(raw.appuser_companyIsActive) : raw.appuser_is_active;
204
204
  return {
205
- id: raw.user_id,
206
- name: raw.user_name,
207
- phone: raw.user_phone,
208
- email: raw.user_email,
209
- profilePictureId: raw.user_profile_picture_id,
205
+ id: raw.appuser_id,
206
+ name: raw.appuser_name,
207
+ phone: raw.appuser_phone,
208
+ email: raw.appuser_email,
209
+ profilePictureId: raw.appuser_profile_picture_id,
210
210
  isActive,
211
- emailVerified: raw.user_email_verified,
212
- phoneVerified: raw.user_phone_verified,
213
- lastLoginAt: raw.user_last_login_at,
214
- additionalFields: raw.user_additional_fields,
215
- createdAt: raw.user_created_at,
216
- updatedAt: raw.user_updated_at,
217
- deletedAt: raw.user_deleted_at,
218
- createdById: raw.user_created_by_id,
219
- updatedById: raw.user_updated_by_id,
220
- deletedById: raw.user_deleted_by_id
211
+ emailVerified: raw.appuser_email_verified,
212
+ phoneVerified: raw.appuser_phone_verified,
213
+ lastLoginAt: raw.appuser_last_login_at,
214
+ additionalFields: raw.appuser_additional_fields,
215
+ createdAt: raw.appuser_created_at,
216
+ updatedAt: raw.appuser_updated_at,
217
+ deletedAt: raw.appuser_deleted_at,
218
+ createdById: raw.appuser_created_by_id,
219
+ updatedById: raw.appuser_updated_by_id,
220
+ deletedById: raw.appuser_deleted_by_id
221
221
  };
222
222
  }
223
223
  convertEntityToDto(entity) {
@@ -243,8 +243,22 @@ let UserService = class UserService extends _classes.RequestScopedApiService {
243
243
  convertEntityListToResponseListDto(entities, isRaw) {
244
244
  return entities.map((entity)=>this.convertEntityToResponseDto(entity, isRaw));
245
245
  }
246
+ async getFilterQuery(query, filter, _user) {
247
+ for (const [key, value] of Object.entries(filter)){
248
+ if (key === 'actionCode' || key === 'isActive') {
249
+ continue; // real continue
250
+ }
251
+ query.andWhere(`${this.entityName}.${key} = :value`, {
252
+ value
253
+ });
254
+ }
255
+ return {
256
+ query,
257
+ isRaw: false
258
+ };
259
+ }
246
260
  async getGlobalSearchQuery(query, search, _user) {
247
- query.andWhere('("user".name LIKE :search OR "user".email LIKE :search OR "user".phone LIKE :search)', {
261
+ query.andWhere('(appuser.name LIKE :search OR appuser.email LIKE :search OR appuser.phone LIKE :search)', {
248
262
  search: `%${search}%`
249
263
  });
250
264
  return {
@@ -253,50 +267,99 @@ let UserService = class UserService extends _classes.RequestScopedApiService {
253
267
  };
254
268
  }
255
269
  async getExtraManipulateQuery(query, filterAndPaginationDto, user) {
256
- let result = await super.getExtraManipulateQuery(query, filterAndPaginationDto, user);
257
- if (this.userEnricher?.enrichListQuery) {
258
- await this.userEnricher.enrichListQuery(query, user);
259
- }
270
+ const superQuery = await super.getExtraManipulateQuery(query, filterAndPaginationDto, user);
260
271
  const isCompanyFeatureEnabled = this.authConfig.isCompanyFeatureEnabled();
261
- if (!isCompanyFeatureEnabled) {
262
- return result;
263
- }
264
- if (user?.companyId && this.permissionRepository) {
265
- query.addSelect(`(SELECT perm.is_active FROM user_company_permissions perm
266
- WHERE perm.user_id = "user".id
267
- AND perm.permission_type = :permissionType
268
- AND perm.target_id = :companyId
269
- LIMIT 1)`, 'user_companyIsActive');
270
- query.setParameter('permissionType', _enums.PermissionType.COMPANY);
271
- query.setParameter('companyId', user.companyId);
272
- if (filterAndPaginationDto.filter?.isActive !== undefined) {
272
+ const filter = filterAndPaginationDto?.filter;
273
+ // --- Action code filter (applies regardless of company feature) ---
274
+ if (filter?.actionCode) {
275
+ const actionCode = filter.actionCode;
276
+ const companyId = isCompanyFeatureEnabled ? user?.companyId : undefined;
277
+ if (isCompanyFeatureEnabled && !companyId) {
278
+ // Company feature is on but no companyId — no results should match
279
+ query.andWhere('1 = 0');
280
+ return {
281
+ query,
282
+ isRaw: true
283
+ };
284
+ }
285
+ const isPermissionModeFound = this.authConfig.isPermissionModeFound();
286
+ if (!isPermissionModeFound) {
287
+ // Optionally log a warning so the caller knows the filter was ignored
288
+ this.logAdapter.warn(`actionCode filter was requested but permission mode is not set to 'found' — filter ignored`);
289
+ } else {
273
290
  query.andWhere(`EXISTS (
274
- SELECT 1 FROM user_company_permissions perm
275
- WHERE perm.user_id = "user".id
276
- AND perm.permission_type = :permissionType
277
- AND perm.target_id = :companyId
278
- AND perm.is_active = :isActiveValue
279
- )`, {
280
- permissionType: _enums.PermissionType.COMPANY,
281
- companyId: user.companyId,
282
- isActiveValue: filterAndPaginationDto.filter.isActive
291
+ SELECT 1 FROM user_iam_permission perm
292
+ WHERE perm.permission_type = 'user_role'
293
+ AND perm.source_id = appuser.id
294
+ AND perm.target_id IN (
295
+ SELECT source_id FROM user_iam_permission
296
+ WHERE permission_type = 'role_action'
297
+ AND target_id = (SELECT id FROM action WHERE code = :actionCode)
298
+ ${isCompanyFeatureEnabled ? 'AND company_id = :actionCompanyId' : ''}
299
+ )
300
+ ) OR EXISTS (
301
+ SELECT 1 FROM user_iam_permission perm
302
+ WHERE perm.permission_type = 'user_action'
303
+ AND perm.source_id = appuser.id
304
+ AND perm.target_id = (SELECT id FROM action WHERE code = :actionCode)
305
+ ${isCompanyFeatureEnabled ? 'AND company_id = :actionCompanyId' : ''}
306
+ )`, {
307
+ actionCode,
308
+ ...isCompanyFeatureEnabled && {
309
+ actionCompanyId: companyId
310
+ }
311
+ });
312
+ }
313
+ }
314
+ // --- Non-company path ---
315
+ if (!isCompanyFeatureEnabled) {
316
+ if (filter?.isActive !== undefined) {
317
+ query.andWhere(`${this.entityName}.isActive = :value`, {
318
+ value: filter.isActive
283
319
  });
284
320
  }
321
+ return superQuery;
322
+ }
323
+ // --- Company feature path ---
324
+ if (!user?.companyId || !this.permissionRepository) {
325
+ return superQuery;
326
+ }
327
+ // Add companyIsActive as a selected column
328
+ query.addSelect(`(SELECT perm.is_active FROM user_company_permissions perm
329
+ WHERE perm.user_id = appuser.id
330
+ AND perm.permission_type = :permissionType
331
+ AND perm.target_id = :companyId
332
+ LIMIT 1)`, 'user_companyIsActive');
333
+ query.setParameter('permissionType', _enums.PermissionType.COMPANY);
334
+ query.setParameter('companyId', user.companyId);
335
+ // Filter by isActive within the company if requested
336
+ if (filter?.isActive !== undefined) {
285
337
  query.andWhere(`EXISTS (
286
- SELECT 1 FROM user_company_permissions perm
287
- WHERE perm.user_id = "user".id
338
+ SELECT 1 FROM user_company_permissions perm
339
+ WHERE perm.user_id = appuser.id
288
340
  AND perm.permission_type = :permissionType
289
341
  AND perm.target_id = :companyId
290
- )`, {
342
+ AND perm.is_active = :isActiveValue
343
+ )`, {
291
344
  permissionType: _enums.PermissionType.COMPANY,
292
- companyId: user.companyId
345
+ companyId: user.companyId,
346
+ isActiveValue: filter.isActive
293
347
  });
294
- return {
295
- query,
296
- isRaw: true
297
- };
298
348
  }
299
- return result;
349
+ // Always restrict to users belonging to this company
350
+ query.andWhere(`EXISTS (
351
+ SELECT 1 FROM user_company_permissions perm
352
+ WHERE perm.user_id = appuser.id
353
+ AND perm.permission_type = :permissionType
354
+ AND perm.target_id = :companyId
355
+ )`, {
356
+ permissionType: _enums.PermissionType.COMPANY,
357
+ companyId: user.companyId
358
+ });
359
+ return {
360
+ query,
361
+ isRaw: true
362
+ };
300
363
  }
301
364
  async insert(dto, user) {
302
365
  const isCompanyFeatureEnabled = this.authConfig.isCompanyFeatureEnabled();
@@ -496,7 +559,7 @@ let UserService = class UserService extends _classes.RequestScopedApiService {
496
559
  }
497
560
  }
498
561
  constructor(cacheManager, utilsService, dataSourceProvider, authConfig, userEnricher){
499
- super('user', null, cacheManager, utilsService, UserService.name, true, 'auth'), _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, "userEnricher", void 0), _define_property(this, "permissionRepository", void 0), _define_property(this, "dataSource", void 0), this.cacheManager = cacheManager, this.utilsService = utilsService, this.dataSourceProvider = dataSourceProvider, this.authConfig = authConfig, this.userEnricher = userEnricher;
562
+ super('appuser', null, cacheManager, utilsService, UserService.name, true, 'auth'), _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, "userEnricher", void 0), _define_property(this, "permissionRepository", void 0), _define_property(this, "dataSource", void 0), _define_property(this, "logAdapter", void 0), this.cacheManager = cacheManager, this.utilsService = utilsService, this.dataSourceProvider = dataSourceProvider, this.authConfig = authConfig, this.userEnricher = userEnricher, this.logAdapter = (0, _classes.createModuleLogger)(this.constructor.name);
500
563
  }
501
564
  };
502
565
  _ts_decorate([
@@ -14,7 +14,7 @@ const _core = require("@nestjs/core");
14
14
  const _passport = require("@nestjs/passport");
15
15
  const _passportjwt = require("passport-jwt");
16
16
  const _config = require("../config");
17
- const _userentity = require("../entities/user.entity");
17
+ const _appuserentity = require("../entities/app-user.entity");
18
18
  const _authconfigservice = require("../services/auth-config.service");
19
19
  const _authdatasourceprovider = require("../services/auth-datasource.provider");
20
20
  const _authenticationservice = require("../services/authentication.service");
@@ -67,7 +67,7 @@ let JwtStrategy = class JwtStrategy extends (0, _passport.PassportStrategy)(_pas
67
67
  strict: false
68
68
  });
69
69
  if (provider) {
70
- return provider.getRepository(_userentity.User);
70
+ return provider.getRepository(_appuserentity.AppUser);
71
71
  }
72
72
  } catch {
73
73
  throw new _common.UnauthorizedException({
@@ -1,3 +1,3 @@
1
1
  import { UserRoot } from '@flusys/nestjs-shared';
2
- export declare class User extends UserRoot {
2
+ export declare class AppUser extends UserRoot {
3
3
  }
@@ -1,20 +1,20 @@
1
+ export * from './app-user.entity';
1
2
  export * from './company-branch.entity';
2
3
  export * from './company.entity';
3
4
  export * from './pending-registration.entity';
4
5
  export { PermissionType, UserCompanyPermission } from './user-company-permission.entity';
5
- export * from './user.entity';
6
6
  export * from './user-token.entity';
7
+ import { AppUser } from './app-user.entity';
7
8
  import { CompanyBranch } from './company-branch.entity';
8
9
  import { Company } from './company.entity';
9
10
  import { PendingRegistration } from './pending-registration.entity';
10
11
  import { UserCompanyPermission } from './user-company-permission.entity';
11
- import { User } from './user.entity';
12
12
  import { UserToken } from './user-token.entity';
13
- declare const BaseEntities: (typeof User | typeof UserToken)[];
13
+ declare const BaseEntities: (typeof AppUser | typeof UserToken)[];
14
14
  declare const EmailEntities: (typeof PendingRegistration)[];
15
15
  declare const CompanyEntities: (typeof Company | typeof CompanyBranch | typeof UserCompanyPermission)[];
16
16
  export interface IAuthEntitiesConfig {
17
17
  enableCompanyFeature?: boolean;
18
18
  enableEmailVerification?: boolean;
19
19
  }
20
- export declare function getEntitiesByConfig(config: IAuthEntitiesConfig): (typeof BaseEntities[number] | typeof EmailEntities[number] | typeof CompanyEntities[number])[];
20
+ export declare function getEntitiesByConfig(config: IAuthEntitiesConfig): ((typeof BaseEntities)[number] | (typeof EmailEntities)[number] | (typeof CompanyEntities)[number])[];
@@ -1,12 +1,12 @@
1
1
  import { PermissionType } from '../enums';
2
+ import { AppUser } from './app-user.entity';
2
3
  import { CompanyBranch } from './company-branch.entity';
3
4
  import { Company } from './company.entity';
4
- import { User } from './user.entity';
5
5
  export { PermissionType };
6
6
  export declare class UserCompanyPermission {
7
7
  id: string;
8
8
  userId: string;
9
- user?: User;
9
+ user?: AppUser;
10
10
  permissionType: string;
11
11
  targetId: string;
12
12
  isActive: boolean;