@flusys/nestjs-auth 7.0.2 → 8.0.0-beta.1

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 (237) hide show
  1. package/README.md +68 -1
  2. package/config/auth.constants.d.ts +2 -0
  3. package/config/event-actions.d.ts +2 -0
  4. package/config/index.d.ts +3 -3
  5. package/config/message-keys.d.ts +23 -0
  6. package/controllers/authentication.controller.d.ts +5 -5
  7. package/controllers/branch.controller.d.ts +2 -2
  8. package/controllers/company-selection.controller.d.ts +4 -4
  9. package/controllers/company.controller.d.ts +2 -2
  10. package/controllers/email-verification.controller.d.ts +6 -6
  11. package/controllers/index.d.ts +9 -7
  12. package/controllers/social-auth-config.controller.d.ts +22 -0
  13. package/controllers/social-auth.controller.d.ts +11 -0
  14. package/controllers/user-permission.controller.d.ts +5 -4
  15. package/controllers/user.controller.d.ts +7 -7
  16. package/docs/auth-swagger.config.d.ts +2 -2
  17. package/docs/index.d.ts +1 -1
  18. package/dtos/index.d.ts +6 -5
  19. package/dtos/social-auth.dto.d.ts +42 -0
  20. package/entities/company-branch.entity.d.ts +1 -1
  21. package/entities/company.entity.d.ts +1 -1
  22. package/entities/index.d.ts +15 -13
  23. package/entities/pending-registration.entity.d.ts +1 -1
  24. package/entities/social-auth-config.entity.d.ts +9 -0
  25. package/entities/user-company-permission.entity.d.ts +4 -4
  26. package/enums/index.d.ts +2 -1
  27. package/enums/social-provider-type.enum.d.ts +6 -0
  28. package/fesm/118.js +1230 -0
  29. package/fesm/120.js +2197 -0
  30. package/fesm/24.js +4389 -0
  31. package/fesm/370.js +1163 -0
  32. package/fesm/446.js +877 -0
  33. package/fesm/chunks/117.js +69 -0
  34. package/fesm/config/index.js +244 -3
  35. package/fesm/controllers/index.js +27 -7
  36. package/fesm/docs/index.js +479 -1
  37. package/fesm/dtos/index.js +123 -5
  38. package/fesm/entities/index.js +68 -19
  39. package/fesm/enums/index.js +53 -1
  40. package/fesm/helpers/index.js +115 -2
  41. package/fesm/index.js +1437 -12
  42. package/fesm/interceptors/index.js +508 -2
  43. package/fesm/interfaces/index.js +75 -7
  44. package/fesm/modules/index.js +546 -1
  45. package/fesm/runtime.js +134 -0
  46. package/fesm/services/index.js +67 -9
  47. package/helpers/auth-response.mapper.d.ts +3 -3
  48. package/helpers/index.d.ts +2 -2
  49. package/helpers/token.helper.d.ts +2 -2
  50. package/index.d.ts +13 -12
  51. package/interceptors/clear-token.interceptor.d.ts +2 -2
  52. package/interceptors/index.d.ts +2 -2
  53. package/interceptors/set-token.interceptor.d.ts +2 -2
  54. package/interfaces/auth-module-options.interface.d.ts +3 -3
  55. package/interfaces/authentication.interface.d.ts +3 -3
  56. package/interfaces/company-branch.interface.d.ts +2 -2
  57. package/interfaces/company.interface.d.ts +1 -1
  58. package/interfaces/index.d.ts +8 -7
  59. package/interfaces/social-auth.interface.d.ts +43 -0
  60. package/interfaces/user-enricher.interface.d.ts +3 -3
  61. package/modules/auth.module.d.ts +4 -4
  62. package/modules/index.d.ts +1 -1
  63. package/package.json +32 -39
  64. package/providers/facebook.social-provider.d.ts +10 -0
  65. package/providers/google.social-provider.d.ts +10 -0
  66. package/providers/index.d.ts +1 -0
  67. package/providers/linkedin.social-provider.d.ts +10 -0
  68. package/providers/microsoft.social-provider.d.ts +10 -0
  69. package/providers/oauth-http.util.d.ts +10 -0
  70. package/providers/social-provider.registry.d.ts +3 -0
  71. package/services/auth-config.service.d.ts +4 -3
  72. package/services/auth-datasource.provider.d.ts +4 -3
  73. package/services/auth-email.service.d.ts +3 -3
  74. package/services/authentication.service.d.ts +15 -11
  75. package/services/branch.service.d.ts +7 -7
  76. package/services/company.service.d.ts +6 -6
  77. package/services/index.d.ts +11 -9
  78. package/services/social-auth-config.service.d.ts +21 -0
  79. package/services/social-auth.service.d.ts +24 -0
  80. package/services/user-permission.service.d.ts +8 -4
  81. package/services/user.service.d.ts +7 -7
  82. package/strategies/jwt.strategy.d.ts +4 -4
  83. package/validators/password.validator.d.ts +1 -1
  84. package/cjs/config/auth.constants.js +0 -41
  85. package/cjs/config/event-actions.js +0 -45
  86. package/cjs/config/index.js +0 -20
  87. package/cjs/config/message-keys.js +0 -108
  88. package/cjs/controllers/authentication.controller.js +0 -427
  89. package/cjs/controllers/authentication.controller.spec.js +0 -219
  90. package/cjs/controllers/branch.controller.js +0 -102
  91. package/cjs/controllers/branch.controller.spec.js +0 -134
  92. package/cjs/controllers/company-selection.controller.js +0 -198
  93. package/cjs/controllers/company-selection.controller.spec.js +0 -84
  94. package/cjs/controllers/company.controller.js +0 -102
  95. package/cjs/controllers/company.controller.spec.js +0 -131
  96. package/cjs/controllers/email-verification.controller.js +0 -224
  97. package/cjs/controllers/email-verification.controller.spec.js +0 -142
  98. package/cjs/controllers/index.js +0 -24
  99. package/cjs/controllers/user-permission.controller.js +0 -223
  100. package/cjs/controllers/user-permission.controller.spec.js +0 -138
  101. package/cjs/controllers/user.controller.js +0 -438
  102. package/cjs/controllers/user.controller.spec.js +0 -204
  103. package/cjs/docs/auth-swagger.config.js +0 -453
  104. package/cjs/docs/auth-swagger.config.spec.js +0 -130
  105. package/cjs/docs/index.js +0 -18
  106. package/cjs/dtos/authentication.dto.js +0 -755
  107. package/cjs/dtos/company-branch.dto.js +0 -294
  108. package/cjs/dtos/company.dto.js +0 -298
  109. package/cjs/dtos/index.js +0 -22
  110. package/cjs/dtos/user-permission.dto.js +0 -358
  111. package/cjs/dtos/user.dto.js +0 -413
  112. package/cjs/entities/app-user.entity.js +0 -25
  113. package/cjs/entities/company-branch.entity.js +0 -163
  114. package/cjs/entities/company.entity.js +0 -146
  115. package/cjs/entities/index.js +0 -65
  116. package/cjs/entities/index.spec.js +0 -73
  117. package/cjs/entities/pending-registration.entity.js +0 -135
  118. package/cjs/entities/user-company-permission.entity.js +0 -153
  119. package/cjs/entities/user-token.entity.js +0 -120
  120. package/cjs/enums/index.js +0 -18
  121. package/cjs/enums/user-org-permission-type.enum.js +0 -15
  122. package/cjs/helpers/auth-response.mapper.js +0 -46
  123. package/cjs/helpers/auth-response.mapper.spec.js +0 -139
  124. package/cjs/helpers/index.js +0 -19
  125. package/cjs/helpers/token.helper.js +0 -58
  126. package/cjs/helpers/token.helper.spec.js +0 -86
  127. package/cjs/index.js +0 -29
  128. package/cjs/interceptors/clear-token.interceptor.js +0 -73
  129. package/cjs/interceptors/clear-token.interceptor.spec.js +0 -107
  130. package/cjs/interceptors/index.js +0 -19
  131. package/cjs/interceptors/set-token.interceptor.js +0 -107
  132. package/cjs/interceptors/set-token.interceptor.spec.js +0 -165
  133. package/cjs/interfaces/auth-email-provider.interface.js +0 -45
  134. package/cjs/interfaces/auth-module-options.interface.js +0 -4
  135. package/cjs/interfaces/authentication.interface.js +0 -4
  136. package/cjs/interfaces/company-branch.interface.js +0 -4
  137. package/cjs/interfaces/company.interface.js +0 -4
  138. package/cjs/interfaces/index.js +0 -24
  139. package/cjs/interfaces/user-enricher.interface.js +0 -4
  140. package/cjs/interfaces/user.interface.js +0 -4
  141. package/cjs/modules/auth.module.js +0 -202
  142. package/cjs/modules/auth.module.spec.js +0 -243
  143. package/cjs/modules/index.js +0 -18
  144. package/cjs/services/auth-config.service.js +0 -110
  145. package/cjs/services/auth-config.service.spec.js +0 -97
  146. package/cjs/services/auth-datasource.provider.js +0 -134
  147. package/cjs/services/auth-datasource.provider.spec.js +0 -161
  148. package/cjs/services/auth-email.service.js +0 -539
  149. package/cjs/services/auth-email.service.spec.js +0 -456
  150. package/cjs/services/authentication.service.js +0 -1173
  151. package/cjs/services/authentication.service.spec.js +0 -962
  152. package/cjs/services/branch.service.js +0 -153
  153. package/cjs/services/branch.service.spec.js +0 -169
  154. package/cjs/services/company-selection-session.service.js +0 -121
  155. package/cjs/services/company-selection-session.service.spec.js +0 -90
  156. package/cjs/services/company.service.js +0 -140
  157. package/cjs/services/company.service.spec.js +0 -127
  158. package/cjs/services/index.js +0 -26
  159. package/cjs/services/user-permission.service.js +0 -236
  160. package/cjs/services/user-permission.service.spec.js +0 -254
  161. package/cjs/services/user.service.js +0 -671
  162. package/cjs/services/user.service.spec.js +0 -718
  163. package/cjs/strategies/jwt.strategy.js +0 -140
  164. package/cjs/strategies/jwt.strategy.spec.js +0 -166
  165. package/cjs/validators/password.validator.js +0 -45
  166. package/cjs/validators/password.validator.spec.js +0 -161
  167. package/fesm/config/auth.constants.js +0 -11
  168. package/fesm/config/event-actions.js +0 -24
  169. package/fesm/config/message-keys.js +0 -78
  170. package/fesm/controllers/authentication.controller.js +0 -417
  171. package/fesm/controllers/authentication.controller.spec.js +0 -215
  172. package/fesm/controllers/branch.controller.js +0 -92
  173. package/fesm/controllers/branch.controller.spec.js +0 -130
  174. package/fesm/controllers/company-selection.controller.js +0 -188
  175. package/fesm/controllers/company-selection.controller.spec.js +0 -80
  176. package/fesm/controllers/company.controller.js +0 -92
  177. package/fesm/controllers/company.controller.spec.js +0 -127
  178. package/fesm/controllers/email-verification.controller.js +0 -214
  179. package/fesm/controllers/email-verification.controller.spec.js +0 -138
  180. package/fesm/controllers/user-permission.controller.js +0 -213
  181. package/fesm/controllers/user-permission.controller.spec.js +0 -134
  182. package/fesm/controllers/user.controller.js +0 -428
  183. package/fesm/controllers/user.controller.spec.js +0 -200
  184. package/fesm/docs/auth-swagger.config.js +0 -446
  185. package/fesm/docs/auth-swagger.config.spec.js +0 -126
  186. package/fesm/dtos/authentication.dto.js +0 -683
  187. package/fesm/dtos/company-branch.dto.js +0 -279
  188. package/fesm/dtos/company.dto.js +0 -283
  189. package/fesm/dtos/user-permission.dto.js +0 -339
  190. package/fesm/dtos/user.dto.js +0 -391
  191. package/fesm/entities/app-user.entity.js +0 -15
  192. package/fesm/entities/company-branch.entity.js +0 -153
  193. package/fesm/entities/company.entity.js +0 -136
  194. package/fesm/entities/index.spec.js +0 -69
  195. package/fesm/entities/pending-registration.entity.js +0 -125
  196. package/fesm/entities/user-company-permission.entity.js +0 -136
  197. package/fesm/entities/user-token.entity.js +0 -104
  198. package/fesm/enums/user-org-permission-type.enum.js +0 -5
  199. package/fesm/helpers/auth-response.mapper.js +0 -25
  200. package/fesm/helpers/auth-response.mapper.spec.js +0 -135
  201. package/fesm/helpers/token.helper.js +0 -40
  202. package/fesm/helpers/token.helper.spec.js +0 -82
  203. package/fesm/interceptors/clear-token.interceptor.js +0 -63
  204. package/fesm/interceptors/clear-token.interceptor.spec.js +0 -103
  205. package/fesm/interceptors/set-token.interceptor.js +0 -98
  206. package/fesm/interceptors/set-token.interceptor.spec.js +0 -161
  207. package/fesm/interfaces/auth-email-provider.interface.js +0 -38
  208. package/fesm/interfaces/auth-module-options.interface.js +0 -3
  209. package/fesm/interfaces/authentication.interface.js +0 -1
  210. package/fesm/interfaces/company-branch.interface.js +0 -1
  211. package/fesm/interfaces/company.interface.js +0 -1
  212. package/fesm/interfaces/user-enricher.interface.js +0 -4
  213. package/fesm/interfaces/user.interface.js +0 -1
  214. package/fesm/modules/auth.module.js +0 -192
  215. package/fesm/modules/auth.module.spec.js +0 -239
  216. package/fesm/services/auth-config.service.js +0 -100
  217. package/fesm/services/auth-config.service.spec.js +0 -93
  218. package/fesm/services/auth-datasource.provider.js +0 -83
  219. package/fesm/services/auth-datasource.provider.spec.js +0 -157
  220. package/fesm/services/auth-email.service.js +0 -488
  221. package/fesm/services/auth-email.service.spec.js +0 -411
  222. package/fesm/services/authentication.service.js +0 -1122
  223. package/fesm/services/authentication.service.spec.js +0 -917
  224. package/fesm/services/branch.service.js +0 -143
  225. package/fesm/services/branch.service.spec.js +0 -165
  226. package/fesm/services/company-selection-session.service.js +0 -111
  227. package/fesm/services/company-selection-session.service.spec.js +0 -86
  228. package/fesm/services/company.service.js +0 -130
  229. package/fesm/services/company.service.spec.js +0 -123
  230. package/fesm/services/user-permission.service.js +0 -226
  231. package/fesm/services/user-permission.service.spec.js +0 -250
  232. package/fesm/services/user.service.js +0 -620
  233. package/fesm/services/user.service.spec.js +0 -673
  234. package/fesm/strategies/jwt.strategy.js +0 -130
  235. package/fesm/strategies/jwt.strategy.spec.js +0 -162
  236. package/fesm/validators/password.validator.js +0 -48
  237. package/fesm/validators/password.validator.spec.js +0 -157
