@flusys/nestjs-auth 0.1.0-beta.3 → 1.0.0-rc

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (102) hide show
  1. package/README.md +274 -301
  2. package/cjs/config/auth.constants.js +22 -4
  3. package/cjs/controllers/authentication.controller.js +222 -38
  4. package/cjs/controllers/branch.controller.js +46 -4
  5. package/cjs/controllers/company-selection.controller.js +27 -20
  6. package/cjs/controllers/company.controller.js +46 -4
  7. package/cjs/controllers/user-permission.controller.js +40 -37
  8. package/cjs/controllers/user.controller.js +222 -23
  9. package/cjs/dtos/authentication.dto.js +119 -13
  10. package/cjs/dtos/user-permission.dto.js +28 -0
  11. package/cjs/dtos/user.dto.js +19 -4
  12. package/cjs/entities/index.js +5 -1
  13. package/cjs/entities/pending-registration.entity.js +125 -0
  14. package/cjs/entities/user-company-permission.entity.js +0 -6
  15. package/cjs/entities/user-token.entity.js +129 -0
  16. package/cjs/guards/auth-throttler.guard.js +53 -0
  17. package/cjs/interceptors/clear-token.interceptor.js +3 -6
  18. package/cjs/interceptors/set-token.interceptor.js +38 -31
  19. package/cjs/interfaces/auth-email-provider.interface.js +45 -0
  20. package/cjs/interfaces/authentication.interface.js +0 -3
  21. package/cjs/interfaces/index.js +2 -0
  22. package/cjs/interfaces/user-enricher.interface.js +4 -0
  23. package/cjs/modules/auth.module.js +8 -20
  24. package/cjs/services/auth-config.service.js +42 -47
  25. package/cjs/services/auth-datasource.provider.js +18 -34
  26. package/cjs/services/auth-email.service.js +471 -0
  27. package/cjs/services/authentication.service.js +240 -153
  28. package/cjs/services/branch.service.js +15 -48
  29. package/cjs/services/company-selection-session.service.js +1 -1
  30. package/cjs/services/company.service.js +7 -36
  31. package/cjs/services/index.js +1 -0
  32. package/cjs/services/user-permission.service.js +9 -29
  33. package/cjs/services/user.service.js +228 -107
  34. package/cjs/strategies/jwt.strategy.js +14 -1
  35. package/cjs/validators/password.validator.js +45 -0
  36. package/config/auth.constants.d.ts +5 -0
  37. package/controllers/authentication.controller.d.ts +13 -9
  38. package/controllers/company-selection.controller.d.ts +6 -2
  39. package/controllers/user.controller.d.ts +33 -0
  40. package/dtos/authentication.dto.d.ts +21 -3
  41. package/dtos/company-branch.dto.d.ts +0 -1
  42. package/dtos/company.dto.d.ts +0 -1
  43. package/dtos/user-permission.dto.d.ts +4 -0
  44. package/dtos/user.dto.d.ts +1 -2
  45. package/entities/index.d.ts +7 -3
  46. package/entities/pending-registration.entity.d.ts +17 -0
  47. package/entities/user-company-permission.entity.d.ts +0 -2
  48. package/entities/user-token.entity.d.ts +15 -0
  49. package/fesm/config/auth.constants.js +11 -8
  50. package/fesm/controllers/authentication.controller.js +224 -40
  51. package/fesm/controllers/branch.controller.js +49 -7
  52. package/fesm/controllers/company-selection.controller.js +28 -21
  53. package/fesm/controllers/company.controller.js +49 -7
  54. package/fesm/controllers/user-permission.controller.js +41 -38
  55. package/fesm/controllers/user.controller.js +225 -26
  56. package/fesm/dtos/authentication.dto.js +123 -111
  57. package/fesm/dtos/user-permission.dto.js +28 -0
  58. package/fesm/dtos/user.dto.js +20 -5
  59. package/fesm/entities/index.js +7 -1
  60. package/fesm/entities/pending-registration.entity.js +115 -0
  61. package/fesm/entities/user-company-permission.entity.js +0 -6
  62. package/fesm/entities/user-token.entity.js +113 -0
  63. package/fesm/guards/auth-throttler.guard.js +43 -0
  64. package/fesm/interceptors/clear-token.interceptor.js +2 -5
  65. package/fesm/interceptors/set-token.interceptor.js +37 -30
  66. package/fesm/interfaces/auth-email-provider.interface.js +38 -0
  67. package/fesm/interfaces/authentication.interface.js +1 -7
  68. package/fesm/interfaces/index.js +2 -0
  69. package/fesm/interfaces/user-enricher.interface.js +26 -0
  70. package/fesm/modules/auth.module.js +10 -22
  71. package/fesm/services/auth-config.service.js +42 -47
  72. package/fesm/services/auth-datasource.provider.js +19 -35
  73. package/fesm/services/auth-email.service.js +420 -0
  74. package/fesm/services/authentication.service.js +238 -151
  75. package/fesm/services/branch.service.js +16 -49
  76. package/fesm/services/company-selection-session.service.js +1 -1
  77. package/fesm/services/company.service.js +8 -37
  78. package/fesm/services/index.js +1 -0
  79. package/fesm/services/user-permission.service.js +10 -30
  80. package/fesm/services/user.service.js +229 -108
  81. package/fesm/strategies/jwt.strategy.js +14 -1
  82. package/fesm/validators/password.validator.js +48 -0
  83. package/guards/auth-throttler.guard.d.ts +7 -0
  84. package/interceptors/set-token.interceptor.d.ts +1 -0
  85. package/interfaces/auth-email-provider.interface.d.ts +6 -0
  86. package/interfaces/auth-module-options.interface.d.ts +4 -1
  87. package/interfaces/authentication.interface.d.ts +14 -0
  88. package/interfaces/index.d.ts +2 -0
  89. package/interfaces/user-enricher.interface.d.ts +64 -0
  90. package/interfaces/user.interface.d.ts +1 -0
  91. package/modules/auth.module.d.ts +0 -1
  92. package/package.json +4 -4
  93. package/services/auth-config.service.d.ts +5 -1
  94. package/services/auth-email.service.d.ts +51 -0
  95. package/services/authentication.service.d.ts +21 -12
  96. package/services/branch.service.d.ts +2 -5
  97. package/services/company-selection-session.service.d.ts +1 -1
  98. package/services/company.service.d.ts +1 -4
  99. package/services/index.d.ts +1 -0
  100. package/services/user-permission.service.d.ts +0 -1
  101. package/services/user.service.d.ts +20 -6
  102. package/validators/password.validator.d.ts +10 -0
