@solidxai/core 0.1.16 → 0.1.17-beta.0

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 (116) hide show
  1. package/CHANGELOG.md +1324 -1
  2. package/dist/controllers/chatter-message-details.controller.d.ts.map +1 -1
  3. package/dist/controllers/chatter-message-details.controller.js +2 -6
  4. package/dist/controllers/chatter-message-details.controller.js.map +1 -1
  5. package/dist/controllers/chatter-message.controller.d.ts.map +1 -1
  6. package/dist/controllers/chatter-message.controller.js +3 -7
  7. package/dist/controllers/chatter-message.controller.js.map +1 -1
  8. package/dist/controllers/dashboard-user-layout.controller.d.ts.map +1 -1
  9. package/dist/controllers/dashboard-user-layout.controller.js +2 -6
  10. package/dist/controllers/dashboard-user-layout.controller.js.map +1 -1
  11. package/dist/controllers/import-transaction-error-log.controller.d.ts.map +1 -1
  12. package/dist/controllers/import-transaction-error-log.controller.js +2 -6
  13. package/dist/controllers/import-transaction-error-log.controller.js.map +1 -1
  14. package/dist/controllers/import-transaction.controller.d.ts.map +1 -1
  15. package/dist/controllers/import-transaction.controller.js +2 -6
  16. package/dist/controllers/import-transaction.controller.js.map +1 -1
  17. package/dist/controllers/list-of-values.controller.d.ts.map +1 -1
  18. package/dist/controllers/list-of-values.controller.js +2 -6
  19. package/dist/controllers/list-of-values.controller.js.map +1 -1
  20. package/dist/controllers/locale.controller.d.ts.map +1 -1
  21. package/dist/controllers/locale.controller.js +2 -6
  22. package/dist/controllers/locale.controller.js.map +1 -1
  23. package/dist/controllers/media.controller.d.ts.map +1 -1
  24. package/dist/controllers/media.controller.js +2 -6
  25. package/dist/controllers/media.controller.js.map +1 -1
  26. package/dist/controllers/model-sequence.controller.d.ts.map +1 -1
  27. package/dist/controllers/model-sequence.controller.js +2 -6
  28. package/dist/controllers/model-sequence.controller.js.map +1 -1
  29. package/dist/controllers/saved-filters.controller.d.ts.map +1 -1
  30. package/dist/controllers/saved-filters.controller.js +2 -6
  31. package/dist/controllers/saved-filters.controller.js.map +1 -1
  32. package/dist/controllers/scheduled-job.controller.d.ts.map +1 -1
  33. package/dist/controllers/scheduled-job.controller.js +2 -6
  34. package/dist/controllers/scheduled-job.controller.js.map +1 -1
  35. package/dist/controllers/security-rule.controller.d.ts.map +1 -1
  36. package/dist/controllers/security-rule.controller.js +2 -6
  37. package/dist/controllers/security-rule.controller.js.map +1 -1
  38. package/dist/controllers/user-activity-history.controller.d.ts.map +1 -1
  39. package/dist/controllers/user-activity-history.controller.js +2 -6
  40. package/dist/controllers/user-activity-history.controller.js.map +1 -1
  41. package/dist/controllers/user-view-metadata.controller.d.ts.map +1 -1
  42. package/dist/controllers/user-view-metadata.controller.js +2 -6
  43. package/dist/controllers/user-view-metadata.controller.js.map +1 -1
  44. package/dist/controllers/workflow-definition.controller.d.ts.map +1 -1
  45. package/dist/controllers/workflow-definition.controller.js +2 -6
  46. package/dist/controllers/workflow-definition.controller.js.map +1 -1
  47. package/dist/controllers/workflow-execution-artifact.controller.d.ts.map +1 -1
  48. package/dist/controllers/workflow-execution-artifact.controller.js +2 -6
  49. package/dist/controllers/workflow-execution-artifact.controller.js.map +1 -1
  50. package/dist/controllers/workflow-execution-log.controller.d.ts.map +1 -1
  51. package/dist/controllers/workflow-execution-log.controller.js +2 -6
  52. package/dist/controllers/workflow-execution-log.controller.js.map +1 -1
  53. package/dist/controllers/workflow-execution.controller.d.ts.map +1 -1
  54. package/dist/controllers/workflow-execution.controller.js +2 -6
  55. package/dist/controllers/workflow-execution.controller.js.map +1 -1
  56. package/dist/controllers/workflow-secret.controller.d.ts.map +1 -1
  57. package/dist/controllers/workflow-secret.controller.js +2 -6
  58. package/dist/controllers/workflow-secret.controller.js.map +1 -1
  59. package/dist/controllers/workflow-step-execution.controller.d.ts.map +1 -1
  60. package/dist/controllers/workflow-step-execution.controller.js +2 -6
  61. package/dist/controllers/workflow-step-execution.controller.js.map +1 -1
  62. package/dist/controllers/workflow-trigger-execution.controller.d.ts.map +1 -1
  63. package/dist/controllers/workflow-trigger-execution.controller.js +2 -6
  64. package/dist/controllers/workflow-trigger-execution.controller.js.map +1 -1
  65. package/dist/dtos/basic-filters.dto.d.ts +3 -5
  66. package/dist/dtos/basic-filters.dto.d.ts.map +1 -1
  67. package/dist/dtos/basic-filters.dto.js +6 -8
  68. package/dist/dtos/basic-filters.dto.js.map +1 -1
  69. package/dist/dtos/otp-sign-up.dto.d.ts +1 -0
  70. package/dist/dtos/otp-sign-up.dto.d.ts.map +1 -1
  71. package/dist/dtos/otp-sign-up.dto.js +12 -1
  72. package/dist/dtos/otp-sign-up.dto.js.map +1 -1
  73. package/dist/enums/show-soft-deleted.enum.d.ts +5 -0
  74. package/dist/enums/show-soft-deleted.enum.d.ts.map +1 -0
  75. package/dist/enums/show-soft-deleted.enum.js +9 -0
  76. package/dist/enums/show-soft-deleted.enum.js.map +1 -0
  77. package/dist/index.d.ts +1 -0
  78. package/dist/index.d.ts.map +1 -1
  79. package/dist/index.js +1 -0
  80. package/dist/index.js.map +1 -1
  81. package/dist/services/authentication.service.d.ts.map +1 -1
  82. package/dist/services/authentication.service.js +15 -6
  83. package/dist/services/authentication.service.js.map +1 -1
  84. package/dist/services/chatter-message.service.d.ts +2 -0
  85. package/dist/services/chatter-message.service.d.ts.map +1 -1
  86. package/dist/services/chatter-message.service.js +48 -21
  87. package/dist/services/chatter-message.service.js.map +1 -1
  88. package/package.json +1 -1
  89. package/postman/signup-intent-verification.postman_collection.json +573 -0
  90. package/src/controllers/chatter-message-details.controller.ts +1 -4
  91. package/src/controllers/chatter-message.controller.ts +1 -4
  92. package/src/controllers/dashboard-user-layout.controller.ts +1 -4
  93. package/src/controllers/import-transaction-error-log.controller.ts +1 -4
  94. package/src/controllers/import-transaction.controller.ts +1 -4
  95. package/src/controllers/list-of-values.controller.ts +1 -4
  96. package/src/controllers/locale.controller.ts +1 -4
  97. package/src/controllers/media.controller.ts +1 -4
  98. package/src/controllers/model-sequence.controller.ts +1 -4
  99. package/src/controllers/saved-filters.controller.ts +1 -4
  100. package/src/controllers/scheduled-job.controller.ts +1 -4
  101. package/src/controllers/security-rule.controller.ts +1 -4
  102. package/src/controllers/user-activity-history.controller.ts +1 -4
  103. package/src/controllers/user-view-metadata.controller.ts +1 -4
  104. package/src/controllers/workflow-definition.controller.ts +1 -4
  105. package/src/controllers/workflow-execution-artifact.controller.ts +1 -4
  106. package/src/controllers/workflow-execution-log.controller.ts +1 -4
  107. package/src/controllers/workflow-execution.controller.ts +1 -4
  108. package/src/controllers/workflow-secret.controller.ts +1 -4
  109. package/src/controllers/workflow-step-execution.controller.ts +1 -4
  110. package/src/controllers/workflow-trigger-execution.controller.ts +1 -4
  111. package/src/dtos/basic-filters.dto.ts +6 -7
  112. package/src/dtos/otp-sign-up.dto.ts +11 -1
  113. package/src/enums/show-soft-deleted.enum.ts +4 -0
  114. package/src/index.ts +1 -0
  115. package/src/services/authentication.service.ts +61 -26
  116. package/src/services/chatter-message.service.ts +54 -23
