@solidstarters/solid-core 1.2.143 → 1.2.145
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/config/common.config.d.ts +2 -0
- package/dist/config/common.config.d.ts.map +1 -1
- package/dist/config/common.config.js +3 -2
- package/dist/config/common.config.js.map +1 -1
- package/dist/constants/error-messages.d.ts +83 -0
- package/dist/constants/error-messages.d.ts.map +1 -0
- package/dist/constants/error-messages.js +86 -0
- package/dist/constants/error-messages.js.map +1 -0
- package/dist/constants/success-messages.d.ts +11 -0
- package/dist/constants/success-messages.d.ts.map +1 -0
- package/dist/constants/success-messages.js +14 -0
- package/dist/constants/success-messages.js.map +1 -0
- package/dist/index.d.ts +7 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -4
- package/dist/index.js.map +1 -1
- package/dist/interfaces.js.map +1 -1
- package/dist/jobs/api-email-subscriber.service.d.ts +1 -1
- package/dist/jobs/api-email-subscriber.service.d.ts.map +1 -1
- package/dist/jobs/api-email-subscriber.service.js +2 -2
- package/dist/jobs/api-email-subscriber.service.js.map +1 -1
- package/dist/jobs/database/api-email-subscriber-database.service.d.ts +1 -1
- package/dist/jobs/database/api-email-subscriber-database.service.d.ts.map +1 -1
- package/dist/jobs/database/api-email-subscriber-database.service.js +2 -2
- package/dist/jobs/database/api-email-subscriber-database.service.js.map +1 -1
- package/dist/jobs/database/email-subscriber-database.service.d.ts +1 -1
- package/dist/jobs/database/email-subscriber-database.service.d.ts.map +1 -1
- package/dist/jobs/database/email-subscriber-database.service.js +2 -2
- package/dist/jobs/database/email-subscriber-database.service.js.map +1 -1
- package/dist/jobs/email-subscriber.service.d.ts +1 -1
- package/dist/jobs/email-subscriber.service.d.ts.map +1 -1
- package/dist/jobs/email-subscriber.service.js +2 -2
- package/dist/jobs/email-subscriber.service.js.map +1 -1
- package/dist/seeders/seed-data/solid-core-metadata.json +12 -12
- package/dist/services/ai-interaction.service.d.ts.map +1 -1
- package/dist/services/ai-interaction.service.js +4 -3
- package/dist/services/ai-interaction.service.js.map +1 -1
- package/dist/services/authentication.service.d.ts +1 -1
- package/dist/services/authentication.service.d.ts.map +1 -1
- package/dist/services/authentication.service.js +68 -66
- package/dist/services/authentication.service.js.map +1 -1
- package/dist/services/crud-helper.service.d.ts.map +1 -1
- package/dist/services/crud-helper.service.js +3 -2
- package/dist/services/crud-helper.service.js.map +1 -1
- package/dist/services/crud.service.d.ts.map +1 -1
- package/dist/services/crud.service.js +23 -21
- package/dist/services/crud.service.js.map +1 -1
- package/dist/services/csv.service.d.ts.map +1 -1
- package/dist/services/csv.service.js +3 -2
- package/dist/services/csv.service.js.map +1 -1
- package/dist/services/excel.service.d.ts.map +1 -1
- package/dist/services/excel.service.js +3 -2
- package/dist/services/excel.service.js.map +1 -1
- package/dist/services/export-transaction.service.d.ts.map +1 -1
- package/dist/services/export-transaction.service.js +2 -1
- package/dist/services/export-transaction.service.js.map +1 -1
- package/dist/services/field-metadata.service.d.ts.map +1 -1
- package/dist/services/field-metadata.service.js +9 -8
- package/dist/services/field-metadata.service.js.map +1 -1
- package/dist/services/file.service.d.ts.map +1 -1
- package/dist/services/file.service.js +5 -4
- package/dist/services/file.service.js.map +1 -1
- package/dist/services/import-transaction.service.d.ts.map +1 -1
- package/dist/services/import-transaction.service.js +11 -9
- package/dist/services/import-transaction.service.js.map +1 -1
- package/dist/services/mail/{ElasticEmailService.d.ts → elastic-email.service.d.ts} +1 -1
- package/dist/services/mail/elastic-email.service.d.ts.map +1 -0
- package/dist/services/mail/{ElasticEmailService.js → elastic-email.service.js} +1 -1
- package/dist/services/mail/elastic-email.service.js.map +1 -0
- package/dist/services/mail/{SMTPEmailService.d.ts → smtp-email.service.d.ts} +3 -3
- package/dist/services/mail/smtp-email.service.d.ts.map +1 -0
- package/dist/services/mail/{SMTPEmailService.js → smtp-email.service.js} +8 -6
- package/dist/services/mail/smtp-email.service.js.map +1 -0
- package/dist/services/media-storage-provider-metadata.service.d.ts.map +1 -1
- package/dist/services/media-storage-provider-metadata.service.js +4 -3
- package/dist/services/media-storage-provider-metadata.service.js.map +1 -1
- package/dist/services/media.service.d.ts.map +1 -1
- package/dist/services/media.service.js +2 -1
- package/dist/services/media.service.js.map +1 -1
- package/dist/services/model-metadata.service.d.ts.map +1 -1
- package/dist/services/model-metadata.service.js +11 -10
- package/dist/services/model-metadata.service.js.map +1 -1
- package/dist/services/module-metadata.service.d.ts.map +1 -1
- package/dist/services/module-metadata.service.js +11 -10
- package/dist/services/module-metadata.service.js.map +1 -1
- package/dist/services/role-metadata.service.d.ts.map +1 -1
- package/dist/services/role-metadata.service.js +3 -2
- package/dist/services/role-metadata.service.js.map +1 -1
- package/dist/services/sql-expression-resolver.service.d.ts.map +1 -1
- package/dist/services/sql-expression-resolver.service.js +2 -1
- package/dist/services/sql-expression-resolver.service.js.map +1 -1
- package/dist/services/user.service.d.ts.map +1 -1
- package/dist/services/user.service.js +11 -10
- 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 +9 -7
- package/dist/solid-core.module.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/config/common.config.ts +3 -2
- package/src/constants/error-messages.ts +123 -0
- package/src/constants/success-messages.ts +13 -0
- package/src/index.ts +10 -4
- package/src/interfaces.ts +3 -3
- package/src/jobs/api-email-subscriber.service.ts +1 -1
- package/src/jobs/database/api-email-subscriber-database.service.ts +1 -1
- package/src/jobs/database/email-subscriber-database.service.ts +1 -1
- package/src/jobs/email-subscriber.service.ts +1 -1
- package/src/seeders/seed-data/solid-core-metadata.json +12 -12
- package/src/services/ai-interaction.service.ts +4 -3
- package/src/services/authentication.service.ts +67 -65
- package/src/services/crud-helper.service.ts +3 -2
- package/src/services/crud.service.ts +23 -23
- package/src/services/csv.service.ts +3 -2
- package/src/services/excel.service.ts +3 -2
- package/src/services/export-transaction.service.ts +2 -1
- package/src/services/field-metadata.service.ts +9 -8
- package/src/services/file.service.ts +5 -4
- package/src/services/import-transaction.service.ts +11 -9
- package/src/services/mail/{SMTPEmailService.ts → smtp-email.service.ts} +7 -5
- package/src/services/media-storage-provider-metadata.service.ts +4 -3
- package/src/services/media.service.ts +2 -1
- package/src/services/model-metadata.service.ts +11 -10
- package/src/services/module-metadata.service.ts +11 -10
- package/src/services/role-metadata.service.ts +3 -2
- package/src/services/sql-expression-resolver.service.ts +2 -1
- package/src/services/user.service.ts +11 -10
- package/src/solid-core.module.ts +5 -3
- package/dist/services/mail/ElasticEmailService.d.ts.map +0 -1
- package/dist/services/mail/ElasticEmailService.js.map +0 -1
- package/dist/services/mail/SMTPEmailService.d.ts.map +0 -1
- package/dist/services/mail/SMTPEmailService.js.map +0 -1
- /package/src/services/mail/{ElasticEmailService.ts → elastic-email.service.ts} +0 -0
|
@@ -15,7 +15,7 @@ import { JwtService } from '@nestjs/jwt';
|
|
|
15
15
|
import { InjectRepository } from '@nestjs/typeorm';
|
|
16
16
|
import { isEmpty, isNotEmpty } from 'class-validator';
|
|
17
17
|
import { randomInt, randomUUID } from 'crypto';
|
|
18
|
-
import { SMTPEMailService } from 'src/services/mail/
|
|
18
|
+
import { SMTPEMailService } from 'src/services/mail/smtp-email.service';
|
|
19
19
|
import { Msg91OTPService } from 'src/services/sms/Msg91OTPService';
|
|
20
20
|
import { Repository } from 'typeorm';
|
|
21
21
|
import { iamConfig, jwtConfig } from '../config/iam.config';
|
|
@@ -46,6 +46,8 @@ import { RoleMetadataService } from './role-metadata.service';
|
|
|
46
46
|
import commonConfig from 'src/config/common.config';
|
|
47
47
|
import { UserActivityHistoryService } from './user-activity-history.service';
|
|
48
48
|
import { RequestContextService } from './request-context.service';
|
|
49
|
+
import { ERROR_MESSAGES } from 'src/constants/error-messages';
|
|
50
|
+
import { SUCCESS_MESSAGES } from 'src/constants/success-messages';
|
|
49
51
|
|
|
50
52
|
|
|
51
53
|
enum LoginProvider {
|
|
@@ -111,17 +113,17 @@ export class AuthenticationService {
|
|
|
111
113
|
const user = await this.resolveUser(signInDto.username, signInDto.email);
|
|
112
114
|
|
|
113
115
|
if (!user) {
|
|
114
|
-
throw new UnauthorizedException(
|
|
116
|
+
throw new UnauthorizedException(ERROR_MESSAGES.USER_NOT_FOUND);
|
|
115
117
|
}
|
|
116
118
|
if (!user.active) {
|
|
117
|
-
throw new UnauthorizedException(
|
|
119
|
+
throw new UnauthorizedException(ERROR_MESSAGES.USER_NOT_ACTIVE);
|
|
118
120
|
}
|
|
119
121
|
const isEqual = await this.hashingService.compare(
|
|
120
122
|
signInDto.password,
|
|
121
123
|
user.password,
|
|
122
124
|
);
|
|
123
125
|
if (!isEqual) {
|
|
124
|
-
throw new UnauthorizedException(
|
|
126
|
+
throw new UnauthorizedException(ERROR_MESSAGES.PASSWORD_INCORRECT);
|
|
125
127
|
}
|
|
126
128
|
|
|
127
129
|
return user;
|
|
@@ -130,7 +132,7 @@ export class AuthenticationService {
|
|
|
130
132
|
async signUp(signUpDto: SignUpDto, activeUser: ActiveUserData = null): Promise<User> {
|
|
131
133
|
// If public registrations are disabled and no activeUser is present when invoking signUp then we throw an exception.
|
|
132
134
|
if (!(await this.settingService.getConfigValue('allowPublicRegistration')) && !activeUser) {
|
|
133
|
-
throw new BadRequestException(
|
|
135
|
+
throw new BadRequestException(ERROR_MESSAGES.PUBLIC_REGISTRATION_DISABLED);
|
|
134
136
|
}
|
|
135
137
|
|
|
136
138
|
try {
|
|
@@ -150,7 +152,7 @@ export class AuthenticationService {
|
|
|
150
152
|
} catch (err) {
|
|
151
153
|
const pgUniqueViolationErrorCode = '23505';
|
|
152
154
|
if (err.code === pgUniqueViolationErrorCode) {
|
|
153
|
-
throw new ConflictException();
|
|
155
|
+
throw new ConflictException(ERROR_MESSAGES.USER_ALREADY_EXISTS);
|
|
154
156
|
}
|
|
155
157
|
throw err;
|
|
156
158
|
}
|
|
@@ -172,7 +174,7 @@ export class AuthenticationService {
|
|
|
172
174
|
catch (err) {
|
|
173
175
|
const pgUniqueViolationErrorCode = '23505';
|
|
174
176
|
if (err.code === pgUniqueViolationErrorCode) {
|
|
175
|
-
throw new ConflictException(parseUniqueConstraintError(err.detail ||
|
|
177
|
+
throw new ConflictException(parseUniqueConstraintError(err.detail || ERROR_MESSAGES.UNIQUE_CONSTRAINT_VIOLATION));
|
|
176
178
|
}
|
|
177
179
|
throw err;
|
|
178
180
|
}
|
|
@@ -275,17 +277,17 @@ export class AuthenticationService {
|
|
|
275
277
|
async otpInitiateRegistration(signUpDto: OTPSignUpDto) {
|
|
276
278
|
try {
|
|
277
279
|
if (!this.isPasswordlessRegistrationEnabled()) {
|
|
278
|
-
throw new BadRequestException(
|
|
280
|
+
throw new BadRequestException(ERROR_MESSAGES.PASSWORDLESS_REGISTRATION_DISABLED);
|
|
279
281
|
}
|
|
280
282
|
// Validate if either mobile or email is present.
|
|
281
283
|
if (isEmpty(signUpDto.mobile) && isEmpty(signUpDto.email)) {
|
|
282
|
-
throw new BadRequestException(
|
|
284
|
+
throw new BadRequestException(ERROR_MESSAGES.REGISTRATION_REQUIRES_CONTACT);
|
|
283
285
|
}
|
|
284
286
|
if (signUpDto.validationSources.includes(TransactionalRegistrationValidationSource.EMAIL) && isEmpty(signUpDto.email)) {
|
|
285
|
-
throw new BadRequestException(
|
|
287
|
+
throw new BadRequestException(ERROR_MESSAGES.EMAIL_REQUIRED_FOR_VALIDATION);
|
|
286
288
|
}
|
|
287
289
|
if (signUpDto.validationSources.includes(TransactionalRegistrationValidationSource.MOBILE) && isEmpty(signUpDto.mobile)) {
|
|
288
|
-
throw new BadRequestException(
|
|
290
|
+
throw new BadRequestException(ERROR_MESSAGES.MOBILE_REQUIRED_FOR_VALIDATION);
|
|
289
291
|
}
|
|
290
292
|
|
|
291
293
|
// Validate if user already exists.
|
|
@@ -297,7 +299,7 @@ export class AuthenticationService {
|
|
|
297
299
|
]
|
|
298
300
|
});
|
|
299
301
|
if (isNotEmpty(existingUser) && existingUser.active) {
|
|
300
|
-
throw new ConflictException(
|
|
302
|
+
throw new ConflictException(ERROR_MESSAGES.USER_ALREADY_EXISTS);
|
|
301
303
|
}
|
|
302
304
|
const finalRegistrationVerificationSources = this.calculateVerificationSources(this.iamConfiguration.passwordlessRegistrationValidateWhat, signUpDto);
|
|
303
305
|
let user = existingUser
|
|
@@ -314,11 +316,11 @@ export class AuthenticationService {
|
|
|
314
316
|
|
|
315
317
|
// Send OTP to the user through email or SMS, depending on the configuration.
|
|
316
318
|
this.notifyUserOnOtpInitiateRegistration(user, finalRegistrationVerificationSources);
|
|
317
|
-
return { message:
|
|
319
|
+
return { message: SUCCESS_MESSAGES.OTP_SENT_SUCCESS_REGISTRATION }
|
|
318
320
|
} catch (err) {
|
|
319
321
|
const pgUniqueViolationErrorCode = '23505';
|
|
320
322
|
if (err.code === pgUniqueViolationErrorCode) {
|
|
321
|
-
throw new ConflictException();
|
|
323
|
+
throw new ConflictException(ERROR_MESSAGES.USER_ALREADY_EXISTS);
|
|
322
324
|
}
|
|
323
325
|
throw err;
|
|
324
326
|
}
|
|
@@ -346,7 +348,7 @@ export class AuthenticationService {
|
|
|
346
348
|
// Generate the validation tokens for the user i.e (system configured + user provided)
|
|
347
349
|
private populateVerificationTokens(finalRegistrationValidationSources: string[], user: User) {
|
|
348
350
|
if (finalRegistrationValidationSources.length === 0) {
|
|
349
|
-
throw new BadRequestException(
|
|
351
|
+
throw new BadRequestException(ERROR_MESSAGES.VALIDATION_SOURCE_REQUIRED);
|
|
350
352
|
}
|
|
351
353
|
if (finalRegistrationValidationSources.includes(TransactionalRegistrationValidationSource.EMAIL)) {
|
|
352
354
|
const { token, expiresAt } = this.otp();
|
|
@@ -407,7 +409,7 @@ export class AuthenticationService {
|
|
|
407
409
|
|
|
408
410
|
async otpConfirmRegistration(confirmSignUpDto: OTPConfirmOTPDto) {
|
|
409
411
|
if (!this.isPasswordlessRegistrationEnabled()) {
|
|
410
|
-
throw new BadRequestException(
|
|
412
|
+
throw new BadRequestException(ERROR_MESSAGES.PASSWORDLESS_REGISTRATION_DISABLED);
|
|
411
413
|
}
|
|
412
414
|
|
|
413
415
|
// Based on the identifier, validate by query the user table.
|
|
@@ -418,13 +420,13 @@ export class AuthenticationService {
|
|
|
418
420
|
}
|
|
419
421
|
});
|
|
420
422
|
if (!user) {
|
|
421
|
-
throw new UnauthorizedException(
|
|
423
|
+
throw new UnauthorizedException(ERROR_MESSAGES.USER_NOT_FOUND);
|
|
422
424
|
}
|
|
423
425
|
if (user.emailVerificationTokenOnRegistration !== confirmSignUpDto.otp) {
|
|
424
|
-
throw new UnauthorizedException(
|
|
426
|
+
throw new UnauthorizedException(ERROR_MESSAGES.INVALID_OTP);
|
|
425
427
|
}
|
|
426
428
|
if (user.emailVerificationTokenOnRegistrationExpiresAt < new Date()) {
|
|
427
|
-
throw new UnauthorizedException(
|
|
429
|
+
throw new UnauthorizedException(ERROR_MESSAGES.OTP_EXPIRED);
|
|
428
430
|
}
|
|
429
431
|
user.emailVerifiedOnRegistrationAt = new Date();
|
|
430
432
|
user.emailVerificationTokenOnRegistration = null;
|
|
@@ -440,13 +442,13 @@ export class AuthenticationService {
|
|
|
440
442
|
}
|
|
441
443
|
});
|
|
442
444
|
if (!user) {
|
|
443
|
-
throw new UnauthorizedException(
|
|
445
|
+
throw new UnauthorizedException(ERROR_MESSAGES.USER_NOT_FOUND);
|
|
444
446
|
}
|
|
445
447
|
if (user.mobileVerificationTokenOnRegistration !== confirmSignUpDto.otp) {
|
|
446
|
-
throw new UnauthorizedException(
|
|
448
|
+
throw new UnauthorizedException(ERROR_MESSAGES.INVALID_OTP);
|
|
447
449
|
}
|
|
448
450
|
if (user.mobileVerificationTokenOnRegistrationExpiresAt < new Date()) {
|
|
449
|
-
throw new UnauthorizedException(
|
|
451
|
+
throw new UnauthorizedException(ERROR_MESSAGES.INVALID_OTP);
|
|
450
452
|
}
|
|
451
453
|
user.mobileVerifiedOnRegistrationAt = new Date();
|
|
452
454
|
user.mobileVerificationTokenOnRegistration = null;
|
|
@@ -456,7 +458,7 @@ export class AuthenticationService {
|
|
|
456
458
|
this.triggerRegistrationEvent(savedUser);
|
|
457
459
|
return { active: savedUser.active, message: `User registration verified for ${confirmSignUpDto.type}` }
|
|
458
460
|
}
|
|
459
|
-
throw new BadRequestException(
|
|
461
|
+
throw new BadRequestException(ERROR_MESSAGES.INVALID_VERIFICATION_TYPE);
|
|
460
462
|
}
|
|
461
463
|
|
|
462
464
|
private triggerRegistrationEvent(savedUser: User) {
|
|
@@ -512,7 +514,7 @@ export class AuthenticationService {
|
|
|
512
514
|
|
|
513
515
|
async otpInitiateLogin(signInDto: OTPSignInDto) {
|
|
514
516
|
if (!this.isPasswordlessRegistrationEnabled()) {
|
|
515
|
-
throw new BadRequestException(
|
|
517
|
+
throw new BadRequestException(ERROR_MESSAGES.PASSWORDLESS_REGISTRATION_DISABLED);
|
|
516
518
|
}
|
|
517
519
|
|
|
518
520
|
// Validate & generate otp token for the user based on the identifier type.
|
|
@@ -523,10 +525,10 @@ export class AuthenticationService {
|
|
|
523
525
|
}
|
|
524
526
|
});
|
|
525
527
|
if (!user) {
|
|
526
|
-
throw new UnauthorizedException(
|
|
528
|
+
throw new UnauthorizedException(ERROR_MESSAGES.USER_NOT_FOUND);
|
|
527
529
|
}
|
|
528
530
|
if (!user.active) {
|
|
529
|
-
throw new UnauthorizedException(
|
|
531
|
+
throw new UnauthorizedException(ERROR_MESSAGES.USER_INACTIVE);
|
|
530
532
|
}
|
|
531
533
|
const { token, expiresAt } = this.otp();
|
|
532
534
|
user.emailVerificationTokenOnLogin = token;
|
|
@@ -540,7 +542,7 @@ export class AuthenticationService {
|
|
|
540
542
|
}
|
|
541
543
|
});
|
|
542
544
|
if (!user) {
|
|
543
|
-
throw new UnauthorizedException(
|
|
545
|
+
throw new UnauthorizedException(ERROR_MESSAGES.USER_NOT_FOUND);
|
|
544
546
|
}
|
|
545
547
|
|
|
546
548
|
const { token, expiresAt } = this.otp();
|
|
@@ -550,9 +552,9 @@ export class AuthenticationService {
|
|
|
550
552
|
this.notifyUserOnOtpInititateLogin(user, RegistrationValidationSource.MOBILE);
|
|
551
553
|
}
|
|
552
554
|
else {
|
|
553
|
-
throw new BadRequestException(
|
|
555
|
+
throw new BadRequestException(ERROR_MESSAGES.INVALID_VERIFICATION_TYPE);
|
|
554
556
|
}
|
|
555
|
-
return { message:
|
|
557
|
+
return { message: SUCCESS_MESSAGES.OTP_SENT_SUCCESS_LOGIN };
|
|
556
558
|
}
|
|
557
559
|
|
|
558
560
|
private async notifyUserOnOtpInititateLogin(user: User, loginType: RegistrationValidationSource) {
|
|
@@ -595,7 +597,7 @@ export class AuthenticationService {
|
|
|
595
597
|
|
|
596
598
|
async otpConfirmLogin(confirmSignInDto: OTPConfirmOTPDto) {
|
|
597
599
|
if (!this.isPasswordlessRegistrationEnabled()) {
|
|
598
|
-
throw new BadRequestException(
|
|
600
|
+
throw new BadRequestException(ERROR_MESSAGES.PASSWORDLESS_REGISTRATION_DISABLED);
|
|
599
601
|
}
|
|
600
602
|
if (confirmSignInDto.type === RegistrationValidationSource.EMAIL) {
|
|
601
603
|
const user = await this.userRepository.findOne({
|
|
@@ -605,16 +607,16 @@ export class AuthenticationService {
|
|
|
605
607
|
relations: ['roles']
|
|
606
608
|
});
|
|
607
609
|
if (!user) {
|
|
608
|
-
throw new UnauthorizedException(
|
|
610
|
+
throw new UnauthorizedException(ERROR_MESSAGES.USER_NOT_FOUND);
|
|
609
611
|
}
|
|
610
612
|
if (!user.active) {
|
|
611
|
-
throw new UnauthorizedException(
|
|
613
|
+
throw new UnauthorizedException(ERROR_MESSAGES.USER_INACTIVE);
|
|
612
614
|
}
|
|
613
615
|
if (user.emailVerificationTokenOnLogin !== confirmSignInDto.otp) {
|
|
614
|
-
throw new UnauthorizedException(
|
|
616
|
+
throw new UnauthorizedException(ERROR_MESSAGES.INVALID_OTP);
|
|
615
617
|
}
|
|
616
618
|
if (user.emailVerificationTokenOnLoginExpiresAt < new Date()) {
|
|
617
|
-
throw new UnauthorizedException(
|
|
619
|
+
throw new UnauthorizedException(ERROR_MESSAGES.INVALID_OTP);
|
|
618
620
|
}
|
|
619
621
|
user.emailVerifiedOnLoginAt = new Date();
|
|
620
622
|
user.emailVerificationTokenOnLogin = null;
|
|
@@ -632,16 +634,16 @@ export class AuthenticationService {
|
|
|
632
634
|
relations: ['roles']
|
|
633
635
|
});
|
|
634
636
|
if (!user) {
|
|
635
|
-
throw new UnauthorizedException(
|
|
637
|
+
throw new UnauthorizedException(ERROR_MESSAGES.USER_NOT_ACTIVE);
|
|
636
638
|
}
|
|
637
639
|
if (!user.active) {
|
|
638
|
-
throw new UnauthorizedException(
|
|
640
|
+
throw new UnauthorizedException(ERROR_MESSAGES.USER_INACTIVE);
|
|
639
641
|
}
|
|
640
642
|
if (user.mobileVerificationTokenOnLogin !== confirmSignInDto.otp) {
|
|
641
|
-
throw new UnauthorizedException(
|
|
643
|
+
throw new UnauthorizedException(ERROR_MESSAGES.INVALID_OTP);
|
|
642
644
|
}
|
|
643
645
|
if (user.mobileVerificationTokenOnLoginExpiresAt < new Date()) {
|
|
644
|
-
throw new UnauthorizedException(
|
|
646
|
+
throw new UnauthorizedException(ERROR_MESSAGES.INVALID_OTP);
|
|
645
647
|
}
|
|
646
648
|
user.mobileVerifiedOnLoginAt = new Date();
|
|
647
649
|
user.mobileVerificationTokenOnLogin = null;
|
|
@@ -653,7 +655,7 @@ export class AuthenticationService {
|
|
|
653
655
|
return { accessToken, refreshToken, user: { id, username, email, mobile, lastLoginProvider, roles } };
|
|
654
656
|
|
|
655
657
|
}
|
|
656
|
-
throw new BadRequestException(
|
|
658
|
+
throw new BadRequestException(ERROR_MESSAGES.INVALID_VERIFICATION_TYPE);
|
|
657
659
|
}
|
|
658
660
|
|
|
659
661
|
async changePassword(changePasswordDto: ChangePasswordDto, activeUser: ActiveUserData) {
|
|
@@ -661,26 +663,26 @@ export class AuthenticationService {
|
|
|
661
663
|
where: { id: changePasswordDto.id }
|
|
662
664
|
});
|
|
663
665
|
if (!user) {
|
|
664
|
-
throw new NotFoundException(
|
|
666
|
+
throw new NotFoundException(ERROR_MESSAGES.USER_NOT_FOUND);
|
|
665
667
|
}
|
|
666
668
|
|
|
667
669
|
if (!user.active) {
|
|
668
|
-
throw new UnauthorizedException(
|
|
670
|
+
throw new UnauthorizedException(ERROR_MESSAGES.USER_INACTIVE);
|
|
669
671
|
}
|
|
670
672
|
|
|
671
673
|
// 2. Validate if user has used a provider which is "local", only then it makes sense for us to initiate the forgot password routine.
|
|
672
674
|
if (user.lastLoginProvider !== 'local') {
|
|
673
|
-
throw new BadRequestException(
|
|
675
|
+
throw new BadRequestException(ERROR_MESSAGES.NON_LOCAL_PROVIDER);
|
|
674
676
|
}
|
|
675
677
|
|
|
676
678
|
// Check if ID's match
|
|
677
679
|
if (!(user.id === activeUser.sub)) {
|
|
678
|
-
throw new BadRequestException(
|
|
680
|
+
throw new BadRequestException(ERROR_MESSAGES.USER_ID_MISMATCH);
|
|
679
681
|
}
|
|
680
682
|
|
|
681
683
|
// Check if username's match
|
|
682
684
|
if (!(user.username === activeUser.username)) {
|
|
683
|
-
throw new BadRequestException(
|
|
685
|
+
throw new BadRequestException(ERROR_MESSAGES.USERNAME_MISMATCH);
|
|
684
686
|
}
|
|
685
687
|
|
|
686
688
|
// Check if old password is matching.
|
|
@@ -689,7 +691,7 @@ export class AuthenticationService {
|
|
|
689
691
|
user.password,
|
|
690
692
|
);
|
|
691
693
|
if (!isEqual) {
|
|
692
|
-
throw new UnauthorizedException(
|
|
694
|
+
throw new UnauthorizedException(ERROR_MESSAGES.INCORRECT_CURRENT_PASSWORD);
|
|
693
695
|
}
|
|
694
696
|
|
|
695
697
|
// Update Password
|
|
@@ -700,7 +702,7 @@ export class AuthenticationService {
|
|
|
700
702
|
user.forcePasswordChange = false;
|
|
701
703
|
|
|
702
704
|
if (await this.isPasswordDuplicate(user)) {
|
|
703
|
-
throw new BadRequestException(
|
|
705
|
+
throw new BadRequestException(ERROR_MESSAGES.PASSWORD_REUSED);
|
|
704
706
|
}
|
|
705
707
|
await this.deleteOldPasswords(user);
|
|
706
708
|
|
|
@@ -724,15 +726,15 @@ export class AuthenticationService {
|
|
|
724
726
|
const user = await this.resolveUser(initiateForgotPasswordDto.username, initiateForgotPasswordDto.email);
|
|
725
727
|
|
|
726
728
|
if (!user) {
|
|
727
|
-
throw new NotFoundException(
|
|
729
|
+
throw new NotFoundException(ERROR_MESSAGES.USER_NOT_FOUND);
|
|
728
730
|
}
|
|
729
731
|
if (!user.active) {
|
|
730
|
-
throw new UnauthorizedException(
|
|
732
|
+
throw new UnauthorizedException(ERROR_MESSAGES.USER_INACTIVE);
|
|
731
733
|
}
|
|
732
734
|
|
|
733
735
|
// 2. Validate if user has used a provider which is "local", only then it makes sense for us to initiate the forgot password routine.
|
|
734
736
|
if (user.lastLoginProvider !== 'local') {
|
|
735
|
-
throw new BadRequestException(
|
|
737
|
+
throw new BadRequestException(ERROR_MESSAGES.NON_LOCAL_PROVIDER);
|
|
736
738
|
}
|
|
737
739
|
|
|
738
740
|
// 3. Generate a 6 digit validation token, we send this token to the user over their email & mobile number (controlled using configuration).
|
|
@@ -746,7 +748,7 @@ export class AuthenticationService {
|
|
|
746
748
|
// 5. Return.
|
|
747
749
|
return {
|
|
748
750
|
status: 'success',
|
|
749
|
-
message:
|
|
751
|
+
message: SUCCESS_MESSAGES.FORGOT_PASSWORD_TOKEN_SENT,
|
|
750
752
|
error: '',
|
|
751
753
|
errorCode: '',
|
|
752
754
|
data: {
|
|
@@ -807,23 +809,23 @@ export class AuthenticationService {
|
|
|
807
809
|
const user = await this.resolveUser(confirmForgotPasswordDto.username, confirmForgotPasswordDto.email);
|
|
808
810
|
|
|
809
811
|
if (!user) {
|
|
810
|
-
throw new NotFoundException(
|
|
812
|
+
throw new NotFoundException(ERROR_MESSAGES.USER_NOT_FOUND);
|
|
811
813
|
}
|
|
812
814
|
|
|
813
815
|
// 2. Validate if user has used a provider which is "local", only then it makes sense for us to initiate the forgot password routine.
|
|
814
816
|
if (user.lastLoginProvider !== 'local') {
|
|
815
|
-
throw new BadRequestException(
|
|
817
|
+
throw new BadRequestException(ERROR_MESSAGES.NON_LOCAL_PROVIDER);
|
|
816
818
|
}
|
|
817
819
|
if (!user.active) {
|
|
818
|
-
throw new UnauthorizedException(
|
|
820
|
+
throw new UnauthorizedException(ERROR_MESSAGES.USER_INACTIVE);
|
|
819
821
|
}
|
|
820
822
|
|
|
821
823
|
// 3. Validate the verification token is proper & update the user record.
|
|
822
824
|
if (user.verificationTokenOnForgotPassword !== confirmForgotPasswordDto.verificationToken) {
|
|
823
|
-
throw new UnauthorizedException(
|
|
825
|
+
throw new UnauthorizedException(ERROR_MESSAGES.INVALID_VERIFICATION_TOKEN);
|
|
824
826
|
}
|
|
825
827
|
if (user.verificationTokenOnForgotPasswordExpiresAt < new Date()) {
|
|
826
|
-
throw new UnauthorizedException(
|
|
828
|
+
throw new UnauthorizedException(ERROR_MESSAGES.INVALID_VERIFICATION_TOKEN);
|
|
827
829
|
}
|
|
828
830
|
user.forgotPasswordConfirmedAt = new Date();
|
|
829
831
|
user.verificationTokenOnForgotPassword = null;
|
|
@@ -834,7 +836,7 @@ export class AuthenticationService {
|
|
|
834
836
|
user.password = confirmForgotPasswordDto.password
|
|
835
837
|
|
|
836
838
|
if (await this.isPasswordDuplicate(user)) {
|
|
837
|
-
throw new BadRequestException(
|
|
839
|
+
throw new BadRequestException(ERROR_MESSAGES.PASSWORD_REUSED);
|
|
838
840
|
}
|
|
839
841
|
await this.deleteOldPasswords(user);
|
|
840
842
|
|
|
@@ -849,7 +851,7 @@ export class AuthenticationService {
|
|
|
849
851
|
|
|
850
852
|
return {
|
|
851
853
|
status: 'success',
|
|
852
|
-
message:
|
|
854
|
+
message: SUCCESS_MESSAGES.FORGOT_PASSWORD_CONFIRMED,
|
|
853
855
|
error: '',
|
|
854
856
|
errorCode: '',
|
|
855
857
|
data: {}
|
|
@@ -950,7 +952,7 @@ export class AuthenticationService {
|
|
|
950
952
|
}
|
|
951
953
|
});
|
|
952
954
|
if (!user) {
|
|
953
|
-
throw new UnauthorizedException();
|
|
955
|
+
throw new UnauthorizedException(ERROR_MESSAGES.SESSION_INVALID);
|
|
954
956
|
}
|
|
955
957
|
|
|
956
958
|
// TODO: Replace the if else condition below with a call to validateAndRotate - Done
|
|
@@ -973,10 +975,10 @@ export class AuthenticationService {
|
|
|
973
975
|
} catch (err) {
|
|
974
976
|
if (err instanceof InvalidatedRefreshTokenError) {
|
|
975
977
|
// Take action: notify user that his refresh token might have been stolen?
|
|
976
|
-
throw new UnauthorizedException(
|
|
978
|
+
throw new UnauthorizedException(ERROR_MESSAGES.ACCESS_DENIED);
|
|
977
979
|
}
|
|
978
980
|
|
|
979
|
-
throw new UnauthorizedException();
|
|
981
|
+
throw new UnauthorizedException(ERROR_MESSAGES.SESSION_EXPIRED);
|
|
980
982
|
}
|
|
981
983
|
}
|
|
982
984
|
|
|
@@ -1007,10 +1009,10 @@ export class AuthenticationService {
|
|
|
1007
1009
|
// TODO: remove the access code both from the database.
|
|
1008
1010
|
return userProfile;
|
|
1009
1011
|
} else {
|
|
1010
|
-
throw new UnauthorizedException(
|
|
1012
|
+
throw new UnauthorizedException(ERROR_MESSAGES.INVALID_USER_PROFILE);
|
|
1011
1013
|
}
|
|
1012
1014
|
} catch (error) {
|
|
1013
|
-
throw new UnauthorizedException(
|
|
1015
|
+
throw new UnauthorizedException(ERROR_MESSAGES.GOOGLE_OAUTH_PROFILE_FETCH_FAILED);
|
|
1014
1016
|
}
|
|
1015
1017
|
}
|
|
1016
1018
|
|
|
@@ -1071,11 +1073,11 @@ export class AuthenticationService {
|
|
|
1071
1073
|
await this.userActivityHistoryService.logEvent('logout', user);
|
|
1072
1074
|
|
|
1073
1075
|
|
|
1074
|
-
return { message:
|
|
1076
|
+
return { message: SUCCESS_MESSAGES.LOGOUT_SUCCESS};
|
|
1075
1077
|
} catch (err) {
|
|
1076
1078
|
throw err instanceof UnauthorizedException || err instanceof InternalServerErrorException
|
|
1077
1079
|
? err
|
|
1078
|
-
: new InternalServerErrorException(
|
|
1080
|
+
: new InternalServerErrorException(ERROR_MESSAGES.LOGOUT_FAILED);
|
|
1079
1081
|
}
|
|
1080
1082
|
}
|
|
1081
1083
|
|
|
@@ -1083,7 +1085,7 @@ export class AuthenticationService {
|
|
|
1083
1085
|
async activateUser(userId: number) {
|
|
1084
1086
|
const user = await this.userService.findOne(userId, {});
|
|
1085
1087
|
if (!user) {
|
|
1086
|
-
throw new NotFoundException(
|
|
1088
|
+
throw new NotFoundException(ERROR_MESSAGES.USER_NOT_FOUND);
|
|
1087
1089
|
}
|
|
1088
1090
|
user.active = true;
|
|
1089
1091
|
await this.userRepository.save(user);
|
|
@@ -4,6 +4,7 @@ import { classify } from "@angular-devkit/core/src/utils/strings";
|
|
|
4
4
|
import { ActiveUserData } from "src/interfaces/active-user-data.interface";
|
|
5
5
|
import { SolidRegistry } from "src/helpers/solid-registry";
|
|
6
6
|
import { Logger } from "@nestjs/common";
|
|
7
|
+
import { ERROR_MESSAGES } from "src/constants/error-messages";
|
|
7
8
|
|
|
8
9
|
|
|
9
10
|
export class CrudHelperService {
|
|
@@ -174,7 +175,7 @@ export class CrudHelperService {
|
|
|
174
175
|
const normalizedSort = this.normalize(sort);
|
|
175
176
|
const normalizedGroupBy = this.normalize(groupBy);
|
|
176
177
|
if (normalizedGroupBy.length > 1) {
|
|
177
|
-
throw new Error(
|
|
178
|
+
throw new Error(ERROR_MESSAGES.GROUP_BY_LIMIT);
|
|
178
179
|
}
|
|
179
180
|
|
|
180
181
|
// Depending upon the populate option, apply the join clause
|
|
@@ -367,7 +368,7 @@ export class CrudHelperService {
|
|
|
367
368
|
const groupByField = filteredDto.groupBy;
|
|
368
369
|
|
|
369
370
|
if (!groupByField || (Array.isArray(groupByField) && groupByField.length !== 1)) {
|
|
370
|
-
throw new Error(
|
|
371
|
+
throw new Error(ERROR_MESSAGES.INVALID_GROUP_BY_COUNT);
|
|
371
372
|
}
|
|
372
373
|
|
|
373
374
|
const field = Array.isArray(groupByField) ? groupByField[0] : groupByField;
|
|
@@ -35,6 +35,8 @@ import { getMediaStorageProvider } from "./mediaStorageProviders";
|
|
|
35
35
|
import { ModelMetadataService } from "./model-metadata.service";
|
|
36
36
|
import { ModuleMetadataService } from "./module-metadata.service";
|
|
37
37
|
import { isArray } from "class-validator";
|
|
38
|
+
import { ERROR_MESSAGES } from "src/constants/error-messages";
|
|
39
|
+
import { SUCCESS_MESSAGES } from "src/constants/success-messages";
|
|
38
40
|
|
|
39
41
|
export class CRUDService<T> { // Add two generic value i.e Person,CreatePersonDto, so we get the proper types in our service
|
|
40
42
|
|
|
@@ -66,7 +68,7 @@ export class CRUDService<T> { // Add two generic value i.e Person,CreatePersonDt
|
|
|
66
68
|
if (solidRequestContext.activeUser) {
|
|
67
69
|
const hasPermission = this.crudHelperService.hasCreatePermissionOnModel(solidRequestContext.activeUser, model.singularName);
|
|
68
70
|
if (!hasPermission) {
|
|
69
|
-
throw new BadRequestException(
|
|
71
|
+
throw new BadRequestException(ERROR_MESSAGES.FORBIDDEN);
|
|
70
72
|
}
|
|
71
73
|
}
|
|
72
74
|
// const inverseRelationFields = await this.loadInverseRelationFields();
|
|
@@ -92,7 +94,7 @@ export class CRUDService<T> { // Add two generic value i.e Person,CreatePersonDt
|
|
|
92
94
|
return savedEntity;
|
|
93
95
|
} catch (error) {
|
|
94
96
|
if (error instanceof QueryFailedError && error.message.includes('duplicate key value violates unique constraint')) {
|
|
95
|
-
throw new BadRequestException(
|
|
97
|
+
throw new BadRequestException(ERROR_MESSAGES.DUPLICATE_ENTRY);
|
|
96
98
|
}
|
|
97
99
|
throw error;
|
|
98
100
|
}
|
|
@@ -153,7 +155,7 @@ export class CRUDService<T> { // Add two generic value i.e Person,CreatePersonDt
|
|
|
153
155
|
//TODO: Will the updates be partial i.e PATCH or full i.e PUT
|
|
154
156
|
async update(id: number, updateDto: any, files: Express.Multer.File[] = [], isPartialUpdate: boolean = false, solidRequestContext: any = {}, isUpdate: boolean = false): Promise<T> {
|
|
155
157
|
if (!id) {
|
|
156
|
-
throw new Error(
|
|
158
|
+
throw new Error(ERROR_MESSAGES.ID_REQUIRED_FOR_UPDATE);
|
|
157
159
|
}
|
|
158
160
|
isUpdate = true;
|
|
159
161
|
const model = await this.loadModel();
|
|
@@ -161,7 +163,7 @@ export class CRUDService<T> { // Add two generic value i.e Person,CreatePersonDt
|
|
|
161
163
|
if (solidRequestContext.activeUser) {
|
|
162
164
|
const hasPermission = this.crudHelperService.hasUpdatePermissionOnModel(solidRequestContext.activeUser, model.singularName);
|
|
163
165
|
if (!hasPermission) {
|
|
164
|
-
throw new BadRequestException(
|
|
166
|
+
throw new BadRequestException(ERROR_MESSAGES.FORBIDDEN);
|
|
165
167
|
}
|
|
166
168
|
}
|
|
167
169
|
const entity = await this.repo.findOne({
|
|
@@ -207,14 +209,14 @@ export class CRUDService<T> { // Add two generic value i.e Person,CreatePersonDt
|
|
|
207
209
|
//TODO: Will the updates be partial i.e PATCH or full i.e PUT
|
|
208
210
|
async delete(id: number, solidRequestContext: any = {}) {
|
|
209
211
|
if (!id) {
|
|
210
|
-
throw new Error(
|
|
212
|
+
throw new Error(ERROR_MESSAGES.ID_REQUIRED_FOR_DELETE);
|
|
211
213
|
}
|
|
212
214
|
const loadedmodel = await this.loadModel();
|
|
213
215
|
// Check wheather user has update permission for model
|
|
214
216
|
if (solidRequestContext.activeUser) {
|
|
215
217
|
const hasPermission = this.crudHelperService.hasDeletePermissionOnModel(solidRequestContext.activeUser, loadedmodel.singularName);
|
|
216
218
|
if (!hasPermission) {
|
|
217
|
-
throw new BadRequestException(
|
|
219
|
+
throw new BadRequestException(ERROR_MESSAGES.FORBIDDEN);
|
|
218
220
|
}
|
|
219
221
|
}
|
|
220
222
|
|
|
@@ -373,7 +375,7 @@ export class CRUDService<T> { // Add two generic value i.e Person,CreatePersonDt
|
|
|
373
375
|
return new ManyToManyRelationFieldCrudManager(inverseManyToManyOptions);
|
|
374
376
|
}
|
|
375
377
|
}
|
|
376
|
-
else throw new Error(
|
|
378
|
+
else throw new Error(ERROR_MESSAGES.RELATION_TYPE_NOT_SUPPORTED);
|
|
377
379
|
// return (fieldMetadata.relationType === 'many-to-one') ? new ManyToOneRelationFieldCrudManager(fieldMetadata, entityManager) : new ManyToManyRelationFieldCrudManager(fieldMetadata, entityManager); //FIXME many-to-many pending
|
|
378
380
|
// ManyToOne -> fieldId. The value is saved as is. No transformation is required
|
|
379
381
|
// OneToMany -> fieldIds. Get the value of the oneToMany field side. No transformation is required (While saving special provision to be made)
|
|
@@ -624,7 +626,7 @@ export class CRUDService<T> { // Add two generic value i.e Person,CreatePersonDt
|
|
|
624
626
|
if (solidRequestContext.activeUser) {
|
|
625
627
|
const hasPermission = this.crudHelperService.hasReadPermissionOnModel(solidRequestContext.activeUser, model.singularName);
|
|
626
628
|
if (!hasPermission) {
|
|
627
|
-
throw new BadRequestException(
|
|
629
|
+
throw new BadRequestException(ERROR_MESSAGES.FORBIDDEN);
|
|
628
630
|
}
|
|
629
631
|
}
|
|
630
632
|
|
|
@@ -659,7 +661,7 @@ export class CRUDService<T> { // Add two generic value i.e Person,CreatePersonDt
|
|
|
659
661
|
if (solidRequestContext.activeUser) {
|
|
660
662
|
const hasPermission = this.crudHelperService.hasCreatePermissionOnModel(solidRequestContext.activeUser, loadedmodel.singularName);
|
|
661
663
|
if (!hasPermission) {
|
|
662
|
-
throw new BadRequestException(
|
|
664
|
+
throw new BadRequestException(ERROR_MESSAGES.FORBIDDEN);
|
|
663
665
|
}
|
|
664
666
|
}
|
|
665
667
|
|
|
@@ -709,7 +711,7 @@ export class CRUDService<T> { // Add two generic value i.e Person,CreatePersonDt
|
|
|
709
711
|
async deleteMany(ids: number[], solidRequestContext: any = {}): Promise<any> {
|
|
710
712
|
|
|
711
713
|
if (!ids || ids.length === 0) {
|
|
712
|
-
throw new Error(
|
|
714
|
+
throw new Error(ERROR_MESSAGES.DELETE_IDS_REQUIRED);
|
|
713
715
|
}
|
|
714
716
|
|
|
715
717
|
const loadedmodel = await this.loadModel();
|
|
@@ -717,7 +719,7 @@ export class CRUDService<T> { // Add two generic value i.e Person,CreatePersonDt
|
|
|
717
719
|
if (solidRequestContext.activeUser) {
|
|
718
720
|
const hasPermission = this.crudHelperService.hasDeletePermissionOnModel(solidRequestContext.activeUser, loadedmodel.singularName);
|
|
719
721
|
if (!hasPermission) {
|
|
720
|
-
throw new BadRequestException(
|
|
722
|
+
throw new BadRequestException(ERROR_MESSAGES.FORBIDDEN);
|
|
721
723
|
}
|
|
722
724
|
}
|
|
723
725
|
const model = await this.modelMetadataService.findOneBySingularName(this.modelName, {
|
|
@@ -757,7 +759,7 @@ export class CRUDService<T> { // Add two generic value i.e Person,CreatePersonDt
|
|
|
757
759
|
if (solidRequestContext.activeUser) {
|
|
758
760
|
const hasPermission = this.crudHelperService.hasRecoverPermissionOnModel(solidRequestContext.activeUser, loadedmodel.singularName);
|
|
759
761
|
if (!hasPermission) {
|
|
760
|
-
throw new BadRequestException(
|
|
762
|
+
throw new BadRequestException(ERROR_MESSAGES.FORBIDDEN);
|
|
761
763
|
}
|
|
762
764
|
}
|
|
763
765
|
|
|
@@ -770,7 +772,7 @@ export class CRUDService<T> { // Add two generic value i.e Person,CreatePersonDt
|
|
|
770
772
|
});
|
|
771
773
|
|
|
772
774
|
if (!softDeletedRows) {
|
|
773
|
-
throw new Error(
|
|
775
|
+
throw new Error(ERROR_MESSAGES.NO_SOFT_DELETED_RECORD_FOUND);
|
|
774
776
|
}
|
|
775
777
|
|
|
776
778
|
await this.repo.update(id, {
|
|
@@ -778,11 +780,11 @@ export class CRUDService<T> { // Add two generic value i.e Person,CreatePersonDt
|
|
|
778
780
|
deletedAt: null, deletedTracker: "not-deleted"
|
|
779
781
|
});
|
|
780
782
|
|
|
781
|
-
return { message:
|
|
783
|
+
return { message: SUCCESS_MESSAGES.RECORD_RECOVERED, data: softDeletedRows };
|
|
782
784
|
} catch (error) {
|
|
783
785
|
if (error instanceof QueryFailedError) {
|
|
784
786
|
if ((error as any).code === '23505') {
|
|
785
|
-
throw new Error(
|
|
787
|
+
throw new Error(ERROR_MESSAGES.CONFLICTING_RECORD_ON_UNARCHIVE);
|
|
786
788
|
}
|
|
787
789
|
}
|
|
788
790
|
|
|
@@ -797,12 +799,12 @@ export class CRUDService<T> { // Add two generic value i.e Person,CreatePersonDt
|
|
|
797
799
|
if (solidRequestContext.activeUser) {
|
|
798
800
|
const hasPermission = this.crudHelperService.hasRecoverPermissionOnModel(solidRequestContext.activeUser, loadedmodel.singularName);
|
|
799
801
|
if (!hasPermission) {
|
|
800
|
-
throw new BadRequestException(
|
|
802
|
+
throw new BadRequestException(ERROR_MESSAGES.FORBIDDEN);
|
|
801
803
|
}
|
|
802
804
|
}
|
|
803
805
|
|
|
804
806
|
if (!ids || ids.length === 0) {
|
|
805
|
-
throw new Error(
|
|
807
|
+
throw new Error(ERROR_MESSAGES.DELETE_IDS_REQUIRED);
|
|
806
808
|
}
|
|
807
809
|
|
|
808
810
|
// Find soft-deleted records matching the given IDs
|
|
@@ -816,7 +818,7 @@ export class CRUDService<T> { // Add two generic value i.e Person,CreatePersonDt
|
|
|
816
818
|
});
|
|
817
819
|
|
|
818
820
|
if (softDeletedRows.length === 0) {
|
|
819
|
-
throw new Error(
|
|
821
|
+
throw new Error(ERROR_MESSAGES.NO_SOFT_DELETED_RECORDS_FOUND);
|
|
820
822
|
}
|
|
821
823
|
|
|
822
824
|
// Recover the specific records by setting deletedAt to null
|
|
@@ -826,13 +828,11 @@ export class CRUDService<T> { // Add two generic value i.e Person,CreatePersonDt
|
|
|
826
828
|
{ deletedAt: null, deletedTracker: "not-deleted" }
|
|
827
829
|
);
|
|
828
830
|
|
|
829
|
-
return { message:
|
|
831
|
+
return { message: SUCCESS_MESSAGES.SELECTED_RECORDS_RECOVERED, recoveredIds: ids };
|
|
830
832
|
} catch (error) {
|
|
831
833
|
if (error instanceof QueryFailedError) {
|
|
832
834
|
if ((error as any).code === "23505") {
|
|
833
|
-
throw new Error(
|
|
834
|
-
"Another record is conflicting with the record you are attempting to Un-Archive, either delete or change the other record to avoid this conflict."
|
|
835
|
-
);
|
|
835
|
+
throw new Error(ERROR_MESSAGES.CONFLICTING_RECORD_ON_UNARCHIVE);
|
|
836
836
|
}
|
|
837
837
|
}
|
|
838
838
|
|
|
@@ -843,7 +843,7 @@ export class CRUDService<T> { // Add two generic value i.e Person,CreatePersonDt
|
|
|
843
843
|
|
|
844
844
|
async getFieldMetadataRecursively(pathParts: string[], fields: FieldMetadata[]) {
|
|
845
845
|
if (!pathParts || pathParts.length === 0) {
|
|
846
|
-
throw new BadRequestException(
|
|
846
|
+
throw new BadRequestException(ERROR_MESSAGES.EMPTY_PATH_PARTS);
|
|
847
847
|
}
|
|
848
848
|
|
|
849
849
|
const [currentPart, ...remainingParts] = pathParts;
|