@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.
Files changed (133) hide show
  1. package/dist/config/common.config.d.ts +2 -0
  2. package/dist/config/common.config.d.ts.map +1 -1
  3. package/dist/config/common.config.js +3 -2
  4. package/dist/config/common.config.js.map +1 -1
  5. package/dist/constants/error-messages.d.ts +83 -0
  6. package/dist/constants/error-messages.d.ts.map +1 -0
  7. package/dist/constants/error-messages.js +86 -0
  8. package/dist/constants/error-messages.js.map +1 -0
  9. package/dist/constants/success-messages.d.ts +11 -0
  10. package/dist/constants/success-messages.d.ts.map +1 -0
  11. package/dist/constants/success-messages.js +14 -0
  12. package/dist/constants/success-messages.js.map +1 -0
  13. package/dist/index.d.ts +7 -3
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/index.js +10 -4
  16. package/dist/index.js.map +1 -1
  17. package/dist/interfaces.js.map +1 -1
  18. package/dist/jobs/api-email-subscriber.service.d.ts +1 -1
  19. package/dist/jobs/api-email-subscriber.service.d.ts.map +1 -1
  20. package/dist/jobs/api-email-subscriber.service.js +2 -2
  21. package/dist/jobs/api-email-subscriber.service.js.map +1 -1
  22. package/dist/jobs/database/api-email-subscriber-database.service.d.ts +1 -1
  23. package/dist/jobs/database/api-email-subscriber-database.service.d.ts.map +1 -1
  24. package/dist/jobs/database/api-email-subscriber-database.service.js +2 -2
  25. package/dist/jobs/database/api-email-subscriber-database.service.js.map +1 -1
  26. package/dist/jobs/database/email-subscriber-database.service.d.ts +1 -1
  27. package/dist/jobs/database/email-subscriber-database.service.d.ts.map +1 -1
  28. package/dist/jobs/database/email-subscriber-database.service.js +2 -2
  29. package/dist/jobs/database/email-subscriber-database.service.js.map +1 -1
  30. package/dist/jobs/email-subscriber.service.d.ts +1 -1
  31. package/dist/jobs/email-subscriber.service.d.ts.map +1 -1
  32. package/dist/jobs/email-subscriber.service.js +2 -2
  33. package/dist/jobs/email-subscriber.service.js.map +1 -1
  34. package/dist/seeders/seed-data/solid-core-metadata.json +12 -12
  35. package/dist/services/ai-interaction.service.d.ts.map +1 -1
  36. package/dist/services/ai-interaction.service.js +4 -3
  37. package/dist/services/ai-interaction.service.js.map +1 -1
  38. package/dist/services/authentication.service.d.ts +1 -1
  39. package/dist/services/authentication.service.d.ts.map +1 -1
  40. package/dist/services/authentication.service.js +68 -66
  41. package/dist/services/authentication.service.js.map +1 -1
  42. package/dist/services/crud-helper.service.d.ts.map +1 -1
  43. package/dist/services/crud-helper.service.js +3 -2
  44. package/dist/services/crud-helper.service.js.map +1 -1
  45. package/dist/services/crud.service.d.ts.map +1 -1
  46. package/dist/services/crud.service.js +23 -21
  47. package/dist/services/crud.service.js.map +1 -1
  48. package/dist/services/csv.service.d.ts.map +1 -1
  49. package/dist/services/csv.service.js +3 -2
  50. package/dist/services/csv.service.js.map +1 -1
  51. package/dist/services/excel.service.d.ts.map +1 -1
  52. package/dist/services/excel.service.js +3 -2
  53. package/dist/services/excel.service.js.map +1 -1
  54. package/dist/services/export-transaction.service.d.ts.map +1 -1
  55. package/dist/services/export-transaction.service.js +2 -1
  56. package/dist/services/export-transaction.service.js.map +1 -1
  57. package/dist/services/field-metadata.service.d.ts.map +1 -1
  58. package/dist/services/field-metadata.service.js +9 -8
  59. package/dist/services/field-metadata.service.js.map +1 -1
  60. package/dist/services/file.service.d.ts.map +1 -1
  61. package/dist/services/file.service.js +5 -4
  62. package/dist/services/file.service.js.map +1 -1
  63. package/dist/services/import-transaction.service.d.ts.map +1 -1
  64. package/dist/services/import-transaction.service.js +11 -9
  65. package/dist/services/import-transaction.service.js.map +1 -1
  66. package/dist/services/mail/{ElasticEmailService.d.ts → elastic-email.service.d.ts} +1 -1
  67. package/dist/services/mail/elastic-email.service.d.ts.map +1 -0
  68. package/dist/services/mail/{ElasticEmailService.js → elastic-email.service.js} +1 -1
  69. package/dist/services/mail/elastic-email.service.js.map +1 -0
  70. package/dist/services/mail/{SMTPEmailService.d.ts → smtp-email.service.d.ts} +3 -3
  71. package/dist/services/mail/smtp-email.service.d.ts.map +1 -0
  72. package/dist/services/mail/{SMTPEmailService.js → smtp-email.service.js} +8 -6
  73. package/dist/services/mail/smtp-email.service.js.map +1 -0
  74. package/dist/services/media-storage-provider-metadata.service.d.ts.map +1 -1
  75. package/dist/services/media-storage-provider-metadata.service.js +4 -3
  76. package/dist/services/media-storage-provider-metadata.service.js.map +1 -1
  77. package/dist/services/media.service.d.ts.map +1 -1
  78. package/dist/services/media.service.js +2 -1
  79. package/dist/services/media.service.js.map +1 -1
  80. package/dist/services/model-metadata.service.d.ts.map +1 -1
  81. package/dist/services/model-metadata.service.js +11 -10
  82. package/dist/services/model-metadata.service.js.map +1 -1
  83. package/dist/services/module-metadata.service.d.ts.map +1 -1
  84. package/dist/services/module-metadata.service.js +11 -10
  85. package/dist/services/module-metadata.service.js.map +1 -1
  86. package/dist/services/role-metadata.service.d.ts.map +1 -1
  87. package/dist/services/role-metadata.service.js +3 -2
  88. package/dist/services/role-metadata.service.js.map +1 -1
  89. package/dist/services/sql-expression-resolver.service.d.ts.map +1 -1
  90. package/dist/services/sql-expression-resolver.service.js +2 -1
  91. package/dist/services/sql-expression-resolver.service.js.map +1 -1
  92. package/dist/services/user.service.d.ts.map +1 -1
  93. package/dist/services/user.service.js +11 -10
  94. package/dist/services/user.service.js.map +1 -1
  95. package/dist/solid-core.module.d.ts.map +1 -1
  96. package/dist/solid-core.module.js +9 -7
  97. package/dist/solid-core.module.js.map +1 -1
  98. package/dist/tsconfig.tsbuildinfo +1 -1
  99. package/package.json +1 -1
  100. package/src/config/common.config.ts +3 -2
  101. package/src/constants/error-messages.ts +123 -0
  102. package/src/constants/success-messages.ts +13 -0
  103. package/src/index.ts +10 -4
  104. package/src/interfaces.ts +3 -3
  105. package/src/jobs/api-email-subscriber.service.ts +1 -1
  106. package/src/jobs/database/api-email-subscriber-database.service.ts +1 -1
  107. package/src/jobs/database/email-subscriber-database.service.ts +1 -1
  108. package/src/jobs/email-subscriber.service.ts +1 -1
  109. package/src/seeders/seed-data/solid-core-metadata.json +12 -12
  110. package/src/services/ai-interaction.service.ts +4 -3
  111. package/src/services/authentication.service.ts +67 -65
  112. package/src/services/crud-helper.service.ts +3 -2
  113. package/src/services/crud.service.ts +23 -23
  114. package/src/services/csv.service.ts +3 -2
  115. package/src/services/excel.service.ts +3 -2
  116. package/src/services/export-transaction.service.ts +2 -1
  117. package/src/services/field-metadata.service.ts +9 -8
  118. package/src/services/file.service.ts +5 -4
  119. package/src/services/import-transaction.service.ts +11 -9
  120. package/src/services/mail/{SMTPEmailService.ts → smtp-email.service.ts} +7 -5
  121. package/src/services/media-storage-provider-metadata.service.ts +4 -3
  122. package/src/services/media.service.ts +2 -1
  123. package/src/services/model-metadata.service.ts +11 -10
  124. package/src/services/module-metadata.service.ts +11 -10
  125. package/src/services/role-metadata.service.ts +3 -2
  126. package/src/services/sql-expression-resolver.service.ts +2 -1
  127. package/src/services/user.service.ts +11 -10
  128. package/src/solid-core.module.ts +5 -3
  129. package/dist/services/mail/ElasticEmailService.d.ts.map +0 -1
  130. package/dist/services/mail/ElasticEmailService.js.map +0 -1
  131. package/dist/services/mail/SMTPEmailService.d.ts.map +0 -1
  132. package/dist/services/mail/SMTPEmailService.js.map +0 -1
  133. /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/SMTPEmailService';
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('User does not exists');
116
+ throw new UnauthorizedException(ERROR_MESSAGES.USER_NOT_FOUND);
115
117
  }
