@solidxai/core 0.1.9-beta.7 → 0.1.9-beta.8
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.
- package/dist/constants/chatter-message.constants.d.ts +6 -0
- package/dist/constants/chatter-message.constants.d.ts.map +1 -1
- package/dist/constants/chatter-message.constants.js +7 -1
- package/dist/constants/chatter-message.constants.js.map +1 -1
- package/dist/controllers/authentication.controller.d.ts +12 -0
- package/dist/controllers/authentication.controller.d.ts.map +1 -1
- package/dist/controllers/authentication.controller.js +13 -0
- package/dist/controllers/authentication.controller.js.map +1 -1
- package/dist/controllers/chatter-message.controller.d.ts +1 -0
- package/dist/controllers/chatter-message.controller.d.ts.map +1 -1
- package/dist/controllers/chatter-message.controller.js +12 -0
- package/dist/controllers/chatter-message.controller.js.map +1 -1
- package/dist/controllers/facebook-authentication.controller.d.ts +27 -0
- package/dist/controllers/facebook-authentication.controller.d.ts.map +1 -0
- package/dist/controllers/facebook-authentication.controller.js +117 -0
- package/dist/controllers/facebook-authentication.controller.js.map +1 -0
- package/dist/controllers/menu-item-metadata.controller.d.ts +1 -0
- package/dist/controllers/menu-item-metadata.controller.d.ts.map +1 -1
- package/dist/controllers/menu-item-metadata.controller.js +15 -0
- package/dist/controllers/menu-item-metadata.controller.js.map +1 -1
- package/dist/controllers/microsoft-authentication.controller.d.ts +27 -0
- package/dist/controllers/microsoft-authentication.controller.d.ts.map +1 -0
- package/dist/controllers/microsoft-authentication.controller.js +118 -0
- package/dist/controllers/microsoft-authentication.controller.js.map +1 -0
- package/dist/controllers/setting.controller.d.ts +2 -2
- package/dist/controllers/setting.controller.js +2 -2
- package/dist/decorators/auth.decorator.d.ts.map +1 -1
- package/dist/decorators/computed-field-provider.decorator.d.ts.map +1 -1
- package/dist/decorators/dashboard-question-data-provider.decorator.d.ts.map +1 -1
- package/dist/decorators/dashboard-selection-provider.decorator.d.ts.map +1 -1
- package/dist/decorators/disallow-in-production.decorator.d.ts.map +1 -1
- package/dist/decorators/error-codes-provider.decorator.d.ts.map +1 -1
- package/dist/decorators/extension-user-creation-provider.decorator.d.ts.map +1 -1
- package/dist/decorators/is-not-in-enum.decorator.d.ts.map +1 -1
- package/dist/decorators/mail-provider.decorator.d.ts.map +1 -1
- package/dist/decorators/roles.decorator.d.ts.map +1 -1
- package/dist/decorators/scheduled-job-provider.decorator.d.ts.map +1 -1
- package/dist/decorators/security-rule-config-provider.decorator.d.ts.map +1 -1
- package/dist/decorators/selection-provider.decorator.d.ts.map +1 -1
- package/dist/decorators/sms-provider.decorator.d.ts.map +1 -1
- package/dist/decorators/solid-database-module.decorator.d.ts.map +1 -1
- package/dist/decorators/whatsapp-provider.decorator.d.ts.map +1 -1
- package/dist/dtos/create-chatter-message.dto.d.ts +1 -0
- package/dist/dtos/create-chatter-message.dto.d.ts.map +1 -1
- package/dist/dtos/create-chatter-message.dto.js +7 -1
- package/dist/dtos/create-chatter-message.dto.js.map +1 -1
- package/dist/dtos/post-chatter-message.dto.d.ts +1 -0
- package/dist/dtos/post-chatter-message.dto.d.ts.map +1 -1
- package/dist/dtos/post-chatter-message.dto.js +6 -1
- package/dist/dtos/post-chatter-message.dto.js.map +1 -1
- package/dist/dtos/update-chatter-message.dto.d.ts +1 -0
- package/dist/dtos/update-chatter-message.dto.d.ts.map +1 -1
- package/dist/dtos/update-chatter-message.dto.js +7 -1
- package/dist/dtos/update-chatter-message.dto.js.map +1 -1
- package/dist/entities/chatter-message.entity.d.ts +1 -0
- package/dist/entities/chatter-message.entity.d.ts.map +1 -1
- package/dist/entities/chatter-message.entity.js +5 -1
- package/dist/entities/chatter-message.entity.js.map +1 -1
- package/dist/entities/user.entity.d.ts +8 -0
- package/dist/entities/user.entity.d.ts.map +1 -1
- package/dist/entities/user.entity.js +33 -1
- package/dist/entities/user.entity.js.map +1 -1
- package/dist/helpers/cors.helper.js +1 -1
- package/dist/helpers/cors.helper.js.map +1 -1
- package/dist/helpers/facebook-oauth.helper.d.ts +8 -0
- package/dist/helpers/facebook-oauth.helper.d.ts.map +1 -0
- package/dist/helpers/facebook-oauth.helper.js +11 -0
- package/dist/helpers/facebook-oauth.helper.js.map +1 -0
- package/dist/helpers/microsoft-oauth.helper.d.ts +9 -0
- package/dist/helpers/microsoft-oauth.helper.d.ts.map +1 -0
- package/dist/helpers/microsoft-oauth.helper.js +12 -0
- package/dist/helpers/microsoft-oauth.helper.js.map +1 -0
- package/dist/helpers/security.helper.d.ts.map +1 -1
- package/dist/helpers/string.helper.d.ts.map +1 -1
- package/dist/helpers/user-helper.d.ts.map +1 -1
- package/dist/helpers/user-helper.js +4 -0
- package/dist/helpers/user-helper.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/interfaces.d.ts +19 -0
- package/dist/interfaces.d.ts.map +1 -1
- package/dist/interfaces.js.map +1 -1
- package/dist/passport-strategies/facebook-oauth.strategy.d.ts +14 -0
- package/dist/passport-strategies/facebook-oauth.strategy.d.ts.map +1 -0
- package/dist/passport-strategies/facebook-oauth.strategy.js +73 -0
- package/dist/passport-strategies/facebook-oauth.strategy.js.map +1 -0
- package/dist/passport-strategies/microsoft-oauth.strategy.d.ts +14 -0
- package/dist/passport-strategies/microsoft-oauth.strategy.d.ts.map +1 -0
- package/dist/passport-strategies/microsoft-oauth.strategy.js +77 -0
- package/dist/passport-strategies/microsoft-oauth.strategy.js.map +1 -0
- package/dist/seeders/seed-data/solid-core-metadata.json +27 -58
- package/dist/services/api-key.service.d.ts +17 -1
- package/dist/services/api-key.service.d.ts.map +1 -1
- package/dist/services/api-key.service.js +38 -2
- package/dist/services/api-key.service.js.map +1 -1
- package/dist/services/authentication.service.d.ts +51 -16
- package/dist/services/authentication.service.d.ts.map +1 -1
- package/dist/services/authentication.service.js +318 -150
- package/dist/services/authentication.service.js.map +1 -1
- package/dist/services/chatter-message.service.d.ts +1 -0
- package/dist/services/chatter-message.service.d.ts.map +1 -1
- package/dist/services/chatter-message.service.js +24 -7
- package/dist/services/chatter-message.service.js.map +1 -1
- package/dist/services/crud-helper.service.d.ts.map +1 -1
- package/dist/services/model-metadata.service.js +1 -1
- package/dist/services/model-metadata.service.js.map +1 -1
- package/dist/services/setting.service.d.ts +5 -2
- package/dist/services/setting.service.d.ts.map +1 -1
- package/dist/services/setting.service.js +51 -6
- package/dist/services/setting.service.js.map +1 -1
- package/dist/services/settings/default-settings-provider.service.d.ts +830 -0
- package/dist/services/settings/default-settings-provider.service.d.ts.map +1 -1
- package/dist/services/settings/default-settings-provider.service.js +1033 -117
- package/dist/services/settings/default-settings-provider.service.js.map +1 -1
- package/dist/services/user.service.d.ts +2 -0
- package/dist/services/user.service.d.ts.map +1 -1
- package/dist/services/user.service.js +72 -0
- package/dist/services/user.service.js.map +1 -1
- package/dist/solid-core.module.d.ts.map +1 -1
- package/dist/solid-core.module.js +11 -3
- package/dist/solid-core.module.js.map +1 -1
- package/dist/transformers/array-transformer.d.ts.map +1 -1
- package/dist/transformers/boolean-transformer.d.ts.map +1 -1
- package/dist/transformers/datetime-transformer.d.ts.map +1 -1
- package/dist/transformers/integer-transformer.d.ts.map +1 -1
- package/dist/validators/is-parsable-int.d.ts.map +1 -1
- package/dist-tests/api/authenticate.spec.js +119 -0
- package/dist-tests/api/authenticate.spec.js.map +1 -0
- package/dist-tests/api/crud-service.findOne.cityMaster.spec.js +97 -0
- package/dist-tests/api/crud-service.findOne.cityMaster.spec.js.map +1 -0
- package/dist-tests/api/ping.spec.js +21 -0
- package/dist-tests/api/ping.spec.js.map +1 -0
- package/dist-tests/helpers/auth.js +41 -0
- package/dist-tests/helpers/auth.js.map +1 -0
- package/dist-tests/helpers/env.js +11 -0
- package/dist-tests/helpers/env.js.map +1 -0
- package/docs/java-spring/README.md +3 -0
- package/docs/java-spring/solid-core-module-deep-dive-report.md +1317 -0
- package/nest +0 -0
- package/package.json +7 -1
- package/src/constants/chatter-message.constants.ts +7 -0
- package/src/controllers/authentication.controller.ts +8 -1
- package/src/controllers/chatter-message.controller.ts +6 -0
- package/src/controllers/facebook-authentication.controller.ts +113 -0
- package/src/controllers/menu-item-metadata.controller.ts +21 -15
- package/src/controllers/microsoft-authentication.controller.ts +116 -0
- package/src/dtos/create-chatter-message.dto.ts +11 -0
- package/src/dtos/post-chatter-message.dto.ts +4 -0
- package/src/dtos/update-chatter-message.dto.ts +13 -1
- package/src/entities/chatter-message.entity.ts +4 -1
- package/src/entities/user.entity.ts +32 -0
- package/src/helpers/cors.helper.ts +1 -1
- package/src/helpers/facebook-oauth.helper.ts +17 -0
- package/src/helpers/microsoft-oauth.helper.ts +19 -0
- package/src/helpers/user-helper.ts +4 -0
- package/src/index.ts +2 -0
- package/src/interfaces.ts +32 -1
- package/src/passport-strategies/facebook-oauth.strategy.ts +64 -0
- package/src/passport-strategies/microsoft-oauth.strategy.ts +70 -0
- package/src/seeders/seed-data/solid-core-metadata.json +27 -58
- package/src/services/api-key.service.ts +77 -35
- package/src/services/authentication.service.ts +1717 -1278
- package/src/services/chatter-message.service.ts +23 -3
- package/src/services/model-metadata.service.ts +1 -1
- package/src/services/setting.service.ts +64 -8
- package/src/services/settings/default-settings-provider.service.ts +1104 -155
- package/src/services/user.service.ts +87 -0
- package/src/solid-core.module.ts +25 -8
- package/.claude/settings.local.json +0 -15
- package/src/services/1.js +0 -6
|
@@ -65,17 +65,14 @@ let AuthenticationService = AuthenticationService_1 = class AuthenticationServic
|
|
|
65
65
|
this.logger = new common_1.Logger(AuthenticationService_1.name);
|
|
66
66
|
}
|
|
67
67
|
async getCompanyLogo() {
|
|
68
|
-
return this.settingService.getConfigValue(
|
|
68
|
+
return this.settingService.getConfigValue("companylogo");
|
|
69
69
|
}
|
|
70
70
|
async resolveUser(username, email) {
|
|
71
71
|
return await this.userRepository.findOne({
|
|
72
|
-
where: [
|
|
73
|
-
{ username: username },
|
|
74
|
-
{ email: email },
|
|
75
|
-
],
|
|
72
|
+
where: [{ username: username }, { email: email }],
|
|
76
73
|
relations: {
|
|
77
|
-
roles: true
|
|
78
|
-
}
|
|
74
|
+
roles: true,
|
|
75
|
+
},
|
|
79
76
|
});
|
|
80
77
|
}
|
|
81
78
|
async updatePasswordDetails(user, newPassword) {
|
|
@@ -87,14 +84,14 @@ let AuthenticationService = AuthenticationService_1 = class AuthenticationServic
|
|
|
87
84
|
password: user.password,
|
|
88
85
|
passwordScheme: user.passwordScheme,
|
|
89
86
|
passwordSchemeVersion: user.passwordSchemeVersion,
|
|
90
|
-
rehashedAt: user.rehashedAt
|
|
87
|
+
rehashedAt: user.rehashedAt,
|
|
91
88
|
});
|
|
92
89
|
return user;
|
|
93
90
|
}
|
|
94
91
|
async resolveUserByVerificationToken(token) {
|
|
95
92
|
return await this.userRepository.findOne({
|
|
96
93
|
where: { verificationTokenOnForgotPassword: token },
|
|
97
|
-
relations: { roles: true }
|
|
94
|
+
relations: { roles: true },
|
|
98
95
|
});
|
|
99
96
|
}
|
|
100
97
|
async validateUserForPasswordLogin(user, password) {
|
|
@@ -157,7 +154,7 @@ let AuthenticationService = AuthenticationService_1 = class AuthenticationServic
|
|
|
157
154
|
return this.performSignUp(signUpDto, entity, extensionUserRepo);
|
|
158
155
|
}
|
|
159
156
|
async populateForSignup(user, signUpDto, isUserActive = true, onForcePasswordChange) {
|
|
160
|
-
let autoGeneratedPwdPermission = this.settingService.getConfigValue(
|
|
157
|
+
let autoGeneratedPwdPermission = this.settingService.getConfigValue("iamAutoGeneratedPassword");
|
|
161
158
|
if (signUpDto.roles && signUpDto.roles.length > 0) {
|
|
162
159
|
for (let i = 0; i < signUpDto.roles.length; i++) {
|
|
163
160
|
const roleName = signUpDto.roles[i];
|
|
@@ -171,20 +168,20 @@ let AuthenticationService = AuthenticationService_1 = class AuthenticationServic
|
|
|
171
168
|
if (signUpDto.mobile) {
|
|
172
169
|
user.mobile = signUpDto.mobile;
|
|
173
170
|
}
|
|
174
|
-
let pwd =
|
|
175
|
-
let autoGeneratedPwd =
|
|
171
|
+
let pwd = "";
|
|
172
|
+
let autoGeneratedPwd = "";
|
|
176
173
|
if (signUpDto.password) {
|
|
177
174
|
pwd = await this.hashingService.hash(signUpDto.password);
|
|
178
175
|
}
|
|
179
176
|
else {
|
|
180
|
-
if (autoGeneratedPwdPermission?.toString().toLowerCase() ===
|
|
177
|
+
if (autoGeneratedPwdPermission?.toString().toLowerCase() === "true") {
|
|
181
178
|
autoGeneratedPwd = this.generatePassword();
|
|
182
179
|
pwd = await this.hashingService.hash(autoGeneratedPwd);
|
|
183
180
|
user.forcePasswordChange = true;
|
|
184
181
|
}
|
|
185
182
|
else {
|
|
186
|
-
if (!await this.isPasswordlessRegistrationEnabled()) {
|
|
187
|
-
this.logger.error(
|
|
183
|
+
if (!(await this.isPasswordlessRegistrationEnabled())) {
|
|
184
|
+
this.logger.error("User being created without password, and password less login is also not enabled in the system. Is this intentional?");
|
|
188
185
|
throw new common_1.BadRequestException(error_messages_1.ERROR_MESSAGES.PASSWORDLESS_REGISTRATION_DISABLED);
|
|
189
186
|
}
|
|
190
187
|
pwd = await this.hashingService.hash(pwd);
|
|
@@ -219,48 +216,48 @@ let AuthenticationService = AuthenticationService_1 = class AuthenticationServic
|
|
|
219
216
|
async notifyUserOnForcePasswordChange(user, autoGeneratedPwd) {
|
|
220
217
|
const companyLogo = await this.getCompanyLogo();
|
|
221
218
|
const mailService = this.mailServiceFactory.getMailService();
|
|
222
|
-
mailService.sendEmailUsingTemplate(user.email,
|
|
223
|
-
solidAppName: this.settingService.getConfigValue(
|
|
224
|
-
solidAppWebsiteUrl: this.settingService.getConfigValue(
|
|
225
|
-
frontendLoginPageUrl: this.settingService.getConfigValue(
|
|
219
|
+
mailService.sendEmailUsingTemplate(user.email, "on-force-password-change", {
|
|
220
|
+
solidAppName: this.settingService.getConfigValue("appTitle"),
|
|
221
|
+
solidAppWebsiteUrl: this.settingService.getConfigValue("solidAppWebsiteUrl"),
|
|
222
|
+
frontendLoginPageUrl: this.settingService.getConfigValue("frontendLoginPageUrl"),
|
|
226
223
|
email: user.email,
|
|
227
224
|
fullName: user.fullName,
|
|
228
225
|
userName: user.username,
|
|
229
226
|
password: autoGeneratedPwd,
|
|
230
|
-
companyLogoUrl: companyLogo
|
|
231
|
-
}, this.settingService.getConfigValue(
|
|
227
|
+
companyLogoUrl: companyLogo,
|
|
228
|
+
}, this.settingService.getConfigValue("shouldQueueEmails"), null, null, "user", user.id);
|
|
232
229
|
}
|
|
233
230
|
async isWelcomeEmailEnabled() {
|
|
234
|
-
const sendWelcomeEmailOnSignup = this.settingService.getConfigValue(
|
|
231
|
+
const sendWelcomeEmailOnSignup = this.settingService.getConfigValue("sendWelcomeEmailOnSignup");
|
|
235
232
|
return sendWelcomeEmailOnSignup;
|
|
236
233
|
}
|
|
237
234
|
async isWelcomeSmsEnabled() {
|
|
238
|
-
const sendWelcomeSmsOnSignup = this.settingService.getConfigValue(
|
|
235
|
+
const sendWelcomeSmsOnSignup = this.settingService.getConfigValue("sendWelcomeSmsOnSignup");
|
|
239
236
|
return sendWelcomeSmsOnSignup;
|
|
240
237
|
}
|
|
241
238
|
async notifyUserOnSignup(user) {
|
|
242
239
|
const companyLogo = await this.getCompanyLogo();
|
|
243
240
|
if (await this.isWelcomeEmailEnabled()) {
|
|
244
241
|
const mailService = this.mailServiceFactory.getMailService();
|
|
245
|
-
mailService.sendEmailUsingTemplate(user.email,
|
|
246
|
-
solidAppName: this.settingService.getConfigValue(
|
|
247
|
-
solidAppWebsiteUrl: this.settingService.getConfigValue(
|
|
248
|
-
frontendLoginPageUrl: this.settingService.getConfigValue(
|
|
242
|
+
mailService.sendEmailUsingTemplate(user.email, "email-on-signup", {
|
|
243
|
+
solidAppName: this.settingService.getConfigValue("appTitle"),
|
|
244
|
+
solidAppWebsiteUrl: this.settingService.getConfigValue("solidAppWebsiteUrl"),
|
|
245
|
+
frontendLoginPageUrl: this.settingService.getConfigValue("frontendLoginPageUrl"),
|
|
249
246
|
email: user.email,
|
|
250
247
|
fullName: user.fullName,
|
|
251
248
|
userName: user.username,
|
|
252
|
-
companyLogoUrl: companyLogo
|
|
253
|
-
}, this.settingService.getConfigValue(
|
|
249
|
+
companyLogoUrl: companyLogo,
|
|
250
|
+
}, this.settingService.getConfigValue("shouldQueueEmails"), null, null, "user", user.id);
|
|
254
251
|
}
|
|
255
252
|
const isWelcomeSmsEnabled = await this.isWelcomeSmsEnabled();
|
|
256
253
|
if (isWelcomeSmsEnabled && user.mobile) {
|
|
257
254
|
const smsService = this.smsFactory.getSmsService();
|
|
258
|
-
smsService.sendSMSUsingTemplate(user.mobile,
|
|
259
|
-
solidAppName: this.settingService.getConfigValue(
|
|
260
|
-
frontendLoginPageUrl: this.settingService.getConfigValue(
|
|
255
|
+
smsService.sendSMSUsingTemplate(user.mobile, "text-on-signup", {
|
|
256
|
+
solidAppName: this.settingService.getConfigValue("appTitle"),
|
|
257
|
+
frontendLoginPageUrl: this.settingService.getConfigValue("frontendLoginPageUrl"),
|
|
261
258
|
firstName: user.username,
|
|
262
|
-
fullName: user.fullName ? user.fullName : user.username
|
|
263
|
-
}, this.settingService.getConfigValue(
|
|
259
|
+
fullName: user.fullName ? user.fullName : user.username,
|
|
260
|
+
}, this.settingService.getConfigValue("shouldQueueSms"));
|
|
264
261
|
}
|
|
265
262
|
}
|
|
266
263
|
async otpInitiateRegistration(signUpDto) {
|
|
@@ -279,7 +276,7 @@ let AuthenticationService = AuthenticationService_1 = class AuthenticationServic
|
|
|
279
276
|
await this.notifyUserOnOtpInitiateRegistration(user, validationSource);
|
|
280
277
|
}
|
|
281
278
|
catch (err) {
|
|
282
|
-
if (err.code ===
|
|
279
|
+
if (err.code === "23505") {
|
|
283
280
|
throw new common_1.ConflictException(error_messages_1.ERROR_MESSAGES.USER_ALREADY_EXISTS);
|
|
284
281
|
}
|
|
285
282
|
throw err;
|
|
@@ -287,10 +284,12 @@ let AuthenticationService = AuthenticationService_1 = class AuthenticationServic
|
|
|
287
284
|
return { message: success_messages_1.SUCCESS_MESSAGES.OTP_SENT_SUCCESS_REGISTRATION };
|
|
288
285
|
}
|
|
289
286
|
validateOtpRegistrationInput(signUpDto, validationSource) {
|
|
290
|
-
if (validationSource === constants_1.PasswordlessRegistrationValidateWhatSources.EMAIL &&
|
|
287
|
+
if (validationSource === constants_1.PasswordlessRegistrationValidateWhatSources.EMAIL &&
|
|
288
|
+
(0, class_validator_1.isEmpty)(signUpDto.email)) {
|
|
291
289
|
throw new common_1.BadRequestException(error_messages_1.ERROR_MESSAGES.EMAIL_REQUIRED_FOR_VALIDATION);
|
|
292
290
|
}
|
|
293
|
-
if (validationSource === constants_1.PasswordlessRegistrationValidateWhatSources.MOBILE &&
|
|
291
|
+
if (validationSource === constants_1.PasswordlessRegistrationValidateWhatSources.MOBILE &&
|
|
292
|
+
(0, class_validator_1.isEmpty)(signUpDto.mobile)) {
|
|
294
293
|
throw new common_1.BadRequestException(error_messages_1.ERROR_MESSAGES.MOBILE_REQUIRED_FOR_VALIDATION);
|
|
295
294
|
}
|
|
296
295
|
}
|
|
@@ -300,11 +299,11 @@ let AuthenticationService = AuthenticationService_1 = class AuthenticationServic
|
|
|
300
299
|
{ email: signUpDto.email },
|
|
301
300
|
{ mobile: signUpDto.mobile },
|
|
302
301
|
{ username: signUpDto.username },
|
|
303
|
-
]
|
|
302
|
+
],
|
|
304
303
|
});
|
|
305
304
|
}
|
|
306
305
|
resolvePasswordlessValidationSource() {
|
|
307
|
-
return this.settingService.getConfigValue(
|
|
306
|
+
return this.settingService.getConfigValue("passwordlessRegistrationValidateWhat");
|
|
308
307
|
}
|
|
309
308
|
async upsertUserWithRegistrationVerificationTokens(existingUser, signUpDto, validationSource) {
|
|
310
309
|
let user = existingUser;
|
|
@@ -334,8 +333,9 @@ let AuthenticationService = AuthenticationService_1 = class AuthenticationServic
|
|
|
334
333
|
if (!passwordlessRegistrationValidateWhat) {
|
|
335
334
|
throw new common_1.BadRequestException(error_messages_1.ERROR_MESSAGES.VALIDATION_SOURCE_REQUIRED);
|
|
336
335
|
}
|
|
337
|
-
const autoLoginUserOnRegistration = this.settingService.getConfigValue(
|
|
338
|
-
if (passwordlessRegistrationValidateWhat ===
|
|
336
|
+
const autoLoginUserOnRegistration = this.settingService.getConfigValue("autoLoginUserOnRegistration");
|
|
337
|
+
if (passwordlessRegistrationValidateWhat ===
|
|
338
|
+
constants_1.PasswordlessRegistrationValidateWhatSources.EMAIL) {
|
|
339
339
|
const { token, expiresAt } = await this.otp();
|
|
340
340
|
user.emailVerificationTokenOnRegistration = token;
|
|
341
341
|
user.emailVerificationTokenOnRegistrationExpiresAt = expiresAt;
|
|
@@ -344,7 +344,8 @@ let AuthenticationService = AuthenticationService_1 = class AuthenticationServic
|
|
|
344
344
|
user.emailVerificationTokenOnLoginExpiresAt = expiresAt;
|
|
345
345
|
}
|
|
346
346
|
}
|
|
347
|
-
if (passwordlessRegistrationValidateWhat ===
|
|
347
|
+
if (passwordlessRegistrationValidateWhat ===
|
|
348
|
+
constants_1.PasswordlessRegistrationValidateWhatSources.MOBILE) {
|
|
348
349
|
const { token, expiresAt } = await this.otp();
|
|
349
350
|
user.mobileVerificationTokenOnRegistration = token;
|
|
350
351
|
user.mobileVerificationTokenOnRegistrationExpiresAt = expiresAt;
|
|
@@ -356,27 +357,29 @@ let AuthenticationService = AuthenticationService_1 = class AuthenticationServic
|
|
|
356
357
|
}
|
|
357
358
|
async notifyUserOnOtpInitiateRegistration(user, registrationValidationSource) {
|
|
358
359
|
const companyLogo = await this.getCompanyLogo();
|
|
359
|
-
if (registrationValidationSource ===
|
|
360
|
+
if (registrationValidationSource ===
|
|
361
|
+
constants_1.PasswordlessLoginValidateWhatSources.EMAIL) {
|
|
360
362
|
const mailService = this.mailServiceFactory.getMailService();
|
|
361
|
-
mailService.sendEmailUsingTemplate(user.email,
|
|
362
|
-
solidAppName: this.settingService.getConfigValue(
|
|
363
|
-
solidAppWebsiteUrl: this.settingService.getConfigValue(
|
|
363
|
+
mailService.sendEmailUsingTemplate(user.email, "otp-on-register", {
|
|
364
|
+
solidAppName: this.settingService.getConfigValue("appTitle"),
|
|
365
|
+
solidAppWebsiteUrl: this.settingService.getConfigValue("solidAppWebsiteUrl"),
|
|
364
366
|
firstName: user.username,
|
|
365
367
|
fullName: user.fullName ? user.fullName : user.username,
|
|
366
368
|
emailVerificationTokenOnRegistration: user.emailVerificationTokenOnRegistration,
|
|
367
|
-
companyLogoUrl: companyLogo
|
|
368
|
-
}, this.settingService.getConfigValue(
|
|
369
|
+
companyLogoUrl: companyLogo,
|
|
370
|
+
}, this.settingService.getConfigValue("shouldQueueEmails"), null, null, "user", user.id);
|
|
369
371
|
}
|
|
370
|
-
if (registrationValidationSource ===
|
|
372
|
+
if (registrationValidationSource ===
|
|
373
|
+
constants_1.PasswordlessLoginValidateWhatSources.MOBILE) {
|
|
371
374
|
const smsService = this.smsFactory.getSmsService();
|
|
372
|
-
smsService.sendSMSUsingTemplate(user.mobile,
|
|
373
|
-
solidAppName: this.settingService.getConfigValue(
|
|
375
|
+
smsService.sendSMSUsingTemplate(user.mobile, "otp-on-register", {
|
|
376
|
+
solidAppName: this.settingService.getConfigValue("appTitle"),
|
|
374
377
|
otp: user.mobileVerificationTokenOnRegistration,
|
|
375
378
|
mobileVerificationTokenOnRegistration: user.mobileVerificationTokenOnRegistration,
|
|
376
379
|
firstName: user.username,
|
|
377
380
|
fullName: user.fullName ? user.fullName : user.username,
|
|
378
|
-
companyLogoUrl: companyLogo
|
|
379
|
-
}, this.settingService.getConfigValue(
|
|
381
|
+
companyLogoUrl: companyLogo,
|
|
382
|
+
}, this.settingService.getConfigValue("shouldQueueSms"));
|
|
380
383
|
}
|
|
381
384
|
}
|
|
382
385
|
async otpConfirmRegistration(confirmSignUpDto) {
|
|
@@ -392,11 +395,15 @@ let AuthenticationService = AuthenticationService_1 = class AuthenticationServic
|
|
|
392
395
|
const user = await this.findUserByRegistrationIdentifier(type, identifier);
|
|
393
396
|
this.validateRegistrationOtp(user, otp, type);
|
|
394
397
|
this.clearRegistrationOtp(user, type);
|
|
395
|
-
user.active =
|
|
396
|
-
|
|
398
|
+
user.active =
|
|
399
|
+
this.settingService.getConfigValue("activateUserOnRegistration") &&
|
|
400
|
+
(await this.areAllPasswordlessRegistrationValidationSourcesVerified(user));
|
|
397
401
|
const savedUser = await this.userRepository.save(user);
|
|
398
402
|
this.triggerRegistrationEvent(savedUser);
|
|
399
|
-
return {
|
|
403
|
+
return {
|
|
404
|
+
active: savedUser.active,
|
|
405
|
+
message: `User registration verified for ${type}`,
|
|
406
|
+
};
|
|
400
407
|
}
|
|
401
408
|
async findUserByRegistrationIdentifier(type, identifier) {
|
|
402
409
|
const where = type === constants_1.PasswordlessRegistrationValidateWhatSources.EMAIL
|
|
@@ -410,8 +417,12 @@ let AuthenticationService = AuthenticationService_1 = class AuthenticationServic
|
|
|
410
417
|
}
|
|
411
418
|
validateRegistrationOtp(user, otp, type) {
|
|
412
419
|
const isEmail = type === constants_1.PasswordlessRegistrationValidateWhatSources.EMAIL;
|
|
413
|
-
const token = isEmail
|
|
414
|
-
|
|
420
|
+
const token = isEmail
|
|
421
|
+
? user.emailVerificationTokenOnRegistration
|
|
422
|
+
: user.mobileVerificationTokenOnRegistration;
|
|
423
|
+
const expiresAt = isEmail
|
|
424
|
+
? user.emailVerificationTokenOnRegistrationExpiresAt
|
|
425
|
+
: user.mobileVerificationTokenOnRegistrationExpiresAt;
|
|
415
426
|
if (token !== otp) {
|
|
416
427
|
throw new common_1.UnauthorizedException(error_messages_1.ERROR_MESSAGES.INVALID_OTP);
|
|
417
428
|
}
|
|
@@ -437,12 +448,14 @@ let AuthenticationService = AuthenticationService_1 = class AuthenticationServic
|
|
|
437
448
|
}
|
|
438
449
|
async areAllPasswordlessRegistrationValidationSourcesVerified(user) {
|
|
439
450
|
const registrationValidationSource = this.resolvePasswordlessValidationSource();
|
|
440
|
-
if (registrationValidationSource ===
|
|
451
|
+
if (registrationValidationSource ===
|
|
452
|
+
constants_1.PasswordlessLoginValidateWhatSources.EMAIL) {
|
|
441
453
|
if (!user.emailVerifiedOnRegistrationAt) {
|
|
442
454
|
return false;
|
|
443
455
|
}
|
|
444
456
|
}
|
|
445
|
-
if (registrationValidationSource ===
|
|
457
|
+
if (registrationValidationSource ===
|
|
458
|
+
constants_1.PasswordlessLoginValidateWhatSources.MOBILE) {
|
|
446
459
|
if (!user.mobileVerifiedOnRegistrationAt) {
|
|
447
460
|
return false;
|
|
448
461
|
}
|
|
@@ -451,7 +464,7 @@ let AuthenticationService = AuthenticationService_1 = class AuthenticationServic
|
|
|
451
464
|
}
|
|
452
465
|
async otp() {
|
|
453
466
|
const now = new Date();
|
|
454
|
-
const otpExpiry = this.settingService.getConfigValue(
|
|
467
|
+
const otpExpiry = this.settingService.getConfigValue("otpExpiry");
|
|
455
468
|
now.setMinutes(now.getMinutes() + otpExpiry);
|
|
456
469
|
return {
|
|
457
470
|
token: (0, crypto_1.randomInt)(100000, 999999).toString(),
|
|
@@ -459,7 +472,7 @@ let AuthenticationService = AuthenticationService_1 = class AuthenticationServic
|
|
|
459
472
|
};
|
|
460
473
|
}
|
|
461
474
|
getDummyOtpForUser(user) {
|
|
462
|
-
const dummyOtp = this.settingService.getConfigValue(
|
|
475
|
+
const dummyOtp = this.settingService.getConfigValue("dummyOtp");
|
|
463
476
|
if (!dummyOtp || !user?.username) {
|
|
464
477
|
return undefined;
|
|
465
478
|
}
|
|
@@ -474,12 +487,12 @@ let AuthenticationService = AuthenticationService_1 = class AuthenticationServic
|
|
|
474
487
|
return allowedUsers.has(username) ? dummyOtp : undefined;
|
|
475
488
|
}
|
|
476
489
|
getDummyOtpUsers() {
|
|
477
|
-
const rawUsers = this.settingService.getConfigValue(
|
|
478
|
-
if (!rawUsers || typeof rawUsers !==
|
|
490
|
+
const rawUsers = this.settingService.getConfigValue("dummyOtpUsers");
|
|
491
|
+
if (!rawUsers || typeof rawUsers !== "string") {
|
|
479
492
|
return new Set();
|
|
480
493
|
}
|
|
481
494
|
return new Set(rawUsers
|
|
482
|
-
.split(
|
|
495
|
+
.split(",")
|
|
483
496
|
.map((value) => value.trim().toLowerCase())
|
|
484
497
|
.filter(Boolean));
|
|
485
498
|
}
|
|
@@ -492,7 +505,7 @@ let AuthenticationService = AuthenticationService_1 = class AuthenticationServic
|
|
|
492
505
|
await this.rehashPasswordIfRequired(user, signInDto.password);
|
|
493
506
|
await this.resetFailedAttempts(user);
|
|
494
507
|
const tokens = await this.generateTokens(user);
|
|
495
|
-
await this.userActivityHistoryService.logEvent(
|
|
508
|
+
await this.userActivityHistoryService.logEvent("login", user);
|
|
496
509
|
return {
|
|
497
510
|
user: {
|
|
498
511
|
email: user.email,
|
|
@@ -500,15 +513,15 @@ let AuthenticationService = AuthenticationService_1 = class AuthenticationServic
|
|
|
500
513
|
username: user.username,
|
|
501
514
|
forcePasswordChange: user.forcePasswordChange,
|
|
502
515
|
id: user.id,
|
|
503
|
-
roles: user.roles.map((role) => role.name)
|
|
516
|
+
roles: user.roles.map((role) => role.name),
|
|
504
517
|
},
|
|
505
|
-
...tokens
|
|
518
|
+
...tokens,
|
|
506
519
|
};
|
|
507
520
|
}
|
|
508
521
|
maskEmail(email) {
|
|
509
522
|
if (!email)
|
|
510
523
|
return null;
|
|
511
|
-
const [localPart, domain] = email.split(
|
|
524
|
+
const [localPart, domain] = email.split("@");
|
|
512
525
|
if (localPart.length <= 2) {
|
|
513
526
|
return `${localPart[0]}***@${domain}`;
|
|
514
527
|
}
|
|
@@ -540,7 +553,7 @@ let AuthenticationService = AuthenticationService_1 = class AuthenticationServic
|
|
|
540
553
|
return this.buildLoginOtpResponse(user, type);
|
|
541
554
|
}
|
|
542
555
|
resolveLoginType(signInDto) {
|
|
543
|
-
const setting = this.settingService.getConfigValue(
|
|
556
|
+
const setting = this.settingService.getConfigValue("passwordlessLoginValidateWhat");
|
|
544
557
|
if (setting === constants_1.PasswordlessLoginValidateWhatSources.SELECTABLE) {
|
|
545
558
|
if (signInDto.type !== constants_1.PasswordlessLoginValidateWhatSources.EMAIL &&
|
|
546
559
|
signInDto.type !== constants_1.PasswordlessLoginValidateWhatSources.MOBILE) {
|
|
@@ -593,7 +606,10 @@ let AuthenticationService = AuthenticationService_1 = class AuthenticationServic
|
|
|
593
606
|
const maskedIdentifier = type === constants_1.PasswordlessLoginValidateWhatSources.EMAIL
|
|
594
607
|
? { email: this.maskEmail(user.email) }
|
|
595
608
|
: { mobile: this.maskMobile(user.mobile) };
|
|
596
|
-
return {
|
|
609
|
+
return {
|
|
610
|
+
message: success_messages_1.SUCCESS_MESSAGES.OTP_SENT_SUCCESS_LOGIN,
|
|
611
|
+
user: maskedIdentifier,
|
|
612
|
+
};
|
|
597
613
|
}
|
|
598
614
|
async notifyUserOnOtpInititateLogin(user, loginType) {
|
|
599
615
|
const companyLogo = await this.getCompanyLogo();
|
|
@@ -602,25 +618,25 @@ let AuthenticationService = AuthenticationService_1 = class AuthenticationServic
|
|
|
602
618
|
return;
|
|
603
619
|
if (loginType === constants_1.PasswordlessLoginValidateWhatSources.EMAIL) {
|
|
604
620
|
const mailService = this.mailServiceFactory.getMailService();
|
|
605
|
-
mailService.sendEmailUsingTemplate(user.email,
|
|
606
|
-
solidAppName: this.settingService.getConfigValue(
|
|
607
|
-
solidAppWebsiteUrl: this.settingService.getConfigValue(
|
|
621
|
+
mailService.sendEmailUsingTemplate(user.email, "otp-on-login", {
|
|
622
|
+
solidAppName: this.settingService.getConfigValue("appTitle"),
|
|
623
|
+
solidAppWebsiteUrl: this.settingService.getConfigValue("solidAppWebsiteUrl"),
|
|
608
624
|
firstName: user.username,
|
|
609
625
|
emailVerificationTokenOnLogin: user.emailVerificationTokenOnLogin,
|
|
610
626
|
fullName: user.fullName ? user.fullName : user.username,
|
|
611
|
-
companyLogoUrl: companyLogo
|
|
612
|
-
}, this.settingService.getConfigValue(
|
|
627
|
+
companyLogoUrl: companyLogo,
|
|
628
|
+
}, this.settingService.getConfigValue("shouldQueueEmails"), null, null, "user", user.id);
|
|
613
629
|
}
|
|
614
630
|
if (loginType === constants_1.PasswordlessLoginValidateWhatSources.MOBILE) {
|
|
615
631
|
const smsService = this.smsFactory.getSmsService();
|
|
616
|
-
smsService.sendSMSUsingTemplate(user.mobile,
|
|
617
|
-
solidAppName: this.settingService.getConfigValue(
|
|
632
|
+
smsService.sendSMSUsingTemplate(user.mobile, "otp-on-login", {
|
|
633
|
+
solidAppName: this.settingService.getConfigValue("appTitle"),
|
|
618
634
|
otp: user.mobileVerificationTokenOnLogin,
|
|
619
635
|
mobileVerificationTokenOnLogin: user.mobileVerificationTokenOnLogin,
|
|
620
636
|
firstName: user.username,
|
|
621
637
|
fullName: user.fullName ? user.fullName : user.username,
|
|
622
|
-
companyLogoUrl: companyLogo
|
|
623
|
-
}, this.settingService.getConfigValue(
|
|
638
|
+
companyLogoUrl: companyLogo,
|
|
639
|
+
}, this.settingService.getConfigValue("shouldQueueSms"));
|
|
624
640
|
}
|
|
625
641
|
}
|
|
626
642
|
async otpConfirmLogin(confirmSignInDto) {
|
|
@@ -633,7 +649,9 @@ let AuthenticationService = AuthenticationService_1 = class AuthenticationServic
|
|
|
633
649
|
type !== constants_1.PasswordlessLoginValidateWhatSources.MOBILE) {
|
|
634
650
|
throw new common_1.BadRequestException(error_messages_1.ERROR_MESSAGES.INVALID_VERIFICATION_TYPE);
|
|
635
651
|
}
|
|
636
|
-
const user = await this.findUserForLogin(type, identifier, {
|
|
652
|
+
const user = await this.findUserForLogin(type, identifier, {
|
|
653
|
+
withRoles: true,
|
|
654
|
+
});
|
|
637
655
|
this.checkAccountBlocked(user);
|
|
638
656
|
const dummyOtp = this.getDummyOtpForUser(user);
|
|
639
657
|
if (dummyOtp) {
|
|
@@ -650,14 +668,18 @@ let AuthenticationService = AuthenticationService_1 = class AuthenticationServic
|
|
|
650
668
|
throw e;
|
|
651
669
|
}
|
|
652
670
|
await this.clearLoginOtp(user, type);
|
|
653
|
-
await this.userActivityHistoryService.logEvent(
|
|
671
|
+
await this.userActivityHistoryService.logEvent("login", user);
|
|
654
672
|
await this.resetFailedAttempts(user);
|
|
655
673
|
return this.buildLoginTokenResponse(user);
|
|
656
674
|
}
|
|
657
675
|
validateLoginOtp(user, otp, type) {
|
|
658
676
|
const isEmail = type === constants_1.PasswordlessLoginValidateWhatSources.EMAIL;
|
|
659
|
-
const token = isEmail
|
|
660
|
-
|
|
677
|
+
const token = isEmail
|
|
678
|
+
? user.emailVerificationTokenOnLogin
|
|
679
|
+
: user.mobileVerificationTokenOnLogin;
|
|
680
|
+
const expiresAt = isEmail
|
|
681
|
+
? user.emailVerificationTokenOnLoginExpiresAt
|
|
682
|
+
: user.mobileVerificationTokenOnLoginExpiresAt;
|
|
661
683
|
if (token !== otp) {
|
|
662
684
|
throw new common_1.UnauthorizedException(error_messages_1.ERROR_MESSAGES.INVALID_OTP);
|
|
663
685
|
}
|
|
@@ -700,7 +722,7 @@ let AuthenticationService = AuthenticationService_1 = class AuthenticationServic
|
|
|
700
722
|
}
|
|
701
723
|
async changePassword(changePasswordDto, activeUser) {
|
|
702
724
|
const user = await this.userRepository.findOne({
|
|
703
|
-
where: { id: changePasswordDto.id }
|
|
725
|
+
where: { id: changePasswordDto.id },
|
|
704
726
|
});
|
|
705
727
|
if (!user) {
|
|
706
728
|
throw new common_1.NotFoundException(error_messages_1.ERROR_MESSAGES.USER_NOT_FOUND);
|
|
@@ -708,7 +730,7 @@ let AuthenticationService = AuthenticationService_1 = class AuthenticationServic
|
|
|
708
730
|
if (!user.active) {
|
|
709
731
|
throw new common_1.UnauthorizedException(error_messages_1.ERROR_MESSAGES.USER_INACTIVE);
|
|
710
732
|
}
|
|
711
|
-
if (user.lastLoginProvider !==
|
|
733
|
+
if (user.lastLoginProvider !== "local") {
|
|
712
734
|
throw new common_1.BadRequestException(error_messages_1.ERROR_MESSAGES.NON_LOCAL_PROVIDER);
|
|
713
735
|
}
|
|
714
736
|
if (!(user.id === activeUser.sub)) {
|
|
@@ -732,7 +754,7 @@ let AuthenticationService = AuthenticationService_1 = class AuthenticationServic
|
|
|
732
754
|
}
|
|
733
755
|
async generateForgotPasswordToken(user) {
|
|
734
756
|
const expiryTime = new Date();
|
|
735
|
-
const forgotPasswordVerificationTokenExpiry = this.settingService.getConfigValue(
|
|
757
|
+
const forgotPasswordVerificationTokenExpiry = this.settingService.getConfigValue("forgotPasswordVerificationTokenExpiry");
|
|
736
758
|
const dummyOtp = this.getDummyOtpForUser(user);
|
|
737
759
|
expiryTime.setMinutes(expiryTime.getMinutes() + forgotPasswordVerificationTokenExpiry);
|
|
738
760
|
return {
|
|
@@ -749,7 +771,7 @@ let AuthenticationService = AuthenticationService_1 = class AuthenticationServic
|
|
|
749
771
|
if (isValidUser && !user?.active) {
|
|
750
772
|
isValidUser = false;
|
|
751
773
|
}
|
|
752
|
-
if (isValidUser && user?.lastLoginProvider !==
|
|
774
|
+
if (isValidUser && user?.lastLoginProvider !== "local") {
|
|
753
775
|
isValidUser = false;
|
|
754
776
|
}
|
|
755
777
|
if (isValidUser) {
|
|
@@ -760,40 +782,43 @@ let AuthenticationService = AuthenticationService_1 = class AuthenticationServic
|
|
|
760
782
|
await this.notifyUserOnForgotPassword(user);
|
|
761
783
|
}
|
|
762
784
|
return {
|
|
763
|
-
status:
|
|
785
|
+
status: "success",
|
|
764
786
|
message: success_messages_1.SUCCESS_MESSAGES.FORGOT_PASSWORD_TOKEN_SENT,
|
|
765
|
-
error:
|
|
766
|
-
errorCode:
|
|
787
|
+
error: "",
|
|
788
|
+
errorCode: "",
|
|
767
789
|
data: {
|
|
768
790
|
user: {
|
|
769
791
|
email: user?.email,
|
|
770
792
|
},
|
|
771
|
-
}
|
|
793
|
+
},
|
|
772
794
|
};
|
|
773
795
|
}
|
|
774
796
|
async notifyUserOnForgotPassword(user) {
|
|
775
797
|
const companyLogo = await this.getCompanyLogo();
|
|
776
|
-
const forgotPasswordSendVerificationTokenOn = this.settingService.getConfigValue(
|
|
777
|
-
if (forgotPasswordSendVerificationTokenOn ==
|
|
798
|
+
const forgotPasswordSendVerificationTokenOn = this.settingService.getConfigValue("forgotPasswordSendVerificationTokenOn");
|
|
799
|
+
if (forgotPasswordSendVerificationTokenOn ==
|
|
800
|
+
constants_1.ForgotPasswordSendVerificationTokenOn.EMAIL) {
|
|
778
801
|
const mailService = this.mailServiceFactory.getMailService();
|
|
779
|
-
mailService.sendEmailUsingTemplate(user.email,
|
|
780
|
-
solidAppName: this.settingService.getConfigValue(
|
|
781
|
-
solidAppWebsiteUrl: this.settingService.getConfigValue(
|
|
802
|
+
mailService.sendEmailUsingTemplate(user.email, "forgot-password", {
|
|
803
|
+
solidAppName: this.settingService.getConfigValue("appTitle"),
|
|
804
|
+
solidAppWebsiteUrl: this.settingService.getConfigValue("solidAppWebsiteUrl"),
|
|
782
805
|
firstName: user.username,
|
|
783
806
|
fullName: user.fullName,
|
|
784
|
-
passwordResetLink: `${this.settingService.getConfigValue(
|
|
785
|
-
companyLogoUrl: companyLogo
|
|
786
|
-
}, this.settingService.getConfigValue(
|
|
807
|
+
passwordResetLink: `${this.settingService.getConfigValue("frontendForgotPasswordPageUrl")}?token=${user.verificationTokenOnForgotPassword}`,
|
|
808
|
+
companyLogoUrl: companyLogo,
|
|
809
|
+
}, this.settingService.getConfigValue("shouldQueueEmails"), null, null, "user", user.id);
|
|
787
810
|
}
|
|
788
|
-
if (forgotPasswordSendVerificationTokenOn ==
|
|
811
|
+
if (forgotPasswordSendVerificationTokenOn ==
|
|
812
|
+
constants_1.ForgotPasswordSendVerificationTokenOn.MOBILE &&
|
|
813
|
+
user.mobile) {
|
|
789
814
|
const smsService = this.smsFactory.getSmsService();
|
|
790
|
-
smsService.sendSMSUsingTemplate(user.mobile,
|
|
791
|
-
solidAppName: this.settingService.getConfigValue(
|
|
815
|
+
smsService.sendSMSUsingTemplate(user.mobile, "forgot-password", {
|
|
816
|
+
solidAppName: this.settingService.getConfigValue("appTitle"),
|
|
792
817
|
otp: user.verificationTokenOnForgotPassword,
|
|
793
818
|
verificationTokenOnForgotPassword: user.verificationTokenOnForgotPassword,
|
|
794
819
|
firstName: user.username,
|
|
795
|
-
companyLogoUrl: companyLogo
|
|
796
|
-
}, this.settingService.getConfigValue(
|
|
820
|
+
companyLogoUrl: companyLogo,
|
|
821
|
+
}, this.settingService.getConfigValue("shouldQueueSms"));
|
|
797
822
|
}
|
|
798
823
|
}
|
|
799
824
|
async confirmForgotPassword(confirmForgotPasswordDto) {
|
|
@@ -801,7 +826,7 @@ let AuthenticationService = AuthenticationService_1 = class AuthenticationServic
|
|
|
801
826
|
const user = await this.resolveUserByVerificationToken(confirmForgotPasswordDto.verificationToken);
|
|
802
827
|
if (!user)
|
|
803
828
|
throw new common_1.UnauthorizedException(error_messages_1.ERROR_MESSAGES.INVALID_CREDENTIALS);
|
|
804
|
-
if (user.lastLoginProvider !==
|
|
829
|
+
if (user.lastLoginProvider !== "local")
|
|
805
830
|
throw new common_1.UnauthorizedException(error_messages_1.ERROR_MESSAGES.INVALID_CREDENTIALS);
|
|
806
831
|
if (!user.active)
|
|
807
832
|
throw new common_1.UnauthorizedException(error_messages_1.ERROR_MESSAGES.INVALID_CREDENTIALS);
|
|
@@ -809,13 +834,15 @@ let AuthenticationService = AuthenticationService_1 = class AuthenticationServic
|
|
|
809
834
|
.createQueryBuilder()
|
|
810
835
|
.update(user_entity_1.User)
|
|
811
836
|
.set({
|
|
812
|
-
forgotPasswordConfirmedAt: () =>
|
|
813
|
-
verificationTokenOnForgotPassword: () =>
|
|
814
|
-
verificationTokenOnForgotPasswordExpiresAt: () =>
|
|
837
|
+
forgotPasswordConfirmedAt: () => "NOW()",
|
|
838
|
+
verificationTokenOnForgotPassword: () => "NULL",
|
|
839
|
+
verificationTokenOnForgotPasswordExpiresAt: () => "NULL",
|
|
815
840
|
})
|
|
816
|
-
.where(
|
|
817
|
-
.andWhere(
|
|
818
|
-
.
|
|
841
|
+
.where("id = :id", { id: user.id })
|
|
842
|
+
.andWhere("verificationTokenOnForgotPassword = :token", {
|
|
843
|
+
token: confirmForgotPasswordDto.verificationToken,
|
|
844
|
+
})
|
|
845
|
+
.andWhere("verificationTokenOnForgotPasswordExpiresAt > NOW()")
|
|
819
846
|
.execute();
|
|
820
847
|
if (affected !== 1) {
|
|
821
848
|
throw new common_1.UnauthorizedException(error_messages_1.ERROR_MESSAGES.INVALID_CREDENTIALS);
|
|
@@ -823,41 +850,48 @@ let AuthenticationService = AuthenticationService_1 = class AuthenticationServic
|
|
|
823
850
|
const pwdHash = await this.hashingService.hash(confirmForgotPasswordDto.password);
|
|
824
851
|
const pwdScheme = this.hashingService.name();
|
|
825
852
|
const pwdSchemeVersion = this.hashingService.currentVersion();
|
|
826
|
-
await m.getRepository(user_entity_1.User).update({ id: user.id }, {
|
|
853
|
+
await m.getRepository(user_entity_1.User).update({ id: user.id }, {
|
|
854
|
+
password: pwdHash,
|
|
855
|
+
passwordScheme: pwdScheme,
|
|
856
|
+
passwordSchemeVersion: pwdSchemeVersion,
|
|
857
|
+
});
|
|
827
858
|
await this.notifyUserOnPasswordChanged(user);
|
|
828
859
|
return {
|
|
829
|
-
status:
|
|
860
|
+
status: "success",
|
|
830
861
|
message: success_messages_1.SUCCESS_MESSAGES.FORGOT_PASSWORD_CONFIRMED,
|
|
831
|
-
error:
|
|
832
|
-
errorCode:
|
|
862
|
+
error: "",
|
|
863
|
+
errorCode: "",
|
|
833
864
|
data: {},
|
|
834
865
|
};
|
|
835
866
|
});
|
|
836
867
|
}
|
|
837
868
|
async notifyUserOnPasswordChanged(user) {
|
|
838
869
|
const companyLogo = await this.getCompanyLogo();
|
|
839
|
-
const forgotPasswordSendVerificationTokenOn = this.settingService.getConfigValue(
|
|
840
|
-
if (forgotPasswordSendVerificationTokenOn ==
|
|
870
|
+
const forgotPasswordSendVerificationTokenOn = this.settingService.getConfigValue("forgotPasswordSendVerificationTokenOn");
|
|
871
|
+
if (forgotPasswordSendVerificationTokenOn ==
|
|
872
|
+
constants_1.ForgotPasswordSendVerificationTokenOn.EMAIL) {
|
|
841
873
|
const mailService = this.mailServiceFactory.getMailService();
|
|
842
|
-
mailService.sendEmailUsingTemplate(user.email,
|
|
843
|
-
solidAppName: this.settingService.getConfigValue(
|
|
844
|
-
solidAppWebsiteUrl: this.settingService.getConfigValue(
|
|
874
|
+
mailService.sendEmailUsingTemplate(user.email, "password-changed", {
|
|
875
|
+
solidAppName: this.settingService.getConfigValue("appTitle"),
|
|
876
|
+
solidAppWebsiteUrl: this.settingService.getConfigValue("solidAppWebsiteUrl"),
|
|
845
877
|
email: user.email,
|
|
846
878
|
firstName: user.username,
|
|
847
879
|
fullName: user.fullName,
|
|
848
|
-
passwordResetLink: `${this.settingService.getConfigValue(
|
|
849
|
-
companyLogoUrl: companyLogo
|
|
850
|
-
}, this.settingService.getConfigValue(
|
|
880
|
+
passwordResetLink: `${this.settingService.getConfigValue("frontendForgotPasswordPageUrl")}?token=${user.verificationTokenOnForgotPassword}`,
|
|
881
|
+
companyLogoUrl: companyLogo,
|
|
882
|
+
}, this.settingService.getConfigValue("shouldQueueEmails"), null, null, "user", user.id);
|
|
851
883
|
}
|
|
852
|
-
if (forgotPasswordSendVerificationTokenOn ==
|
|
884
|
+
if (forgotPasswordSendVerificationTokenOn ==
|
|
885
|
+
constants_1.ForgotPasswordSendVerificationTokenOn.MOBILE &&
|
|
886
|
+
user.mobile) {
|
|
853
887
|
const smsService = this.smsFactory.getSmsService();
|
|
854
|
-
smsService.sendSMSUsingTemplate(user.mobile,
|
|
855
|
-
solidAppName: this.settingService.getConfigValue(
|
|
888
|
+
smsService.sendSMSUsingTemplate(user.mobile, "forgot-password", {
|
|
889
|
+
solidAppName: this.settingService.getConfigValue("appTitle"),
|
|
856
890
|
otp: user.verificationTokenOnForgotPassword,
|
|
857
891
|
verificationTokenOnForgotPassword: user.verificationTokenOnForgotPassword,
|
|
858
892
|
firstName: user.username,
|
|
859
|
-
companyLogoUrl: companyLogo
|
|
860
|
-
}, this.settingService.getConfigValue(
|
|
893
|
+
companyLogoUrl: companyLogo,
|
|
894
|
+
}, this.settingService.getConfigValue("shouldQueueSms"));
|
|
861
895
|
}
|
|
862
896
|
}
|
|
863
897
|
async generateTokens(user) {
|
|
@@ -900,14 +934,14 @@ let AuthenticationService = AuthenticationService_1 = class AuthenticationServic
|
|
|
900
934
|
id: sub,
|
|
901
935
|
},
|
|
902
936
|
relations: {
|
|
903
|
-
roles: true
|
|
904
|
-
}
|
|
937
|
+
roles: true,
|
|
938
|
+
},
|
|
905
939
|
});
|
|
906
940
|
if (!user) {
|
|
907
941
|
throw new common_1.UnauthorizedException(error_messages_1.ERROR_MESSAGES.SESSION_INVALID);
|
|
908
942
|
}
|
|
909
943
|
const currentRefreshToken = await this.refreshTokenIdsStorage.validateAndRotate(user, refreshTokenDto.refreshToken);
|
|
910
|
-
await this.userActivityHistoryService.logEvent(
|
|
944
|
+
await this.userActivityHistoryService.logEvent("tokenRefreshed", user);
|
|
911
945
|
return {
|
|
912
946
|
accessToken: await this.generateAccessToken(user),
|
|
913
947
|
refreshToken: currentRefreshToken,
|
|
@@ -938,7 +972,8 @@ let AuthenticationService = AuthenticationService_1 = class AuthenticationServic
|
|
|
938
972
|
try {
|
|
939
973
|
const response = await this.httpService.axiosRef.get(`https://www.googleapis.com/oauth2/v1/userinfo?alt=json&access_token=${user.googleAccessToken}`);
|
|
940
974
|
const userProfile = response.data;
|
|
941
|
-
if (userProfile.email === user.email &&
|
|
975
|
+
if (userProfile.email === user.email &&
|
|
976
|
+
userProfile.id === user.googleId) {
|
|
942
977
|
return userProfile;
|
|
943
978
|
}
|
|
944
979
|
else {
|
|
@@ -952,11 +987,11 @@ let AuthenticationService = AuthenticationService_1 = class AuthenticationServic
|
|
|
952
987
|
async signInUsingGoogle(accessCode) {
|
|
953
988
|
const user = await this.userRepository.findOne({
|
|
954
989
|
where: {
|
|
955
|
-
accessCode: accessCode
|
|
990
|
+
accessCode: accessCode,
|
|
956
991
|
},
|
|
957
992
|
relations: {
|
|
958
|
-
roles: true
|
|
959
|
-
}
|
|
993
|
+
roles: true,
|
|
994
|
+
},
|
|
960
995
|
});
|
|
961
996
|
if (!user) {
|
|
962
997
|
throw new common_1.UnauthorizedException(error_messages_1.ERROR_MESSAGES.USER_NOT_FOUND);
|
|
@@ -977,24 +1012,156 @@ let AuthenticationService = AuthenticationService_1 = class AuthenticationServic
|
|
|
977
1012
|
mobile: user.mobile,
|
|
978
1013
|
username: user.username,
|
|
979
1014
|
id: user.id,
|
|
980
|
-
roles: user.roles.map((role) => role.name)
|
|
1015
|
+
roles: user.roles.map((role) => role.name),
|
|
1016
|
+
},
|
|
1017
|
+
...tokens,
|
|
1018
|
+
};
|
|
1019
|
+
}
|
|
1020
|
+
async validateUserUsingFacebook(user) {
|
|
1021
|
+
try {
|
|
1022
|
+
const response = await this.httpService.axiosRef.get(`https://graph.facebook.com/me?fields=id,name,email&access_token=${user.facebookAccessToken}`);
|
|
1023
|
+
const userProfile = response.data;
|
|
1024
|
+
if (userProfile.id === user.facebookId &&
|
|
1025
|
+
(!user.email || !userProfile.email || userProfile.email === user.email)) {
|
|
1026
|
+
return userProfile;
|
|
1027
|
+
}
|
|
1028
|
+
else {
|
|
1029
|
+
throw new common_1.UnauthorizedException(error_messages_1.ERROR_MESSAGES.INVALID_USER_PROFILE);
|
|
1030
|
+
}
|
|
1031
|
+
}
|
|
1032
|
+
catch (error) {
|
|
1033
|
+
throw new common_1.UnauthorizedException("Facebook OAuth profile fetch failed");
|
|
1034
|
+
}
|
|
1035
|
+
}
|
|
1036
|
+
async signInUsingFacebook(accessCode) {
|
|
1037
|
+
const user = await this.userRepository.findOne({
|
|
1038
|
+
where: {
|
|
1039
|
+
accessCode: accessCode,
|
|
1040
|
+
},
|
|
1041
|
+
relations: {
|
|
1042
|
+
roles: true,
|
|
1043
|
+
},
|
|
1044
|
+
});
|
|
1045
|
+
if (!user) {
|
|
1046
|
+
throw new common_1.UnauthorizedException(error_messages_1.ERROR_MESSAGES.USER_NOT_FOUND);
|
|
1047
|
+
}
|
|
1048
|
+
this.checkAccountBlocked(user);
|
|
1049
|
+
try {
|
|
1050
|
+
await this.validateUserUsingFacebook(user);
|
|
1051
|
+
}
|
|
1052
|
+
catch (e) {
|
|
1053
|
+
await this.incrementFailedAttempts(user);
|
|
1054
|
+
throw e;
|
|
1055
|
+
}
|
|
1056
|
+
await this.resetFailedAttempts(user);
|
|
1057
|
+
const tokens = await this.generateTokens(user);
|
|
1058
|
+
return {
|
|
1059
|
+
user: {
|
|
1060
|
+
email: user.email,
|
|
1061
|
+
mobile: user.mobile,
|
|
1062
|
+
username: user.username,
|
|
1063
|
+
id: user.id,
|
|
1064
|
+
roles: user.roles.map((role) => role.name),
|
|
1065
|
+
},
|
|
1066
|
+
...tokens,
|
|
1067
|
+
};
|
|
1068
|
+
}
|
|
1069
|
+
async validateUserUsingMicrosoft(user) {
|
|
1070
|
+
try {
|
|
1071
|
+
const response = await this.httpService.axiosRef.get(`https://graph.microsoft.com/v1.0/me`, {
|
|
1072
|
+
headers: {
|
|
1073
|
+
Authorization: `Bearer ${user.microsoftAccessToken}`,
|
|
1074
|
+
},
|
|
1075
|
+
});
|
|
1076
|
+
const userProfile = response.data;
|
|
1077
|
+
const profileEmail = userProfile.mail || userProfile.userPrincipalName;
|
|
1078
|
+
if (userProfile.id === user.microsoftId &&
|
|
1079
|
+
(!user.email || profileEmail === user.email)) {
|
|
1080
|
+
return userProfile;
|
|
1081
|
+
}
|
|
1082
|
+
else {
|
|
1083
|
+
throw new common_1.UnauthorizedException(error_messages_1.ERROR_MESSAGES.INVALID_USER_PROFILE);
|
|
1084
|
+
}
|
|
1085
|
+
}
|
|
1086
|
+
catch (error) {
|
|
1087
|
+
throw new common_1.UnauthorizedException("Microsoft OAuth profile fetch failed");
|
|
1088
|
+
}
|
|
1089
|
+
}
|
|
1090
|
+
async signInUsingMicrosoft(accessCode) {
|
|
1091
|
+
const user = await this.userRepository.findOne({
|
|
1092
|
+
where: {
|
|
1093
|
+
accessCode: accessCode,
|
|
1094
|
+
},
|
|
1095
|
+
relations: {
|
|
1096
|
+
roles: true,
|
|
981
1097
|
},
|
|
982
|
-
|
|
1098
|
+
});
|
|
1099
|
+
if (!user) {
|
|
1100
|
+
throw new common_1.UnauthorizedException(error_messages_1.ERROR_MESSAGES.USER_NOT_FOUND);
|
|
1101
|
+
}
|
|
1102
|
+
this.checkAccountBlocked(user);
|
|
1103
|
+
try {
|
|
1104
|
+
await this.validateUserUsingMicrosoft(user);
|
|
1105
|
+
}
|
|
1106
|
+
catch (e) {
|
|
1107
|
+
await this.incrementFailedAttempts(user);
|
|
1108
|
+
throw e;
|
|
1109
|
+
}
|
|
1110
|
+
await this.resetFailedAttempts(user);
|
|
1111
|
+
const tokens = await this.generateTokens(user);
|
|
1112
|
+
return {
|
|
1113
|
+
user: {
|
|
1114
|
+
email: user.email,
|
|
1115
|
+
mobile: user.mobile,
|
|
1116
|
+
username: user.username,
|
|
1117
|
+
id: user.id,
|
|
1118
|
+
roles: user.roles.map((role) => role.name),
|
|
1119
|
+
},
|
|
1120
|
+
...tokens,
|
|
1121
|
+
};
|
|
1122
|
+
}
|
|
1123
|
+
async signInUsingApple(accessCode) {
|
|
1124
|
+
const user = await this.userRepository.findOne({
|
|
1125
|
+
where: {
|
|
1126
|
+
accessCode: accessCode,
|
|
1127
|
+
},
|
|
1128
|
+
relations: {
|
|
1129
|
+
roles: true,
|
|
1130
|
+
},
|
|
1131
|
+
});
|
|
1132
|
+
if (!user) {
|
|
1133
|
+
throw new common_1.UnauthorizedException(error_messages_1.ERROR_MESSAGES.USER_NOT_FOUND);
|
|
1134
|
+
}
|
|
1135
|
+
this.checkAccountBlocked(user);
|
|
1136
|
+
await this.resetFailedAttempts(user);
|
|
1137
|
+
const tokens = await this.generateTokens(user);
|
|
1138
|
+
return {
|
|
1139
|
+
user: {
|
|
1140
|
+
email: user.email,
|
|
1141
|
+
mobile: user.mobile,
|
|
1142
|
+
username: user.username,
|
|
1143
|
+
id: user.id,
|
|
1144
|
+
roles: user.roles.map((role) => role.name),
|
|
1145
|
+
},
|
|
1146
|
+
...tokens,
|
|
983
1147
|
};
|
|
984
1148
|
}
|
|
985
1149
|
async isPasswordlessRegistrationEnabled() {
|
|
986
|
-
return this.settingService.getConfigValue(
|
|
1150
|
+
return this.settingService.getConfigValue("passwordLessAuth");
|
|
987
1151
|
}
|
|
988
1152
|
checkAccountBlocked(user) {
|
|
989
|
-
const maxFailedAttempts = this.settingService.getConfigValue(
|
|
990
|
-
if (maxFailedAttempts > 0 &&
|
|
1153
|
+
const maxFailedAttempts = this.settingService.getConfigValue("maxFailedLoginAttempts");
|
|
1154
|
+
if (maxFailedAttempts > 0 &&
|
|
1155
|
+
user.failedLoginAttempts >= maxFailedAttempts) {
|
|
991
1156
|
throw new common_1.ForbiddenException(error_messages_1.ERROR_MESSAGES.ACCOUNT_BLOCKED);
|
|
992
1157
|
}
|
|
993
1158
|
}
|
|
994
1159
|
async incrementFailedAttempts(user) {
|
|
995
1160
|
const nextFailedAttempts = (user.failedLoginAttempts ?? 0) + 1;
|
|
996
1161
|
user.failedLoginAttempts = nextFailedAttempts;
|
|
997
|
-
await this.userRepository.update(user.id, {
|
|
1162
|
+
await this.userRepository.update(user.id, {
|
|
1163
|
+
failedLoginAttempts: nextFailedAttempts,
|
|
1164
|
+
});
|
|
998
1165
|
}
|
|
999
1166
|
async resetFailedAttempts(user) {
|
|
1000
1167
|
if (user.failedLoginAttempts === 0)
|
|
@@ -1013,13 +1180,14 @@ let AuthenticationService = AuthenticationService_1 = class AuthenticationServic
|
|
|
1013
1180
|
const user = await this.userRepository.findOne({
|
|
1014
1181
|
where: {
|
|
1015
1182
|
id: userId,
|
|
1016
|
-
}
|
|
1183
|
+
},
|
|
1017
1184
|
});
|
|
1018
|
-
await this.userActivityHistoryService.logEvent(
|
|
1185
|
+
await this.userActivityHistoryService.logEvent("logout", user);
|
|
1019
1186
|
return { message: success_messages_1.SUCCESS_MESSAGES.LOGOUT_SUCCESS };
|
|
1020
1187
|
}
|
|
1021
1188
|
catch (err) {
|
|
1022
|
-
throw err instanceof common_1.UnauthorizedException ||
|
|
1189
|
+
throw err instanceof common_1.UnauthorizedException ||
|
|
1190
|
+
err instanceof common_1.InternalServerErrorException
|
|
1023
1191
|
? err
|
|
1024
1192
|
: new common_1.InternalServerErrorException(error_messages_1.ERROR_MESSAGES.LOGOUT_FAILED);
|
|
1025
1193
|
}
|
|
@@ -1038,8 +1206,8 @@ let AuthenticationService = AuthenticationService_1 = class AuthenticationServic
|
|
|
1038
1206
|
id: activeUser.sub,
|
|
1039
1207
|
},
|
|
1040
1208
|
relations: {
|
|
1041
|
-
roles: true
|
|
1042
|
-
}
|
|
1209
|
+
roles: true,
|
|
1210
|
+
},
|
|
1043
1211
|
});
|
|
1044
1212
|
const refreshTokenState = await this.refreshTokenIdsStorage.getCurrentRefreshTokenState(user.id);
|
|
1045
1213
|
const response = {
|
|
@@ -1098,9 +1266,9 @@ function parseUniqueConstraintError(detail) {
|
|
|
1098
1266
|
const field = match[1];
|
|
1099
1267
|
const value = match[2];
|
|
1100
1268
|
const fieldMap = {
|
|
1101
|
-
username:
|
|
1102
|
-
email:
|
|
1103
|
-
full_name_user_key:
|
|
1269
|
+
username: "username",
|
|
1270
|
+
email: "email address",
|
|
1271
|
+
full_name_user_key: "full name",
|
|
1104
1272
|
};
|
|
1105
1273
|
const friendlyField = fieldMap[field] || field;
|
|
1106
1274
|
return `A user with ${friendlyField} "${value}" already exists.`;
|