@@ -1,1173 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", {
3
- value: true
4
- });
5
- Object.defineProperty(exports, "AuthenticationService", {
6
- enumerable: true,
7
- get: function() {
8
- return AuthenticationService;
9
- }
10
- });
11
- const _nestjsshared = require("@flusys/nestjs-shared");
12
- const _classes = require("@flusys/nestjs-shared/classes");
13
- const _constants = require("@flusys/nestjs-shared/constants");
14
- const _enums = require("@flusys/nestjs-shared/enums");
15
- const _interfaces = require("@flusys/nestjs-shared/interfaces");
16
- const _utils = require("@flusys/nestjs-shared/utils");
17
- const _common = require("@nestjs/common");
18
- const _jwt = require("@nestjs/jwt");
19
- const _bcrypt = /*#__PURE__*/ _interop_require_wildcard(require("bcrypt"));
20
- const _config = require("../config");
21
- const _authenticationdto = require("../dtos/authentication.dto");
22
- const _appuserentity = require("../entities/app-user.entity");
23
- const _companybranchentity = require("../entities/company-branch.entity");
24
- const _companyentity = require("../entities/company.entity");
25
- const _pendingregistrationentity = require("../entities/pending-registration.entity");
26
- const _usercompanypermissionentity = require("../entities/user-company-permission.entity");
27
- const _enums1 = require("../enums");
28
- const _helpers = require("../helpers");
29
- const _userenricherinterface = require("../interfaces/user-enricher.interface");
30
- const _authconfigservice = require("./auth-config.service");
31
- const _authdatasourceprovider = require("./auth-datasource.provider");
32
- const _authemailservice = require("./auth-email.service");
33
- const _companyselectionsessionservice = require("./company-selection-session.service");
34
- function _define_property(obj, key, value) {
35
- if (key in obj) {
36
- Object.defineProperty(obj, key, {
37
- value: value,
38
- enumerable: true,
39
- configurable: true,
40
- writable: true
41
- });
42
- } else {
43
- obj[key] = value;
44
- }
45
- return obj;
46
- }
47
- function _getRequireWildcardCache(nodeInterop) {
48
- if (typeof WeakMap !== "function") return null;
49
- var cacheBabelInterop = new WeakMap();
50
- var cacheNodeInterop = new WeakMap();
51
- return (_getRequireWildcardCache = function(nodeInterop) {
52
- return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
53
- })(nodeInterop);
54
- }
55
- function _interop_require_wildcard(obj, nodeInterop) {
56
- if (!nodeInterop && obj && obj.__esModule) {
57
- return obj;
58
- }
59
- if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
60
- return {
61
- default: obj
62
- };
63
- }
64
- var cache = _getRequireWildcardCache(nodeInterop);
65
- if (cache && cache.has(obj)) {
66
- return cache.get(obj);
67
- }
68
- var newObj = {
69
- __proto__: null
70
- };
71
- var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
72
- for(var key in obj){
73
- if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
74
- var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
75
- if (desc && (desc.get || desc.set)) {
76
- Object.defineProperty(newObj, key, desc);
77
- } else {
78
- newObj[key] = obj[key];
79
- }
80
- }
81
- }
82
- newObj.default = obj;
83
- if (cache) {
84
- cache.set(obj, newObj);
85
- }
86
- return newObj;
87
- }
88
- function _ts_decorate(decorators, target, key, desc) {
89
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
90
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
91
- 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;
92
- return c > 3 && r && Object.defineProperty(target, key, r), r;
93
- }
94
- function _ts_metadata(k, v) {
95
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
96
- }
97
- function _ts_param(paramIndex, decorator) {
98
- return function(target, key) {
99
- decorator(target, key, paramIndex);
100
- };
101
- }
102
- let AuthenticationService = class AuthenticationService {
103
- isCompanyFeatureEnabled() {
104
- return this.dataSourceProvider?.isCompanyFeatureEnabled() ?? this.authConfig.isCompanyFeatureEnabled();
105
- }
106
- isEmailVerificationEnabled() {
107
- const featureEnabled = this.dataSourceProvider?.isEmailVerificationEnabled() ?? this.authConfig.isEmailVerificationEnabled();
108
- const providerAvailable = this.authEmailService?.isEmailEnabled() ?? false;
109
- return featureEnabled && providerAvailable;
110
- }
111
- async getUserRepository() {
112
- if (!this.dataSourceProvider) {
113
- throw new _common.InternalServerErrorException({
114
- message: 'User repository not available',
115
- messageKey: _constants.SYSTEM_MESSAGES.REPOSITORY_NOT_AVAILABLE,
116
- messageVariables: {
117
- entity: 'AppUser'
118
- }
119
- });
120
- }
121
- return this.dataSourceProvider.getRepository(_appuserentity.AppUser);
122
- }
123
- async getCompanyScopedRepository(entity) {
124
- if (!this.isCompanyFeatureEnabled() || !this.dataSourceProvider) return null;
125
- return this.dataSourceProvider.getRepository(entity);
126
- }
127
- async login(email, password) {
128
- if (this.isEmailVerificationEnabled() && await this.authEmailService.hasPendingRegistration(email)) {
129
- return {
130
- requiresEmailVerification: true,
131
- email,
132
- message: 'Please verify your email address to complete registration.',
133
- messageKey: _config.EMAIL_VERIFICATION_MESSAGES.VERIFICATION_SENT
134
- };
135
- }
136
- const user = await this.validateUser(email, password);
137
- if (!user.isActive) {
138
- throw new _common.ForbiddenException({
139
- message: 'User account is deactivated',
140
- messageKey: _config.AUTH_MESSAGES.LOGIN_ACCOUNT_DEACTIVATED
141
- });
142
- }
143
- if (this.isEmailVerificationEnabled() && !user.emailVerified) {
144
- return {
145
- requiresEmailVerification: true,
146
- email: user.email,
147
- message: 'Please verify your email address before logging in.',
148
- messageKey: _config.AUTH_MESSAGES.LOGIN_EMAIL_NOT_VERIFIED
149
- };
150
- }
151
- if (!this.isCompanyFeatureEnabled()) {
152
- return this.generateLoginResponse(user);
153
- }
154
- return await this.handleCompanyBasedLogin(user);
155
- }
156
- async handleCompanyBasedLogin(user) {
157
- const permissionRepository = await this.getCompanyScopedRepository(_usercompanypermissionentity.UserCompanyPermission);
158
- const branchRepository = await this.getCompanyScopedRepository(_companybranchentity.CompanyBranch);
159
- if (!permissionRepository || !branchRepository) {
160
- return this.generateLoginResponse(user);
161
- }
162
- const companyPermissions = await permissionRepository.find({
163
- where: {
164
- userId: user.id,
165
- permissionType: _enums1.PermissionType.COMPANY
166
- }
167
- });
168
- const companyRepository = await this.getCompanyScopedRepository(_companyentity.Company);
169
- if (!companyRepository) {
170
- return this.generateLoginResponse(user);
171
- }
172
- const companyIds = companyPermissions.map((p)=>p.targetId);
173
- const companies = companyIds.length > 0 ? await companyRepository.createQueryBuilder('c').where('c.id IN (:...ids)', {
174
- ids: companyIds
175
- }).andWhere('c.is_active = :active', {
176
- active: true
177
- }).getMany() : [];
178
- if (companies.length === 0) {
179
- return this.generateLoginResponse(user);
180
- }
181
- const branchPermissions = await permissionRepository.find({
182
- where: {
183
- userId: user.id,
184
- permissionType: _enums1.PermissionType.BRANCH
185
- }
186
- });
187
- const branchIds = branchPermissions.map((p)=>p.targetId);
188
- const branches = branchIds.length > 0 ? await branchRepository.createQueryBuilder('b').leftJoinAndSelect('b.company', 'company').where('b.id IN (:...ids)', {
189
- ids: branchIds
190
- }).andWhere('b.is_active = :active', {
191
- active: true
192
- }).getMany() : [];
193
- if (companies.length === 1 && branches.length === 1) {
194
- return this.generateLoginResponseWithCompany(user, companies[0], branches[0]);
195
- }
196
- return await this.generateCompanySelectionResponse(user, companies, branches);
197
- }
198
- async register(dto, verifyUrlBase) {
199
- const userRepository = await this.getUserRepository();
200
- const existingUser = await userRepository.findOne({
201
- where: {
202
- email: dto.email
203
- }
204
- });
205
- if (existingUser && this.isCompanyFeatureEnabled()) {
206
- return await this.handleExistingUserCompanyRegistration(existingUser, dto);
207
- }
208
- if (existingUser) {
209
- throw new _common.BadRequestException({
210
- message: 'Registration failed due to email exists. Please try again or contact support.',
211
- messageKey: _config.AUTH_MESSAGES.REGISTER_EMAIL_EXISTS
212
- });
213
- }
214
- if (this.isEmailVerificationEnabled() && verifyUrlBase) {
215
- const companyData = this.isCompanyFeatureEnabled() ? {
216
- companySlug: dto.companySlug,
217
- branchSlug: dto.branchSlug,
218
- newCompanyName: dto.newCompanyName,
219
- newCompanyPhone: dto.newCompanyPhone,
220
- newCompanyAddress: dto.newCompanyAddress
221
- } : undefined;
222
- const result = await this.authEmailService.createPendingRegistration({
223
- email: dto.email,
224
- name: dto.name,
225
- phone: dto.phone,
226
- password: dto.password,
227
- companyData,
228
- additionalFields: dto.additionalFields,
229
- verifyUrlBase
230
- });
231
- return {
232
- requiresEmailVerification: true,
233
- message: result.message,
234
- messageKey: _config.EMAIL_VERIFICATION_MESSAGES.VERIFICATION_SENT
235
- };
236
- }
237
- return await this.createUserDirectly(dto);
238
- }
239
- async handleExistingUserCompanyRegistration(existingUser, dto) {
240
- if (!dto.companySlug && !dto.newCompanyName) {
241
- throw new _common.BadRequestException({
242
- message: 'Email already registered. Please login or provide a company to join/create.',
243
- messageKey: _config.AUTH_MESSAGES.REGISTER_EMAIL_EXISTS
244
- });
245
- }
246
- const permissionRepository = await this.getCompanyScopedRepository(_usercompanypermissionentity.UserCompanyPermission);
247
- const companyRepository = await this.getCompanyScopedRepository(_companyentity.Company);
248
- if (!permissionRepository || !companyRepository) {
249
- throw new _common.BadRequestException({
250
- message: 'Company feature repositories not available',
251
- messageKey: _constants.SYSTEM_MESSAGES.REPOSITORY_NOT_AVAILABLE,
252
- messageVariables: {
253
- entity: 'Company feature'
254
- }
255
- });
256
- }
257
- if (dto.companySlug) {
258
- const company = await companyRepository.findOne({
259
- where: {
260
- slug: dto.companySlug,
261
- isActive: true
262
- }
263
- });
264
- if (company) {
265
- const existingPermission = await permissionRepository.findOne({
266
- where: {
267
- userId: existingUser.id,
268
- permissionType: _enums1.PermissionType.COMPANY,
269
- targetId: company.id
270
- }
271
- });
272
- if (existingPermission) {
273
- throw new _common.BadRequestException({
274
- message: 'You are already assigned to this company. Please login.',
275
- messageKey: _config.AUTH_MESSAGES.REGISTER_COMPANY_ALREADY_ASSIGNED
276
- });
277
- }
278
- }
279
- }
280
- return await this.processCompanyRegistration(existingUser, dto, true);
281
- }
282
- async createUserDirectly(dto) {
283
- if (!this.dataSourceProvider) {
284
- throw new _common.BadRequestException({
285
- message: 'Data source not available',
286
- messageKey: _constants.SYSTEM_MESSAGES.DATASOURCE_NOT_AVAILABLE
287
- });
288
- }
289
- const dataSource = await this.dataSourceProvider.getDataSource();
290
- const queryRunner = dataSource.createQueryRunner();
291
- await queryRunner.connect();
292
- await queryRunner.startTransaction();
293
- try {
294
- const hashedPassword = await _bcrypt.hash(dto.password, _config.BCRYPT_SALT_ROUNDS);
295
- const user = queryRunner.manager.create(_appuserentity.AppUser, {
296
- name: dto.name,
297
- email: dto.email,
298
- phone: dto.phone,
299
- password: hashedPassword,
300
- isActive: true,
301
- emailVerified: false,
302
- phoneVerified: false
303
- });
304
- await queryRunner.manager.save(_appuserentity.AppUser, user);
305
- if (this.userEnricher?.onUserCreated) {
306
- await this.userEnricher.onUserCreated(user.id, dto.additionalFields ?? null, queryRunner);
307
- }
308
- await queryRunner.commitTransaction();
309
- if (!this.isCompanyFeatureEnabled()) {
310
- return this.generateRegistrationResponse(user);
311
- }
312
- return await this.processCompanyRegistration(user, dto);
313
- } catch (error) {
314
- await queryRunner.rollbackTransaction();
315
- if (error instanceof _common.BadRequestException) {
316
- throw error;
317
- }
318
- throw new _common.BadRequestException({
319
- message: 'Registration failed. Please try again.',
320
- messageKey: _config.AUTH_MESSAGES.REGISTER_FAILED
321
- });
322
- } finally{
323
- await queryRunner.release();
324
- }
325
- }
326
- async createUserFromPendingRegistration(pending) {
327
- if (!this.dataSourceProvider) {
328
- throw new _common.BadRequestException({
329
- message: 'Data source not available',
330
- messageKey: _constants.SYSTEM_MESSAGES.DATASOURCE_NOT_AVAILABLE
331
- });
332
- }
333
- const dataSource = await this.dataSourceProvider.getDataSource();
334
- const queryRunner = dataSource.createQueryRunner();
335
- await queryRunner.connect();
336
- await queryRunner.startTransaction();
337
- try {
338
- const existingUser = await queryRunner.manager.findOne(_appuserentity.AppUser, {
339
- where: {
340
- email: pending.email
341
- }
342
- });
343
- if (existingUser) {
344
- throw new _common.BadRequestException({
345
- message: 'This email has already been registered.',
346
- messageKey: _config.AUTH_MESSAGES.REGISTER_EMAIL_EXISTS
347
- });
348
- }
349
- const user = queryRunner.manager.create(_appuserentity.AppUser, {
350
- name: pending.name,
351
- email: pending.email,
352
- phone: pending.phone,
353
- password: pending.passwordHash,
354
- isActive: true,
355
- emailVerified: true,
356
- phoneVerified: false
357
- });
358
- await queryRunner.manager.save(_appuserentity.AppUser, user);
359
- if (this.userEnricher?.onUserCreated) {
360
- await this.userEnricher.onUserCreated(user.id, pending.additionalFields ?? null, queryRunner);
361
- }
362
- await queryRunner.commitTransaction();
363
- if (this.isCompanyFeatureEnabled() && pending.companyData) {
364
- return await this.processCompanyRegistration(user, pending.companyData);
365
- }
366
- return this.generateRegistrationResponse(user);
367
- } catch (error) {
368
- await queryRunner.rollbackTransaction();
369
- if (error instanceof _common.BadRequestException) {
370
- throw error;
371
- }
372
- throw new _common.BadRequestException({
373
- message: 'Registration failed. Please try again.',
374
- messageKey: _config.AUTH_MESSAGES.REGISTER_FAILED
375
- });
376
- } finally{
377
- await queryRunner.release();
378
- }
379
- }
380
- async processCompanyRegistration(user, data, throwOnUnavailable = false) {
381
- const companyRepository = await this.getCompanyScopedRepository(_companyentity.Company);
382
- const branchRepository = await this.getCompanyScopedRepository(_companybranchentity.CompanyBranch);
383
- const permissionRepository = await this.getCompanyScopedRepository(_usercompanypermissionentity.UserCompanyPermission);
384
- if (!companyRepository || !branchRepository || !permissionRepository) {
385
- if (throwOnUnavailable) throw new _common.BadRequestException({
386
- message: 'Company feature repositories not available',
387
- messageKey: _constants.SYSTEM_MESSAGES.REPOSITORY_NOT_AVAILABLE,
388
- messageVariables: {
389
- entity: 'Company feature'
390
- }
391
- });
392
- return this.generateRegistrationResponse(user);
393
- }
394
- const { company, branch } = await this.findOrCreateCompanyAndBranch(data, companyRepository, branchRepository);
395
- if (company) {
396
- await this.assignUserPermissions(user.id, company.id, branch?.id, permissionRepository);
397
- return this.generateRegistrationResponseWithCompany(user, company, branch ?? undefined);
398
- }
399
- return this.generateRegistrationResponse(user);
400
- }
401
- async findOrCreateCompanyAndBranch(data, companyRepo, branchRepo) {
402
- if (data.companySlug) {
403
- const company = await companyRepo.findOne({
404
- where: {
405
- slug: data.companySlug,
406
- isActive: true
407
- }
408
- });
409
- if (!company) throw new _common.BadRequestException({
410
- message: 'Company not found or inactive',
411
- messageKey: _config.AUTH_MESSAGES.COMPANY_NOT_FOUND
412
- });
413
- const branch = data.branchSlug ? await branchRepo.findOne({
414
- where: {
415
- slug: data.branchSlug,
416
- companyId: company.id,
417
- isActive: true
418
- }
419
- }) : await branchRepo.findOne({
420
- where: {
421
- companyId: company.id,
422
- isActive: true
423
- },
424
- order: {
425
- serial: 'ASC',
426
- createdAt: 'ASC'
427
- }
428
- });
429
- if (data.branchSlug && !branch) throw new _common.BadRequestException({
430
- message: 'Branch not found or inactive',
431
- messageKey: _config.AUTH_MESSAGES.BRANCH_NOT_FOUND
432
- });
433
- return {
434
- company,
435
- branch
436
- };
437
- }
438
- if (data.newCompanyName) {
439
- const slug = await (0, _utils.generateUniqueSlug)(data.newCompanyName, async (baseSlug)=>{
440
- const rows = await companyRepo.createQueryBuilder('c').select('c.slug').where('c.slug = :base OR c.slug LIKE :pattern', {
441
- base: baseSlug,
442
- pattern: `${baseSlug}-%`
443
- }).getMany();
444
- return rows.map((r)=>r.slug);
445
- });
446
- const company = companyRepo.create({
447
- name: data.newCompanyName,
448
- slug,
449
- phone: data.newCompanyPhone,
450
- address: data.newCompanyAddress,
451
- isActive: true
452
- });
453
- await companyRepo.save(company);
454
- const branch = branchRepo.create({
455
- name: 'Main Branch',
456
- slug: 'main-branch',
457
- companyId: company.id,
458
- isActive: true
459
- });
460
- await branchRepo.save(branch);
461
- return {
462
- company,
463
- branch
464
- };
465
- }
466
- return {
467
- company: null,
468
- branch: null
469
- };
470
- }
471
- async assignUserPermissions(userId, companyId, branchId, permissionRepo) {
472
- await permissionRepo.save(permissionRepo.create({
473
- userId,
474
- permissionType: _enums1.PermissionType.COMPANY,
475
- targetId: companyId
476
- }));
477
- if (branchId) {
478
- await permissionRepo.save(permissionRepo.create({
479
- userId,
480
- permissionType: _enums1.PermissionType.BRANCH,
481
- targetId: branchId
482
- }));
483
- }
484
- }
485
- async select(sessionId, companyId, branchId) {
486
- this.ensureCompanyFeatureEnabled();
487
- if (!this.sessionService) {
488
- throw new _common.BadRequestException({
489
- message: 'Session service not available',
490
- messageKey: _config.AUTH_MESSAGES.SESSION_NOT_AVAILABLE
491
- });
492
- }
493
- const session = await this.sessionService.consumeSession(sessionId);
494
- if (!session) {
495
- throw new _common.UnauthorizedException({
496
- message: 'Invalid or expired session',
497
- messageKey: _config.AUTH_MESSAGES.SESSION_INVALID
498
- });
499
- }
500
- return await this.validateAndLoginWithCompany(session.userId, companyId, branchId);
501
- }
502
- async switchCompany(userId, companyId, branchId) {
503
- this.ensureCompanyFeatureEnabled();
504
- return await this.validateAndLoginWithCompany(userId, companyId, branchId);
505
- }
506
- async validateAndLoginWithCompany(userId, companyId, branchId) {
507
- const userRepository = await this.getUserRepository();
508
- const user = await userRepository.findOne({
509
- where: {
510
- id: userId
511
- }
512
- });
513
- if (!user) {
514
- throw new _common.NotFoundException({
515
- message: 'User not found',
516
- messageKey: _config.USER_MESSAGES.NOT_FOUND
517
- });
518
- }
519
- const permissionRepository = await this.getCompanyScopedRepository(_usercompanypermissionentity.UserCompanyPermission);
520
- const companyRepository = await this.getCompanyScopedRepository(_companyentity.Company);
521
- const branchRepository = await this.getCompanyScopedRepository(_companybranchentity.CompanyBranch);
522
- if (!permissionRepository || !companyRepository || !branchRepository) {
523
- throw new _common.BadRequestException({
524
- message: 'Repositories not available',
525
- messageKey: _constants.SYSTEM_MESSAGES.REPOSITORY_NOT_AVAILABLE,
526
- messageVariables: {
527
- entity: 'Some'
528
- }
529
- });
530
- }
531
- const hasCompanyAccess = await permissionRepository.findOne({
532
- where: {
533
- userId,
534
- permissionType: _enums1.PermissionType.COMPANY,
535
- targetId: companyId
536
- }
537
- });
538
- if (!hasCompanyAccess) {
539
- throw new _common.ForbiddenException({
540
- message: 'No access to this company',
541
- messageKey: _config.AUTH_MESSAGES.COMPANY_NO_ACCESS
542
- });
543
- }
544
- const company = await companyRepository.findOne({
545
- where: {
546
- id: companyId,
547
- isActive: true
548
- }
549
- });
550
- if (!company) {
551
- throw new _common.NotFoundException({
552
- message: 'Company not found or inactive',
553
- messageKey: _config.AUTH_MESSAGES.COMPANY_NOT_FOUND
554
- });
555
- }
556
- const hasBranchAccess = await permissionRepository.findOne({
557
- where: {
558
- userId,
559
- permissionType: _enums1.PermissionType.BRANCH,
560
- targetId: branchId
561
- }
562
- });
563
- if (!hasBranchAccess) {
564
- throw new _common.ForbiddenException({
565
- message: 'No access to this branch',
566
- messageKey: _config.AUTH_MESSAGES.BRANCH_NO_ACCESS
567
- });
568
- }
569
- const branch = await branchRepository.findOne({
570
- where: {
571
- id: branchId,
572
- companyId,
573
- isActive: true
574
- }
575
- });
576
- if (!branch) {
577
- throw new _common.NotFoundException({
578
- message: 'Branch not found or inactive',
579
- messageKey: _config.AUTH_MESSAGES.BRANCH_NOT_FOUND
580
- });
581
- }
582
- const response = this.generateLoginResponseWithCompany(user, company, branch);
583
- this.publishAuthEvent(_config.AUTH_EVENT_ENTITIES.SESSION, _config.AUTH_EVENT_ACTIONS.COMPANY_SWITCHED, user, {
584
- companyId: company.id,
585
- branchId: branch.id
586
- });
587
- return response;
588
- }
589
- async refreshToken(refreshToken) {
590
- try {
591
- const payload = this.jwtService.verify(refreshToken, {
592
- secret: this.authConfig.getRefreshTokenSecret(),
593
- algorithms: [
594
- 'HS256'
595
- ]
596
- });
597
- if (await this.isTokenRevoked(payload.id, payload.iat)) {
598
- throw new _common.UnauthorizedException({
599
- message: 'Token has been revoked',
600
- messageKey: _config.AUTH_MESSAGES.TOKEN_REVOKED
601
- });
602
- }
603
- const userRepository = await this.getUserRepository();
604
- const user = await userRepository.findOne({
605
- where: {
606
- id: payload.id
607
- }
608
- });
609
- if (!user || !user.isActive) {
610
- throw new _common.UnauthorizedException({
611
- message: 'Invalid refresh token',
612
- messageKey: _config.AUTH_MESSAGES.TOKEN_INVALID
613
- });
614
- }
615
- if (payload.companyId) {
616
- const companyRepository = await this.getCompanyScopedRepository(_companyentity.Company);
617
- const permissionRepository = await this.getCompanyScopedRepository(_usercompanypermissionentity.UserCompanyPermission);
618
- if (companyRepository) {
619
- const company = await companyRepository.findOne({
620
- where: {
621
- id: payload.companyId,
622
- isActive: true
623
- }
624
- });
625
- if (!company) {
626
- throw new _common.UnauthorizedException({
627
- message: 'Company not found or inactive',
628
- messageKey: _config.AUTH_MESSAGES.COMPANY_NOT_FOUND
629
- });
630
- }
631
- }
632
- if (permissionRepository) {
633
- const hasCompanyAccess = await permissionRepository.findOne({
634
- where: {
635
- userId: user.id,
636
- permissionType: _enums1.PermissionType.COMPANY,
637
- targetId: payload.companyId
638
- }
639
- });
640
- if (!hasCompanyAccess) {
641
- throw new _common.UnauthorizedException({
642
- message: 'No access to this company',
643
- messageKey: _config.AUTH_MESSAGES.COMPANY_NO_ACCESS
644
- });
645
- }
646
- }
647
- if (payload.branchId) {
648
- const branchRepository = await this.getCompanyScopedRepository(_companybranchentity.CompanyBranch);
649
- if (branchRepository) {
650
- const branch = await branchRepository.findOne({
651
- where: {
652
- id: payload.branchId,
653
- companyId: payload.companyId,
654
- isActive: true
655
- }
656
- });
657
- if (!branch) {
658
- throw new _common.UnauthorizedException({
659
- message: 'Branch not found or inactive',
660
- messageKey: _config.AUTH_MESSAGES.BRANCH_NOT_FOUND
661
- });
662
- }
663
- }
664
- if (permissionRepository) {
665
- const hasBranchAccess = await permissionRepository.findOne({
666
- where: {
667
- userId: user.id,
668
- permissionType: _enums1.PermissionType.BRANCH,
669
- targetId: payload.branchId
670
- }
671
- });
672
- if (!hasBranchAccess) {
673
- throw new _common.UnauthorizedException({
674
- message: 'No access to this branch',
675
- messageKey: _config.AUTH_MESSAGES.BRANCH_NO_ACCESS
676
- });
677
- }
678
- }
679
- }
680
- }
681
- const tokens = (0, _helpers.generateTokens)(this.jwtService, this.authConfig, {
682
- id: user.id,
683
- email: user.email,
684
- type: 'access',
685
- profilePictureId: user.profilePictureId ?? undefined,
686
- ...payload.companyId && {
687
- companyId: payload.companyId
688
- },
689
- ...payload.branchId && {
690
- branchId: payload.branchId
691
- }
692
- });
693
- this.publishAuthEvent(_config.AUTH_EVENT_ENTITIES.SESSION, _config.AUTH_EVENT_ACTIONS.TOKEN_REFRESHED, user, {
694
- companyId: payload.companyId ?? null,
695
- branchId: payload.branchId ?? null
696
- });
697
- return tokens;
698
- } catch {
699
- throw new _common.UnauthorizedException({
700
- message: 'Invalid or expired refresh token',
701
- messageKey: _config.AUTH_MESSAGES.TOKEN_EXPIRED
702
- });
703
- }
704
- }
705
- async changePassword(userId, currentPassword, newPassword) {
706
- const userRepository = await this.getUserRepository();
707
- const user = await userRepository.findOne({
708
- where: {
709
- id: userId
710
- }
711
- });
712
- if (!user) throw new _common.UnauthorizedException({
713
- message: 'User not found',
714
- messageKey: _config.USER_MESSAGES.NOT_FOUND
715
- });
716
- if (!await _bcrypt.compare(currentPassword, user.password || '')) {
717
- throw new _common.UnauthorizedException({
718
- message: 'Current password is incorrect',
719
- messageKey: _config.AUTH_MESSAGES.PASSWORD_CHANGE_INVALID_CURRENT
720
- });
721
- }
722
- user.password = await _bcrypt.hash(newPassword, _config.BCRYPT_SALT_ROUNDS);
723
- await userRepository.save(user);
724
- this.publishAuthEvent(_config.AUTH_EVENT_ENTITIES.USER, _config.AUTH_EVENT_ACTIONS.PASSWORD_CHANGED, user);
725
- }
726
- async logout(userId) {
727
- if (!this.cacheManager) {
728
- throw new _common.BadRequestException({
729
- message: 'Logout service temporarily unavailable. Please try again later.',
730
- messageKey: _config.AUTH_MESSAGES.LOGOUT_SERVICE_UNAVAILABLE
731
- });
732
- }
733
- const revokedAt = Math.floor(Date.now() / 1000);
734
- const cacheKey = `${_config.TOKEN_REVOKED_PREFIX}:${userId}`;
735
- const refreshTokenExpiry = this.authConfig.getRefreshTokenExpiration();
736
- const ttlMs = (0, _helpers.parseExpiryToMs)(refreshTokenExpiry);
737
- await this.cacheManager.set(cacheKey, revokedAt, ttlMs);
738
- await (0, _classes.publishDomainEvent)({
739
- module: _config.AUTH_EVENT_MODULE,
740
- entity: _config.AUTH_EVENT_ENTITIES.SESSION,
741
- action: _config.AUTH_EVENT_ACTIONS.LOGGED_OUT,
742
- ids: [
743
- userId
744
- ],
745
- user: {
746
- id: userId
747
- }
748
- });
749
- }
750
- async isTokenRevoked(userId, tokenIssuedAt) {
751
- if (!this.cacheManager || !tokenIssuedAt) {
752
- return false;
753
- }
754
- const cacheKey = `${_config.TOKEN_REVOKED_PREFIX}:${userId}`;
755
- const revokedAt = await this.cacheManager.get(cacheKey);
756
- if (!revokedAt) {
757
- return false;
758
- }
759
- return tokenIssuedAt < revokedAt;
760
- }
761
- async getUserCompanies(userId) {
762
- this.ensureCompanyFeatureEnabled();
763
- const permissionRepository = await this.getCompanyScopedRepository(_usercompanypermissionentity.UserCompanyPermission);
764
- const companyRepository = await this.getCompanyScopedRepository(_companyentity.Company);
765
- if (!permissionRepository || !companyRepository) {
766
- throw new _common.BadRequestException({
767
- message: 'Repositories not available',
768
- messageKey: _constants.SYSTEM_MESSAGES.REPOSITORY_NOT_AVAILABLE,
769
- messageVariables: {
770
- entity: 'Some'
771
- }
772
- });
773
- }
774
- const permissions = await permissionRepository.find({
775
- where: {
776
- userId,
777
- permissionType: _enums1.PermissionType.COMPANY
778
- }
779
- });
780
- const companyIds = permissions.map((p)=>p.targetId);
781
- if (companyIds.length === 0) return [];
782
- return companyRepository.createQueryBuilder('c').where('c.id IN (:...ids)', {
783
- ids: companyIds
784
- }).andWhere('c.is_active = :active', {
785
- active: true
786
- }).orderBy('c.name', 'ASC').getMany();
787
- }
788
- async getUserBranches(userId, companyId) {
789
- this.ensureCompanyFeatureEnabled();
790
- const permissionRepository = await this.getCompanyScopedRepository(_usercompanypermissionentity.UserCompanyPermission);
791
- const branchRepository = await this.getCompanyScopedRepository(_companybranchentity.CompanyBranch);
792
- if (!permissionRepository || !branchRepository) {
793
- throw new _common.BadRequestException({
794
- message: 'Repositories not available',
795
- messageKey: _constants.SYSTEM_MESSAGES.REPOSITORY_NOT_AVAILABLE,
796
- messageVariables: {
797
- entity: 'Some'
798
- }
799
- });
800
- }
801
- const companyPermission = await permissionRepository.findOne({
802
- where: {
803
- userId,
804
- permissionType: _enums1.PermissionType.COMPANY,
805
- targetId: companyId
806
- }
807
- });
808
- if (!companyPermission) {
809
- throw new _common.UnauthorizedException({
810
- message: 'No access to this company',
811
- messageKey: _config.AUTH_MESSAGES.COMPANY_NO_ACCESS
812
- });
813
- }
814
- const branchPermissions = await permissionRepository.find({
815
- where: {
816
- userId,
817
- permissionType: _enums1.PermissionType.BRANCH
818
- }
819
- });
820
- const branchIds = branchPermissions.map((p)=>p.targetId);
821
- if (branchIds.length === 0) return [];
822
- return branchRepository.createQueryBuilder('b').where('b.id IN (:...ids)', {
823
- ids: branchIds
824
- }).andWhere('b.company_id = :companyId', {
825
- companyId
826
- }).andWhere('b.is_active = :active', {
827
- active: true
828
- }).orderBy('b.serial', 'ASC').addOrderBy('b.name', 'ASC').getMany();
829
- }
830
- async getCompanyById(companyId) {
831
- const companyRepository = await this.getCompanyScopedRepository(_companyentity.Company);
832
- if (!companyRepository) {
833
- return null;
834
- }
835
- return companyRepository.findOne({
836
- where: {
837
- id: companyId
838
- }
839
- });
840
- }
841
- async getBranchById(branchId) {
842
- const branchRepository = await this.getCompanyScopedRepository(_companybranchentity.CompanyBranch);
843
- if (!branchRepository) {
844
- return null;
845
- }
846
- return branchRepository.findOne({
847
- where: {
848
- id: branchId
849
- }
850
- });
851
- }
852
- async getUserInfo(userId, companyId, branchId) {
853
- const userRepository = await this.getUserRepository();
854
- const user = await userRepository.findOne({
855
- where: {
856
- id: userId
857
- }
858
- });
859
- if (!user) throw new _common.UnauthorizedException({
860
- message: 'User not found',
861
- messageKey: _config.USER_MESSAGES.NOT_FOUND
862
- });
863
- const response = {
864
- user: (0, _helpers.toUserInfo)(user)
865
- };
866
- if (this.isCompanyFeatureEnabled()) {
867
- if (!companyId) {
868
- throw new _common.UnauthorizedException({
869
- message: 'Company feature is enabled but user has no company assigned.',
870
- messageKey: _config.AUTH_MESSAGES.COMPANY_REQUIRED
871
- });
872
- }
873
- const company = await this.getCompanyById(companyId);
874
- if (!company) throw new _common.UnauthorizedException({
875
- message: 'Company not found.',
876
- messageKey: _config.AUTH_MESSAGES.COMPANY_NOT_FOUND
877
- });
878
- response.company = (0, _helpers.toCompanyInfo)(company);
879
- if (branchId) {
880
- const branch = await this.getBranchById(branchId);
881
- if (!branch) throw new _common.UnauthorizedException({
882
- message: 'Branch not found.',
883
- messageKey: _config.AUTH_MESSAGES.BRANCH_NOT_FOUND
884
- });
885
- response.branch = (0, _helpers.toBranchInfo)(branch);
886
- }
887
- }
888
- return response;
889
- }
890
- ensureCompanyFeatureEnabled() {
891
- if (!this.isCompanyFeatureEnabled()) {
892
- throw new _common.BadRequestException({
893
- message: 'Company feature is not enabled',
894
- messageKey: _config.AUTH_MESSAGES.COMPANY_FEATURE_NOT_ENABLED
895
- });
896
- }
897
- }
898
- async validateUser(email, password) {
899
- const userRepository = await this.getUserRepository();
900
- const user = await userRepository.findOne({
901
- where: {
902
- email
903
- }
904
- });
905
- if (!user || !await _bcrypt.compare(password, user.password || '')) {
906
- throw new _common.UnauthorizedException({
907
- message: 'Invalid credentials',
908
- messageKey: _config.AUTH_MESSAGES.LOGIN_INVALID_CREDENTIALS
909
- });
910
- }
911
- user.lastLoginAt = new Date();
912
- await userRepository.save(user);
913
- return user;
914
- }
915
- generateLoginResponse(user) {
916
- const { accessToken, refreshToken } = (0, _helpers.generateTokens)(this.jwtService, this.authConfig, {
917
- id: user.id,
918
- email: user.email,
919
- type: 'access'
920
- });
921
- this.sendLoginNotification(user.id);
922
- this.publishAuthEvent(_config.AUTH_EVENT_ENTITIES.SESSION, _config.AUTH_EVENT_ACTIONS.LOGGED_IN, user);
923
- return {
924
- accessToken,
925
- refreshToken,
926
- user: (0, _helpers.toUserInfo)(user)
927
- };
928
- }
929
- generateLoginResponseWithCompany(user, company, branch) {
930
- const { accessToken, refreshToken } = (0, _helpers.generateTokens)(this.jwtService, this.authConfig, {
931
- id: user.id,
932
- email: user.email,
933
- type: 'access',
934
- companyId: company.id,
935
- branchId: branch?.id
936
- });
937
- this.sendLoginNotification(user.id, company.id);
938
- this.publishAuthEvent(_config.AUTH_EVENT_ENTITIES.SESSION, _config.AUTH_EVENT_ACTIONS.LOGGED_IN, user, {
939
- companyId: company.id,
940
- branchId: branch?.id ?? null
941
- });
942
- return {
943
- accessToken,
944
- refreshToken,
945
- user: (0, _helpers.toUserInfo)(user),
946
- company: (0, _helpers.toCompanyInfo)(company),
947
- branch: branch ? (0, _helpers.toBranchInfo)(branch) : undefined
948
- };
949
- }
950
- sendLoginNotification(userId, companyId) {
951
- if (!this.notificationAdapter) return;
952
- this.notificationAdapter.send({
953
- userId,
954
- title: 'Login successful',
955
- message: 'You have successfully logged in to your account.',
956
- type: _enums.NotificationType.INFO,
957
- companyId,
958
- realtime: false
959
- }).catch(()=>{
960
- // Silent failure - notification is non-critical
961
- });
962
- }
963
- async generateCompanySelectionResponse(user, companies, branches) {
964
- if (!this.sessionService) {
965
- throw new _common.BadRequestException({
966
- message: 'Session service not available',
967
- messageKey: _config.AUTH_MESSAGES.SESSION_NOT_AVAILABLE
968
- });
969
- }
970
- const sessionId = await this.sessionService.createSession(user.id);
971
- const companiesWithBranches = companies.map((company)=>({
972
- ...(0, _helpers.toCompanyInfo)(company),
973
- isActive: company.isActive,
974
- branches: branches.filter((b)=>b.companyId === company.id).map((b)=>({
975
- ...(0, _helpers.toBranchInfo)(b),
976
- isActive: b.isActive
977
- }))
978
- }));
979
- return {
980
- requiresSelection: true,
981
- sessionId,
982
- expiresAt: new Date(Date.now() + 5 * 60 * 1000),
983
- user: (0, _helpers.toUserInfo)(user),
984
- companies: companiesWithBranches
985
- };
986
- }
987
- generateRegistrationResponse(user) {
988
- const response = {
989
- ...this.generateLoginResponse(user),
990
- requiresEmailVerification: false
991
- };
992
- this.publishAuthEvent(_config.AUTH_EVENT_ENTITIES.USER, _config.AUTH_EVENT_ACTIONS.REGISTERED, user);
993
- return response;
994
- }
995
- generateRegistrationResponseWithCompany(user, company, branch) {
996
- const response = {
997
- ...this.generateLoginResponseWithCompany(user, company, branch),
998
- requiresEmailVerification: false
999
- };
1000
- this.publishAuthEvent(_config.AUTH_EVENT_ENTITIES.USER, _config.AUTH_EVENT_ACTIONS.REGISTERED, user, {
1001
- companyId: company.id,
1002
- branchId: branch?.id ?? null
1003
- });
1004
- return response;
1005
- }
1006
- /** Never awaited - a login must not wait on, or fail because of, the event bus */ publishAuthEvent(entity, action, user, metadata = {}) {
1007
- void (0, _classes.publishDomainEvent)({
1008
- module: _config.AUTH_EVENT_MODULE,
1009
- entity,
1010
- action,
1011
- ids: [
1012
- user.id
1013
- ],
1014
- metadata: {
1015
- email: user.email,
1016
- ...metadata
1017
- },
1018
- user: {
1019
- id: user.id,
1020
- email: user.email
1021
- }
1022
- });
1023
- }
1024
- // NOTE: @Inject() required for bundled code - type metadata may be lost during esbuild
1025
- constructor(jwtService, authConfig, cacheManager, dataSourceProvider, sessionService, authEmailService, userEnricher, notificationAdapter){
1026
- _define_property(this, "jwtService", void 0);
1027
- _define_property(this, "authConfig", void 0);
1028
- _define_property(this, "cacheManager", void 0);
1029
- _define_property(this, "dataSourceProvider", void 0);
1030
- _define_property(this, "sessionService", void 0);
1031
- _define_property(this, "authEmailService", void 0);
1032
- _define_property(this, "userEnricher", void 0);
1033
- _define_property(this, "notificationAdapter", void 0);
1034
- this.jwtService = jwtService;
1035
- this.authConfig = authConfig;
1036
- this.cacheManager = cacheManager;
1037
- this.dataSourceProvider = dataSourceProvider;
1038
- this.sessionService = sessionService;
1039
- this.authEmailService = authEmailService;
1040
- this.userEnricher = userEnricher;
1041
- this.notificationAdapter = notificationAdapter;
1042
- }
1043
- };
1044
- _ts_decorate([
1045
- (0, _nestjsshared.LogAction)({
1046
- action: 'auth.login',
1047
- module: 'auth',
1048
- includeParams: false
1049
- }),
1050
- _ts_metadata("design:type", Function),
1051
- _ts_metadata("design:paramtypes", [
1052
- String,
1053
- String
1054
- ]),
1055
- _ts_metadata("design:returntype", Promise)
1056
- ], AuthenticationService.prototype, "login", null);
1057
- _ts_decorate([
1058
- (0, _nestjsshared.LogAction)({
1059
- action: 'auth.register',
1060
- module: 'auth',
1061
- includeParams: false
1062
- }),
1063
- _ts_metadata("design:type", Function),
1064
- _ts_metadata("design:paramtypes", [
1065
- typeof _authenticationdto.RegistrationDto === "undefined" ? Object : _authenticationdto.RegistrationDto,
1066
- String
1067
- ]),
1068
- _ts_metadata("design:returntype", Promise)
1069
- ], AuthenticationService.prototype, "register", null);
1070
- _ts_decorate([
1071
- (0, _nestjsshared.LogAction)({
1072
- action: 'auth.createUser',
1073
- module: 'auth',
1074
- includeParams: false
1075
- }),
1076
- _ts_metadata("design:type", Function),
1077
- _ts_metadata("design:paramtypes", [
1078
- typeof _authenticationdto.RegistrationDto === "undefined" ? Object : _authenticationdto.RegistrationDto
1079
- ]),
1080
- _ts_metadata("design:returntype", Promise)
1081
- ], AuthenticationService.prototype, "createUserDirectly", null);
1082
- _ts_decorate([
1083
- (0, _nestjsshared.LogAction)({
1084
- action: 'auth.createUserFromPending',
1085
- module: 'auth',
1086
- includeParams: false
1087
- }),
1088
- _ts_metadata("design:type", Function),
1089
- _ts_metadata("design:paramtypes", [
1090
- typeof _pendingregistrationentity.PendingRegistration === "undefined" ? Object : _pendingregistrationentity.PendingRegistration
1091
- ]),
1092
- _ts_metadata("design:returntype", Promise)
1093
- ], AuthenticationService.prototype, "createUserFromPendingRegistration", null);
1094
- _ts_decorate([
1095
- (0, _nestjsshared.LogAction)({
1096
- action: 'auth.companySwitch',
1097
- module: 'auth'
1098
- }),
1099
- _ts_metadata("design:type", Function),
1100
- _ts_metadata("design:paramtypes", [
1101
- String,
1102
- String,
1103
- String
1104
- ]),
1105
- _ts_metadata("design:returntype", Promise)
1106
- ], AuthenticationService.prototype, "validateAndLoginWithCompany", null);
1107
- _ts_decorate([
1108
- (0, _nestjsshared.LogAction)({
1109
- action: 'auth.refreshToken',
1110
- module: 'auth',
1111
- includeParams: false
1112
- }),
1113
- _ts_metadata("design:type", Function),
1114
- _ts_metadata("design:paramtypes", [
1115
- String
1116
- ]),
1117
- _ts_metadata("design:returntype", Promise)
1118
- ], AuthenticationService.prototype, "refreshToken", null);
1119
- _ts_decorate([
1120
- (0, _nestjsshared.LogAction)({
1121
- action: 'auth.changePassword',
1122
- module: 'auth',
1123
- includeParams: false
1124
- }),
1125
- _ts_metadata("design:type", Function),
1126
- _ts_metadata("design:paramtypes", [
1127
- String,
1128
- String,
1129
- String
1130
- ]),
1131
- _ts_metadata("design:returntype", Promise)
1132
- ], AuthenticationService.prototype, "changePassword", null);
1133
- _ts_decorate([
1134
- (0, _nestjsshared.LogAction)({
1135
- action: 'auth.logout',
1136
- module: 'auth'
1137
- }),
1138
- _ts_metadata("design:type", Function),
1139
- _ts_metadata("design:paramtypes", [
1140
- String
1141
- ]),
1142
- _ts_metadata("design:returntype", Promise)
1143
- ], AuthenticationService.prototype, "logout", null);
1144
- AuthenticationService = _ts_decorate([
1145
- (0, _common.Injectable)({
1146
- scope: _common.Scope.REQUEST
1147
- }),
1148
- _ts_param(0, (0, _common.Inject)(_jwt.JwtService)),
1149
- _ts_param(1, (0, _common.Inject)(_authconfigservice.AuthConfigService)),
1150
- _ts_param(2, (0, _common.Optional)()),
1151
- _ts_param(2, (0, _common.Inject)('CACHE_INSTANCE')),
1152
- _ts_param(3, (0, _common.Optional)()),
1153
- _ts_param(3, (0, _common.Inject)(_authdatasourceprovider.AuthDataSourceProvider)),
1154
- _ts_param(4, (0, _common.Optional)()),
1155
- _ts_param(4, (0, _common.Inject)(_companyselectionsessionservice.CompanySelectionSessionService)),
1156
- _ts_param(5, (0, _common.Optional)()),
1157
- _ts_param(5, (0, _common.Inject)(_authemailservice.AuthEmailService)),
1158
- _ts_param(6, (0, _common.Optional)()),
1159
- _ts_param(6, (0, _common.Inject)(_config.USER_ENRICHER)),
1160
- _ts_param(7, (0, _common.Optional)()),
1161
- _ts_param(7, (0, _common.Inject)(_interfaces.NOTIFICATION_ADAPTER)),
1162
- _ts_metadata("design:type", Function),
1163
- _ts_metadata("design:paramtypes", [
1164
- typeof _jwt.JwtService === "undefined" ? Object : _jwt.JwtService,
1165
- typeof _authconfigservice.AuthConfigService === "undefined" ? Object : _authconfigservice.AuthConfigService,
1166
- typeof _classes.HybridCache === "undefined" ? Object : _classes.HybridCache,
1167
- typeof _authdatasourceprovider.AuthDataSourceProvider === "undefined" ? Object : _authdatasourceprovider.AuthDataSourceProvider,
1168
- typeof _companyselectionsessionservice.CompanySelectionSessionService === "undefined" ? Object : _companyselectionsessionservice.CompanySelectionSessionService,
1169
- typeof _authemailservice.AuthEmailService === "undefined" ? Object : _authemailservice.AuthEmailService,
1170
- typeof _userenricherinterface.IUserEnricher === "undefined" ? Object : _userenricherinterface.IUserEnricher,
1171
- typeof _interfaces.INotificationAdapter === "undefined" ? Object : _interfaces.INotificationAdapter
1172
- ])
1173
- ], AuthenticationService);