116
118
  if (!user.active) {
117
- throw new UnauthorizedException('User profile not activated');
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('Password does not match');
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('Public registrations are disabled.');
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 || 'A unique constraint violation occurred.'));
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('Passwordless registration is not enabled');
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('Either mobile or email is required for initiating registration');
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('Email is required for email validation source');
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('Mobile is required for mobile validation source');
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('User already exists. Please sign in');
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: 'User registration initiated. OTP sent to the user.' }
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('At least one validation source is required');
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('Passwordless registration is not enabled');
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('User does not exist');
423
+ throw new UnauthorizedException(ERROR_MESSAGES.USER_NOT_FOUND);
422
424
  }
423
425
  if (user.emailVerificationTokenOnRegistration !== confirmSignUpDto.otp) {
424
- throw new UnauthorizedException('Invalid OTP');
426
+ throw new UnauthorizedException(ERROR_MESSAGES.INVALID_OTP);
425
427
  }
426
428
  if (user.emailVerificationTokenOnRegistrationExpiresAt < new Date()) {
427
- throw new UnauthorizedException('OTP expired');
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('User does not exist');
445
+ throw new UnauthorizedException(ERROR_MESSAGES.USER_NOT_FOUND);
444
446
  }
445
447
  if (user.mobileVerificationTokenOnRegistration !== confirmSignUpDto.otp) {
446
- throw new UnauthorizedException('Invalid OTP');
448
+ throw new UnauthorizedException(ERROR_MESSAGES.INVALID_OTP);
447
449
  }