@@ -10,6 +10,7 @@ Object.defineProperty(exports, "BranchService", {
10
10
  });
11
11
  const _classes = require("@flusys/nestjs-shared/classes");
12
12
  const _modules = require("@flusys/nestjs-shared/modules");
13
+ const _utils = require("@flusys/nestjs-shared/utils");
13
14
  const _common = require("@nestjs/common");
14
15
  const _companybranchentity = require("../entities/company-branch.entity");
15
16
  const _authconfigservice = require("./auth-config.service");
@@ -42,41 +43,15 @@ function _ts_param(paramIndex, decorator) {
42
43
  };
43
44
  }
44
45
  let BranchService = class BranchService extends _classes.RequestScopedApiService {
45
- /**
46
- * Resolve entity class for this service
47
- * @returns CompanyBranch entity class
48
- */ resolveEntity() {
46
+ resolveEntity() {
49
47
  return _companybranchentity.CompanyBranch;
50
48
  }
51
- /**
52
- * Get DataSource provider for this service
53
- * @returns AuthDataSourceProvider instance
54
- */ getDataSourceProvider() {
49
+ getDataSourceProvider() {
55
50
  return this.dataSourceProvider;
56
51
  }
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
- }
52
+ // Query Customization
77
53
  async getSelectQuery(query, _user, select) {
78
- // Repository initialization is handled automatically by RequestScopedApiService
79
- if (!select || !select.length) {
54
+ if (!select?.length) {
80
55
  select = [
81
56
  'id',
82
57
  'name',
@@ -85,14 +60,13 @@ let BranchService = class BranchService extends _classes.RequestScopedApiService
85
60
  'createdAt'
86
61
  ];
87
62
  }
88
- const selectFields = select.map((field)=>`${this.entityName}.${field}`);
89
- query.select(selectFields);
63
+ query.select(select.map((f)=>`${this.entityName}.${f}`));
90
64
  return {
91
65
  query,
92
66
  isRaw: false
93
67
  };
94
68
  }
95
- async getGlobalSearchQuery(query, search, _user) {
69
+ async getGlobalSearchQuery(query, search) {
96
70
  query.andWhere('(company_branch.name LIKE :search OR company_branch.slug LIKE :search OR company_branch.email LIKE :search)', {
97
71
  search: `%${search}%`
98
72
  });
@@ -101,24 +75,17 @@ let BranchService = class BranchService extends _classes.RequestScopedApiService
101
75
  isRaw: false
102
76
  };
103
77
  }
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) {
112
- query.andWhere('company_branch.company_id = :companyId', {
113
- companyId: user.companyId
114
- });
115
- }
78
+ async getExtraManipulateQuery(query, filterDto, user) {
79
+ const result = await super.getExtraManipulateQuery(query, filterDto, user);
80
+ (0, _utils.applyCompanyFilter)(query, {
81
+ isCompanyFeatureEnabled: this.authConfig.isCompanyFeatureEnabled(),
82
+ entityAlias: 'company_branch',
83
+ columnName: 'company_id'
84
+ }, user);
116
85
  return result;
117
86
  }
118
- // NOTE: @Inject() required for bundled code - type metadata may be lost during esbuild
119
87
  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);
88
+ 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
89
  }
123
90
  };
124
91
  BranchService = _ts_decorate([
@@ -43,7 +43,7 @@ const SESSION_TTL_MS = 5 * 60 * 1000; // 5 minutes
43
43
  let CompanySelectionSessionService = class CompanySelectionSessionService {
44
44
  /**
45
45
  * Create a new session for company/branch selection
46
- */ async createSession(userId, companyId) {
46
+ */ async createSession(userId) {
47
47
  const sessionId = (0, _crypto.randomUUID)();
48
48
  const now = new Date();
49
49
  const expiresAt = new Date(now.getTime() + SESSION_TTL_MS);
@@ -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([
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", {
3
3
  value: true
4
4
  });
5
5
  _export_star(require("./authentication.service"), exports);
6
+ _export_star(require("./auth-email.service"), exports);
6
7
  _export_star(require("./company-selection-session.service"), exports);
7
8
  _export_star(require("./user.service"), exports);
8
9
  _export_star(require("./company.service"), exports);
@@ -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: {
@@ -168,10 +150,8 @@ let UserPermissionService = class UserPermissionService {
168
150
  // NOTE: @Inject() required for bundled code - type metadata may be lost during esbuild
169
151
  constructor(dataSourceProvider){
170
152
  _define_property(this, "dataSourceProvider", void 0);
171
- _define_property(this, "logger", void 0);
172
153
  _define_property(this, "_repository", void 0);
173
154
  this.dataSourceProvider = dataSourceProvider;
174
- this.logger = new _common.Logger(UserPermissionService.name);
175
155
  this._repository = null;
176
156
  }
177
157
  };