@@ -1 +1 @@
1
- {"version":3,"file":"authentication.service.js","sourceRoot":"","sources":["../../src/services/authentication.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { HttpService } from \"@nestjs/axios\";\nimport type { SolidCoreSetting } from \"src/services/settings/default-settings-provider.service\";\nimport {\n BadRequestException,\n ConflictException,\n ForbiddenException,\n Injectable,\n InternalServerErrorException,\n Logger,\n NotFoundException,\n UnauthorizedException,\n} from \"@nestjs/common\";\nimport { EventEmitter2 } from \"@nestjs/event-emitter\";\nimport { JwtService } from \"@nestjs/jwt\";\nimport { InjectDataSource } from \"@nestjs/typeorm\";\nimport { isEmpty, isNotEmpty } from \"class-validator\";\nimport { randomInt, randomUUID } from \"crypto\";\nimport { ERROR_MESSAGES } from \"src/constants/error-messages\";\nimport { SUCCESS_MESSAGES } from \"src/constants/success-messages\";\nimport { CreateUserDto } from \"src/dtos/create-user.dto\";\nimport { MailFactory } from \"src/factories/mail.factory\";\nimport { UserRepository } from \"src/repository/user.repository\";\nimport { DataSource, DeepPartial, FindOptionsWhere, Repository } from \"typeorm\";\nimport { v4 as uuidv4 } from \"uuid\";\nimport {\n ForgotPasswordSendVerificationTokenOn,\n PasswordlessLoginValidateWhatSources,\n PasswordlessRegistrationValidateWhatSources,\n} from \"../constants\";\nimport { ChangePasswordDto } from \"../dtos/change-password.dto\";\nimport { ConfirmForgotPasswordDto } from \"../dtos/confirm-forgot-password.dto\";\nimport { InitiateForgotPasswordDto } from \"../dtos/initiate-forgot-password.dto\";\nimport { OTPConfirmOTPDto } from \"../dtos/otp-confirm-otp.dto\";\nimport { OTPSignInDto } from \"../dtos/otp-sign-in.dto\";\nimport { OTPSignUpDto } from \"../dtos/otp-sign-up.dto\";\nimport { RefreshTokenDto } from \"../dtos/refresh-token.dto\";\nimport { SignInDto } from \"../dtos/sign-in.dto\";\nimport { SignUpDto } from \"../dtos/sign-up.dto\";\nimport { SignupIntent } from \"../enums/signup-intent.enum\";\nimport { User } from \"../entities/user.entity\";\nimport { EventDetails, EventType } from \"../interfaces\";\nimport { ActiveUserData } from \"../interfaces/active-user-data.interface\";\nimport { ActiveSessionStorageService } from \"./active-session-storage.service\";\nimport { AccessTokenDenylistService } from \"./access-token-denylist.service\";\nimport { HashingService } from \"./hashing.service\";\nimport {\n InvalidatedRefreshTokenError,\n RefreshTokenIdsStorageService,\n} from \"./refresh-token-ids-storage.service\";\nimport { SsoCodeStorageService } from \"./sso-code-storage.service\";\nimport { RoleMetadataService } from \"./role-metadata.service\";\nimport { SettingService } from \"./setting.service\";\nimport { UserActivityHistoryService } from \"./user-activity-history.service\";\nimport { MetadataValidationService } from \"./metadata-validation.service\";\nimport { UserService } from \"./user.service\";\nimport { SmsFactory } from \"src/factories/sms.factory\";\nimport { WhatsAppFactory } from \"src/factories/whatsapp.factory\";\nimport { SolidRegistry } from \"src/helpers/solid-registry\";\n\nenum LoginProvider {\n LOCAL = \"local\",\n GOOGLE = \"google\",\n OTP = \"otp\",\n}\n\ninterface otp {\n token: string;\n expiresAt: Date;\n}\n\n/** Where a signup's role names come from. */\nenum RolesSource {\n /** None from the caller: performSignUp applies the configured `defaultRole`. */\n Default,\n /** `provider.roles(dto)`, unconditionally. */\n Provider,\n /** The caller's own `dto.roles`. */\n Caller,\n}\n\n/**\n * The single place that decides, per intent, which entity a signup builds and where\n * its roles come from.\n *\n * `useProvider` is currently computable from `rolesSource` (`Caller` implies false),\n * but the two answer different questions - \"which entity?\" and \"which roles?\" - that\n * merely coincide across these three intents. Keep both, and change behaviour here\n * rather than at a call site.\n */\nconst SIGNUP_POLICY: Record<\n SignupIntent,\n { useProvider: boolean; rolesSource: RolesSource }\n> = {\n [SignupIntent.SelfRegistration]: {\n useProvider: true,\n rolesSource: RolesSource.Default,\n },\n [SignupIntent.ExtensionModel]: {\n useProvider: true,\n rolesSource: RolesSource.Provider,\n },\n [SignupIntent.CoreUser]: {\n useProvider: false,\n rolesSource: RolesSource.Caller,\n },\n};\n\n@Injectable()\nexport class AuthenticationService {\n private readonly logger = new Logger(AuthenticationService.name);\n // private readonly mailService: IMail;\n constructor(\n private readonly userService: UserService,\n // @InjectRepository(User) private readonly userRepository: Repository<User>,\n private readonly userRepository: UserRepository,\n private readonly hashingService: HashingService,\n private readonly jwtService: JwtService,\n private readonly activeSessionStorage: ActiveSessionStorageService,\n private readonly accessTokenDenylist: AccessTokenDenylistService,\n private readonly refreshTokenIdsStorage: RefreshTokenIdsStorageService,\n private readonly httpService: HttpService,\n // private readonly mailService: SMTPEMailService,\n private readonly mailServiceFactory: MailFactory,\n // private readonly smsService: Msg91OTPService,\n private readonly smsFactory: SmsFactory,\n private readonly whatsAppFactory: WhatsAppFactory,\n private readonly eventEmitter: EventEmitter2,\n private readonly settingService: SettingService,\n private readonly roleMetadataService: RoleMetadataService,\n private readonly userActivityHistoryService: UserActivityHistoryService,\n private readonly ssoCodeStorage: SsoCodeStorageService,\n private readonly metadataValidationService: MetadataValidationService,\n\n @InjectDataSource()\n private readonly dataSource: DataSource,\n private readonly solidRegistry: SolidRegistry,\n ) {\n // this.mailService = this.mailServiceFactory.getMailService();\n }\n\n private async getCompanyLogo(): Promise<string> {\n return this.settingService.getConfigValue<SolidCoreSetting>(\"companylogo\");\n }\n\n async resolveUser(username: string, email: string) {\n return await this.userRepository.findOne({\n where: [{ username: username }, { email: email }],\n relations: {\n roles: true,\n },\n });\n }\n\n private async resolveUserForPasswordSignIn(username: string, email: string) {\n const normalizedEmail = email?.trim().toLowerCase();\n const query = (await this.userRepository\n .createSecurityRuleAwareQueryBuilder(\"u\"))\n .leftJoinAndSelect(\"u.roles\", \"roles\");\n\n if (username) {\n query.where(\"u.username = :username\", { username });\n }\n if (normalizedEmail) {\n if (username) {\n query.orWhere(\"LOWER(u.email) = :email\", { email: normalizedEmail });\n } else {\n query.where(\"LOWER(u.email) = :email\", { email: normalizedEmail });\n }\n }\n\n return await query.getOne();\n }\n\n async updatePasswordDetails(user: User, newPassword: string) {\n user.password = await this.hashingService.hash(newPassword);\n user.passwordScheme = this.hashingService.name();\n user.passwordSchemeVersion = this.hashingService.currentVersion();\n user.rehashedAt = new Date();\n await this.userRepository.update(user.id, {\n password: user.password,\n passwordScheme: user.passwordScheme,\n passwordSchemeVersion: user.passwordSchemeVersion,\n rehashedAt: user.rehashedAt,\n });\n return user;\n }\n\n async resolveUserByVerificationToken(token: string) {\n return await this.userRepository.findOne({\n where: { verificationTokenOnForgotPassword: token },\n relations: { roles: true },\n });\n }\n\n private async validateUserForPasswordLogin(\n user: User,\n password: string,\n ): Promise<void> {\n if (!user.active) {\n throw new UnauthorizedException(ERROR_MESSAGES.USER_NOT_ACTIVE);\n }\n this.checkAccountBlocked(user);\n const isEqual = await this.hashingService.compare(\n password,\n user.password,\n user.passwordSchemeVersion,\n );\n if (!isEqual) {\n await this.incrementFailedAttempts(user);\n throw new UnauthorizedException(ERROR_MESSAGES.INVALID_CREDENTIALS);\n }\n }\n\n private async rehashPasswordIfRequired(\n user: User,\n password: string,\n ): Promise<void> {\n if (\n this.hashingService.needsRehash(user.password, user.passwordSchemeVersion)\n ) {\n await this.updatePasswordDetails(user, password);\n }\n }\n\n async signUp(\n signUpDto: SignUpDto & Record<string, any>,\n activeUser: ActiveUserData = null,\n intent: SignupIntent = SignupIntent.SelfRegistration,\n ): Promise<User> {\n const { useProvider, rolesSource } = SIGNUP_POLICY[intent];\n\n if (intent === SignupIntent.SelfRegistration) {\n this.assertPublicRegistrationEnabled();\n }\n\n const { entity, repo } = await this.userService.buildSignupTarget(\n signUpDto,\n useProvider,\n );\n const roles = this.resolveSignupRoles(signUpDto, rolesSource);\n\n return this.performSignUp({ ...signUpDto, roles }, entity, repo);\n }\n\n private resolveSignupRoles(\n dto: Record<string, any>,\n source: RolesSource,\n ): string[] {\n switch (source) {\n case RolesSource.Provider:\n // Sole authority. `dto.roles` is deliberately not read - not as a preference,\n // not as a fallback. Reading it would skip roles(), which is where a provider\n // validates its discriminator, and CreateUserDto types roles as\n // UpdateRoleMetadataDto[] where performSignUp expects role-name strings.\n return (\n this.solidRegistry\n .getExtensionUserCreationProvider()\n ?.roles(dto as any) ?? []\n );\n\n case RolesSource.Caller:\n return dto.roles ?? [];\n\n case RolesSource.Default:\n // Public signup: the form has no business naming roles. Returning empty lets\n // performSignUp apply the configured `defaultRole`, rather than adding a\n // second mechanism for the same thing.\n if (dto.roles?.length) {\n this.logger.warn(\n `Ignoring caller-supplied roles on public registration for \"${dto.username}\"`,\n );\n }\n return [];\n }\n }\n\n private async performSignUp<T extends User>(\n signUpDto: SignUpDto,\n entity: T,\n repo: Repository<T>,\n ): Promise<T> {\n try {\n await this.assertUniqueSignupIdentifiers(signUpDto);\n await this.metadataValidationService.validateCreateDto(\"user\", signUpDto);\n\n const onForcePasswordChange =\n this.settingService.getConfigValue<SolidCoreSetting>(\n \"forceChangePasswordOnFirstLogin\",\n );\n const activateUserOnRegistration =\n this.settingService.getConfigValue<SolidCoreSetting>(\n \"activateUserOnRegistration\",\n );\n const defaultRole =\n this.settingService.getConfigValue<SolidCoreSetting>(\"defaultRole\");\n\n var { user, pwd, autoGeneratedPwd } = await this.populateForSignup<T>(\n entity,\n signUpDto,\n activateUserOnRegistration,\n onForcePasswordChange,\n );\n // An explicitly supplied value wins over whatever the entity carries. The\n // entity's own flag cannot be trusted as a signal: User initialises it to\n // false, so \"the provider set it\" is indistinguishable from \"nobody set it\".\n const privateDto = signUpDto as { isAllowedToGenerateApiKeys?: boolean };\n if (privateDto.isAllowedToGenerateApiKeys !== undefined) {\n user.isAllowedToGenerateApiKeys = privateDto.isAllowedToGenerateApiKeys;\n }\n const savedUser = await repo.save(user);\n const userRoles = signUpDto.roles ?? [];\n if (\n (signUpDto.roles?.length ?? 0) === 0 &&\n signUpDto.username !== \"sa\" &&\n defaultRole\n ) {\n userRoles.push(defaultRole);\n }\n await this.handlePostSignup(savedUser, userRoles, pwd, autoGeneratedPwd);\n await this.handlePasswordlessSignupOtp(savedUser, signUpDto, autoGeneratedPwd, repo);\n this.triggerRegistrationEvent(savedUser);\n\n return savedUser;\n } catch (err: any) {\n const pgUniqueViolationErrorCode = \"23505\";\n if (err.code === pgUniqueViolationErrorCode) {\n throw new ConflictException(\n parseUniqueConstraintError(\n err.detail || ERROR_MESSAGES.UNIQUE_CONSTRAINT_VIOLATION,\n ),\n );\n }\n throw err;\n }\n }\n\n /**\n * Always queries the base `User` repository, never the caller's repository.\n *\n * `User` is a `@TableInheritance` root, so a child repository scopes every query\n * to its own discriminator. Checking through one would only compare against users\n * of the same subtype, and `email`/`mobile` carry non-unique `@Index()` - there is\n * no database constraint behind them to catch what the query misses. A duplicate\n * against a base `User` or a sibling subtype would be silently accepted.\n */\n private async assertUniqueSignupIdentifiers(\n signUpDto: SignUpDto,\n ): Promise<void> {\n const username = signUpDto.username?.trim();\n const email = signUpDto.email?.trim();\n const mobile = signUpDto.mobile?.trim();\n\n const where: FindOptionsWhere<User>[] = [];\n\n if (username) {\n where.push({ username });\n }\n\n if (email) {\n where.push({ email });\n }\n\n if (mobile) {\n where.push({ mobile });\n }\n\n if (where.length === 0) {\n return;\n }\n\n const existingUser = await this.userRepository.findOne({ where });\n\n if (!existingUser) {\n return;\n }\n\n if (email && existingUser.email === email) {\n throw new ConflictException(\n `A user with email address \"${email}\" already exists.`,\n );\n }\n\n if (mobile && existingUser.mobile === mobile) {\n throw new ConflictException(\n `A user with mobile number \"${mobile}\" already exists.`,\n );\n }\n\n if (username && existingUser.username === username) {\n throw new ConflictException(\n `A user with username \"${username}\" already exists.`,\n );\n }\n\n throw new ConflictException(ERROR_MESSAGES.USER_ALREADY_EXISTS);\n }\n\n private async handlePasswordlessSignupOtp<T extends User>(\n user: T,\n signUpDto: SignUpDto,\n autoGeneratedPwd: string,\n repo: Repository<T>,\n ): Promise<void> {\n const isPasswordProvided = !!signUpDto.password;\n const isAutoGeneratedPassword = !!autoGeneratedPwd;\n if (isPasswordProvided || isAutoGeneratedPassword) {\n return;\n }\n\n if (!user.mobile) {\n this.logger.warn(\n `Skipping passwordless signup OTP WhatsApp notification for user ${user.username}: mobile is missing.`,\n );\n return;\n }\n\n const isPasswordlessRegistrationEnabled =\n await this.isPasswordlessRegistrationEnabled();\n if (!isPasswordlessRegistrationEnabled) {\n return;\n }\n\n await this.assignRegistrationOtp(\n PasswordlessRegistrationValidateWhatSources.MOBILE,\n user,\n );\n await repo.save(user);\n await this.notifyUserOnOtpInitiateRegistration(\n user,\n PasswordlessRegistrationValidateWhatSources.MOBILE,\n );\n }\n\n /** @deprecated Use IExtensionUserCreationProvider instead. Kept for backward compatibility. */\n async signupForExtensionUser<T extends User>(\n signUpDto: SignUpDto,\n extensionUserDto: DeepPartial<T>,\n extensionUserRepo: Repository<T>,\n ): Promise<T> {\n const entity = extensionUserRepo.create(extensionUserDto);\n return this.performSignUp(signUpDto, entity, extensionUserRepo);\n }\n\n private async populateForSignup<T extends User>(\n user: T,\n signUpDto: SignUpDto,\n isUserActive: boolean = true,\n onForcePasswordChange?: boolean,\n ) {\n // const user = new User();\n let autoGeneratedPwdPermission =\n this.settingService.getConfigValue<SolidCoreSetting>(\n \"iamAutoGeneratedPassword\",\n );\n if (signUpDto.roles && signUpDto.roles.length > 0) {\n for (let i = 0; i < signUpDto.roles.length; i++) {\n const roleName = signUpDto.roles[i];\n await this.roleMetadataService.assertRoleExistsByName(roleName);\n }\n }\n user.username = signUpDto.username;\n user.email = signUpDto.email;\n // `fullName` is optional on SignUpDto and the stock signup screen only sends it when\n // showNameFieldsForRegistration is on, so assigning it unconditionally left every\n // self-registered user with a null display name. `username` is always present -\n // non-nullable on the entity and @IsNotEmpty() on the DTO - so it is a safe fallback.\n // `||` rather than `??`: a form posting an empty string means \"not supplied\" too.\n user.fullName = signUpDto.fullName?.trim() || signUpDto.username;\n user.forcePasswordChange = onForcePasswordChange;\n if (signUpDto.mobile) {\n user.mobile = signUpDto.mobile;\n }\n // this.logger.debug(\"user\", user);\n\n // If password has been specified by the user, then we simply create & activate the user based on the configuration parameter \"activateUserOnRegistration\".\n let pwd = \"\";\n let autoGeneratedPwd = \"\";\n\n // User has specified password\n if (signUpDto.password) {\n pwd = await this.hashingService.hash(signUpDto.password);\n }\n // User has not specified password\n else {\n // When user does not specify password, and system is configured to auto generate passwords.\n if (autoGeneratedPwdPermission?.toString().toLowerCase() === \"true\") {\n autoGeneratedPwd = this.generatePassword();\n pwd = await this.hashingService.hash(autoGeneratedPwd);\n user.forcePasswordChange = true;\n }\n // When user does not specify password, and system is not configured to auto generate passwords.\n else {\n // This means that most likely the system is going to be using password-less login.\n // If that is not the case then we can raise a bad request exception...\n if (!(await this.isPasswordlessRegistrationEnabled())) {\n this.logger.error(\n \"User being created without password, and password less login is also not enabled in the system. Is this intentional?\",\n );\n throw new BadRequestException(\n ERROR_MESSAGES.PASSWORDLESS_REGISTRATION_DISABLED,\n );\n }\n\n // Save the hash of the blank password, anyways since passwordless login is enabled it does not matter.\n pwd = await this.hashingService.hash(pwd);\n }\n }\n\n user.password = pwd;\n user.passwordScheme = this.hashingService.name(); // e.g. bcrypt\n user.passwordSchemeVersion = this.hashingService.currentVersion(); // e.g. 1, 2, 3 ...\n user.active = isUserActive;\n return { user, pwd, autoGeneratedPwd };\n }\n\n private async handlePostSignup(\n user: User,\n roles: string[] = [],\n pwd: string,\n autoGeneratedPwd: string,\n ) {\n await this.userService.initializeRolesForNewUser(roles, user);\n\n // if forcePasswordChange is true, then we trigger an email to the user to change the password, this needs to be done using a queue.\n // Create a new method like notifyUserOnForcePasswordChange, create a new email template we can call it on-force-password-change this template to include the random password\n if (user.forcePasswordChange && autoGeneratedPwd) {\n try {\n await this.notifyUserOnForcePasswordChange(user, autoGeneratedPwd);\n } catch (error: any) {\n this.logger.error(\n `Failed to send force-password-change email for user ${user.id}: ${error?.message ?? error}`,\n );\n }\n }\n\n // Send welcome notifications (email/SMS) if enabled.\n try {\n await this.notifyUserOnSignup(user);\n } catch (error: any) {\n this.logger.error(\n `Failed to send signup notifications for user ${user.id}: ${error?.message ?? error}`,\n );\n }\n }\n\n generatePassword(length: number = 8): string {\n const upperCase = \"ABCDEFGHIJKLMNOPQRSTUVWXYZ\";\n const lowerCase = \"abcdefghijklmnopqrstuvwxyz\";\n const numbers = \"0123456789\";\n const specialChars = \"@$#\";\n const allChars = upperCase + lowerCase + numbers + specialChars;\n\n let password = \"\";\n\n for (let i = 0; i < length; i++) {\n const randomIndex = Math.floor(Math.random() * allChars.length);\n password += allChars[randomIndex];\n }\n\n return password;\n }\n\n private async notifyUserOnForcePasswordChange(\n user: User,\n autoGeneratedPwd: string,\n ) {\n const companyLogo = await this.getCompanyLogo();\n const mailService = this.mailServiceFactory.getMailService();\n mailService.sendEmailUsingTemplate(\n user.email,\n \"on-force-password-change\",\n {\n solidAppName:\n this.settingService.getConfigValue<SolidCoreSetting>(\"appTitle\"),\n solidAppWebsiteUrl:\n this.settingService.getConfigValue<SolidCoreSetting>(\n \"solidAppWebsiteUrl\",\n ),\n frontendLoginPageUrl:\n this.settingService.getConfigValue<SolidCoreSetting>(\n \"frontendLoginPageUrl\",\n ),\n email: user.email,\n fullName: user.fullName,\n userName: user.username,\n password: autoGeneratedPwd,\n companyLogoUrl: companyLogo,\n },\n this.settingService.getConfigValue<SolidCoreSetting>(\"shouldQueueEmails\"),\n null,\n null,\n \"user\",\n user.id,\n );\n }\n\n private async isWelcomeEmailEnabled(): Promise<boolean> {\n const sendWelcomeEmailOnSignup =\n this.settingService.getConfigValue<SolidCoreSetting>(\n \"sendWelcomeEmailOnSignup\",\n );\n return sendWelcomeEmailOnSignup;\n }\n\n private async isWelcomeSmsEnabled(): Promise<boolean> {\n const sendWelcomeSmsOnSignup =\n this.settingService.getConfigValue<SolidCoreSetting>(\n \"sendWelcomeSmsOnSignup\",\n );\n return sendWelcomeSmsOnSignup;\n }\n\n private async notifyUserOnSignup(user: User) {\n const companyLogo = await this.getCompanyLogo();\n // Email welcome\n if (await this.isWelcomeEmailEnabled()) {\n const mailService = this.mailServiceFactory.getMailService();\n mailService.sendEmailUsingTemplate(\n user.email,\n \"email-on-signup\",\n {\n solidAppName:\n this.settingService.getConfigValue<SolidCoreSetting>(\"appTitle\"),\n solidAppWebsiteUrl:\n this.settingService.getConfigValue<SolidCoreSetting>(\n \"solidAppWebsiteUrl\",\n ),\n frontendLoginPageUrl:\n this.settingService.getConfigValue<SolidCoreSetting>(\n \"frontendLoginPageUrl\",\n ),\n email: user.email,\n fullName: user.fullName,\n userName: user.username,\n companyLogoUrl: companyLogo,\n },\n this.settingService.getConfigValue<SolidCoreSetting>(\n \"shouldQueueEmails\",\n ),\n null,\n null,\n \"user\",\n user.id,\n );\n }\n\n // SMS welcome\n const isWelcomeSmsEnabled = await this.isWelcomeSmsEnabled();\n if (isWelcomeSmsEnabled && user.mobile) {\n const smsService = this.smsFactory.getSmsService();\n smsService.sendSMSUsingTemplate(\n user.mobile,\n \"text-on-signup\",\n {\n solidAppName:\n this.settingService.getConfigValue<SolidCoreSetting>(\"appTitle\"),\n frontendLoginPageUrl:\n this.settingService.getConfigValue<SolidCoreSetting>(\n \"frontendLoginPageUrl\",\n ),\n firstName: user.username,\n fullName: user.fullName ? user.fullName : user.username,\n },\n this.settingService.getConfigValue<SolidCoreSetting>(\"shouldQueueSms\"),\n );\n }\n }\n\n /**\n * Gates *self-service* account creation only - the public register endpoints, where\n * an anonymous visitor creates their own account. Callers that create a user on\n * someone else's behalf (the admin console, an extension model's CRUD form, the\n * seeders) are deliberately unaffected, so turning this off does not disable user\n * creation across the system.\n *\n * Compared against both representations because `getConfigValue` returns the raw\n * cached value, which is a boolean when it comes from the provider default and a\n * string once persisted or edited through the Settings screen - see the same\n * defensive comparison for `mcpEnabled` in setting.service.ts. A plain falsy check\n * would read `'false'` as truthy and never fire.\n */\n private assertPublicRegistrationEnabled(): void {\n const allowPublicRegistration =\n this.settingService.getConfigValue<SolidCoreSetting>(\n \"allowPublicRegistration\",\n );\n if (allowPublicRegistration === false || allowPublicRegistration === \"false\") {\n throw new ForbiddenException(ERROR_MESSAGES.PUBLIC_REGISTRATION_DISABLED);\n }\n }\n\n async otpInitiateRegistration(signUpDto: OTPSignUpDto) {\n this.assertPublicRegistrationEnabled();\n\n const isPasswordlessRegistrationEnabled =\n await this.isPasswordlessRegistrationEnabled();\n if (!isPasswordlessRegistrationEnabled) {\n throw new BadRequestException(\n ERROR_MESSAGES.PASSWORDLESS_REGISTRATION_DISABLED,\n );\n }\n\n const validationSource = this.resolvePasswordlessValidationSource();\n this.validateOtpRegistrationInput(signUpDto, validationSource);\n\n const existingUser = await this.findExistingRegistrationUser(signUpDto);\n if (isNotEmpty(existingUser) && existingUser.active) {\n throw new ConflictException(ERROR_MESSAGES.USER_ALREADY_EXISTS);\n }\n\n try {\n const user = await this.upsertUserWithRegistrationVerificationTokens(\n existingUser,\n signUpDto,\n validationSource,\n );\n await this.notifyUserOnOtpInitiateRegistration(user, validationSource);\n } catch (err: any) {\n if (err.code === \"23505\") {\n throw new ConflictException(ERROR_MESSAGES.USER_ALREADY_EXISTS);\n }\n throw err;\n }\n\n return { message: SUCCESS_MESSAGES.OTP_SENT_SUCCESS_REGISTRATION };\n }\n\n private validateOtpRegistrationInput(\n signUpDto: OTPSignUpDto,\n validationSource: string,\n ): void {\n if (\n validationSource === PasswordlessRegistrationValidateWhatSources.EMAIL &&\n isEmpty(signUpDto.email)\n ) {\n throw new BadRequestException(\n ERROR_MESSAGES.EMAIL_REQUIRED_FOR_VALIDATION,\n );\n }\n if (\n validationSource === PasswordlessRegistrationValidateWhatSources.MOBILE &&\n isEmpty(signUpDto.mobile)\n ) {\n throw new BadRequestException(\n ERROR_MESSAGES.MOBILE_REQUIRED_FOR_VALIDATION,\n );\n }\n }\n\n private async findExistingRegistrationUser(\n signUpDto: OTPSignUpDto,\n ): Promise<User> {\n return this.userRepository.findOne({\n //TODO Perhaps we should use the user service instead of the repository directly.\n where: [\n { email: signUpDto.email },\n { mobile: signUpDto.mobile },\n { username: signUpDto.username },\n ],\n });\n }\n\n private resolvePasswordlessValidationSource(): string {\n return this.settingService.getConfigValue<SolidCoreSetting>(\n \"passwordlessRegistrationValidateWhat\",\n );\n }\n\n private async upsertUserWithRegistrationVerificationTokens(\n existingUser: User,\n signUpDto: OTPSignUpDto,\n validationSource: string,\n ): Promise<User> {\n if (isEmpty(existingUser)) {\n // A new registration is saved through whichever repository createUser resolved,\n // which is the provider's when the app registers one.\n const { entity: user, repo } = await this.createUser(signUpDto);\n user.active = false; // User will be activated only after OTP verification, hence setting active to false for new user.\n await this.assignRegistrationOtp(validationSource, user);\n await repo.save(user);\n await this.userService.addRoleToUser(\n user.username,\n this.settingService.getConfigValue<SolidCoreSetting>(\"defaultRole\"),\n );\n return user;\n }\n\n // An existing row is saved back through the base repository: `User` is the\n // inheritance root, so TypeORM hydrated it as its own subclass on the way in and\n // round-trips the discriminator on the way out.\n const user = existingUser;\n await this.assignRegistrationOtp(validationSource, user);\n await this.userRepository.save(user);\n return user;\n }\n\n /**\n * Creates a new user entity for OTP registration - of whichever type this app\n * registers its users as, since passwordless signup is self-registration like any\n * other. Returns the repository alongside it, because a provider-built entity has\n * to be saved through the provider's own repository.\n */\n private async createUser(\n signUpDto: OTPSignUpDto,\n ): Promise<{ entity: User; repo: Repository<User> }> {\n const { useProvider } = SIGNUP_POLICY[SignupIntent.SelfRegistration];\n const { entity, repo } = await this.userService.buildSignupTarget(\n signUpDto,\n useProvider,\n );\n\n entity.username = signUpDto.username;\n entity.email = signUpDto.email;\n entity.mobile = signUpDto.mobile;\n // OTPSignUpDto declares no `fullName`, so username is the only source here. Mirrors\n // the fallback in populateForSignup, which this path does not go through.\n entity.fullName = signUpDto.username;\n entity.customPayload = signUpDto.customPayload;\n entity.lastLoginProvider = LoginProvider.OTP;\n\n return { entity, repo };\n }\n\n // Generate the validation tokens for the user i.e (system configured + user provided)\n private async assignRegistrationOtp(\n passwordlessRegistrationValidateWhat: string,\n user: User,\n ) {\n if (!passwordlessRegistrationValidateWhat) {\n throw new BadRequestException(ERROR_MESSAGES.VALIDATION_SOURCE_REQUIRED);\n }\n const autoLoginUserOnRegistration =\n this.settingService.getConfigValue<SolidCoreSetting>(\n \"autoLoginUserOnRegistration\",\n );\n if (\n passwordlessRegistrationValidateWhat ===\n PasswordlessRegistrationValidateWhatSources.EMAIL\n ) {\n const { token, expiresAt } = await this.otp();\n user.emailVerificationTokenOnRegistration = token;\n user.emailVerificationTokenOnRegistrationExpiresAt = expiresAt;\n if (autoLoginUserOnRegistration) {\n user.emailVerificationTokenOnLogin = token;\n user.emailVerificationTokenOnLoginExpiresAt = expiresAt;\n }\n }\n if (\n passwordlessRegistrationValidateWhat ===\n PasswordlessRegistrationValidateWhatSources.MOBILE\n ) {\n const { token, expiresAt } = await this.otp();\n user.mobileVerificationTokenOnRegistration = token;\n user.mobileVerificationTokenOnRegistrationExpiresAt = expiresAt;\n if (autoLoginUserOnRegistration) {\n user.mobileVerificationTokenOnLogin = token;\n user.mobileVerificationTokenOnLoginExpiresAt = expiresAt;\n }\n }\n }\n\n private async notifyUserOnOtpInitiateRegistration(\n user: User,\n registrationValidationSource: string,\n ) {\n const companyLogo = await this.getCompanyLogo();\n if (\n registrationValidationSource ===\n PasswordlessRegistrationValidateWhatSources.EMAIL\n ) {\n const mailService = this.mailServiceFactory.getMailService();\n mailService.sendEmailUsingTemplate(\n user.email,\n \"otp-on-register\",\n {\n solidAppName:\n this.settingService.getConfigValue<SolidCoreSetting>(\"appTitle\"),\n solidAppWebsiteUrl:\n this.settingService.getConfigValue<SolidCoreSetting>(\n \"solidAppWebsiteUrl\",\n ),\n firstName: user.username,\n fullName: user.fullName ? user.fullName : user.username,\n emailVerificationTokenOnRegistration:\n user.emailVerificationTokenOnRegistration,\n companyLogoUrl: companyLogo,\n },\n this.settingService.getConfigValue<SolidCoreSetting>(\n \"shouldQueueEmails\",\n ),\n null,\n null,\n \"user\",\n user.id,\n );\n }\n if (\n registrationValidationSource ===\n PasswordlessRegistrationValidateWhatSources.MOBILE\n ) {\n const templateParams = {\n solidAppName:\n this.settingService.getConfigValue<SolidCoreSetting>(\"appTitle\"),\n otp: user.mobileVerificationTokenOnRegistration,\n mobileVerificationTokenOnRegistration:\n user.mobileVerificationTokenOnRegistration,\n firstName: user.username,\n fullName: user.fullName ? user.fullName : user.username,\n companyLogoUrl: companyLogo,\n };\n\n const whatsappDestination = this.normalizeWhatsAppDestination(\n user.mobile,\n );\n const gupshupTemplateAppName =\n process.env.COMMON_GUPSHUP_APP_NAME || \"Gupshup\";\n const whatsappTemplateId =\n this.settingService.getConfigValue<SolidCoreSetting>(\n \"otpWhatsappTemplateId\",\n ) || \"common_otp\";\n const whatsappIndependentEnabled =\n this.settingService.getConfigValue<SolidCoreSetting>(\n \"otpWhatsappIndependentEnabled\",\n ) !== false;\n\n let smsSent = false;\n let whatsappSent = false;\n let smsErrorMessage: string | undefined;\n let whatsappErrorMessage: string | undefined;\n\n this.logger.debug(\n `OTP SMS send attempt: destination=${user.mobile}, whatsappDestination=${whatsappDestination}`,\n );\n\n try {\n const smsService = this.smsFactory.getSmsService();\n await smsService.sendSMSUsingTemplate(\n user.mobile,\n \"otp-on-register\",\n templateParams,\n false,\n );\n smsSent = true;\n } catch (smsError: any) {\n smsErrorMessage = smsError?.message;\n this.logger.warn(\n `OTP SMS failed: destination=${user.mobile}, message=${smsErrorMessage}`,\n );\n }\n\n if (whatsappIndependentEnabled) {\n if (!whatsappDestination) {\n whatsappErrorMessage = \"Normalized WhatsApp destination is empty\";\n this.logger.error(\n `Independent OTP WhatsApp skipped: destination=${user.mobile}, message=${whatsappErrorMessage}`,\n );\n } else {\n this.logger.debug(\n `Independent OTP WhatsApp send attempt: destination=${user.mobile}, whatsappDestination=${whatsappDestination}, templateId=${whatsappTemplateId}`,\n );\n try {\n await this.sendOtpToWhatsappProvider(\n whatsappDestination,\n String(whatsappTemplateId),\n String(gupshupTemplateAppName),\n String(templateParams.otp || \"\"),\n );\n whatsappSent = true;\n this.logger.log(\n `Independent OTP WhatsApp success: destination=${user.mobile}, whatsappDestination=${whatsappDestination}, templateId=${whatsappTemplateId}`,\n );\n } catch (waError: any) {\n whatsappErrorMessage = waError?.message;\n this.logger.error(\n `Independent OTP WhatsApp failed: destination=${user.mobile}, whatsappDestination=${whatsappDestination}, templateId=${whatsappTemplateId}, message=${whatsappErrorMessage}`,\n );\n }\n }\n }\n\n if (!smsSent && !whatsappSent) {\n throw new Error(\n `OTP delivery failed on both channels. smsError=${smsErrorMessage || \"unknown\"}, whatsappError=${whatsappErrorMessage || \"disabled/unknown\"}`,\n );\n }\n }\n }\n\n private normalizeWhatsAppDestination(rawMobile: string): string {\n const raw = (rawMobile || \"\").trim();\n let sanitized = raw.replace(/[^\\d+]/g, \"\");\n\n if (sanitized.startsWith(\"00\")) {\n sanitized = `+${sanitized.slice(2)}`;\n }\n\n const defaultDialCode = String(\n this.settingService.getConfigValue<SolidCoreSetting>(\n \"otpDefaultCountryDialCode\",\n ) || \"\",\n ).replace(/\\D/g, \"\");\n\n if (sanitized.startsWith(\"+\")) {\n const e164Digits = sanitized.slice(1).replace(/\\D/g, \"\");\n if (e164Digits.length >= 8 && e164Digits.length <= 15) {\n return e164Digits;\n }\n }\n\n const digits = sanitized.replace(/\\D/g, \"\");\n\n if (digits.length >= 11 && digits.length <= 15) {\n return digits;\n }\n\n if (digits.length === 10 && defaultDialCode) {\n return `${defaultDialCode}${digits}`;\n }\n\n return digits;\n }\n\n private async sendOtpToWhatsappProvider(\n destination: string,\n templateId: string,\n appName: string,\n otp: string,\n ): Promise<void> {\n const whatsappService = this.whatsAppFactory.getWhatsappService();\n await whatsappService.sendWhatsAppMessage(destination, null, {\n type: \"text\",\n text: `${appName} OTP is ${otp}. It is valid for 10 mins.`,\n });\n }\n\n async otpConfirmRegistration(confirmSignUpDto: OTPConfirmOTPDto) {\n const isPasswordlessRegistrationEnabled =\n await this.isPasswordlessRegistrationEnabled();\n if (!isPasswordlessRegistrationEnabled) {\n throw new BadRequestException(\n ERROR_MESSAGES.PASSWORDLESS_REGISTRATION_DISABLED,\n );\n }\n\n const { type, identifier, otp } = confirmSignUpDto;\n if (\n type !== PasswordlessRegistrationValidateWhatSources.EMAIL &&\n type !== PasswordlessRegistrationValidateWhatSources.MOBILE\n ) {\n throw new BadRequestException(ERROR_MESSAGES.INVALID_VERIFICATION_TYPE);\n }\n\n const user = await this.findUserByRegistrationIdentifier(type, identifier);\n this.validateRegistrationOtp(user, otp, type);\n this.clearRegistrationOtp(user, type);\n user.active =\n this.settingService.getConfigValue<SolidCoreSetting>(\n \"activateUserOnRegistration\",\n ) &&\n (await this.areAllPasswordlessRegistrationValidationSourcesVerified(\n user,\n ));\n\n const savedUser: User = await this.userRepository.save(user);\n this.triggerRegistrationEvent(savedUser);\n return {\n active: savedUser.active,\n message: `User registration verified for ${type}`,\n };\n }\n\n private async findUserByRegistrationIdentifier(\n type: PasswordlessRegistrationValidateWhatSources,\n identifier: string,\n ): Promise<User> {\n const where =\n type === PasswordlessRegistrationValidateWhatSources.EMAIL\n ? { email: identifier }\n : { mobile: identifier };\n const user = await this.userRepository.findOne({ where });\n if (!user) {\n throw new UnauthorizedException(ERROR_MESSAGES.USER_NOT_FOUND);\n }\n return user;\n }\n\n private validateRegistrationOtp(\n user: User,\n otp: string,\n type: PasswordlessRegistrationValidateWhatSources,\n ): void {\n const isEmail = type === PasswordlessRegistrationValidateWhatSources.EMAIL;\n const token = isEmail\n ? user.emailVerificationTokenOnRegistration\n : user.mobileVerificationTokenOnRegistration;\n const expiresAt = isEmail\n ? user.emailVerificationTokenOnRegistrationExpiresAt\n : user.mobileVerificationTokenOnRegistrationExpiresAt;\n\n if (token !== otp) {\n throw new UnauthorizedException(ERROR_MESSAGES.INVALID_OTP);\n }\n if (expiresAt < new Date()) {\n throw new UnauthorizedException(ERROR_MESSAGES.OTP_EXPIRED);\n }\n }\n\n private clearRegistrationOtp(\n user: User,\n type: PasswordlessRegistrationValidateWhatSources,\n ): void {\n if (type === PasswordlessRegistrationValidateWhatSources.EMAIL) {\n user.emailVerifiedOnRegistrationAt = new Date();\n user.emailVerificationTokenOnRegistration = null;\n user.emailVerificationTokenOnRegistrationExpiresAt = null;\n } else {\n user.mobileVerifiedOnRegistrationAt = new Date();\n user.mobileVerificationTokenOnRegistration = null;\n user.mobileVerificationTokenOnRegistrationExpiresAt = null;\n }\n }\n\n private triggerRegistrationEvent(savedUser: User) {\n // Trigger events for user registration.\n const event = new EventDetails<User>(EventType.USER_REGISTERED, savedUser);\n this.eventEmitter.emit(EventType.USER_REGISTERED, event);\n }\n\n private async areAllPasswordlessRegistrationValidationSourcesVerified(\n user: User,\n ): Promise<boolean> {\n const registrationValidationSource =\n this.resolvePasswordlessValidationSource();\n if (\n registrationValidationSource ===\n PasswordlessRegistrationValidateWhatSources.EMAIL\n ) {\n if (!user.emailVerifiedOnRegistrationAt) {\n return false;\n }\n }\n if (\n registrationValidationSource ===\n PasswordlessRegistrationValidateWhatSources.MOBILE\n ) {\n if (!user.mobileVerifiedOnRegistrationAt) {\n return false;\n }\n }\n return true;\n }\n\n private async otp(): Promise<otp> {\n const now = new Date();\n const otpExpiry =\n this.settingService.getConfigValue<SolidCoreSetting>(\"otpExpiry\");\n now.setMinutes(now.getMinutes() + otpExpiry);\n return {\n token: randomInt(100000, 999999).toString(),\n expiresAt: now,\n };\n }\n\n private getDummyOtpForUser(user?: User): string | undefined {\n const dummyOtp =\n this.settingService.getConfigValue<SolidCoreSetting>(\"dummyOtp\");\n if (!dummyOtp || !user?.username) {\n return undefined;\n }\n const allowedUsers = this.getDummyOtpUsers();\n if (!allowedUsers.size) {\n return undefined;\n }\n const username = user.username.trim().toLowerCase();\n if (!username) {\n return undefined;\n }\n return allowedUsers.has(username) ? dummyOtp : undefined;\n }\n\n private getDummyOtpUsers(): Set<string> {\n const rawUsers =\n this.settingService.getConfigValue<SolidCoreSetting>(\"dummyOtpUsers\");\n if (!rawUsers || typeof rawUsers !== \"string\") {\n return new Set();\n }\n return new Set(\n rawUsers\n .split(\",\")\n .map((value) => value.trim().toLowerCase())\n .filter(Boolean),\n );\n }\n\n async signIn(signInDto: SignInDto) {\n const user = await this.resolveUserForPasswordSignIn(\n signInDto.username,\n signInDto.email,\n );\n if (!user) {\n throw new UnauthorizedException(ERROR_MESSAGES.INVALID_CREDENTIALS);\n }\n await this.validateUserForPasswordLogin(user, signInDto.password);\n await this.rehashPasswordIfRequired(user, signInDto.password);\n await this.resetFailedAttempts(user);\n\n const tokens = await this.generateTokens(user);\n\n await this.userActivityHistoryService.logEvent(\"login\", user);\n\n return {\n user: {\n email: user.email,\n mobile: user.mobile,\n username: user.username,\n forcePasswordChange: user.forcePasswordChange,\n id: user.id,\n roles: user.roles.map((role) => role.name),\n },\n ...tokens,\n };\n }\n\n private maskEmail(email: string): string {\n if (!email) return null;\n\n const [localPart, domain] = email.split(\"@\");\n if (localPart.length <= 2) {\n return `${localPart[0]}***@${domain}`;\n }\n\n const visibleStart = localPart.slice(0, 2);\n const visibleEnd = localPart.slice(-1);\n return `${visibleStart}***${visibleEnd}@${domain}`;\n }\n\n private maskMobile(mobile: string): string {\n if (!mobile) return null;\n\n if (mobile.length <= 4) {\n return mobile;\n }\n\n const visibleEnd = mobile.slice(-4);\n return `***${visibleEnd}`;\n }\n\n async otpInitiateLogin(signInDto: OTPSignInDto) {\n const isPasswordlessRegistrationEnabled =\n await this.isPasswordlessRegistrationEnabled();\n if (!isPasswordlessRegistrationEnabled) {\n throw new BadRequestException(\n ERROR_MESSAGES.PASSWORDLESS_REGISTRATION_DISABLED,\n );\n }\n\n const type = this.resolveLoginType(signInDto);\n const user = await this.findUserForLogin(type, signInDto.identifier);\n const dummyOtp = this.getDummyOtpForUser(user);\n if (!dummyOtp) {\n await this.assignLoginOtp(user, type);\n await this.notifyUserOnOtpInititateLogin(user, type);\n }\n return this.buildLoginOtpResponse(user, type);\n }\n\n private resolveLoginType(\n signInDto: OTPSignInDto,\n ): PasswordlessLoginValidateWhatSources {\n const setting = this.settingService.getConfigValue<SolidCoreSetting>(\n \"passwordlessLoginValidateWhat\",\n ) as PasswordlessLoginValidateWhatSources;\n\n if (setting === PasswordlessLoginValidateWhatSources.SELECTABLE) {\n if (\n signInDto.type !== PasswordlessLoginValidateWhatSources.EMAIL &&\n signInDto.type !== PasswordlessLoginValidateWhatSources.MOBILE\n ) {\n throw new BadRequestException(ERROR_MESSAGES.INVALID_VERIFICATION_TYPE);\n }\n return signInDto.type as PasswordlessLoginValidateWhatSources;\n }\n\n if (\n setting === PasswordlessLoginValidateWhatSources.EMAIL ||\n setting === PasswordlessLoginValidateWhatSources.MOBILE\n ) {\n return setting;\n }\n\n throw new BadRequestException(ERROR_MESSAGES.INVALID_VERIFICATION_TYPE);\n }\n\n private async resolveUserForOtpEmailSignIn(identifier: string,options: { withRoles?: boolean } = {},): Promise<User | null> {\n const normalizedEmail = identifier?.trim().toLowerCase();\n const query =\n await this.userRepository.createSecurityRuleAwareQueryBuilder(\"u\");\n\n if (options.withRoles) {\n query.leftJoinAndSelect(\"u.roles\", \"roles\");\n }\n\n query.where(\"u.username = :username\", { username: identifier });\n\n if (normalizedEmail) {\n query.orWhere(\"LOWER(u.email) = :email\", { email: normalizedEmail });\n }\n\n return await query.getOne();\n }\n\n private async findUserForLogin(\n type: PasswordlessLoginValidateWhatSources,\n identifier: string,\n options: { withRoles?: boolean } = {},\n ): Promise<User> {\n const user =\n type === PasswordlessLoginValidateWhatSources.EMAIL\n ? await this.resolveUserForOtpEmailSignIn(identifier, options)\n : await this.userRepository.findOne({\n where: [{ username: identifier }, { mobile: identifier }],\n ...(options.withRoles ? { relations: { roles: true } } : {}),\n });\n if (!user) {\n throw new UnauthorizedException(ERROR_MESSAGES.USER_NOT_FOUND);\n }\n if (!user.active) {\n throw new UnauthorizedException(ERROR_MESSAGES.USER_INACTIVE);\n }\n return user;\n }\n\n private async assignLoginOtp(\n user: User,\n type: PasswordlessLoginValidateWhatSources,\n ): Promise<void> {\n const { token, expiresAt } = await this.otp();\n if (type === PasswordlessLoginValidateWhatSources.EMAIL) {\n user.emailVerificationTokenOnLogin = token;\n user.emailVerificationTokenOnLoginExpiresAt = expiresAt;\n await this.userRepository.update(user.id, {\n emailVerificationTokenOnLogin: token,\n emailVerificationTokenOnLoginExpiresAt: expiresAt,\n });\n } else {\n user.mobileVerificationTokenOnLogin = token;\n user.mobileVerificationTokenOnLoginExpiresAt = expiresAt;\n await this.userRepository.update(user.id, {\n mobileVerificationTokenOnLogin: token,\n mobileVerificationTokenOnLoginExpiresAt: expiresAt,\n });\n }\n }\n\n private buildLoginOtpResponse(\n user: User,\n type: PasswordlessLoginValidateWhatSources,\n ) {\n const maskedIdentifier =\n type === PasswordlessLoginValidateWhatSources.EMAIL\n ? { email: this.maskEmail(user.email) }\n : { mobile: this.maskMobile(user.mobile) };\n return {\n message: SUCCESS_MESSAGES.OTP_SENT_SUCCESS_LOGIN,\n user: maskedIdentifier,\n };\n }\n\n private async notifyUserOnOtpInititateLogin(\n user: User,\n loginType: PasswordlessLoginValidateWhatSources,\n ) {\n const companyLogo = await this.getCompanyLogo();\n const dummyOtp = this.getDummyOtpForUser(user);\n\n if (dummyOtp) return; // Do nothing if dummy otp is configured.\n if (loginType === PasswordlessLoginValidateWhatSources.EMAIL) {\n const mailService = this.mailServiceFactory.getMailService();\n mailService.sendEmailUsingTemplate(\n user.email,\n \"otp-on-login\",\n {\n solidAppName:\n this.settingService.getConfigValue<SolidCoreSetting>(\"appTitle\"),\n solidAppWebsiteUrl:\n this.settingService.getConfigValue<SolidCoreSetting>(\n \"solidAppWebsiteUrl\",\n ),\n firstName: user.username,\n emailVerificationTokenOnLogin: user.emailVerificationTokenOnLogin,\n fullName: user.fullName ? user.fullName : user.username,\n companyLogoUrl: companyLogo,\n },\n this.settingService.getConfigValue<SolidCoreSetting>(\n \"shouldQueueEmails\",\n ),\n null,\n null,\n \"user\",\n user.id,\n );\n }\n if (loginType === PasswordlessLoginValidateWhatSources.MOBILE) {\n const templateParams = {\n solidAppName:\n this.settingService.getConfigValue<SolidCoreSetting>(\"appTitle\"),\n otp: user.mobileVerificationTokenOnLogin,\n mobileVerificationTokenOnLogin: user.mobileVerificationTokenOnLogin,\n firstName: user.username,\n fullName: user.fullName ? user.fullName : user.username,\n companyLogoUrl: companyLogo,\n };\n\n const whatsappDestination = this.normalizeWhatsAppDestination(user.mobile);\n const gupshupTemplateAppName =\n process.env.COMMON_GUPSHUP_APP_NAME || \"Gupshup\";\n const whatsappTemplateId =\n this.settingService.getConfigValue<SolidCoreSetting>(\n \"otpWhatsappTemplateId\",\n ) || \"common_otp\";\n const whatsappIndependentEnabled =\n this.settingService.getConfigValue<SolidCoreSetting>(\n \"otpWhatsappIndependentEnabled\",\n ) !== false;\n\n let smsSent = false;\n let whatsappSent = false;\n let smsErrorMessage: string | undefined;\n let whatsappErrorMessage: string | undefined;\n\n this.logger.debug(\n `OTP LOGIN SMS send attempt: destination=${user.mobile}, whatsappDestination=${whatsappDestination}`,\n );\n\n try {\n const smsService = this.smsFactory.getSmsService();\n await smsService.sendSMSUsingTemplate(\n user.mobile,\n \"otp-on-login\",\n templateParams,\n false,\n );\n smsSent = true;\n } catch (smsError: any) {\n smsErrorMessage = smsError?.message;\n this.logger.warn(\n `OTP LOGIN SMS failed: destination=${user.mobile}, message=${smsErrorMessage}`,\n );\n }\n\n if (whatsappIndependentEnabled) {\n if (!whatsappDestination) {\n whatsappErrorMessage = \"Normalized WhatsApp destination is empty\";\n this.logger.error(\n `OTP LOGIN WhatsApp skipped: destination=${user.mobile}, message=${whatsappErrorMessage}`,\n );\n } else {\n this.logger.debug(\n `OTP LOGIN WhatsApp send attempt: destination=${user.mobile}, whatsappDestination=${whatsappDestination}, templateId=${whatsappTemplateId}`,\n );\n try {\n await this.sendOtpToWhatsappProvider(\n whatsappDestination,\n String(whatsappTemplateId),\n String(gupshupTemplateAppName),\n String(templateParams.otp || \"\"),\n );\n whatsappSent = true;\n this.logger.log(\n `OTP LOGIN WhatsApp success: destination=${user.mobile}, whatsappDestination=${whatsappDestination}, templateId=${whatsappTemplateId}`,\n );\n } catch (waError: any) {\n whatsappErrorMessage = waError?.message;\n this.logger.error(\n `OTP LOGIN WhatsApp failed: destination=${user.mobile}, whatsappDestination=${whatsappDestination}, templateId=${whatsappTemplateId}, message=${whatsappErrorMessage}`,\n );\n }\n }\n }\n\n if (!smsSent && !whatsappSent) {\n throw new Error(\n `OTP LOGIN delivery failed on both channels. smsError=${smsErrorMessage || \"unknown\"}, whatsappError=${whatsappErrorMessage || \"disabled/unknown\"}`,\n );\n }\n }\n }\n\n async otpConfirmLogin(confirmSignInDto: OTPConfirmOTPDto) {\n const isPasswordlessRegistrationEnabled =\n await this.isPasswordlessRegistrationEnabled();\n if (!isPasswordlessRegistrationEnabled) {\n throw new BadRequestException(\n ERROR_MESSAGES.PASSWORDLESS_REGISTRATION_DISABLED,\n );\n }\n\n const { type, identifier, otp } = confirmSignInDto;\n if (\n type !== PasswordlessLoginValidateWhatSources.EMAIL &&\n type !== PasswordlessLoginValidateWhatSources.MOBILE\n ) {\n throw new BadRequestException(ERROR_MESSAGES.INVALID_VERIFICATION_TYPE);\n }\n\n const user = await this.findUserForLogin(type, identifier, {\n withRoles: true,\n });\n this.checkAccountBlocked(user);\n const dummyOtp = this.getDummyOtpForUser(user);\n\n if (dummyOtp) {\n if (otp !== dummyOtp) {\n throw new UnauthorizedException(ERROR_MESSAGES.INVALID_OTP);\n }\n return this.buildLoginTokenResponse(user);\n }\n\n try {\n this.validateLoginOtp(user, otp, type);\n } catch (e) {\n await this.incrementFailedAttempts(user);\n throw e;\n }\n\n await this.clearLoginOtp(user, type);\n await this.userActivityHistoryService.logEvent(\"login\", user);\n await this.resetFailedAttempts(user);\n return this.buildLoginTokenResponse(user);\n }\n\n private validateLoginOtp(\n user: User,\n otp: string,\n type: PasswordlessLoginValidateWhatSources,\n ): void {\n const isEmail = type === PasswordlessLoginValidateWhatSources.EMAIL;\n const token = isEmail\n ? user.emailVerificationTokenOnLogin\n : user.mobileVerificationTokenOnLogin;\n const expiresAt = isEmail\n ? user.emailVerificationTokenOnLoginExpiresAt\n : user.mobileVerificationTokenOnLoginExpiresAt;\n\n if (token !== otp) {\n throw new UnauthorizedException(ERROR_MESSAGES.INVALID_OTP);\n }\n if (expiresAt < new Date()) {\n throw new UnauthorizedException(ERROR_MESSAGES.OTP_EXPIRED);\n }\n }\n\n private async clearLoginOtp(\n user: User,\n type: PasswordlessLoginValidateWhatSources,\n ): Promise<void> {\n if (type === PasswordlessLoginValidateWhatSources.EMAIL) {\n const verifiedAt = new Date();\n user.emailVerifiedOnLoginAt = verifiedAt;\n user.emailVerificationTokenOnLogin = null;\n user.emailVerificationTokenOnLoginExpiresAt = null;\n await this.userRepository.update(user.id, {\n emailVerifiedOnLoginAt: verifiedAt,\n emailVerificationTokenOnLogin: null,\n emailVerificationTokenOnLoginExpiresAt: null,\n });\n } else {\n const verifiedAt = new Date();\n user.mobileVerifiedOnLoginAt = verifiedAt;\n user.mobileVerificationTokenOnLogin = null;\n user.mobileVerificationTokenOnLoginExpiresAt = null;\n await this.userRepository.update(user.id, {\n mobileVerifiedOnLoginAt: verifiedAt,\n mobileVerificationTokenOnLogin: null,\n mobileVerificationTokenOnLoginExpiresAt: null,\n });\n }\n }\n\n private buildUserPayload(user: User) {\n const { id, username, email, mobile, lastLoginProvider } = user;\n const roles = user.roles.map((role) => role.name);\n return { id, username, email, mobile, lastLoginProvider, roles };\n }\n\n private async buildLoginTokenResponse(user: User) {\n const { accessToken, refreshToken } = await this.generateTokens(user);\n return { accessToken, refreshToken, user: this.buildUserPayload(user) };\n }\n\n async changePassword(\n changePasswordDto: ChangePasswordDto,\n activeUser: ActiveUserData,\n ) {\n const user = await this.userRepository.findOne({\n where: { id: changePasswordDto.id },\n });\n if (!user) {\n throw new NotFoundException(ERROR_MESSAGES.USER_NOT_FOUND);\n }\n\n if (!user.active) {\n throw new UnauthorizedException(ERROR_MESSAGES.USER_INACTIVE);\n }\n\n // 2. Validate if user has used a provider which is \"local\", only then it makes sense for us to initiate the forgot password routine.\n if (user.lastLoginProvider !== \"local\") {\n throw new BadRequestException(ERROR_MESSAGES.NON_LOCAL_PROVIDER);\n }\n\n // Check if ID's match\n if (!(user.id === activeUser.sub)) {\n throw new BadRequestException(ERROR_MESSAGES.USER_ID_MISMATCH);\n }\n\n // Check if username's match\n if (!(user.username === activeUser.username)) {\n throw new BadRequestException(ERROR_MESSAGES.USERNAME_MISMATCH);\n }\n\n // Check if old password is matching.\n const isEqual = await this.hashingService.compare(\n changePasswordDto.currentPassword,\n user.password,\n user.passwordSchemeVersion,\n );\n if (!isEqual) {\n throw new UnauthorizedException(\n ERROR_MESSAGES.INCORRECT_CURRENT_PASSWORD,\n );\n }\n\n // Update Password\n const pwdData = await this.userService.hashPassword(\n changePasswordDto.newPassword,\n );\n user.password = changePasswordDto.newPassword;\n\n user.password = pwdData.password;\n user.passwordScheme = pwdData.passwordScheme;\n user.passwordSchemeVersion = pwdData.passwordSchemeVersion;\n // Everytime the user changes the password we reset the forcePasswordChange flag back to false.\n user.forcePasswordChange = false;\n\n await this.userRepository.save(user);\n\n return true;\n }\n\n // generate uuid token for forgot password\n private async generateForgotPasswordToken(user?: User) {\n const expiryTime = new Date();\n const forgotPasswordVerificationTokenExpiry =\n this.settingService.getConfigValue<SolidCoreSetting>(\n \"forgotPasswordVerificationTokenExpiry\",\n );\n const dummyOtp = this.getDummyOtpForUser(user);\n expiryTime.setMinutes(\n expiryTime.getMinutes() + forgotPasswordVerificationTokenExpiry,\n );\n\n return {\n token: dummyOtp ? dummyOtp : uuidv4(),\n expiresAt: expiryTime,\n };\n }\n\n async initiateForgotPassword(\n initiateForgotPasswordDto: InitiateForgotPasswordDto,\n ) {\n // Steps / Algorithm:\n // 1. Identify the user using the specified \"username\", if not found exit.\n // const user = await this.userRepository.findOne({\n // where: { username: initiateForgotPasswordDto.username, }\n // });\n const user = await this.resolveUser(\n initiateForgotPasswordDto.username,\n initiateForgotPasswordDto.email,\n );\n\n let isValidUser = true; // Instead of throwing exceptions we will simply return success message, this is to avoid user enumeration attacks.\n if (!user) {\n isValidUser = false;\n // throw new NotFoundException(ERROR_MESSAGES.INVALID_CREDENTIALS);\n }\n if (isValidUser && !user?.active) {\n isValidUser = false;\n // throw new UnauthorizedException(ERROR_MESSAGES.INVALID_CREDENTIALS);\n }\n\n // 2. Validate if user has used a provider which is \"local\", only then it makes sense for us to initiate the forgot password routine.\n if (isValidUser && user?.lastLoginProvider !== \"local\") {\n isValidUser = false;\n // throw new BadRequestException(ERROR_MESSAGES.INVALID_CREDENTIALS);\n }\n\n // 3. Generate a 6 digit validation token, we send this token to the user over their email & mobile number (controlled using configuration).\n // 4. Save this validation token in new fields on the user record.\n if (isValidUser) {\n const { token, expiresAt } = await this.generateForgotPasswordToken(user);\n user.verificationTokenOnForgotPassword = token;\n user.verificationTokenOnForgotPasswordExpiresAt = expiresAt;\n await this.userRepository.save(user);\n await this.notifyUserOnForgotPassword(user);\n }\n\n // 5. Return.\n return {\n status: \"success\",\n message: SUCCESS_MESSAGES.FORGOT_PASSWORD_TOKEN_SENT,\n error: \"\",\n errorCode: \"\",\n data: {\n user: {\n email: user?.email,\n // mobile: user.mobile,\n // username: user.username,\n },\n },\n };\n }\n\n private async notifyUserOnForgotPassword(user: User) {\n const companyLogo = await this.getCompanyLogo();\n\n const forgotPasswordSendVerificationTokenOn =\n this.settingService.getConfigValue<SolidCoreSetting>(\n \"forgotPasswordSendVerificationTokenOn\",\n );\n\n if (\n forgotPasswordSendVerificationTokenOn ==\n ForgotPasswordSendVerificationTokenOn.EMAIL\n ) {\n const mailService = this.mailServiceFactory.getMailService();\n mailService.sendEmailUsingTemplate(\n user.email,\n \"forgot-password\",\n {\n solidAppName:\n this.settingService.getConfigValue<SolidCoreSetting>(\"appTitle\"),\n solidAppWebsiteUrl:\n this.settingService.getConfigValue<SolidCoreSetting>(\n \"solidAppWebsiteUrl\",\n ),\n firstName: user.username,\n fullName: user.fullName,\n // TODO: Need to prefix this with the page url where the forgot password page will open up.\n passwordResetLink: `${this.settingService.getConfigValue<SolidCoreSetting>(\"frontendForgotPasswordPageUrl\")}?token=${user.verificationTokenOnForgotPassword}`,\n companyLogoUrl: companyLogo,\n },\n this.settingService.getConfigValue<SolidCoreSetting>(\n \"shouldQueueEmails\",\n ),\n null,\n null,\n \"user\",\n user.id,\n );\n }\n // Assuming all users do not have mobile as mandatory.\n if (\n forgotPasswordSendVerificationTokenOn ==\n ForgotPasswordSendVerificationTokenOn.MOBILE &&\n user.mobile\n ) {\n const smsService = this.smsFactory.getSmsService();\n smsService.sendSMSUsingTemplate(\n user.mobile,\n \"forgot-password\",\n {\n solidAppName:\n this.settingService.getConfigValue<SolidCoreSetting>(\"appTitle\"),\n otp: user.verificationTokenOnForgotPassword,\n verificationTokenOnForgotPassword:\n user.verificationTokenOnForgotPassword,\n firstName: user.username,\n companyLogoUrl: companyLogo,\n },\n this.settingService.getConfigValue<SolidCoreSetting>(\"shouldQueueSms\"),\n );\n }\n }\n\n async confirmForgotPassword(\n confirmForgotPasswordDto: ConfirmForgotPasswordDto,\n ) {\n return this.dataSource.transaction(async (m) => {\n // Resolve the user id first (by username/email), but DON'T check the token in JS.\n const user = await this.resolveUserByVerificationToken(\n confirmForgotPasswordDto.verificationToken,\n );\n if (!user) throw new UnauthorizedException(\"Invalid verification token\");\n if (user.lastLoginProvider !== \"local\")\n throw new UnauthorizedException(ERROR_MESSAGES.INVALID_CREDENTIALS);\n if (!user.active) throw new UnauthorizedException(\"User is inactive\");\n\n // 1) Atomically consume the token (only one request can succeed)\n const { affected } = await m\n .createQueryBuilder()\n .update(User)\n .set({\n forgotPasswordConfirmedAt: () => \"NOW()\",\n verificationTokenOnForgotPassword: () => \"NULL\",\n verificationTokenOnForgotPasswordExpiresAt: () => \"NULL\",\n })\n .where(\"id = :id\", { id: user.id })\n .andWhere(\"verificationTokenOnForgotPassword = :token\", {\n token: confirmForgotPasswordDto.verificationToken,\n })\n .andWhere(\"verificationTokenOnForgotPasswordExpiresAt > NOW()\")\n .execute();\n\n if (affected !== 1) {\n // Token invalid/expired/already used (or a parallel call already consumed it)\n throw new UnauthorizedException(ERROR_MESSAGES.INVALID_CREDENTIALS);\n }\n\n // 2) Now update the password & history (still inside the same transaction)\n const pwdHash = await this.hashingService.hash(\n confirmForgotPasswordDto.password,\n );\n const pwdScheme = this.hashingService.name(); // e.g. bcrypt\n const pwdSchemeVersion = this.hashingService.currentVersion(); // e.g. 1, 2, 3 ...\n\n // Check reuse with your existing method (ensure it looks at hashes).\n await m.getRepository(User).update(\n { id: user.id },\n {\n password: pwdHash,\n passwordScheme: pwdScheme,\n passwordSchemeVersion: pwdSchemeVersion,\n },\n );\n await this.notifyUserOnPasswordChanged(user);\n\n return {\n status: \"success\",\n message: SUCCESS_MESSAGES.FORGOT_PASSWORD_CONFIRMED,\n error: \"\",\n errorCode: \"\",\n data: {},\n };\n });\n }\n\n private async notifyUserOnPasswordChanged(user: User) {\n const companyLogo = await this.getCompanyLogo();\n const forgotPasswordSendVerificationTokenOn =\n this.settingService.getConfigValue<SolidCoreSetting>(\n \"forgotPasswordSendVerificationTokenOn\",\n );\n\n if (\n forgotPasswordSendVerificationTokenOn ==\n ForgotPasswordSendVerificationTokenOn.EMAIL\n ) {\n const mailService = this.mailServiceFactory.getMailService();\n mailService.sendEmailUsingTemplate(\n user.email,\n \"password-changed\",\n {\n solidAppName:\n this.settingService.getConfigValue<SolidCoreSetting>(\"appTitle\"),\n solidAppWebsiteUrl:\n this.settingService.getConfigValue<SolidCoreSetting>(\n \"solidAppWebsiteUrl\",\n ),\n email: user.email,\n firstName: user.username,\n fullName: user.fullName,\n // TODO: Need to prefix this with the page url where the forgot password page will open up.\n passwordResetLink: `${this.settingService.getConfigValue<SolidCoreSetting>(\"frontendForgotPasswordPageUrl\")}?token=${user.verificationTokenOnForgotPassword}`,\n companyLogoUrl: companyLogo,\n },\n this.settingService.getConfigValue<SolidCoreSetting>(\n \"shouldQueueEmails\",\n ),\n null,\n null,\n \"user\",\n user.id,\n );\n }\n // Assuming all users do not have mobile as mandatory.\n if (\n forgotPasswordSendVerificationTokenOn ==\n ForgotPasswordSendVerificationTokenOn.MOBILE &&\n user.mobile\n ) {\n const smsService = this.smsFactory.getSmsService();\n smsService.sendSMSUsingTemplate(\n user.mobile,\n \"forgot-password\",\n {\n solidAppName:\n this.settingService.getConfigValue<SolidCoreSetting>(\"appTitle\"),\n otp: user.verificationTokenOnForgotPassword,\n verificationTokenOnForgotPassword:\n user.verificationTokenOnForgotPassword,\n firstName: user.username,\n companyLogoUrl: companyLogo,\n },\n this.settingService.getConfigValue<SolidCoreSetting>(\"shouldQueueSms\"),\n );\n }\n }\n\n /**\n * @param deviceId optional stable per-device identifier. Supplied by callers\n * that own a device credential; otherwise a key is minted per login so that\n * clients with no device concept (the web UI) still get their own bucket\n * instead of sharing - and evicting - one.\n */\n async generateTokens(user: User, deviceId?: string) {\n const sessionId = this.shouldPreventConcurrentLogins()\n ? randomUUID()\n : undefined;\n if (sessionId) {\n await this.activeSessionStorage.setActiveSession(user.id, sessionId);\n } else {\n await this.activeSessionStorage.clearActiveSession(user.id);\n }\n\n // Mutually exclusive with sessionId by construction: per-device buckets\n // exist only when preventConcurrentLogins is off, sessionId only when it\n // is on.\n const deviceKey = this.refreshTokenIdsStorage.areConcurrentLoginsAllowed()\n ? deviceId ?? randomUUID()\n : undefined;\n\n const [accessToken, refreshToken] = await Promise.all([\n await this.generateAccessToken(user, sessionId, deviceKey),\n await this.generateRefreshToken(user, undefined, deviceKey),\n ]);\n\n return {\n accessToken,\n refreshToken,\n };\n }\n\n async generateAccessToken(user: User, sessionId?: string, deviceKey?: string) {\n // const userRoleNames = user.roles.map((role) => role.name).join(';')\n const userRoleNames = user.roles.map((role) => role.name);\n const resolvedSessionId = this.shouldPreventConcurrentLogins()\n ? sessionId ?? (await this.activeSessionStorage.getActiveSession(user.id))\n : undefined;\n\n const accessTokenTtl =\n this.settingService.getConfigValue<SolidCoreSetting>(\"accessTokenTtl\");\n const accessToken = await this.signToken<Partial<ActiveUserData>>(\n user.id,\n accessTokenTtl,\n {\n username: user.username,\n email: user.email,\n roles: userRoleNames,\n ...(resolvedSessionId ? { sessionId: resolvedSessionId } : {}),\n // Carried so that bearer-authenticated endpoints which need this\n // session's refresh token - generateSsoCode, me - can locate its\n // bucket. The refresh token is not available to them.\n ...(deviceKey ? { deviceKey } : {}),\n },\n );\n\n return accessToken;\n }\n\n async generateRefreshToken(\n user: User,\n previousRefreshToken?: string,\n deviceKey?: string,\n ) {\n const refreshTokenId = randomUUID();\n const refreshTokenTtl =\n this.settingService.getConfigValue<SolidCoreSetting>(\"refreshTokenTtl\");\n\n // Only per-device tokens carry an epoch - it is what makes bulk\n // invalidation possible without enumerating buckets. Single-slot tokens\n // are invalidated by deleting their one key.\n const epoch = deviceKey\n ? await this.refreshTokenIdsStorage.getEpoch(user.id)\n : undefined;\n\n const refreshToken = await this.signToken(user.id, refreshTokenTtl, {\n refreshTokenId,\n ...(deviceKey ? { deviceKey } : {}),\n ...(epoch !== undefined ? { epoch } : {}),\n });\n\n // store the refresh token id in the redis storage.\n await this.refreshTokenIdsStorage.insert(\n user.id,\n refreshToken,\n previousRefreshToken,\n deviceKey,\n );\n\n return refreshToken;\n }\n\n async refreshTokens(refreshTokenDto: RefreshTokenDto) {\n try {\n const secret =\n this.settingService.getConfigValue<SolidCoreSetting>(\"secret\");\n const audience =\n this.settingService.getConfigValue<SolidCoreSetting>(\"audience\");\n const issuer =\n this.settingService.getConfigValue<SolidCoreSetting>(\"issuer\");\n\n // deviceKey/epoch are absent on tokens issued before per-device sessions,\n // and on tokens issued while preventConcurrentLogins is on. That absence\n // is the signal the storage layer branches on - no request-body change\n // and no client change is needed to carry it.\n const { sub, deviceKey, epoch } = await this.jwtService.verifyAsync<\n Pick<ActiveUserData, \"sub\"> & {\n refreshTokenId: string;\n deviceKey?: string;\n epoch?: number;\n }\n >(refreshTokenDto.refreshToken, {\n secret,\n audience,\n issuer,\n });\n // const user = await this.userRepository.findOneByOrFail({ id: sub });\n const user = await this.userRepository.findOne({\n where: {\n id: sub,\n },\n relations: {\n roles: true,\n },\n });\n if (!user) {\n throw new UnauthorizedException(ERROR_MESSAGES.SESSION_INVALID);\n }\n\n // TODO: Replace the if else condition below with a call to validateAndRotate - Done\n // const isValid = await this.refreshTokenIdsStorage.validate(user.id, refreshTokenId);\n // if (isValid) {\n // // Refresh token rotation.\n // await this.refreshTokenIdsStorage.invalidate(user.id);\n // } else {\n // throw new Error('Refresh token is invalid');\n // }\n\n const rotated = await this.refreshTokenIdsStorage.validateAndRotate(\n user,\n refreshTokenDto.refreshToken,\n { deviceKey, epoch },\n );\n\n await this.userActivityHistoryService.logEvent(\"tokenRefreshed\", user);\n\n return {\n // The rotated key, not the incoming one: a session migrating out of the\n // pre-deploy single slot is assigned a bucket here, and the new access\n // token has to name the same one.\n accessToken: await this.generateAccessToken(\n user,\n undefined,\n rotated.deviceKey,\n ),\n refreshToken: rotated.refreshToken,\n };\n } catch (err: any) {\n if (err instanceof InvalidatedRefreshTokenError) {\n // Take action: notify user that his refresh token might have been stolen?\n throw new UnauthorizedException(ERROR_MESSAGES.ACCESS_DENIED);\n }\n\n throw new UnauthorizedException(ERROR_MESSAGES.SESSION_EXPIRED);\n }\n }\n\n private async signToken<T>(userId: number, expiresIn: number, payload?: T) {\n const audience =\n this.settingService.getConfigValue<SolidCoreSetting>(\"audience\");\n const issuer =\n this.settingService.getConfigValue<SolidCoreSetting>(\"issuer\");\n const secret =\n this.settingService.getConfigValue<SolidCoreSetting>(\"secret\");\n\n return await this.jwtService.signAsync(\n {\n sub: userId,\n ...payload,\n },\n {\n audience,\n issuer,\n secret,\n expiresIn,\n },\n );\n }\n\n // PROVIDER SPECIFIC CODE\n async validateUserUsingGoogle(user: User) {\n try {\n // Make API call to Google OAuth service to fetch user profile\n const response = await this.httpService.axiosRef.get(\n `https://www.googleapis.com/oauth2/v1/userinfo?alt=json&access_token=${user.googleAccessToken}`,\n );\n const userProfile = response.data;\n\n // Ensure the fetched profile email & provider Id match the ones we have stored in the database earlier.\n if (\n userProfile.email === user.email &&\n userProfile.id === user.googleId\n ) {\n // TODO: remove the access code both from the database.\n return userProfile;\n } else {\n throw new UnauthorizedException(ERROR_MESSAGES.INVALID_USER_PROFILE);\n }\n } catch (error: any) {\n throw new UnauthorizedException(\n ERROR_MESSAGES.GOOGLE_OAUTH_PROFILE_FETCH_FAILED,\n );\n }\n }\n\n async signInUsingGoogle(accessCode: string) {\n const user = await this.userRepository.findOne({\n where: {\n accessCode: accessCode,\n },\n relations: {\n roles: true,\n },\n });\n\n if (!user) {\n throw new UnauthorizedException(ERROR_MESSAGES.USER_NOT_FOUND);\n }\n this.checkAccountBlocked(user);\n\n try {\n await this.validateUserUsingGoogle(user);\n } catch (e) {\n await this.incrementFailedAttempts(user);\n throw e;\n }\n\n await this.resetFailedAttempts(user);\n const tokens = await this.generateTokens(user);\n return {\n user: {\n email: user.email,\n mobile: user.mobile,\n username: user.username,\n // forcePasswordChange: user.forcePasswordChange,\n id: user.id,\n roles: user.roles.map((role) => role.name),\n },\n ...tokens,\n };\n }\n\n async validateUserUsingFacebook(user: User) {\n if (!user.facebookAccessToken || !user.facebookId) {\n throw new UnauthorizedException(ERROR_MESSAGES.USER_NOT_FOUND);\n }\n\n try {\n const response = await this.httpService.axiosRef.get(\n `https://graph.facebook.com/me`,\n {\n params: { fields: \"id,name,email\" },\n headers: {\n Authorization: `Bearer ${user.facebookAccessToken}`,\n },\n },\n );\n const userProfile = response.data;\n\n if (\n userProfile.id === user.facebookId &&\n (!user.email || !userProfile.email || userProfile.email === user.email)\n ) {\n return userProfile;\n } else {\n throw new UnauthorizedException(ERROR_MESSAGES.INVALID_USER_PROFILE);\n }\n } catch (error: any) {\n if (error instanceof UnauthorizedException) {\n throw error;\n }\n throw new UnauthorizedException(ERROR_MESSAGES.USER_NOT_FOUND);\n }\n }\n\n async signInUsingFacebook(accessCode: string) {\n const user = await this.userRepository.findOne({\n where: {\n accessCode: accessCode,\n },\n relations: {\n roles: true,\n },\n });\n\n if (!user) {\n throw new UnauthorizedException(ERROR_MESSAGES.USER_NOT_FOUND);\n }\n this.checkAccountBlocked(user);\n\n try {\n await this.validateUserUsingFacebook(user);\n } catch (e) {\n await this.incrementFailedAttempts(user);\n throw e;\n }\n\n await this.resetFailedAttempts(user);\n const tokens = await this.generateTokens(user);\n return {\n user: {\n email: user.email,\n mobile: user.mobile,\n username: user.username,\n id: user.id,\n roles: user.roles.map((role) => role.name),\n },\n ...tokens,\n };\n }\n\n async validateUserUsingMicrosoft(user: User) {\n try {\n const response = await this.httpService.axiosRef.get(\n `https://graph.microsoft.com/v1.0/me`,\n {\n headers: {\n Authorization: `Bearer ${user.microsoftAccessToken}`,\n },\n },\n );\n const userProfile = response.data;\n const profileEmail = userProfile.mail || userProfile.userPrincipalName;\n\n if (\n userProfile.id === user.microsoftId &&\n (!user.email || profileEmail === user.email)\n ) {\n return userProfile;\n } else {\n throw new UnauthorizedException(ERROR_MESSAGES.INVALID_USER_PROFILE);\n }\n } catch (error: any) {\n throw new UnauthorizedException(\"Microsoft OAuth profile fetch failed\");\n }\n }\n\n async signInUsingMicrosoft(accessCode: string) {\n const user = await this.userRepository.findOne({\n where: {\n accessCode: accessCode,\n },\n relations: {\n roles: true,\n },\n });\n\n if (!user) {\n throw new UnauthorizedException(ERROR_MESSAGES.USER_NOT_FOUND);\n }\n this.checkAccountBlocked(user);\n\n try {\n await this.validateUserUsingMicrosoft(user);\n } catch (e) {\n await this.incrementFailedAttempts(user);\n throw e;\n }\n\n await this.resetFailedAttempts(user);\n const tokens = await this.generateTokens(user);\n return {\n user: {\n email: user.email,\n mobile: user.mobile,\n username: user.username,\n id: user.id,\n roles: user.roles.map((role) => role.name),\n },\n ...tokens,\n };\n }\n\n async validateUserUsingMicrosoftActiveDirectory(user: User) {\n if (\n !user.microsoftActiveDirectoryAccessToken ||\n !user.microsoftActiveDirectoryId\n ) {\n throw new UnauthorizedException(ERROR_MESSAGES.USER_NOT_FOUND);\n }\n\n try {\n const response = await this.httpService.axiosRef.get(\n `https://graph.microsoft.com/v1.0/me?$select=id,displayName,mail,userPrincipalName`,\n {\n headers: {\n Authorization: `Bearer ${user.microsoftActiveDirectoryAccessToken}`,\n },\n },\n );\n const userProfile = response.data;\n const profileEmail = (userProfile.mail || userProfile.userPrincipalName)\n ?.trim()\n .toLowerCase();\n const userEmail = user.email?.trim().toLowerCase();\n\n if (\n userProfile.id === user.microsoftActiveDirectoryId &&\n (!userEmail || profileEmail === userEmail)\n ) {\n return userProfile;\n } else {\n throw new UnauthorizedException(ERROR_MESSAGES.INVALID_USER_PROFILE);\n }\n } catch (error: any) {\n if (error instanceof UnauthorizedException) {\n throw error;\n }\n\n throw new UnauthorizedException(\n ERROR_MESSAGES.MICROSOFT_ACTIVE_DIRECTORY_OAUTH_PROFILE_FETCH_FAILED,\n );\n }\n }\n\n async signInUsingMicrosoftActiveDirectory(accessCode: string) {\n const user = await this.userRepository.findOne({\n where: {\n accessCode: accessCode,\n },\n relations: {\n roles: true,\n },\n });\n\n if (!user) {\n throw new UnauthorizedException(ERROR_MESSAGES.USER_NOT_FOUND);\n }\n this.checkAccountBlocked(user);\n\n try {\n await this.validateUserUsingMicrosoftActiveDirectory(user);\n } catch (e) {\n await this.incrementFailedAttempts(user);\n throw e;\n }\n\n await this.resetFailedAttempts(user);\n const tokens = await this.generateTokens(user);\n return {\n user: {\n email: user.email,\n mobile: user.mobile,\n username: user.username,\n id: user.id,\n roles: user.roles.map((role) => role.name),\n },\n ...tokens,\n };\n }\n\n async signInUsingApple(accessCode: string) {\n const user = await this.userRepository.findOne({\n where: {\n accessCode: accessCode,\n },\n relations: {\n roles: true,\n },\n });\n\n if (!user) {\n throw new UnauthorizedException(ERROR_MESSAGES.USER_NOT_FOUND);\n }\n this.checkAccountBlocked(user);\n\n // Apple OAuth token validation is typically handled by the strategy itself\n // as it involves verifying the JWT idToken.\n // If we want to re-verify here, we'd need to verify the appleAccessToken or idToken.\n // For now, we follow the pattern of trust in the accessCode generated after successful strategy validation.\n\n await this.resetFailedAttempts(user);\n const tokens = await this.generateTokens(user);\n return {\n user: {\n email: user.email,\n mobile: user.mobile,\n username: user.username,\n id: user.id,\n roles: user.roles.map((role) => role.name),\n },\n ...tokens,\n };\n }\n\n private async isPasswordlessRegistrationEnabled() {\n // return this.settingService.getConfigValue<SolidCoreSetting>('passwordlessRegistration');\n return this.settingService.getConfigValue<SolidCoreSetting>(\n \"passwordLessAuth\",\n );\n }\n\n private shouldPreventConcurrentLogins(): boolean {\n return (\n this.settingService.getConfigValue<SolidCoreSetting>(\n \"preventConcurrentLogins\",\n ) === true\n );\n }\n\n private checkAccountBlocked(user: User): void {\n const maxFailedAttempts =\n this.settingService.getConfigValue<SolidCoreSetting>(\n \"maxFailedLoginAttempts\",\n ) as number;\n if (\n maxFailedAttempts > 0 &&\n user.failedLoginAttempts >= maxFailedAttempts\n ) {\n throw new ForbiddenException(ERROR_MESSAGES.ACCOUNT_BLOCKED);\n }\n }\n\n private async incrementFailedAttempts(user: User): Promise<void> {\n const nextFailedAttempts = (user.failedLoginAttempts ?? 0) + 1;\n user.failedLoginAttempts = nextFailedAttempts;\n await this.userRepository.update(user.id, {\n failedLoginAttempts: nextFailedAttempts,\n });\n }\n\n private async resetFailedAttempts(user: User): Promise<void> {\n if (user.failedLoginAttempts === 0) return;\n user.failedLoginAttempts = 0;\n await this.userRepository.update(user.id, { failedLoginAttempts: 0 });\n }\n\n //FIXME - Pending implementation\n // async logout() {\n // // const user = this.request.user; //TODO: // Access the user from the execution context\n\n // // Invalidate the refresh token\n // // await this.refreshTokenIdsStorage.invalidate(user.id);\n // }\n async logout(refreshToken: string, allDevices = false) {\n try {\n const payload = await this.verifyRefreshTokenForLogout(refreshToken);\n\n // Nothing verifiable to act on: forged, malformed, or signed with another\n // secret. Acting on an unauthenticated `sub` is exactly the hole this\n // closes - the route is @Public(), so a decoded-but-unverified token let\n // anyone log out an arbitrary user. Report success either way: logout\n // must be safe to call blindly from a client error path, and a 401/200\n // split here would leak whether a token string is genuine (RFC 7009 §2.2\n // takes the same position for revocation endpoints).\n if (!payload?.sub) {\n this.logger.warn(\"logout called with an unverifiable refresh token\");\n return { message: SUCCESS_MESSAGES.LOGOUT_SUCCESS };\n }\n\n const userId = payload.sub;\n\n if (allDevices) {\n // Deliberately not gated on session ownership: \"log out everywhere\"\n // treats any verifiable refresh token as sufficient authority, which is\n // what invalidateAll already accepts.\n await this.refreshTokenIdsStorage.invalidateAll(userId);\n await this.accessTokenDenylist.revokeAllForUser(userId);\n } else if (await this.ownsLiveSession(userId, payload, refreshToken)) {\n // Scoped to the bucket this token belongs to, so signing out on one\n // device leaves the others alive. A token with no deviceKey names the\n // single slot, which is the same key as before.\n await this.refreshTokenIdsStorage.invalidate(userId, payload.deviceKey);\n await this.accessTokenDenylist.revokeSession(\n userId,\n await this.resolveRevocationKey(userId, payload),\n );\n await this.activeSessionStorage.clearActiveSession(userId);\n } else {\n // The token names a session that is already gone - superseded by a\n // newer login into the same bucket. Acting on it would destroy the\n // session that replaced it. Nothing to do, but log it: the failure is\n // otherwise invisible, and a cluster of these means clients are losing\n // token state and their logouts are no-ops.\n this.logger.warn(\n `logout: refresh token does not match the live session for user ${userId}; nothing invalidated`,\n );\n }\n\n const user = await this.userRepository.findOne({\n where: {\n id: userId,\n },\n });\n // Log logout event\n if (user) {\n await this.userActivityHistoryService.logEvent(\"logout\", user);\n }\n\n return { message: SUCCESS_MESSAGES.LOGOUT_SUCCESS };\n } catch (err: any) {\n // JWT problems no longer reach here - verifyRefreshTokenForLogout\n // swallows them - so this is left for genuine infrastructure failures\n // (cache or database unavailable), where a 500 is the correct answer.\n throw err instanceof UnauthorizedException ||\n err instanceof InternalServerErrorException\n ? err\n : new InternalServerErrorException(ERROR_MESSAGES.LOGOUT_FAILED);\n }\n }\n\n /**\n * Whether this refresh token belongs to the session that currently occupies\n * its bucket.\n *\n * A per-device bucket holds exactly one session - deviceKey is a fresh\n * randomUUID per login - so a token carrying one is that session by\n * construction and needs no further proof. Only the bare `user-<id>` bucket\n * is shared across logins (preventConcurrentLogins on, or a pre-migration\n * token), and that is the sole case where a stale token can name a session\n * that has since been replaced. Without this, a laptop whose session was\n * superseded by a phone login would, on logging out, destroy the phone's\n * session instead of its own.\n *\n * Matches current OR previous, and deliberately does not consult\n * isWithinGraceWindow: that window governs whether a rotated-out token may\n * still be exchanged, whereas the question here is only which session the\n * token belongs to - which stays true however long ago it rotated.\n *\n * Missing state means it owns nothing. Safe, because the refresh state and\n * active-session entry share one cache: if the state is gone the session\n * entry is too, so the actions being skipped were no-ops anyway.\n */\n private async ownsLiveSession(\n userId: number,\n payload: { deviceKey?: string },\n refreshToken: string,\n ): Promise<boolean> {\n if (payload.deviceKey) {\n return true;\n }\n\n const state =\n await this.refreshTokenIdsStorage.getCurrentRefreshTokenState(userId);\n return (\n state?.currentRefreshToken === refreshToken ||\n (!!state?.previousRefreshToken &&\n state.previousRefreshToken === refreshToken)\n );\n }\n\n /**\n * The key a session's access tokens are denylisted under. Mirrors how the\n * access token itself is stamped: deviceKey while concurrent logins are\n * allowed, sessionId while they are not - and in the latter case only one\n * session exists, so the recorded active session IS this session's id.\n *\n * Must be read before clearActiveSession, which deletes the value it reads.\n */\n private async resolveRevocationKey(\n userId: number,\n payload: { deviceKey?: string },\n ): Promise<string | undefined> {\n return (\n payload.deviceKey ??\n (await this.activeSessionStorage.getActiveSession(userId))\n );\n }\n\n /**\n * Public seam for consuming projects that need a logout of their own shape -\n * for instance revoking the access token while deliberately leaving the\n * refresh token valid.\n *\n * Verifies the refresh token (signature/audience/issuer enforced, expiry\n * tolerated), confirms it owns the live session, and returns the key its\n * access tokens are denylisted under.\n *\n * null - unverifiable: forged, malformed, or an access\n * token presented here\n * revocationKey undefined - verified, but nothing safe to revoke: either a\n * superseded session, or no session key could be\n * resolved. userId is still returned so the caller\n * can log the event or call revokeAllForUser.\n *\n * logout() uses this same method, so the seam cannot silently rot.\n */\n async resolveSessionRevocationKey(\n refreshToken: string,\n ): Promise<{ userId: number; revocationKey?: string } | null> {\n const payload = await this.verifyRefreshTokenForLogout(refreshToken);\n if (!payload?.sub) {\n return null;\n }\n\n const userId = payload.sub;\n if (!(await this.ownsLiveSession(userId, payload, refreshToken))) {\n return { userId };\n }\n\n return {\n userId,\n revocationKey: await this.resolveRevocationKey(userId, payload),\n };\n }\n\n private async verifyRefreshTokenForLogout(\n refreshToken: string,\n ): Promise<{ sub: number; deviceKey?: string } | null> {\n try {\n const payload = await this.jwtService.verifyAsync(refreshToken, {\n secret: this.settingService.getConfigValue<SolidCoreSetting>(\"secret\"),\n audience:\n this.settingService.getConfigValue<SolidCoreSetting>(\"audience\"),\n issuer: this.settingService.getConfigValue<SolidCoreSetting>(\"issuer\"),\n // Signature, audience and issuer are still enforced; only `exp` is\n // tolerated. An expired session must still be able to log out - the\n // previous jwtService.decode() allowed that, and a plain verifyAsync\n // would throw TokenExpiredError, which the catch above would turn into\n // a 500 on an ordinary sign-out.\n ignoreExpiration: true,\n });\n\n // Access and refresh tokens share secret, audience and issuer, so only\n // this claim distinguishes them. Reject an access token presented here.\n return payload?.refreshTokenId ? payload : null;\n } catch {\n return null; // bad signature or malformed\n }\n }\n\n async activateUser(userId: number) {\n const user = await this.userService.findOne(userId, {});\n if (!user) {\n throw new NotFoundException(ERROR_MESSAGES.USER_NOT_FOUND);\n }\n user.active = true;\n await this.userRepository.save(user);\n }\n\n async me(activeUser: ActiveUserData) {\n const user = await this.userRepository.findOne({\n where: {\n id: activeUser.sub,\n },\n relations: {\n roles: true,\n },\n });\n\n // const tokens = await this.generateTokens(user);\n\n // Get the refresh token for a user from refresh token storage. The bucket\n // is named by the access token's own deviceKey claim; absent for\n // single-slot sessions, which resolves to the same key as before.\n const refreshTokenState =\n await this.refreshTokenIdsStorage.getCurrentRefreshTokenState(\n user.id,\n activeUser.deviceKey,\n );\n\n const response = {\n user: {\n email: user.email,\n mobile: user.mobile,\n username: user.username,\n // forcePasswordChange: user.forcePasswordChange,\n id: user.id,\n roles: user.roles.map((role) => role.name),\n },\n // Null-guarded because the cache entry now carries a TTL: once it\n // expires - or after a logout followed by a call with a still-valid\n // access token - there is no state to read. Matches the existing\n // handling in generateSsoCode.\n refreshToken: refreshTokenState?.currentRefreshToken ?? null,\n // ...tokens\n };\n return response;\n }\n\n async generateSsoCode(\n activeUser: ActiveUserData,\n rawAccessToken: string,\n ): Promise<{ ssoCode: string }> {\n const refreshTokenState =\n await this.refreshTokenIdsStorage.getCurrentRefreshTokenState(\n activeUser.sub,\n activeUser.deviceKey,\n );\n if (!refreshTokenState?.currentRefreshToken) {\n throw new UnauthorizedException(\"No active session found\");\n }\n const ssoCode = await this.ssoCodeStorage.generateCode(\n activeUser.sub,\n rawAccessToken,\n refreshTokenState.currentRefreshToken,\n );\n return { ssoCode };\n }\n\n async exchangeSsoCode(code: string) {\n const { userId, accessToken, refreshToken } =\n await this.ssoCodeStorage.consumeCode(code);\n const user = await this.userRepository.findOne({\n where: { id: userId },\n relations: { roles: true },\n });\n if (!user) {\n throw new UnauthorizedException(\"User not found\");\n }\n return { accessToken, refreshToken, user: this.buildUserPayload(user) };\n }\n}\n\nfunction parseUniqueConstraintError(detail: string): string {\n const match = detail.match(/Key \\(([^)]+)\\)=\\(([^)]+)\\) already exists\\./);\n if (match) {\n const field = match[1];\n const value = match[2];\n const fieldMap: Record<string, string> = {\n username: \"username\",\n email: \"email address\",\n mobile: \"mobile number\",\n full_name_user_key: \"full name\",\n };\n const friendlyField = fieldMap[field] || field;\n return `A user with ${friendlyField} \"${value}\" already exists.`;\n }\n return detail;\n}\n"]}
1
+ {"version":3,"file":"authentication.service.js","sourceRoot":"","sources":["../../src/services/authentication.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { HttpService } from \"@nestjs/axios\";\nimport type { SolidCoreSetting } from \"src/services/settings/default-settings-provider.service\";\nimport {\n BadRequestException,\n ConflictException,\n ForbiddenException,\n Injectable,\n InternalServerErrorException,\n Logger,\n NotFoundException,\n UnauthorizedException,\n} from \"@nestjs/common\";\nimport { EventEmitter2 } from \"@nestjs/event-emitter\";\nimport { JwtService } from \"@nestjs/jwt\";\nimport { InjectDataSource } from \"@nestjs/typeorm\";\nimport { isEmpty, isNotEmpty } from \"class-validator\";\nimport { randomInt, randomUUID } from \"crypto\";\nimport { ERROR_MESSAGES } from \"src/constants/error-messages\";\nimport { SUCCESS_MESSAGES } from \"src/constants/success-messages\";\nimport { CreateUserDto } from \"src/dtos/create-user.dto\";\nimport { MailFactory } from \"src/factories/mail.factory\";\nimport { UserRepository } from \"src/repository/user.repository\";\nimport { DataSource, DeepPartial, FindOptionsWhere, Repository } from \"typeorm\";\nimport { v4 as uuidv4 } from \"uuid\";\nimport {\n ForgotPasswordSendVerificationTokenOn,\n PasswordlessLoginValidateWhatSources,\n PasswordlessRegistrationValidateWhatSources,\n} from \"../constants\";\nimport { ChangePasswordDto } from \"../dtos/change-password.dto\";\nimport { ConfirmForgotPasswordDto } from \"../dtos/confirm-forgot-password.dto\";\nimport { InitiateForgotPasswordDto } from \"../dtos/initiate-forgot-password.dto\";\nimport { OTPConfirmOTPDto } from \"../dtos/otp-confirm-otp.dto\";\nimport { OTPSignInDto } from \"../dtos/otp-sign-in.dto\";\nimport { OTPSignUpDto } from \"../dtos/otp-sign-up.dto\";\nimport { RefreshTokenDto } from \"../dtos/refresh-token.dto\";\nimport { SignInDto } from \"../dtos/sign-in.dto\";\nimport { SignUpDto } from \"../dtos/sign-up.dto\";\nimport { SignupIntent } from \"../enums/signup-intent.enum\";\nimport { User } from \"../entities/user.entity\";\nimport { EventDetails, EventType } from \"../interfaces\";\nimport { ActiveUserData } from \"../interfaces/active-user-data.interface\";\nimport { ActiveSessionStorageService } from \"./active-session-storage.service\";\nimport { AccessTokenDenylistService } from \"./access-token-denylist.service\";\nimport { HashingService } from \"./hashing.service\";\nimport {\n InvalidatedRefreshTokenError,\n RefreshTokenIdsStorageService,\n} from \"./refresh-token-ids-storage.service\";\nimport { SsoCodeStorageService } from \"./sso-code-storage.service\";\nimport { RoleMetadataService } from \"./role-metadata.service\";\nimport { SettingService } from \"./setting.service\";\nimport { UserActivityHistoryService } from \"./user-activity-history.service\";\nimport { MetadataValidationService } from \"./metadata-validation.service\";\nimport { UserService } from \"./user.service\";\nimport { SmsFactory } from \"src/factories/sms.factory\";\nimport { WhatsAppFactory } from \"src/factories/whatsapp.factory\";\nimport { SolidRegistry } from \"src/helpers/solid-registry\";\n\nenum LoginProvider {\n LOCAL = \"local\",\n GOOGLE = \"google\",\n OTP = \"otp\",\n}\n\ninterface otp {\n token: string;\n expiresAt: Date;\n}\n\n/** Where a signup's role names come from. */\nenum RolesSource {\n /**\n * Ask nobody; returning [] lets performSignUp apply the configured `defaultRole`.\n *\n * No intent maps here today - it is kept for paths that deliberately bypass the\n * provider. OAuth is the live example: its DTO can never carry a discriminator, so\n * it takes `defaultRole` outright (currently inline in UserService).\n */\n Default,\n /**\n * `provider.roles(dto)` - and nothing else. Yields [] when no provider is registered\n * or when the provider declines to name any, which falls through to `defaultRole`.\n */\n Provider,\n /** The caller's own `dto.roles`. */\n Caller,\n}\n\n/**\n * The single place that decides, per intent, which entity a signup builds and where\n * its roles come from.\n *\n * Where an extension user provider is registered it is the authority on that app's user\n * roles, so every provider-backed intent asks it. `defaultRole` is the *fallback* for\n * when it names none - or when there is no provider at all - not the rule.\n *\n * SelfRegistration and ExtensionModel resolve identically today. They stay separate\n * intents because only SelfRegistration is gated on `allowPublicRegistration`, and\n * because \"an anonymous visitor signing themselves up\" and \"an admin creating a user\n * from the model's own form\" are different things that may yet need to diverge.\n *\n * `useProvider` is computable from `rolesSource` today (`Caller` implies false), but the\n * two answer different questions - \"which entity?\" and \"which roles?\" - that merely\n * coincide across these intents. Keep both, and change behaviour here, not at a call site.\n */\nconst SIGNUP_POLICY: Record<\n SignupIntent,\n { useProvider: boolean; rolesSource: RolesSource }\n> = {\n [SignupIntent.SelfRegistration]: {\n useProvider: true,\n rolesSource: RolesSource.Provider,\n },\n [SignupIntent.ExtensionModel]: {\n useProvider: true,\n rolesSource: RolesSource.Provider,\n },\n [SignupIntent.CoreUser]: {\n useProvider: false,\n rolesSource: RolesSource.Caller,\n },\n};\n\n@Injectable()\nexport class AuthenticationService {\n private readonly logger = new Logger(AuthenticationService.name);\n // private readonly mailService: IMail;\n constructor(\n private readonly userService: UserService,\n // @InjectRepository(User) private readonly userRepository: Repository<User>,\n private readonly userRepository: UserRepository,\n private readonly hashingService: HashingService,\n private readonly jwtService: JwtService,\n private readonly activeSessionStorage: ActiveSessionStorageService,\n private readonly accessTokenDenylist: AccessTokenDenylistService,\n private readonly refreshTokenIdsStorage: RefreshTokenIdsStorageService,\n private readonly httpService: HttpService,\n // private readonly mailService: SMTPEMailService,\n private readonly mailServiceFactory: MailFactory,\n // private readonly smsService: Msg91OTPService,\n private readonly smsFactory: SmsFactory,\n private readonly whatsAppFactory: WhatsAppFactory,\n private readonly eventEmitter: EventEmitter2,\n private readonly settingService: SettingService,\n private readonly roleMetadataService: RoleMetadataService,\n private readonly userActivityHistoryService: UserActivityHistoryService,\n private readonly ssoCodeStorage: SsoCodeStorageService,\n private readonly metadataValidationService: MetadataValidationService,\n\n @InjectDataSource()\n private readonly dataSource: DataSource,\n private readonly solidRegistry: SolidRegistry,\n ) {\n // this.mailService = this.mailServiceFactory.getMailService();\n }\n\n private async getCompanyLogo(): Promise<string> {\n return this.settingService.getConfigValue<SolidCoreSetting>(\"companylogo\");\n }\n\n async resolveUser(username: string, email: string) {\n return await this.userRepository.findOne({\n where: [{ username: username }, { email: email }],\n relations: {\n roles: true,\n },\n });\n }\n\n private async resolveUserForPasswordSignIn(username: string, email: string) {\n const normalizedEmail = email?.trim().toLowerCase();\n const query = (await this.userRepository\n .createSecurityRuleAwareQueryBuilder(\"u\"))\n .leftJoinAndSelect(\"u.roles\", \"roles\");\n\n if (username) {\n query.where(\"u.username = :username\", { username });\n }\n if (normalizedEmail) {\n if (username) {\n query.orWhere(\"LOWER(u.email) = :email\", { email: normalizedEmail });\n } else {\n query.where(\"LOWER(u.email) = :email\", { email: normalizedEmail });\n }\n }\n\n return await query.getOne();\n }\n\n async updatePasswordDetails(user: User, newPassword: string) {\n user.password = await this.hashingService.hash(newPassword);\n user.passwordScheme = this.hashingService.name();\n user.passwordSchemeVersion = this.hashingService.currentVersion();\n user.rehashedAt = new Date();\n await this.userRepository.update(user.id, {\n password: user.password,\n passwordScheme: user.passwordScheme,\n passwordSchemeVersion: user.passwordSchemeVersion,\n rehashedAt: user.rehashedAt,\n });\n return user;\n }\n\n async resolveUserByVerificationToken(token: string) {\n return await this.userRepository.findOne({\n where: { verificationTokenOnForgotPassword: token },\n relations: { roles: true },\n });\n }\n\n private async validateUserForPasswordLogin(\n user: User,\n password: string,\n ): Promise<void> {\n if (!user.active) {\n throw new UnauthorizedException(ERROR_MESSAGES.USER_NOT_ACTIVE);\n }\n this.checkAccountBlocked(user);\n const isEqual = await this.hashingService.compare(\n password,\n user.password,\n user.passwordSchemeVersion,\n );\n if (!isEqual) {\n await this.incrementFailedAttempts(user);\n throw new UnauthorizedException(ERROR_MESSAGES.INVALID_CREDENTIALS);\n }\n }\n\n private async rehashPasswordIfRequired(\n user: User,\n password: string,\n ): Promise<void> {\n if (\n this.hashingService.needsRehash(user.password, user.passwordSchemeVersion)\n ) {\n await this.updatePasswordDetails(user, password);\n }\n }\n\n async signUp(\n signUpDto: SignUpDto & Record<string, any>,\n activeUser: ActiveUserData = null,\n intent: SignupIntent = SignupIntent.SelfRegistration,\n ): Promise<User> {\n const { useProvider, rolesSource } = SIGNUP_POLICY[intent];\n\n if (intent === SignupIntent.SelfRegistration) {\n this.assertPublicRegistrationEnabled();\n }\n\n const { entity, repo } = await this.userService.buildSignupTarget(\n signUpDto,\n useProvider,\n );\n const roles = this.resolveSignupRoles(signUpDto, rolesSource);\n\n return this.performSignUp({ ...signUpDto, roles }, entity, repo);\n }\n\n private resolveSignupRoles(\n dto: Record<string, any>,\n source: RolesSource,\n ): string[] {\n // Only `Caller` reads dto.roles. Anywhere else, roles in the body are ignored -\n // which is what keeps an anonymous caller from naming their own on a @Public()\n // endpoint - so say so rather than dropping them silently.\n if (source !== RolesSource.Caller && dto.roles?.length) {\n this.logger.warn(\n `Ignoring caller-supplied roles for \"${dto.username}\": roles on this path come from ` +\n (source === RolesSource.Provider\n ? \"the extension user provider\"\n : \"the configured defaultRole\"),\n );\n }\n\n switch (source) {\n case RolesSource.Provider:\n // Sole authority. Reading dto.roles as a preference or fallback would skip\n // roles(), which is where a provider validates its discriminator, and\n // CreateUserDto types roles as UpdateRoleMetadataDto[] where performSignUp\n // expects role-name strings. [] here falls through to `defaultRole`.\n return (\n this.solidRegistry\n .getExtensionUserCreationProvider()\n ?.roles(dto as any) ?? []\n );\n\n case RolesSource.Caller:\n return dto.roles ?? [];\n\n case RolesSource.Default:\n return [];\n }\n }\n\n private async performSignUp<T extends User>(\n signUpDto: SignUpDto,\n entity: T,\n repo: Repository<T>,\n ): Promise<T> {\n try {\n await this.assertUniqueSignupIdentifiers(signUpDto);\n await this.metadataValidationService.validateCreateDto(\"user\", signUpDto);\n\n const onForcePasswordChange =\n this.settingService.getConfigValue<SolidCoreSetting>(\n \"forceChangePasswordOnFirstLogin\",\n );\n const activateUserOnRegistration =\n this.settingService.getConfigValue<SolidCoreSetting>(\n \"activateUserOnRegistration\",\n );\n const defaultRole =\n this.settingService.getConfigValue<SolidCoreSetting>(\"defaultRole\");\n\n var { user, pwd, autoGeneratedPwd } = await this.populateForSignup<T>(\n entity,\n signUpDto,\n activateUserOnRegistration,\n onForcePasswordChange,\n );\n // An explicitly supplied value wins over whatever the entity carries. The\n // entity's own flag cannot be trusted as a signal: User initialises it to\n // false, so \"the provider set it\" is indistinguishable from \"nobody set it\".\n const privateDto = signUpDto as { isAllowedToGenerateApiKeys?: boolean };\n if (privateDto.isAllowedToGenerateApiKeys !== undefined) {\n user.isAllowedToGenerateApiKeys = privateDto.isAllowedToGenerateApiKeys;\n }\n const savedUser = await repo.save(user);\n const userRoles = signUpDto.roles ?? [];\n if (\n (signUpDto.roles?.length ?? 0) === 0 &&\n signUpDto.username !== \"sa\" &&\n defaultRole\n ) {\n userRoles.push(defaultRole);\n }\n await this.handlePostSignup(savedUser, userRoles, pwd, autoGeneratedPwd);\n await this.handlePasswordlessSignupOtp(savedUser, signUpDto, autoGeneratedPwd, repo);\n this.triggerRegistrationEvent(savedUser);\n\n return savedUser;\n } catch (err: any) {\n const pgUniqueViolationErrorCode = \"23505\";\n if (err.code === pgUniqueViolationErrorCode) {\n throw new ConflictException(\n parseUniqueConstraintError(\n err.detail || ERROR_MESSAGES.UNIQUE_CONSTRAINT_VIOLATION,\n ),\n );\n }\n throw err;\n }\n }\n\n /**\n * Always queries the base `User` repository, never the caller's repository.\n *\n * `User` is a `@TableInheritance` root, so a child repository scopes every query\n * to its own discriminator. Checking through one would only compare against users\n * of the same subtype, and `email`/`mobile` carry non-unique `@Index()` - there is\n * no database constraint behind them to catch what the query misses. A duplicate\n * against a base `User` or a sibling subtype would be silently accepted.\n */\n private async assertUniqueSignupIdentifiers(\n signUpDto: SignUpDto,\n ): Promise<void> {\n const username = signUpDto.username?.trim();\n const email = signUpDto.email?.trim();\n const mobile = signUpDto.mobile?.trim();\n\n const where: FindOptionsWhere<User>[] = [];\n\n if (username) {\n where.push({ username });\n }\n\n if (email) {\n where.push({ email });\n }\n\n if (mobile) {\n where.push({ mobile });\n }\n\n if (where.length === 0) {\n return;\n }\n\n const existingUser = await this.userRepository.findOne({ where });\n\n if (!existingUser) {\n return;\n }\n\n if (email && existingUser.email === email) {\n throw new ConflictException(\n `A user with email address \"${email}\" already exists.`,\n );\n }\n\n if (mobile && existingUser.mobile === mobile) {\n throw new ConflictException(\n `A user with mobile number \"${mobile}\" already exists.`,\n );\n }\n\n if (username && existingUser.username === username) {\n throw new ConflictException(\n `A user with username \"${username}\" already exists.`,\n );\n }\n\n throw new ConflictException(ERROR_MESSAGES.USER_ALREADY_EXISTS);\n }\n\n private async handlePasswordlessSignupOtp<T extends User>(\n user: T,\n signUpDto: SignUpDto,\n autoGeneratedPwd: string,\n repo: Repository<T>,\n ): Promise<void> {\n const isPasswordProvided = !!signUpDto.password;\n const isAutoGeneratedPassword = !!autoGeneratedPwd;\n if (isPasswordProvided || isAutoGeneratedPassword) {\n return;\n }\n\n if (!user.mobile) {\n this.logger.warn(\n `Skipping passwordless signup OTP WhatsApp notification for user ${user.username}: mobile is missing.`,\n );\n return;\n }\n\n const isPasswordlessRegistrationEnabled =\n await this.isPasswordlessRegistrationEnabled();\n if (!isPasswordlessRegistrationEnabled) {\n return;\n }\n\n await this.assignRegistrationOtp(\n PasswordlessRegistrationValidateWhatSources.MOBILE,\n user,\n );\n await repo.save(user);\n await this.notifyUserOnOtpInitiateRegistration(\n user,\n PasswordlessRegistrationValidateWhatSources.MOBILE,\n );\n }\n\n /** @deprecated Use IExtensionUserCreationProvider instead. Kept for backward compatibility. */\n async signupForExtensionUser<T extends User>(\n signUpDto: SignUpDto,\n extensionUserDto: DeepPartial<T>,\n extensionUserRepo: Repository<T>,\n ): Promise<T> {\n const entity = extensionUserRepo.create(extensionUserDto);\n return this.performSignUp(signUpDto, entity, extensionUserRepo);\n }\n\n private async populateForSignup<T extends User>(\n user: T,\n signUpDto: SignUpDto,\n isUserActive: boolean = true,\n onForcePasswordChange?: boolean,\n ) {\n // const user = new User();\n let autoGeneratedPwdPermission =\n this.settingService.getConfigValue<SolidCoreSetting>(\n \"iamAutoGeneratedPassword\",\n );\n if (signUpDto.roles && signUpDto.roles.length > 0) {\n for (let i = 0; i < signUpDto.roles.length; i++) {\n const roleName = signUpDto.roles[i];\n await this.roleMetadataService.assertRoleExistsByName(roleName);\n }\n }\n user.username = signUpDto.username;\n user.email = signUpDto.email;\n // `fullName` is optional on SignUpDto and the stock signup screen only sends it when\n // showNameFieldsForRegistration is on, so assigning it unconditionally left every\n // self-registered user with a null display name. `username` is always present -\n // non-nullable on the entity and @IsNotEmpty() on the DTO - so it is a safe fallback.\n // `||` rather than `??`: a form posting an empty string means \"not supplied\" too.\n user.fullName = signUpDto.fullName?.trim() || signUpDto.username;\n user.forcePasswordChange = onForcePasswordChange;\n if (signUpDto.mobile) {\n user.mobile = signUpDto.mobile;\n }\n // this.logger.debug(\"user\", user);\n\n // If password has been specified by the user, then we simply create & activate the user based on the configuration parameter \"activateUserOnRegistration\".\n let pwd = \"\";\n let autoGeneratedPwd = \"\";\n\n // User has specified password\n if (signUpDto.password) {\n pwd = await this.hashingService.hash(signUpDto.password);\n }\n // User has not specified password\n else {\n // When user does not specify password, and system is configured to auto generate passwords.\n if (autoGeneratedPwdPermission?.toString().toLowerCase() === \"true\") {\n autoGeneratedPwd = this.generatePassword();\n pwd = await this.hashingService.hash(autoGeneratedPwd);\n user.forcePasswordChange = true;\n }\n // When user does not specify password, and system is not configured to auto generate passwords.\n else {\n // This means that most likely the system is going to be using password-less login.\n // If that is not the case then we can raise a bad request exception...\n if (!(await this.isPasswordlessRegistrationEnabled())) {\n this.logger.error(\n \"User being created without password, and password less login is also not enabled in the system. Is this intentional?\",\n );\n throw new BadRequestException(\n ERROR_MESSAGES.PASSWORDLESS_REGISTRATION_DISABLED,\n );\n }\n\n // Save the hash of the blank password, anyways since passwordless login is enabled it does not matter.\n pwd = await this.hashingService.hash(pwd);\n }\n }\n\n user.password = pwd;\n user.passwordScheme = this.hashingService.name(); // e.g. bcrypt\n user.passwordSchemeVersion = this.hashingService.currentVersion(); // e.g. 1, 2, 3 ...\n user.active = isUserActive;\n return { user, pwd, autoGeneratedPwd };\n }\n\n private async handlePostSignup(\n user: User,\n roles: string[] = [],\n pwd: string,\n autoGeneratedPwd: string,\n ) {\n await this.userService.initializeRolesForNewUser(roles, user);\n\n // if forcePasswordChange is true, then we trigger an email to the user to change the password, this needs to be done using a queue.\n // Create a new method like notifyUserOnForcePasswordChange, create a new email template we can call it on-force-password-change this template to include the random password\n if (user.forcePasswordChange && autoGeneratedPwd) {\n try {\n await this.notifyUserOnForcePasswordChange(user, autoGeneratedPwd);\n } catch (error: any) {\n this.logger.error(\n `Failed to send force-password-change email for user ${user.id}: ${error?.message ?? error}`,\n );\n }\n }\n\n // Send welcome notifications (email/SMS) if enabled.\n try {\n await this.notifyUserOnSignup(user);\n } catch (error: any) {\n this.logger.error(\n `Failed to send signup notifications for user ${user.id}: ${error?.message ?? error}`,\n );\n }\n }\n\n generatePassword(length: number = 8): string {\n const upperCase = \"ABCDEFGHIJKLMNOPQRSTUVWXYZ\";\n const lowerCase = \"abcdefghijklmnopqrstuvwxyz\";\n const numbers = \"0123456789\";\n const specialChars = \"@$#\";\n const allChars = upperCase + lowerCase + numbers + specialChars;\n\n let password = \"\";\n\n for (let i = 0; i < length; i++) {\n const randomIndex = Math.floor(Math.random() * allChars.length);\n password += allChars[randomIndex];\n }\n\n return password;\n }\n\n private async notifyUserOnForcePasswordChange(\n user: User,\n autoGeneratedPwd: string,\n ) {\n const companyLogo = await this.getCompanyLogo();\n const mailService = this.mailServiceFactory.getMailService();\n mailService.sendEmailUsingTemplate(\n user.email,\n \"on-force-password-change\",\n {\n solidAppName:\n this.settingService.getConfigValue<SolidCoreSetting>(\"appTitle\"),\n solidAppWebsiteUrl:\n this.settingService.getConfigValue<SolidCoreSetting>(\n \"solidAppWebsiteUrl\",\n ),\n frontendLoginPageUrl:\n this.settingService.getConfigValue<SolidCoreSetting>(\n \"frontendLoginPageUrl\",\n ),\n email: user.email,\n fullName: user.fullName,\n userName: user.username,\n password: autoGeneratedPwd,\n companyLogoUrl: companyLogo,\n },\n this.settingService.getConfigValue<SolidCoreSetting>(\"shouldQueueEmails\"),\n null,\n null,\n \"user\",\n user.id,\n );\n }\n\n private async isWelcomeEmailEnabled(): Promise<boolean> {\n const sendWelcomeEmailOnSignup =\n this.settingService.getConfigValue<SolidCoreSetting>(\n \"sendWelcomeEmailOnSignup\",\n );\n return sendWelcomeEmailOnSignup;\n }\n\n private async isWelcomeSmsEnabled(): Promise<boolean> {\n const sendWelcomeSmsOnSignup =\n this.settingService.getConfigValue<SolidCoreSetting>(\n \"sendWelcomeSmsOnSignup\",\n );\n return sendWelcomeSmsOnSignup;\n }\n\n private async notifyUserOnSignup(user: User) {\n const companyLogo = await this.getCompanyLogo();\n // Email welcome\n if (await this.isWelcomeEmailEnabled()) {\n const mailService = this.mailServiceFactory.getMailService();\n mailService.sendEmailUsingTemplate(\n user.email,\n \"email-on-signup\",\n {\n solidAppName:\n this.settingService.getConfigValue<SolidCoreSetting>(\"appTitle\"),\n solidAppWebsiteUrl:\n this.settingService.getConfigValue<SolidCoreSetting>(\n \"solidAppWebsiteUrl\",\n ),\n frontendLoginPageUrl:\n this.settingService.getConfigValue<SolidCoreSetting>(\n \"frontendLoginPageUrl\",\n ),\n email: user.email,\n fullName: user.fullName,\n userName: user.username,\n companyLogoUrl: companyLogo,\n },\n this.settingService.getConfigValue<SolidCoreSetting>(\n \"shouldQueueEmails\",\n ),\n null,\n null,\n \"user\",\n user.id,\n );\n }\n\n // SMS welcome\n const isWelcomeSmsEnabled = await this.isWelcomeSmsEnabled();\n if (isWelcomeSmsEnabled && user.mobile) {\n const smsService = this.smsFactory.getSmsService();\n smsService.sendSMSUsingTemplate(\n user.mobile,\n \"text-on-signup\",\n {\n solidAppName:\n this.settingService.getConfigValue<SolidCoreSetting>(\"appTitle\"),\n frontendLoginPageUrl:\n this.settingService.getConfigValue<SolidCoreSetting>(\n \"frontendLoginPageUrl\",\n ),\n firstName: user.username,\n fullName: user.fullName ? user.fullName : user.username,\n },\n this.settingService.getConfigValue<SolidCoreSetting>(\"shouldQueueSms\"),\n );\n }\n }\n\n /**\n * Gates *self-service* account creation only - the public register endpoints, where\n * an anonymous visitor creates their own account. Callers that create a user on\n * someone else's behalf (the admin console, an extension model's CRUD form, the\n * seeders) are deliberately unaffected, so turning this off does not disable user\n * creation across the system.\n *\n * Compared against both representations because `getConfigValue` returns the raw\n * cached value, which is a boolean when it comes from the provider default and a\n * string once persisted or edited through the Settings screen - see the same\n * defensive comparison for `mcpEnabled` in setting.service.ts. A plain falsy check\n * would read `'false'` as truthy and never fire.\n */\n private assertPublicRegistrationEnabled(): void {\n const allowPublicRegistration =\n this.settingService.getConfigValue<SolidCoreSetting>(\n \"allowPublicRegistration\",\n );\n if (allowPublicRegistration === false || allowPublicRegistration === \"false\") {\n throw new ForbiddenException(ERROR_MESSAGES.PUBLIC_REGISTRATION_DISABLED);\n }\n }\n\n async otpInitiateRegistration(signUpDto: OTPSignUpDto) {\n this.assertPublicRegistrationEnabled();\n\n const isPasswordlessRegistrationEnabled =\n await this.isPasswordlessRegistrationEnabled();\n if (!isPasswordlessRegistrationEnabled) {\n throw new BadRequestException(\n ERROR_MESSAGES.PASSWORDLESS_REGISTRATION_DISABLED,\n );\n }\n\n const validationSource = this.resolvePasswordlessValidationSource();\n this.validateOtpRegistrationInput(signUpDto, validationSource);\n\n const existingUser = await this.findExistingRegistrationUser(signUpDto);\n if (isNotEmpty(existingUser) && existingUser.active) {\n throw new ConflictException(ERROR_MESSAGES.USER_ALREADY_EXISTS);\n }\n\n try {\n const user = await this.upsertUserWithRegistrationVerificationTokens(\n existingUser,\n signUpDto,\n validationSource,\n );\n await this.notifyUserOnOtpInitiateRegistration(user, validationSource);\n } catch (err: any) {\n if (err.code === \"23505\") {\n throw new ConflictException(ERROR_MESSAGES.USER_ALREADY_EXISTS);\n }\n throw err;\n }\n\n return { message: SUCCESS_MESSAGES.OTP_SENT_SUCCESS_REGISTRATION };\n }\n\n private validateOtpRegistrationInput(\n signUpDto: OTPSignUpDto,\n validationSource: string,\n ): void {\n if (\n validationSource === PasswordlessRegistrationValidateWhatSources.EMAIL &&\n isEmpty(signUpDto.email)\n ) {\n throw new BadRequestException(\n ERROR_MESSAGES.EMAIL_REQUIRED_FOR_VALIDATION,\n );\n }\n if (\n validationSource === PasswordlessRegistrationValidateWhatSources.MOBILE &&\n isEmpty(signUpDto.mobile)\n ) {\n throw new BadRequestException(\n ERROR_MESSAGES.MOBILE_REQUIRED_FOR_VALIDATION,\n );\n }\n }\n\n private async findExistingRegistrationUser(\n signUpDto: OTPSignUpDto,\n ): Promise<User> {\n return this.userRepository.findOne({\n //TODO Perhaps we should use the user service instead of the repository directly.\n where: [\n { email: signUpDto.email },\n { mobile: signUpDto.mobile },\n { username: signUpDto.username },\n ],\n });\n }\n\n private resolvePasswordlessValidationSource(): string {\n return this.settingService.getConfigValue<SolidCoreSetting>(\n \"passwordlessRegistrationValidateWhat\",\n );\n }\n\n private async upsertUserWithRegistrationVerificationTokens(\n existingUser: User,\n signUpDto: OTPSignUpDto,\n validationSource: string,\n ): Promise<User> {\n if (isEmpty(existingUser)) {\n // Resolved before anything is written: where a provider requires its discriminator\n // roles() throws, and that should surface as a rejected request rather than as a\n // half-registered user with no roles.\n const roles = this.resolveSignupRoles(\n signUpDto,\n SIGNUP_POLICY[SignupIntent.SelfRegistration].rolesSource,\n );\n\n // A new registration is saved through whichever repository createUser resolved,\n // which is the provider's when the app registers one.\n const { entity: user, repo } = await this.createUser(signUpDto);\n user.active = false; // User will be activated only after OTP verification, hence setting active to false for new user.\n await this.assignRegistrationOtp(validationSource, user);\n await repo.save(user);\n\n if (roles.length) {\n await this.userService.addRolesToUser(user.username, roles);\n } else {\n // The provider named none, or there is no provider: fall back to the configured\n // default, matching what performSignUp does on the password paths.\n await this.userService.addRoleToUser(\n user.username,\n this.settingService.getConfigValue<SolidCoreSetting>(\"defaultRole\"),\n );\n }\n return user;\n }\n\n // An existing row is saved back through the base repository: `User` is the\n // inheritance root, so TypeORM hydrated it as its own subclass on the way in and\n // round-trips the discriminator on the way out.\n const user = existingUser;\n await this.assignRegistrationOtp(validationSource, user);\n await this.userRepository.save(user);\n return user;\n }\n\n /**\n * Creates a new user entity for OTP registration - of whichever type this app\n * registers its users as, since passwordless signup is self-registration like any\n * other. Returns the repository alongside it, because a provider-built entity has\n * to be saved through the provider's own repository.\n */\n private async createUser(\n signUpDto: OTPSignUpDto,\n ): Promise<{ entity: User; repo: Repository<User> }> {\n const { useProvider } = SIGNUP_POLICY[SignupIntent.SelfRegistration];\n const { entity, repo } = await this.userService.buildSignupTarget(\n signUpDto,\n useProvider,\n );\n\n entity.username = signUpDto.username;\n entity.email = signUpDto.email;\n entity.mobile = signUpDto.mobile;\n // OTPSignUpDto declares no `fullName`, so username is the only source here. Mirrors the fallback in populateForSignup, which this path does not go through.\n entity.fullName = signUpDto.fullName?.trim() || signUpDto.username;\n entity.customPayload = signUpDto.customPayload;\n entity.lastLoginProvider = LoginProvider.OTP;\n\n return { entity, repo };\n }\n\n // Generate the validation tokens for the user i.e (system configured + user provided)\n private async assignRegistrationOtp(\n passwordlessRegistrationValidateWhat: string,\n user: User,\n ) {\n if (!passwordlessRegistrationValidateWhat) {\n throw new BadRequestException(ERROR_MESSAGES.VALIDATION_SOURCE_REQUIRED);\n }\n const autoLoginUserOnRegistration =\n this.settingService.getConfigValue<SolidCoreSetting>(\n \"autoLoginUserOnRegistration\",\n );\n if (\n passwordlessRegistrationValidateWhat ===\n PasswordlessRegistrationValidateWhatSources.EMAIL\n ) {\n const { token, expiresAt } = await this.otp();\n user.emailVerificationTokenOnRegistration = token;\n user.emailVerificationTokenOnRegistrationExpiresAt = expiresAt;\n if (autoLoginUserOnRegistration) {\n user.emailVerificationTokenOnLogin = token;\n user.emailVerificationTokenOnLoginExpiresAt = expiresAt;\n }\n }\n if (\n passwordlessRegistrationValidateWhat ===\n PasswordlessRegistrationValidateWhatSources.MOBILE\n ) {\n const { token, expiresAt } = await this.otp();\n user.mobileVerificationTokenOnRegistration = token;\n user.mobileVerificationTokenOnRegistrationExpiresAt = expiresAt;\n if (autoLoginUserOnRegistration) {\n user.mobileVerificationTokenOnLogin = token;\n user.mobileVerificationTokenOnLoginExpiresAt = expiresAt;\n }\n }\n }\n\n private async notifyUserOnOtpInitiateRegistration(\n user: User,\n registrationValidationSource: string,\n ) {\n const companyLogo = await this.getCompanyLogo();\n if (\n registrationValidationSource ===\n PasswordlessRegistrationValidateWhatSources.EMAIL\n ) {\n const mailService = this.mailServiceFactory.getMailService();\n mailService.sendEmailUsingTemplate(\n user.email,\n \"otp-on-register\",\n {\n solidAppName:\n this.settingService.getConfigValue<SolidCoreSetting>(\"appTitle\"),\n solidAppWebsiteUrl:\n this.settingService.getConfigValue<SolidCoreSetting>(\n \"solidAppWebsiteUrl\",\n ),\n firstName: user.username,\n fullName: user.fullName ? user.fullName : user.username,\n emailVerificationTokenOnRegistration:\n user.emailVerificationTokenOnRegistration,\n companyLogoUrl: companyLogo,\n },\n this.settingService.getConfigValue<SolidCoreSetting>(\n \"shouldQueueEmails\",\n ),\n null,\n null,\n \"user\",\n user.id,\n );\n }\n if (\n registrationValidationSource ===\n PasswordlessRegistrationValidateWhatSources.MOBILE\n ) {\n const templateParams = {\n solidAppName:\n this.settingService.getConfigValue<SolidCoreSetting>(\"appTitle\"),\n otp: user.mobileVerificationTokenOnRegistration,\n mobileVerificationTokenOnRegistration:\n user.mobileVerificationTokenOnRegistration,\n firstName: user.username,\n fullName: user.fullName ? user.fullName : user.username,\n companyLogoUrl: companyLogo,\n };\n\n const whatsappDestination = this.normalizeWhatsAppDestination(\n user.mobile,\n );\n const gupshupTemplateAppName =\n process.env.COMMON_GUPSHUP_APP_NAME || \"Gupshup\";\n const whatsappTemplateId =\n this.settingService.getConfigValue<SolidCoreSetting>(\n \"otpWhatsappTemplateId\",\n ) || \"common_otp\";\n const whatsappIndependentEnabled =\n this.settingService.getConfigValue<SolidCoreSetting>(\n \"otpWhatsappIndependentEnabled\",\n ) !== false;\n\n let smsSent = false;\n let whatsappSent = false;\n let smsErrorMessage: string | undefined;\n let whatsappErrorMessage: string | undefined;\n\n this.logger.debug(\n `OTP SMS send attempt: destination=${user.mobile}, whatsappDestination=${whatsappDestination}`,\n );\n\n try {\n const smsService = this.smsFactory.getSmsService();\n await smsService.sendSMSUsingTemplate(\n user.mobile,\n \"otp-on-register\",\n templateParams,\n false,\n );\n smsSent = true;\n } catch (smsError: any) {\n smsErrorMessage = smsError?.message;\n this.logger.warn(\n `OTP SMS failed: destination=${user.mobile}, message=${smsErrorMessage}`,\n );\n }\n\n if (whatsappIndependentEnabled) {\n if (!whatsappDestination) {\n whatsappErrorMessage = \"Normalized WhatsApp destination is empty\";\n this.logger.error(\n `Independent OTP WhatsApp skipped: destination=${user.mobile}, message=${whatsappErrorMessage}`,\n );\n } else {\n this.logger.debug(\n `Independent OTP WhatsApp send attempt: destination=${user.mobile}, whatsappDestination=${whatsappDestination}, templateId=${whatsappTemplateId}`,\n );\n try {\n await this.sendOtpToWhatsappProvider(\n whatsappDestination,\n String(whatsappTemplateId),\n String(gupshupTemplateAppName),\n String(templateParams.otp || \"\"),\n );\n whatsappSent = true;\n this.logger.log(\n `Independent OTP WhatsApp success: destination=${user.mobile}, whatsappDestination=${whatsappDestination}, templateId=${whatsappTemplateId}`,\n );\n } catch (waError: any) {\n whatsappErrorMessage = waError?.message;\n this.logger.error(\n `Independent OTP WhatsApp failed: destination=${user.mobile}, whatsappDestination=${whatsappDestination}, templateId=${whatsappTemplateId}, message=${whatsappErrorMessage}`,\n );\n }\n }\n }\n\n if (!smsSent && !whatsappSent) {\n throw new Error(\n `OTP delivery failed on both channels. smsError=${smsErrorMessage || \"unknown\"}, whatsappError=${whatsappErrorMessage || \"disabled/unknown\"}`,\n );\n }\n }\n }\n\n private normalizeWhatsAppDestination(rawMobile: string): string {\n const raw = (rawMobile || \"\").trim();\n let sanitized = raw.replace(/[^\\d+]/g, \"\");\n\n if (sanitized.startsWith(\"00\")) {\n sanitized = `+${sanitized.slice(2)}`;\n }\n\n const defaultDialCode = String(\n this.settingService.getConfigValue<SolidCoreSetting>(\n \"otpDefaultCountryDialCode\",\n ) || \"\",\n ).replace(/\\D/g, \"\");\n\n if (sanitized.startsWith(\"+\")) {\n const e164Digits = sanitized.slice(1).replace(/\\D/g, \"\");\n if (e164Digits.length >= 8 && e164Digits.length <= 15) {\n return e164Digits;\n }\n }\n\n const digits = sanitized.replace(/\\D/g, \"\");\n\n if (digits.length >= 11 && digits.length <= 15) {\n return digits;\n }\n\n if (digits.length === 10 && defaultDialCode) {\n return `${defaultDialCode}${digits}`;\n }\n\n return digits;\n }\n\n private async sendOtpToWhatsappProvider(\n destination: string,\n templateId: string,\n appName: string,\n otp: string,\n ): Promise<void> {\n const whatsappService = this.whatsAppFactory.getWhatsappService();\n await whatsappService.sendWhatsAppMessage(destination, null, {\n type: \"text\",\n text: `${appName} OTP is ${otp}. It is valid for 10 mins.`,\n });\n }\n\n async otpConfirmRegistration(confirmSignUpDto: OTPConfirmOTPDto) {\n const isPasswordlessRegistrationEnabled =\n await this.isPasswordlessRegistrationEnabled();\n if (!isPasswordlessRegistrationEnabled) {\n throw new BadRequestException(\n ERROR_MESSAGES.PASSWORDLESS_REGISTRATION_DISABLED,\n );\n }\n\n const { type, identifier, otp } = confirmSignUpDto;\n if (\n type !== PasswordlessRegistrationValidateWhatSources.EMAIL &&\n type !== PasswordlessRegistrationValidateWhatSources.MOBILE\n ) {\n throw new BadRequestException(ERROR_MESSAGES.INVALID_VERIFICATION_TYPE);\n }\n\n const user = await this.findUserByRegistrationIdentifier(type, identifier);\n this.validateRegistrationOtp(user, otp, type);\n this.clearRegistrationOtp(user, type);\n user.active =\n this.settingService.getConfigValue<SolidCoreSetting>(\n \"activateUserOnRegistration\",\n ) &&\n (await this.areAllPasswordlessRegistrationValidationSourcesVerified(\n user,\n ));\n\n const savedUser: User = await this.userRepository.save(user);\n this.triggerRegistrationEvent(savedUser);\n return {\n active: savedUser.active,\n message: `User registration verified for ${type}`,\n };\n }\n\n private async findUserByRegistrationIdentifier(\n type: PasswordlessRegistrationValidateWhatSources,\n identifier: string,\n ): Promise<User> {\n const where =\n type === PasswordlessRegistrationValidateWhatSources.EMAIL\n ? { email: identifier }\n : { mobile: identifier };\n const user = await this.userRepository.findOne({ where });\n if (!user) {\n throw new UnauthorizedException(ERROR_MESSAGES.USER_NOT_FOUND);\n }\n return user;\n }\n\n private validateRegistrationOtp(\n user: User,\n otp: string,\n type: PasswordlessRegistrationValidateWhatSources,\n ): void {\n const isEmail = type === PasswordlessRegistrationValidateWhatSources.EMAIL;\n const token = isEmail\n ? user.emailVerificationTokenOnRegistration\n : user.mobileVerificationTokenOnRegistration;\n const expiresAt = isEmail\n ? user.emailVerificationTokenOnRegistrationExpiresAt\n : user.mobileVerificationTokenOnRegistrationExpiresAt;\n\n if (token !== otp) {\n throw new UnauthorizedException(ERROR_MESSAGES.INVALID_OTP);\n }\n if (expiresAt < new Date()) {\n throw new UnauthorizedException(ERROR_MESSAGES.OTP_EXPIRED);\n }\n }\n\n private clearRegistrationOtp(\n user: User,\n type: PasswordlessRegistrationValidateWhatSources,\n ): void {\n if (type === PasswordlessRegistrationValidateWhatSources.EMAIL) {\n user.emailVerifiedOnRegistrationAt = new Date();\n user.emailVerificationTokenOnRegistration = null;\n user.emailVerificationTokenOnRegistrationExpiresAt = null;\n } else {\n user.mobileVerifiedOnRegistrationAt = new Date();\n user.mobileVerificationTokenOnRegistration = null;\n user.mobileVerificationTokenOnRegistrationExpiresAt = null;\n }\n }\n\n private triggerRegistrationEvent(savedUser: User) {\n // Trigger events for user registration.\n const event = new EventDetails<User>(EventType.USER_REGISTERED, savedUser);\n this.eventEmitter.emit(EventType.USER_REGISTERED, event);\n }\n\n private async areAllPasswordlessRegistrationValidationSourcesVerified(\n user: User,\n ): Promise<boolean> {\n const registrationValidationSource =\n this.resolvePasswordlessValidationSource();\n if (\n registrationValidationSource ===\n PasswordlessRegistrationValidateWhatSources.EMAIL\n ) {\n if (!user.emailVerifiedOnRegistrationAt) {\n return false;\n }\n }\n if (\n registrationValidationSource ===\n PasswordlessRegistrationValidateWhatSources.MOBILE\n ) {\n if (!user.mobileVerifiedOnRegistrationAt) {\n return false;\n }\n }\n return true;\n }\n\n private async otp(): Promise<otp> {\n const now = new Date();\n const otpExpiry =\n this.settingService.getConfigValue<SolidCoreSetting>(\"otpExpiry\");\n now.setMinutes(now.getMinutes() + otpExpiry);\n return {\n token: randomInt(100000, 999999).toString(),\n expiresAt: now,\n };\n }\n\n private getDummyOtpForUser(user?: User): string | undefined {\n const dummyOtp =\n this.settingService.getConfigValue<SolidCoreSetting>(\"dummyOtp\");\n if (!dummyOtp || !user?.username) {\n return undefined;\n }\n const allowedUsers = this.getDummyOtpUsers();\n if (!allowedUsers.size) {\n return undefined;\n }\n const username = user.username.trim().toLowerCase();\n if (!username) {\n return undefined;\n }\n return allowedUsers.has(username) ? dummyOtp : undefined;\n }\n\n private getDummyOtpUsers(): Set<string> {\n const rawUsers =\n this.settingService.getConfigValue<SolidCoreSetting>(\"dummyOtpUsers\");\n if (!rawUsers || typeof rawUsers !== \"string\") {\n return new Set();\n }\n return new Set(\n rawUsers\n .split(\",\")\n .map((value) => value.trim().toLowerCase())\n .filter(Boolean),\n );\n }\n\n async signIn(signInDto: SignInDto) {\n const user = await this.resolveUserForPasswordSignIn(\n signInDto.username,\n signInDto.email,\n );\n if (!user) {\n throw new UnauthorizedException(ERROR_MESSAGES.INVALID_CREDENTIALS);\n }\n await this.validateUserForPasswordLogin(user, signInDto.password);\n await this.rehashPasswordIfRequired(user, signInDto.password);\n await this.resetFailedAttempts(user);\n\n const tokens = await this.generateTokens(user);\n\n await this.userActivityHistoryService.logEvent(\"login\", user);\n\n return {\n user: {\n email: user.email,\n mobile: user.mobile,\n username: user.username,\n forcePasswordChange: user.forcePasswordChange,\n id: user.id,\n roles: user.roles.map((role) => role.name),\n },\n ...tokens,\n };\n }\n\n private maskEmail(email: string): string {\n if (!email) return null;\n\n const [localPart, domain] = email.split(\"@\");\n if (localPart.length <= 2) {\n return `${localPart[0]}***@${domain}`;\n }\n\n const visibleStart = localPart.slice(0, 2);\n const visibleEnd = localPart.slice(-1);\n return `${visibleStart}***${visibleEnd}@${domain}`;\n }\n\n private maskMobile(mobile: string): string {\n if (!mobile) return null;\n\n if (mobile.length <= 4) {\n return mobile;\n }\n\n const visibleEnd = mobile.slice(-4);\n return `***${visibleEnd}`;\n }\n\n async otpInitiateLogin(signInDto: OTPSignInDto) {\n const isPasswordlessRegistrationEnabled =\n await this.isPasswordlessRegistrationEnabled();\n if (!isPasswordlessRegistrationEnabled) {\n throw new BadRequestException(\n ERROR_MESSAGES.PASSWORDLESS_REGISTRATION_DISABLED,\n );\n }\n\n const type = this.resolveLoginType(signInDto);\n const user = await this.findUserForLogin(type, signInDto.identifier);\n const dummyOtp = this.getDummyOtpForUser(user);\n if (!dummyOtp) {\n await this.assignLoginOtp(user, type);\n await this.notifyUserOnOtpInititateLogin(user, type);\n }\n return this.buildLoginOtpResponse(user, type);\n }\n\n private resolveLoginType(\n signInDto: OTPSignInDto,\n ): PasswordlessLoginValidateWhatSources {\n const setting = this.settingService.getConfigValue<SolidCoreSetting>(\n \"passwordlessLoginValidateWhat\",\n ) as PasswordlessLoginValidateWhatSources;\n\n if (setting === PasswordlessLoginValidateWhatSources.SELECTABLE) {\n if (\n signInDto.type !== PasswordlessLoginValidateWhatSources.EMAIL &&\n signInDto.type !== PasswordlessLoginValidateWhatSources.MOBILE\n ) {\n throw new BadRequestException(ERROR_MESSAGES.INVALID_VERIFICATION_TYPE);\n }\n return signInDto.type as PasswordlessLoginValidateWhatSources;\n }\n\n if (\n setting === PasswordlessLoginValidateWhatSources.EMAIL ||\n setting === PasswordlessLoginValidateWhatSources.MOBILE\n ) {\n return setting;\n }\n\n throw new BadRequestException(ERROR_MESSAGES.INVALID_VERIFICATION_TYPE);\n }\n\n private async resolveUserForOtpEmailSignIn(identifier: string,options: { withRoles?: boolean } = {},): Promise<User | null> {\n const normalizedEmail = identifier?.trim().toLowerCase();\n const query =\n await this.userRepository.createSecurityRuleAwareQueryBuilder(\"u\");\n\n if (options.withRoles) {\n query.leftJoinAndSelect(\"u.roles\", \"roles\");\n }\n\n query.where(\"u.username = :username\", { username: identifier });\n\n if (normalizedEmail) {\n query.orWhere(\"LOWER(u.email) = :email\", { email: normalizedEmail });\n }\n\n return await query.getOne();\n }\n\n private async findUserForLogin(\n type: PasswordlessLoginValidateWhatSources,\n identifier: string,\n options: { withRoles?: boolean } = {},\n ): Promise<User> {\n const user =\n type === PasswordlessLoginValidateWhatSources.EMAIL\n ? await this.resolveUserForOtpEmailSignIn(identifier, options)\n : await this.userRepository.findOne({\n where: [{ username: identifier }, { mobile: identifier }],\n ...(options.withRoles ? { relations: { roles: true } } : {}),\n });\n if (!user) {\n throw new UnauthorizedException(ERROR_MESSAGES.USER_NOT_FOUND);\n }\n if (!user.active) {\n throw new UnauthorizedException(ERROR_MESSAGES.USER_INACTIVE);\n }\n return user;\n }\n\n private async assignLoginOtp(\n user: User,\n type: PasswordlessLoginValidateWhatSources,\n ): Promise<void> {\n const { token, expiresAt } = await this.otp();\n if (type === PasswordlessLoginValidateWhatSources.EMAIL) {\n user.emailVerificationTokenOnLogin = token;\n user.emailVerificationTokenOnLoginExpiresAt = expiresAt;\n await this.userRepository.update(user.id, {\n emailVerificationTokenOnLogin: token,\n emailVerificationTokenOnLoginExpiresAt: expiresAt,\n });\n } else {\n user.mobileVerificationTokenOnLogin = token;\n user.mobileVerificationTokenOnLoginExpiresAt = expiresAt;\n await this.userRepository.update(user.id, {\n mobileVerificationTokenOnLogin: token,\n mobileVerificationTokenOnLoginExpiresAt: expiresAt,\n });\n }\n }\n\n private buildLoginOtpResponse(\n user: User,\n type: PasswordlessLoginValidateWhatSources,\n ) {\n const maskedIdentifier =\n type === PasswordlessLoginValidateWhatSources.EMAIL\n ? { email: this.maskEmail(user.email) }\n : { mobile: this.maskMobile(user.mobile) };\n return {\n message: SUCCESS_MESSAGES.OTP_SENT_SUCCESS_LOGIN,\n user: maskedIdentifier,\n };\n }\n\n private async notifyUserOnOtpInititateLogin(\n user: User,\n loginType: PasswordlessLoginValidateWhatSources,\n ) {\n const companyLogo = await this.getCompanyLogo();\n const dummyOtp = this.getDummyOtpForUser(user);\n\n if (dummyOtp) return; // Do nothing if dummy otp is configured.\n if (loginType === PasswordlessLoginValidateWhatSources.EMAIL) {\n const mailService = this.mailServiceFactory.getMailService();\n mailService.sendEmailUsingTemplate(\n user.email,\n \"otp-on-login\",\n {\n solidAppName:\n this.settingService.getConfigValue<SolidCoreSetting>(\"appTitle\"),\n solidAppWebsiteUrl:\n this.settingService.getConfigValue<SolidCoreSetting>(\n \"solidAppWebsiteUrl\",\n ),\n firstName: user.username,\n emailVerificationTokenOnLogin: user.emailVerificationTokenOnLogin,\n fullName: user.fullName ? user.fullName : user.username,\n companyLogoUrl: companyLogo,\n },\n this.settingService.getConfigValue<SolidCoreSetting>(\n \"shouldQueueEmails\",\n ),\n null,\n null,\n \"user\",\n user.id,\n );\n }\n if (loginType === PasswordlessLoginValidateWhatSources.MOBILE) {\n const templateParams = {\n solidAppName:\n this.settingService.getConfigValue<SolidCoreSetting>(\"appTitle\"),\n otp: user.mobileVerificationTokenOnLogin,\n mobileVerificationTokenOnLogin: user.mobileVerificationTokenOnLogin,\n firstName: user.username,\n fullName: user.fullName ? user.fullName : user.username,\n companyLogoUrl: companyLogo,\n };\n\n const whatsappDestination = this.normalizeWhatsAppDestination(user.mobile);\n const gupshupTemplateAppName =\n process.env.COMMON_GUPSHUP_APP_NAME || \"Gupshup\";\n const whatsappTemplateId =\n this.settingService.getConfigValue<SolidCoreSetting>(\n \"otpWhatsappTemplateId\",\n ) || \"common_otp\";\n const whatsappIndependentEnabled =\n this.settingService.getConfigValue<SolidCoreSetting>(\n \"otpWhatsappIndependentEnabled\",\n ) !== false;\n\n let smsSent = false;\n let whatsappSent = false;\n let smsErrorMessage: string | undefined;\n let whatsappErrorMessage: string | undefined;\n\n this.logger.debug(\n `OTP LOGIN SMS send attempt: destination=${user.mobile}, whatsappDestination=${whatsappDestination}`,\n );\n\n try {\n const smsService = this.smsFactory.getSmsService();\n await smsService.sendSMSUsingTemplate(\n user.mobile,\n \"otp-on-login\",\n templateParams,\n false,\n );\n smsSent = true;\n } catch (smsError: any) {\n smsErrorMessage = smsError?.message;\n this.logger.warn(\n `OTP LOGIN SMS failed: destination=${user.mobile}, message=${smsErrorMessage}`,\n );\n }\n\n if (whatsappIndependentEnabled) {\n if (!whatsappDestination) {\n whatsappErrorMessage = \"Normalized WhatsApp destination is empty\";\n this.logger.error(\n `OTP LOGIN WhatsApp skipped: destination=${user.mobile}, message=${whatsappErrorMessage}`,\n );\n } else {\n this.logger.debug(\n `OTP LOGIN WhatsApp send attempt: destination=${user.mobile}, whatsappDestination=${whatsappDestination}, templateId=${whatsappTemplateId}`,\n );\n try {\n await this.sendOtpToWhatsappProvider(\n whatsappDestination,\n String(whatsappTemplateId),\n String(gupshupTemplateAppName),\n String(templateParams.otp || \"\"),\n );\n whatsappSent = true;\n this.logger.log(\n `OTP LOGIN WhatsApp success: destination=${user.mobile}, whatsappDestination=${whatsappDestination}, templateId=${whatsappTemplateId}`,\n );\n } catch (waError: any) {\n whatsappErrorMessage = waError?.message;\n this.logger.error(\n `OTP LOGIN WhatsApp failed: destination=${user.mobile}, whatsappDestination=${whatsappDestination}, templateId=${whatsappTemplateId}, message=${whatsappErrorMessage}`,\n );\n }\n }\n }\n\n if (!smsSent && !whatsappSent) {\n throw new Error(\n `OTP LOGIN delivery failed on both channels. smsError=${smsErrorMessage || \"unknown\"}, whatsappError=${whatsappErrorMessage || \"disabled/unknown\"}`,\n );\n }\n }\n }\n\n async otpConfirmLogin(confirmSignInDto: OTPConfirmOTPDto) {\n const isPasswordlessRegistrationEnabled =\n await this.isPasswordlessRegistrationEnabled();\n if (!isPasswordlessRegistrationEnabled) {\n throw new BadRequestException(\n ERROR_MESSAGES.PASSWORDLESS_REGISTRATION_DISABLED,\n );\n }\n\n const { type, identifier, otp } = confirmSignInDto;\n if (\n type !== PasswordlessLoginValidateWhatSources.EMAIL &&\n type !== PasswordlessLoginValidateWhatSources.MOBILE\n ) {\n throw new BadRequestException(ERROR_MESSAGES.INVALID_VERIFICATION_TYPE);\n }\n\n const user = await this.findUserForLogin(type, identifier, {\n withRoles: true,\n });\n this.checkAccountBlocked(user);\n const dummyOtp = this.getDummyOtpForUser(user);\n\n if (dummyOtp) {\n if (otp !== dummyOtp) {\n throw new UnauthorizedException(ERROR_MESSAGES.INVALID_OTP);\n }\n return this.buildLoginTokenResponse(user);\n }\n\n try {\n this.validateLoginOtp(user, otp, type);\n } catch (e) {\n await this.incrementFailedAttempts(user);\n throw e;\n }\n\n await this.clearLoginOtp(user, type);\n await this.userActivityHistoryService.logEvent(\"login\", user);\n await this.resetFailedAttempts(user);\n return this.buildLoginTokenResponse(user);\n }\n\n private validateLoginOtp(\n user: User,\n otp: string,\n type: PasswordlessLoginValidateWhatSources,\n ): void {\n const isEmail = type === PasswordlessLoginValidateWhatSources.EMAIL;\n const token = isEmail\n ? user.emailVerificationTokenOnLogin\n : user.mobileVerificationTokenOnLogin;\n const expiresAt = isEmail\n ? user.emailVerificationTokenOnLoginExpiresAt\n : user.mobileVerificationTokenOnLoginExpiresAt;\n\n if (token !== otp) {\n throw new UnauthorizedException(ERROR_MESSAGES.INVALID_OTP);\n }\n if (expiresAt < new Date()) {\n throw new UnauthorizedException(ERROR_MESSAGES.OTP_EXPIRED);\n }\n }\n\n private async clearLoginOtp(\n user: User,\n type: PasswordlessLoginValidateWhatSources,\n ): Promise<void> {\n if (type === PasswordlessLoginValidateWhatSources.EMAIL) {\n const verifiedAt = new Date();\n user.emailVerifiedOnLoginAt = verifiedAt;\n user.emailVerificationTokenOnLogin = null;\n user.emailVerificationTokenOnLoginExpiresAt = null;\n await this.userRepository.update(user.id, {\n emailVerifiedOnLoginAt: verifiedAt,\n emailVerificationTokenOnLogin: null,\n emailVerificationTokenOnLoginExpiresAt: null,\n });\n } else {\n const verifiedAt = new Date();\n user.mobileVerifiedOnLoginAt = verifiedAt;\n user.mobileVerificationTokenOnLogin = null;\n user.mobileVerificationTokenOnLoginExpiresAt = null;\n await this.userRepository.update(user.id, {\n mobileVerifiedOnLoginAt: verifiedAt,\n mobileVerificationTokenOnLogin: null,\n mobileVerificationTokenOnLoginExpiresAt: null,\n });\n }\n }\n\n private buildUserPayload(user: User) {\n const { id, username, email, mobile, lastLoginProvider } = user;\n const roles = user.roles.map((role) => role.name);\n return { id, username, email, mobile, lastLoginProvider, roles };\n }\n\n private async buildLoginTokenResponse(user: User) {\n const { accessToken, refreshToken } = await this.generateTokens(user);\n return { accessToken, refreshToken, user: this.buildUserPayload(user) };\n }\n\n async changePassword(\n changePasswordDto: ChangePasswordDto,\n activeUser: ActiveUserData,\n ) {\n const user = await this.userRepository.findOne({\n where: { id: changePasswordDto.id },\n });\n if (!user) {\n throw new NotFoundException(ERROR_MESSAGES.USER_NOT_FOUND);\n }\n\n if (!user.active) {\n throw new UnauthorizedException(ERROR_MESSAGES.USER_INACTIVE);\n }\n\n // 2. Validate if user has used a provider which is \"local\", only then it makes sense for us to initiate the forgot password routine.\n if (user.lastLoginProvider !== \"local\") {\n throw new BadRequestException(ERROR_MESSAGES.NON_LOCAL_PROVIDER);\n }\n\n // Check if ID's match\n if (!(user.id === activeUser.sub)) {\n throw new BadRequestException(ERROR_MESSAGES.USER_ID_MISMATCH);\n }\n\n // Check if username's match\n if (!(user.username === activeUser.username)) {\n throw new BadRequestException(ERROR_MESSAGES.USERNAME_MISMATCH);\n }\n\n // Check if old password is matching.\n const isEqual = await this.hashingService.compare(\n changePasswordDto.currentPassword,\n user.password,\n user.passwordSchemeVersion,\n );\n if (!isEqual) {\n throw new UnauthorizedException(\n ERROR_MESSAGES.INCORRECT_CURRENT_PASSWORD,\n );\n }\n\n // Update Password\n const pwdData = await this.userService.hashPassword(\n changePasswordDto.newPassword,\n );\n user.password = changePasswordDto.newPassword;\n\n user.password = pwdData.password;\n user.passwordScheme = pwdData.passwordScheme;\n user.passwordSchemeVersion = pwdData.passwordSchemeVersion;\n // Everytime the user changes the password we reset the forcePasswordChange flag back to false.\n user.forcePasswordChange = false;\n\n await this.userRepository.save(user);\n\n return true;\n }\n\n // generate uuid token for forgot password\n private async generateForgotPasswordToken(user?: User) {\n const expiryTime = new Date();\n const forgotPasswordVerificationTokenExpiry =\n this.settingService.getConfigValue<SolidCoreSetting>(\n \"forgotPasswordVerificationTokenExpiry\",\n );\n const dummyOtp = this.getDummyOtpForUser(user);\n expiryTime.setMinutes(\n expiryTime.getMinutes() + forgotPasswordVerificationTokenExpiry,\n );\n\n return {\n token: dummyOtp ? dummyOtp : uuidv4(),\n expiresAt: expiryTime,\n };\n }\n\n async initiateForgotPassword(\n initiateForgotPasswordDto: InitiateForgotPasswordDto,\n ) {\n // Steps / Algorithm:\n // 1. Identify the user using the specified \"username\", if not found exit.\n // const user = await this.userRepository.findOne({\n // where: { username: initiateForgotPasswordDto.username, }\n // });\n const user = await this.resolveUser(\n initiateForgotPasswordDto.username,\n initiateForgotPasswordDto.email,\n );\n\n let isValidUser = true; // Instead of throwing exceptions we will simply return success message, this is to avoid user enumeration attacks.\n if (!user) {\n isValidUser = false;\n // throw new NotFoundException(ERROR_MESSAGES.INVALID_CREDENTIALS);\n }\n if (isValidUser && !user?.active) {\n isValidUser = false;\n // throw new UnauthorizedException(ERROR_MESSAGES.INVALID_CREDENTIALS);\n }\n\n // 2. Validate if user has used a provider which is \"local\", only then it makes sense for us to initiate the forgot password routine.\n if (isValidUser && user?.lastLoginProvider !== \"local\") {\n isValidUser = false;\n // throw new BadRequestException(ERROR_MESSAGES.INVALID_CREDENTIALS);\n }\n\n // 3. Generate a 6 digit validation token, we send this token to the user over their email & mobile number (controlled using configuration).\n // 4. Save this validation token in new fields on the user record.\n if (isValidUser) {\n const { token, expiresAt } = await this.generateForgotPasswordToken(user);\n user.verificationTokenOnForgotPassword = token;\n user.verificationTokenOnForgotPasswordExpiresAt = expiresAt;\n await this.userRepository.save(user);\n await this.notifyUserOnForgotPassword(user);\n }\n\n // 5. Return.\n return {\n status: \"success\",\n message: SUCCESS_MESSAGES.FORGOT_PASSWORD_TOKEN_SENT,\n error: \"\",\n errorCode: \"\",\n data: {\n user: {\n email: user?.email,\n // mobile: user.mobile,\n // username: user.username,\n },\n },\n };\n }\n\n private async notifyUserOnForgotPassword(user: User) {\n const companyLogo = await this.getCompanyLogo();\n\n const forgotPasswordSendVerificationTokenOn =\n this.settingService.getConfigValue<SolidCoreSetting>(\n \"forgotPasswordSendVerificationTokenOn\",\n );\n\n if (\n forgotPasswordSendVerificationTokenOn ==\n ForgotPasswordSendVerificationTokenOn.EMAIL\n ) {\n const mailService = this.mailServiceFactory.getMailService();\n mailService.sendEmailUsingTemplate(\n user.email,\n \"forgot-password\",\n {\n solidAppName:\n this.settingService.getConfigValue<SolidCoreSetting>(\"appTitle\"),\n solidAppWebsiteUrl:\n this.settingService.getConfigValue<SolidCoreSetting>(\n \"solidAppWebsiteUrl\",\n ),\n firstName: user.username,\n fullName: user.fullName,\n // TODO: Need to prefix this with the page url where the forgot password page will open up.\n passwordResetLink: `${this.settingService.getConfigValue<SolidCoreSetting>(\"frontendForgotPasswordPageUrl\")}?token=${user.verificationTokenOnForgotPassword}`,\n companyLogoUrl: companyLogo,\n },\n this.settingService.getConfigValue<SolidCoreSetting>(\n \"shouldQueueEmails\",\n ),\n null,\n null,\n \"user\",\n user.id,\n );\n }\n // Assuming all users do not have mobile as mandatory.\n if (\n forgotPasswordSendVerificationTokenOn ==\n ForgotPasswordSendVerificationTokenOn.MOBILE &&\n user.mobile\n ) {\n const smsService = this.smsFactory.getSmsService();\n smsService.sendSMSUsingTemplate(\n user.mobile,\n \"forgot-password\",\n {\n solidAppName:\n this.settingService.getConfigValue<SolidCoreSetting>(\"appTitle\"),\n otp: user.verificationTokenOnForgotPassword,\n verificationTokenOnForgotPassword:\n user.verificationTokenOnForgotPassword,\n firstName: user.username,\n companyLogoUrl: companyLogo,\n },\n this.settingService.getConfigValue<SolidCoreSetting>(\"shouldQueueSms\"),\n );\n }\n }\n\n async confirmForgotPassword(\n confirmForgotPasswordDto: ConfirmForgotPasswordDto,\n ) {\n return this.dataSource.transaction(async (m) => {\n // Resolve the user id first (by username/email), but DON'T check the token in JS.\n const user = await this.resolveUserByVerificationToken(\n confirmForgotPasswordDto.verificationToken,\n );\n if (!user) throw new UnauthorizedException(\"Invalid verification token\");\n if (user.lastLoginProvider !== \"local\")\n throw new UnauthorizedException(ERROR_MESSAGES.INVALID_CREDENTIALS);\n if (!user.active) throw new UnauthorizedException(\"User is inactive\");\n\n // 1) Atomically consume the token (only one request can succeed)\n const { affected } = await m\n .createQueryBuilder()\n .update(User)\n .set({\n forgotPasswordConfirmedAt: () => \"NOW()\",\n verificationTokenOnForgotPassword: () => \"NULL\",\n verificationTokenOnForgotPasswordExpiresAt: () => \"NULL\",\n })\n .where(\"id = :id\", { id: user.id })\n .andWhere(\"verificationTokenOnForgotPassword = :token\", {\n token: confirmForgotPasswordDto.verificationToken,\n })\n .andWhere(\"verificationTokenOnForgotPasswordExpiresAt > NOW()\")\n .execute();\n\n if (affected !== 1) {\n // Token invalid/expired/already used (or a parallel call already consumed it)\n throw new UnauthorizedException(ERROR_MESSAGES.INVALID_CREDENTIALS);\n }\n\n // 2) Now update the password & history (still inside the same transaction)\n const pwdHash = await this.hashingService.hash(\n confirmForgotPasswordDto.password,\n );\n const pwdScheme = this.hashingService.name(); // e.g. bcrypt\n const pwdSchemeVersion = this.hashingService.currentVersion(); // e.g. 1, 2, 3 ...\n\n // Check reuse with your existing method (ensure it looks at hashes).\n await m.getRepository(User).update(\n { id: user.id },\n {\n password: pwdHash,\n passwordScheme: pwdScheme,\n passwordSchemeVersion: pwdSchemeVersion,\n },\n );\n await this.notifyUserOnPasswordChanged(user);\n\n return {\n status: \"success\",\n message: SUCCESS_MESSAGES.FORGOT_PASSWORD_CONFIRMED,\n error: \"\",\n errorCode: \"\",\n data: {},\n };\n });\n }\n\n private async notifyUserOnPasswordChanged(user: User) {\n const companyLogo = await this.getCompanyLogo();\n const forgotPasswordSendVerificationTokenOn =\n this.settingService.getConfigValue<SolidCoreSetting>(\n \"forgotPasswordSendVerificationTokenOn\",\n );\n\n if (\n forgotPasswordSendVerificationTokenOn ==\n ForgotPasswordSendVerificationTokenOn.EMAIL\n ) {\n const mailService = this.mailServiceFactory.getMailService();\n mailService.sendEmailUsingTemplate(\n user.email,\n \"password-changed\",\n {\n solidAppName:\n this.settingService.getConfigValue<SolidCoreSetting>(\"appTitle\"),\n solidAppWebsiteUrl:\n this.settingService.getConfigValue<SolidCoreSetting>(\n \"solidAppWebsiteUrl\",\n ),\n email: user.email,\n firstName: user.username,\n fullName: user.fullName,\n // TODO: Need to prefix this with the page url where the forgot password page will open up.\n passwordResetLink: `${this.settingService.getConfigValue<SolidCoreSetting>(\"frontendForgotPasswordPageUrl\")}?token=${user.verificationTokenOnForgotPassword}`,\n companyLogoUrl: companyLogo,\n },\n this.settingService.getConfigValue<SolidCoreSetting>(\n \"shouldQueueEmails\",\n ),\n null,\n null,\n \"user\",\n user.id,\n );\n }\n // Assuming all users do not have mobile as mandatory.\n if (\n forgotPasswordSendVerificationTokenOn ==\n ForgotPasswordSendVerificationTokenOn.MOBILE &&\n user.mobile\n ) {\n const smsService = this.smsFactory.getSmsService();\n smsService.sendSMSUsingTemplate(\n user.mobile,\n \"forgot-password\",\n {\n solidAppName:\n this.settingService.getConfigValue<SolidCoreSetting>(\"appTitle\"),\n otp: user.verificationTokenOnForgotPassword,\n verificationTokenOnForgotPassword:\n user.verificationTokenOnForgotPassword,\n firstName: user.username,\n companyLogoUrl: companyLogo,\n },\n this.settingService.getConfigValue<SolidCoreSetting>(\"shouldQueueSms\"),\n );\n }\n }\n\n /**\n * @param deviceId optional stable per-device identifier. Supplied by callers\n * that own a device credential; otherwise a key is minted per login so that\n * clients with no device concept (the web UI) still get their own bucket\n * instead of sharing - and evicting - one.\n */\n async generateTokens(user: User, deviceId?: string) {\n const sessionId = this.shouldPreventConcurrentLogins()\n ? randomUUID()\n : undefined;\n if (sessionId) {\n await this.activeSessionStorage.setActiveSession(user.id, sessionId);\n } else {\n await this.activeSessionStorage.clearActiveSession(user.id);\n }\n\n // Mutually exclusive with sessionId by construction: per-device buckets\n // exist only when preventConcurrentLogins is off, sessionId only when it\n // is on.\n const deviceKey = this.refreshTokenIdsStorage.areConcurrentLoginsAllowed()\n ? deviceId ?? randomUUID()\n : undefined;\n\n const [accessToken, refreshToken] = await Promise.all([\n await this.generateAccessToken(user, sessionId, deviceKey),\n await this.generateRefreshToken(user, undefined, deviceKey),\n ]);\n\n return {\n accessToken,\n refreshToken,\n };\n }\n\n async generateAccessToken(user: User, sessionId?: string, deviceKey?: string) {\n // const userRoleNames = user.roles.map((role) => role.name).join(';')\n const userRoleNames = user.roles.map((role) => role.name);\n const resolvedSessionId = this.shouldPreventConcurrentLogins()\n ? sessionId ?? (await this.activeSessionStorage.getActiveSession(user.id))\n : undefined;\n\n const accessTokenTtl =\n this.settingService.getConfigValue<SolidCoreSetting>(\"accessTokenTtl\");\n const accessToken = await this.signToken<Partial<ActiveUserData>>(\n user.id,\n accessTokenTtl,\n {\n username: user.username,\n email: user.email,\n roles: userRoleNames,\n ...(resolvedSessionId ? { sessionId: resolvedSessionId } : {}),\n // Carried so that bearer-authenticated endpoints which need this\n // session's refresh token - generateSsoCode, me - can locate its\n // bucket. The refresh token is not available to them.\n ...(deviceKey ? { deviceKey } : {}),\n },\n );\n\n return accessToken;\n }\n\n async generateRefreshToken(\n user: User,\n previousRefreshToken?: string,\n deviceKey?: string,\n ) {\n const refreshTokenId = randomUUID();\n const refreshTokenTtl =\n this.settingService.getConfigValue<SolidCoreSetting>(\"refreshTokenTtl\");\n\n // Only per-device tokens carry an epoch - it is what makes bulk\n // invalidation possible without enumerating buckets. Single-slot tokens\n // are invalidated by deleting their one key.\n const epoch = deviceKey\n ? await this.refreshTokenIdsStorage.getEpoch(user.id)\n : undefined;\n\n const refreshToken = await this.signToken(user.id, refreshTokenTtl, {\n refreshTokenId,\n ...(deviceKey ? { deviceKey } : {}),\n ...(epoch !== undefined ? { epoch } : {}),\n });\n\n // store the refresh token id in the redis storage.\n await this.refreshTokenIdsStorage.insert(\n user.id,\n refreshToken,\n previousRefreshToken,\n deviceKey,\n );\n\n return refreshToken;\n }\n\n async refreshTokens(refreshTokenDto: RefreshTokenDto) {\n try {\n const secret =\n this.settingService.getConfigValue<SolidCoreSetting>(\"secret\");\n const audience =\n this.settingService.getConfigValue<SolidCoreSetting>(\"audience\");\n const issuer =\n this.settingService.getConfigValue<SolidCoreSetting>(\"issuer\");\n\n // deviceKey/epoch are absent on tokens issued before per-device sessions,\n // and on tokens issued while preventConcurrentLogins is on. That absence\n // is the signal the storage layer branches on - no request-body change\n // and no client change is needed to carry it.\n const { sub, deviceKey, epoch } = await this.jwtService.verifyAsync<\n Pick<ActiveUserData, \"sub\"> & {\n refreshTokenId: string;\n deviceKey?: string;\n epoch?: number;\n }\n >(refreshTokenDto.refreshToken, {\n secret,\n audience,\n issuer,\n });\n // const user = await this.userRepository.findOneByOrFail({ id: sub });\n const user = await this.userRepository.findOne({\n where: {\n id: sub,\n },\n relations: {\n roles: true,\n },\n });\n if (!user) {\n throw new UnauthorizedException(ERROR_MESSAGES.SESSION_INVALID);\n }\n\n // TODO: Replace the if else condition below with a call to validateAndRotate - Done\n // const isValid = await this.refreshTokenIdsStorage.validate(user.id, refreshTokenId);\n // if (isValid) {\n // // Refresh token rotation.\n // await this.refreshTokenIdsStorage.invalidate(user.id);\n // } else {\n // throw new Error('Refresh token is invalid');\n // }\n\n const rotated = await this.refreshTokenIdsStorage.validateAndRotate(\n user,\n refreshTokenDto.refreshToken,\n { deviceKey, epoch },\n );\n\n await this.userActivityHistoryService.logEvent(\"tokenRefreshed\", user);\n\n return {\n // The rotated key, not the incoming one: a session migrating out of the\n // pre-deploy single slot is assigned a bucket here, and the new access\n // token has to name the same one.\n accessToken: await this.generateAccessToken(\n user,\n undefined,\n rotated.deviceKey,\n ),\n refreshToken: rotated.refreshToken,\n };\n } catch (err: any) {\n if (err instanceof InvalidatedRefreshTokenError) {\n // Take action: notify user that his refresh token might have been stolen?\n throw new UnauthorizedException(ERROR_MESSAGES.ACCESS_DENIED);\n }\n\n throw new UnauthorizedException(ERROR_MESSAGES.SESSION_EXPIRED);\n }\n }\n\n private async signToken<T>(userId: number, expiresIn: number, payload?: T) {\n const audience =\n this.settingService.getConfigValue<SolidCoreSetting>(\"audience\");\n const issuer =\n this.settingService.getConfigValue<SolidCoreSetting>(\"issuer\");\n const secret =\n this.settingService.getConfigValue<SolidCoreSetting>(\"secret\");\n\n return await this.jwtService.signAsync(\n {\n sub: userId,\n ...payload,\n },\n {\n audience,\n issuer,\n secret,\n expiresIn,\n },\n );\n }\n\n // PROVIDER SPECIFIC CODE\n async validateUserUsingGoogle(user: User) {\n try {\n // Make API call to Google OAuth service to fetch user profile\n const response = await this.httpService.axiosRef.get(\n `https://www.googleapis.com/oauth2/v1/userinfo?alt=json&access_token=${user.googleAccessToken}`,\n );\n const userProfile = response.data;\n\n // Ensure the fetched profile email & provider Id match the ones we have stored in the database earlier.\n if (\n userProfile.email === user.email &&\n userProfile.id === user.googleId\n ) {\n // TODO: remove the access code both from the database.\n return userProfile;\n } else {\n throw new UnauthorizedException(ERROR_MESSAGES.INVALID_USER_PROFILE);\n }\n } catch (error: any) {\n throw new UnauthorizedException(\n ERROR_MESSAGES.GOOGLE_OAUTH_PROFILE_FETCH_FAILED,\n );\n }\n }\n\n async signInUsingGoogle(accessCode: string) {\n const user = await this.userRepository.findOne({\n where: {\n accessCode: accessCode,\n },\n relations: {\n roles: true,\n },\n });\n\n if (!user) {\n throw new UnauthorizedException(ERROR_MESSAGES.USER_NOT_FOUND);\n }\n this.checkAccountBlocked(user);\n\n try {\n await this.validateUserUsingGoogle(user);\n } catch (e) {\n await this.incrementFailedAttempts(user);\n throw e;\n }\n\n await this.resetFailedAttempts(user);\n const tokens = await this.generateTokens(user);\n return {\n user: {\n email: user.email,\n mobile: user.mobile,\n username: user.username,\n // forcePasswordChange: user.forcePasswordChange,\n id: user.id,\n roles: user.roles.map((role) => role.name),\n },\n ...tokens,\n };\n }\n\n async validateUserUsingFacebook(user: User) {\n if (!user.facebookAccessToken || !user.facebookId) {\n throw new UnauthorizedException(ERROR_MESSAGES.USER_NOT_FOUND);\n }\n\n try {\n const response = await this.httpService.axiosRef.get(\n `https://graph.facebook.com/me`,\n {\n params: { fields: \"id,name,email\" },\n headers: {\n Authorization: `Bearer ${user.facebookAccessToken}`,\n },\n },\n );\n const userProfile = response.data;\n\n if (\n userProfile.id === user.facebookId &&\n (!user.email || !userProfile.email || userProfile.email === user.email)\n ) {\n return userProfile;\n } else {\n throw new UnauthorizedException(ERROR_MESSAGES.INVALID_USER_PROFILE);\n }\n } catch (error: any) {\n if (error instanceof UnauthorizedException) {\n throw error;\n }\n throw new UnauthorizedException(ERROR_MESSAGES.USER_NOT_FOUND);\n }\n }\n\n async signInUsingFacebook(accessCode: string) {\n const user = await this.userRepository.findOne({\n where: {\n accessCode: accessCode,\n },\n relations: {\n roles: true,\n },\n });\n\n if (!user) {\n throw new UnauthorizedException(ERROR_MESSAGES.USER_NOT_FOUND);\n }\n this.checkAccountBlocked(user);\n\n try {\n await this.validateUserUsingFacebook(user);\n } catch (e) {\n await this.incrementFailedAttempts(user);\n throw e;\n }\n\n await this.resetFailedAttempts(user);\n const tokens = await this.generateTokens(user);\n return {\n user: {\n email: user.email,\n mobile: user.mobile,\n username: user.username,\n id: user.id,\n roles: user.roles.map((role) => role.name),\n },\n ...tokens,\n };\n }\n\n async validateUserUsingMicrosoft(user: User) {\n try {\n const response = await this.httpService.axiosRef.get(\n `https://graph.microsoft.com/v1.0/me`,\n {\n headers: {\n Authorization: `Bearer ${user.microsoftAccessToken}`,\n },\n },\n );\n const userProfile = response.data;\n const profileEmail = userProfile.mail || userProfile.userPrincipalName;\n\n if (\n userProfile.id === user.microsoftId &&\n (!user.email || profileEmail === user.email)\n ) {\n return userProfile;\n } else {\n throw new UnauthorizedException(ERROR_MESSAGES.INVALID_USER_PROFILE);\n }\n } catch (error: any) {\n throw new UnauthorizedException(\"Microsoft OAuth profile fetch failed\");\n }\n }\n\n async signInUsingMicrosoft(accessCode: string) {\n const user = await this.userRepository.findOne({\n where: {\n accessCode: accessCode,\n },\n relations: {\n roles: true,\n },\n });\n\n if (!user) {\n throw new UnauthorizedException(ERROR_MESSAGES.USER_NOT_FOUND);\n }\n this.checkAccountBlocked(user);\n\n try {\n await this.validateUserUsingMicrosoft(user);\n } catch (e) {\n await this.incrementFailedAttempts(user);\n throw e;\n }\n\n await this.resetFailedAttempts(user);\n const tokens = await this.generateTokens(user);\n return {\n user: {\n email: user.email,\n mobile: user.mobile,\n username: user.username,\n id: user.id,\n roles: user.roles.map((role) => role.name),\n },\n ...tokens,\n };\n }\n\n async validateUserUsingMicrosoftActiveDirectory(user: User) {\n if (\n !user.microsoftActiveDirectoryAccessToken ||\n !user.microsoftActiveDirectoryId\n ) {\n throw new UnauthorizedException(ERROR_MESSAGES.USER_NOT_FOUND);\n }\n\n try {\n const response = await this.httpService.axiosRef.get(\n `https://graph.microsoft.com/v1.0/me?$select=id,displayName,mail,userPrincipalName`,\n {\n headers: {\n Authorization: `Bearer ${user.microsoftActiveDirectoryAccessToken}`,\n },\n },\n );\n const userProfile = response.data;\n const profileEmail = (userProfile.mail || userProfile.userPrincipalName)\n ?.trim()\n .toLowerCase();\n const userEmail = user.email?.trim().toLowerCase();\n\n if (\n userProfile.id === user.microsoftActiveDirectoryId &&\n (!userEmail || profileEmail === userEmail)\n ) {\n return userProfile;\n } else {\n throw new UnauthorizedException(ERROR_MESSAGES.INVALID_USER_PROFILE);\n }\n } catch (error: any) {\n if (error instanceof UnauthorizedException) {\n throw error;\n }\n\n throw new UnauthorizedException(\n ERROR_MESSAGES.MICROSOFT_ACTIVE_DIRECTORY_OAUTH_PROFILE_FETCH_FAILED,\n );\n }\n }\n\n async signInUsingMicrosoftActiveDirectory(accessCode: string) {\n const user = await this.userRepository.findOne({\n where: {\n accessCode: accessCode,\n },\n relations: {\n roles: true,\n },\n });\n\n if (!user) {\n throw new UnauthorizedException(ERROR_MESSAGES.USER_NOT_FOUND);\n }\n this.checkAccountBlocked(user);\n\n try {\n await this.validateUserUsingMicrosoftActiveDirectory(user);\n } catch (e) {\n await this.incrementFailedAttempts(user);\n throw e;\n }\n\n await this.resetFailedAttempts(user);\n const tokens = await this.generateTokens(user);\n return {\n user: {\n email: user.email,\n mobile: user.mobile,\n username: user.username,\n id: user.id,\n roles: user.roles.map((role) => role.name),\n },\n ...tokens,\n };\n }\n\n async signInUsingApple(accessCode: string) {\n const user = await this.userRepository.findOne({\n where: {\n accessCode: accessCode,\n },\n relations: {\n roles: true,\n },\n });\n\n if (!user) {\n throw new UnauthorizedException(ERROR_MESSAGES.USER_NOT_FOUND);\n }\n this.checkAccountBlocked(user);\n\n // Apple OAuth token validation is typically handled by the strategy itself\n // as it involves verifying the JWT idToken.\n // If we want to re-verify here, we'd need to verify the appleAccessToken or idToken.\n // For now, we follow the pattern of trust in the accessCode generated after successful strategy validation.\n\n await this.resetFailedAttempts(user);\n const tokens = await this.generateTokens(user);\n return {\n user: {\n email: user.email,\n mobile: user.mobile,\n username: user.username,\n id: user.id,\n roles: user.roles.map((role) => role.name),\n },\n ...tokens,\n };\n }\n\n private async isPasswordlessRegistrationEnabled() {\n // return this.settingService.getConfigValue<SolidCoreSetting>('passwordlessRegistration');\n return this.settingService.getConfigValue<SolidCoreSetting>(\n \"passwordLessAuth\",\n );\n }\n\n private shouldPreventConcurrentLogins(): boolean {\n return (\n this.settingService.getConfigValue<SolidCoreSetting>(\n \"preventConcurrentLogins\",\n ) === true\n );\n }\n\n private checkAccountBlocked(user: User): void {\n const maxFailedAttempts =\n this.settingService.getConfigValue<SolidCoreSetting>(\n \"maxFailedLoginAttempts\",\n ) as number;\n if (\n maxFailedAttempts > 0 &&\n user.failedLoginAttempts >= maxFailedAttempts\n ) {\n throw new ForbiddenException(ERROR_MESSAGES.ACCOUNT_BLOCKED);\n }\n }\n\n private async incrementFailedAttempts(user: User): Promise<void> {\n const nextFailedAttempts = (user.failedLoginAttempts ?? 0) + 1;\n user.failedLoginAttempts = nextFailedAttempts;\n await this.userRepository.update(user.id, {\n failedLoginAttempts: nextFailedAttempts,\n });\n }\n\n private async resetFailedAttempts(user: User): Promise<void> {\n if (user.failedLoginAttempts === 0) return;\n user.failedLoginAttempts = 0;\n await this.userRepository.update(user.id, { failedLoginAttempts: 0 });\n }\n\n //FIXME - Pending implementation\n // async logout() {\n // // const user = this.request.user; //TODO: // Access the user from the execution context\n\n // // Invalidate the refresh token\n // // await this.refreshTokenIdsStorage.invalidate(user.id);\n // }\n async logout(refreshToken: string, allDevices = false) {\n try {\n const payload = await this.verifyRefreshTokenForLogout(refreshToken);\n\n // Nothing verifiable to act on: forged, malformed, or signed with another\n // secret. Acting on an unauthenticated `sub` is exactly the hole this\n // closes - the route is @Public(), so a decoded-but-unverified token let\n // anyone log out an arbitrary user. Report success either way: logout\n // must be safe to call blindly from a client error path, and a 401/200\n // split here would leak whether a token string is genuine (RFC 7009 §2.2\n // takes the same position for revocation endpoints).\n if (!payload?.sub) {\n this.logger.warn(\"logout called with an unverifiable refresh token\");\n return { message: SUCCESS_MESSAGES.LOGOUT_SUCCESS };\n }\n\n const userId = payload.sub;\n\n if (allDevices) {\n // Deliberately not gated on session ownership: \"log out everywhere\"\n // treats any verifiable refresh token as sufficient authority, which is\n // what invalidateAll already accepts.\n await this.refreshTokenIdsStorage.invalidateAll(userId);\n await this.accessTokenDenylist.revokeAllForUser(userId);\n } else if (await this.ownsLiveSession(userId, payload, refreshToken)) {\n // Scoped to the bucket this token belongs to, so signing out on one\n // device leaves the others alive. A token with no deviceKey names the\n // single slot, which is the same key as before.\n await this.refreshTokenIdsStorage.invalidate(userId, payload.deviceKey);\n await this.accessTokenDenylist.revokeSession(\n userId,\n await this.resolveRevocationKey(userId, payload),\n );\n await this.activeSessionStorage.clearActiveSession(userId);\n } else {\n // The token names a session that is already gone - superseded by a\n // newer login into the same bucket. Acting on it would destroy the\n // session that replaced it. Nothing to do, but log it: the failure is\n // otherwise invisible, and a cluster of these means clients are losing\n // token state and their logouts are no-ops.\n this.logger.warn(\n `logout: refresh token does not match the live session for user ${userId}; nothing invalidated`,\n );\n }\n\n const user = await this.userRepository.findOne({\n where: {\n id: userId,\n },\n });\n // Log logout event\n if (user) {\n await this.userActivityHistoryService.logEvent(\"logout\", user);\n }\n\n return { message: SUCCESS_MESSAGES.LOGOUT_SUCCESS };\n } catch (err: any) {\n // JWT problems no longer reach here - verifyRefreshTokenForLogout\n // swallows them - so this is left for genuine infrastructure failures\n // (cache or database unavailable), where a 500 is the correct answer.\n throw err instanceof UnauthorizedException ||\n err instanceof InternalServerErrorException\n ? err\n : new InternalServerErrorException(ERROR_MESSAGES.LOGOUT_FAILED);\n }\n }\n\n /**\n * Whether this refresh token belongs to the session that currently occupies\n * its bucket.\n *\n * A per-device bucket holds exactly one session - deviceKey is a fresh\n * randomUUID per login - so a token carrying one is that session by\n * construction and needs no further proof. Only the bare `user-<id>` bucket\n * is shared across logins (preventConcurrentLogins on, or a pre-migration\n * token), and that is the sole case where a stale token can name a session\n * that has since been replaced. Without this, a laptop whose session was\n * superseded by a phone login would, on logging out, destroy the phone's\n * session instead of its own.\n *\n * Matches current OR previous, and deliberately does not consult\n * isWithinGraceWindow: that window governs whether a rotated-out token may\n * still be exchanged, whereas the question here is only which session the\n * token belongs to - which stays true however long ago it rotated.\n *\n * Missing state means it owns nothing. Safe, because the refresh state and\n * active-session entry share one cache: if the state is gone the session\n * entry is too, so the actions being skipped were no-ops anyway.\n */\n private async ownsLiveSession(\n userId: number,\n payload: { deviceKey?: string },\n refreshToken: string,\n ): Promise<boolean> {\n if (payload.deviceKey) {\n return true;\n }\n\n const state =\n await this.refreshTokenIdsStorage.getCurrentRefreshTokenState(userId);\n return (\n state?.currentRefreshToken === refreshToken ||\n (!!state?.previousRefreshToken &&\n state.previousRefreshToken === refreshToken)\n );\n }\n\n /**\n * The key a session's access tokens are denylisted under. Mirrors how the\n * access token itself is stamped: deviceKey while concurrent logins are\n * allowed, sessionId while they are not - and in the latter case only one\n * session exists, so the recorded active session IS this session's id.\n *\n * Must be read before clearActiveSession, which deletes the value it reads.\n */\n private async resolveRevocationKey(\n userId: number,\n payload: { deviceKey?: string },\n ): Promise<string | undefined> {\n return (\n payload.deviceKey ??\n (await this.activeSessionStorage.getActiveSession(userId))\n );\n }\n\n /**\n * Public seam for consuming projects that need a logout of their own shape -\n * for instance revoking the access token while deliberately leaving the\n * refresh token valid.\n *\n * Verifies the refresh token (signature/audience/issuer enforced, expiry\n * tolerated), confirms it owns the live session, and returns the key its\n * access tokens are denylisted under.\n *\n * null - unverifiable: forged, malformed, or an access\n * token presented here\n * revocationKey undefined - verified, but nothing safe to revoke: either a\n * superseded session, or no session key could be\n * resolved. userId is still returned so the caller\n * can log the event or call revokeAllForUser.\n *\n * logout() uses this same method, so the seam cannot silently rot.\n */\n async resolveSessionRevocationKey(\n refreshToken: string,\n ): Promise<{ userId: number; revocationKey?: string } | null> {\n const payload = await this.verifyRefreshTokenForLogout(refreshToken);\n if (!payload?.sub) {\n return null;\n }\n\n const userId = payload.sub;\n if (!(await this.ownsLiveSession(userId, payload, refreshToken))) {\n return { userId };\n }\n\n return {\n userId,\n revocationKey: await this.resolveRevocationKey(userId, payload),\n };\n }\n\n private async verifyRefreshTokenForLogout(\n refreshToken: string,\n ): Promise<{ sub: number; deviceKey?: string } | null> {\n try {\n const payload = await this.jwtService.verifyAsync(refreshToken, {\n secret: this.settingService.getConfigValue<SolidCoreSetting>(\"secret\"),\n audience:\n this.settingService.getConfigValue<SolidCoreSetting>(\"audience\"),\n issuer: this.settingService.getConfigValue<SolidCoreSetting>(\"issuer\"),\n // Signature, audience and issuer are still enforced; only `exp` is\n // tolerated. An expired session must still be able to log out - the\n // previous jwtService.decode() allowed that, and a plain verifyAsync\n // would throw TokenExpiredError, which the catch above would turn into\n // a 500 on an ordinary sign-out.\n ignoreExpiration: true,\n });\n\n // Access and refresh tokens share secret, audience and issuer, so only\n // this claim distinguishes them. Reject an access token presented here.\n return payload?.refreshTokenId ? payload : null;\n } catch {\n return null; // bad signature or malformed\n }\n }\n\n async activateUser(userId: number) {\n const user = await this.userService.findOne(userId, {});\n if (!user) {\n throw new NotFoundException(ERROR_MESSAGES.USER_NOT_FOUND);\n }\n user.active = true;\n await this.userRepository.save(user);\n }\n\n async me(activeUser: ActiveUserData) {\n const user = await this.userRepository.findOne({\n where: {\n id: activeUser.sub,\n },\n relations: {\n roles: true,\n },\n });\n\n // const tokens = await this.generateTokens(user);\n\n // Get the refresh token for a user from refresh token storage. The bucket\n // is named by the access token's own deviceKey claim; absent for\n // single-slot sessions, which resolves to the same key as before.\n const refreshTokenState =\n await this.refreshTokenIdsStorage.getCurrentRefreshTokenState(\n user.id,\n activeUser.deviceKey,\n );\n\n const response = {\n user: {\n email: user.email,\n mobile: user.mobile,\n username: user.username,\n // forcePasswordChange: user.forcePasswordChange,\n id: user.id,\n roles: user.roles.map((role) => role.name),\n },\n // Null-guarded because the cache entry now carries a TTL: once it\n // expires - or after a logout followed by a call with a still-valid\n // access token - there is no state to read. Matches the existing\n // handling in generateSsoCode.\n refreshToken: refreshTokenState?.currentRefreshToken ?? null,\n // ...tokens\n };\n return response;\n }\n\n async generateSsoCode(\n activeUser: ActiveUserData,\n rawAccessToken: string,\n ): Promise<{ ssoCode: string }> {\n const refreshTokenState =\n await this.refreshTokenIdsStorage.getCurrentRefreshTokenState(\n activeUser.sub,\n activeUser.deviceKey,\n );\n if (!refreshTokenState?.currentRefreshToken) {\n throw new UnauthorizedException(\"No active session found\");\n }\n const ssoCode = await this.ssoCodeStorage.generateCode(\n activeUser.sub,\n rawAccessToken,\n refreshTokenState.currentRefreshToken,\n );\n return { ssoCode };\n }\n\n async exchangeSsoCode(code: string) {\n const { userId, accessToken, refreshToken } =\n await this.ssoCodeStorage.consumeCode(code);\n const user = await this.userRepository.findOne({\n where: { id: userId },\n relations: { roles: true },\n });\n if (!user) {\n throw new UnauthorizedException(\"User not found\");\n }\n return { accessToken, refreshToken, user: this.buildUserPayload(user) };\n }\n}\n\nfunction parseUniqueConstraintError(detail: string): string {\n const match = detail.match(/Key \\(([^)]+)\\)=\\(([^)]+)\\) already exists\\./);\n if (match) {\n const field = match[1];\n const value = match[2];\n const fieldMap: Record<string, string> = {\n username: \"username\",\n email: \"email address\",\n mobile: \"mobile number\",\n full_name_user_key: \"full name\",\n };\n const friendlyField = fieldMap[field] || field;\n return `A user with ${friendlyField} \"${value}\" already exists.`;\n }\n return detail;\n}\n"]}