448
450
  if (user.mobileVerificationTokenOnRegistrationExpiresAt < new Date()) {
449
- throw new UnauthorizedException('Invalid OTP');
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('Invalid type. Must be either email or mobile');
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('Passwordless registration is not enabled');
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('User does not exist');
528
+ throw new UnauthorizedException(ERROR_MESSAGES.USER_NOT_FOUND);
527
529
  }
528
530
  if (!user.active) {
529
- throw new UnauthorizedException('User is inactive');
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('User does not exist');
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('Invalid type. Must be either email or mobile');
555
+ throw new BadRequestException(ERROR_MESSAGES.INVALID_VERIFICATION_TYPE);
554
556
  }
555
- return { message: 'User login initiated. OTP sent to the user.' };
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('Passwordless registration is not enabled');
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('User does not exist');
610
+ throw new UnauthorizedException(ERROR_MESSAGES.USER_NOT_FOUND);
609
611
  }
610
612
  if (!user.active) {
611
- throw new UnauthorizedException('User is inactive');
613
+ throw new UnauthorizedException(ERROR_MESSAGES.USER_INACTIVE);
612
614
  }
613
615
  if (user.emailVerificationTokenOnLogin !== confirmSignInDto.otp) {
614
- throw new UnauthorizedException('Invalid OTP');
616
+ throw new UnauthorizedException(ERROR_MESSAGES.INVALID_OTP);
615
617
  }
616
618
  if (user.emailVerificationTokenOnLoginExpiresAt < new Date()) {
617
- throw new UnauthorizedException('Invalid OTP');
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('User does not exist');
637
+ throw new UnauthorizedException(ERROR_MESSAGES.USER_NOT_ACTIVE);
636
638
  }
637
639
  if (!user.active) {
638
- throw new UnauthorizedException('User is inactive');
640
+ throw new UnauthorizedException(ERROR_MESSAGES.USER_INACTIVE);
639
641
  }
640
642
  if (user.mobileVerificationTokenOnLogin !== confirmSignInDto.otp) {
641
- throw new UnauthorizedException('Invalid OTP');
643
+ throw new UnauthorizedException(ERROR_MESSAGES.INVALID_OTP);
642
644
  }
643
645
  if (user.mobileVerificationTokenOnLoginExpiresAt < new Date()) {
644
- throw new UnauthorizedException('Invalid OTP');
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('Invalid type. Must be either email or mobile');
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('User does not exists');
666
+ throw new NotFoundException(ERROR_MESSAGES.USER_NOT_FOUND);
665
667
  }
666
668
 
667
669
  if (!user.active) {
668
- throw new UnauthorizedException('User is inactive');
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('User seems to have used a passwordless mode to authenticate.');
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("User ID's do not match ");
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("User username's do not match");
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('Incorrect current password specified...');
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('Previously used passwords cannot be used again.');
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('User does not exists');
729
+ throw new NotFoundException(ERROR_MESSAGES.USER_NOT_FOUND);
728
730
  }
729
731
  if (!user.active) {
730
- throw new UnauthorizedException('User is inactive');
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('User seems to have used a passwordless mode to authenticate.');
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: 'Forgot password - token generated and sent',
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('User does not exists');
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('User seems to have used a passwordless mode to authenticate.');
817
+ throw new BadRequestException(ERROR_MESSAGES.NON_LOCAL_PROVIDER);
816
818
  }
817
819
  if (!user.active) {
818
- throw new UnauthorizedException('User is inactive');
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('Invalid verification token');
825
+ throw new UnauthorizedException(ERROR_MESSAGES.INVALID_VERIFICATION_TOKEN);
824
826
  }
825
827
  if (user.verificationTokenOnForgotPasswordExpiresAt < new Date()) {
826
- throw new UnauthorizedException('Invalid verification token');
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('Previously used passwords cannot be used again.');
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: 'Forgot password confirmed',
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('Access denied');
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('Invalid user profile');
1012
+ throw new UnauthorizedException(ERROR_MESSAGES.INVALID_USER_PROFILE);
1011
1013
  }
1012
1014
  } catch (error) {
1013
- throw new UnauthorizedException('Failed to fetch user profile from Google OAuth service');
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: 'Logged out successfully' };
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('Logout failed due to an unexpected error.');
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('User not found');
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('buildFilterQuery: Only 1 Group by field is supported currently');
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('Exactly one groupBy field is required to count grouped records.');
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('Forbidden');
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('Duplicate entry. A record with similar unique fields already exists.');
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('Id is required for update');
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('Forbidden');
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('Id is required for update');
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('Forbidden');
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('Relation type not supported in crud service');
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('Forbidden');
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('Forbidden');
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('At least one ID is required for deletion');
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('Forbidden');
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('Forbidden');
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('No soft-deleted record found with the given ID.');
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: 'Record successfully recovered', data: softDeletedRows };
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('Another record is conflicting with the record you are attempting to Un-Archive, either delete or change the other record so as to avoid this conflict.');
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('Forbidden');
802
+ throw new BadRequestException(ERROR_MESSAGES.FORBIDDEN);
801
803
  }
802
804
  }
803
805
 
804
806
  if (!ids || ids.length === 0) {
805
- throw new Error("No IDs provided for recovery.");
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("No matching soft-deleted records found.");
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: "Selected records successfully recovered", recoveredIds: ids };
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('Path parts cannot be empty');
846
+ throw new BadRequestException(ERROR_MESSAGES.EMPTY_PATH_PARTS);
847
847
  }
848
848
 
849
849
  const [currentPart, ...remainingParts] = pathParts;