diff --git a/src/shared/i18n/de/mail.json b/src/shared/i18n/de/mail.json index ec1071d282..7269b53c1a 100644 --- a/src/shared/i18n/de/mail.json +++ b/src/shared/i18n/de/mail.json @@ -19,6 +19,11 @@ "salutation": "Deine Online-Identifikation ist fehlgeschlagen", "body": "

Wir haben festgestellt, dass die Online-Identifizierung fehlgeschlagen ist. Wir haben jedoch bereits die Video-Identifikation freigeschaltet.
Weiter geht es, indem man auf der Payment Seite (Kaufen, Verkaufen & Staking) auf den Refresh Button (roter Pfeil in Kreisoptik) klickt oder hier.

Mache den letzten Schritt und beginne noch heute deine Reise zur finanziellen Freiheit

Dein DFX Team
Bitcoiners by heart ♥

", "title": "Online Identifikation fehlgeschlagen" + }, + "success": { + "salutation": "Verifikation erfolgreich", + "body": "
Deine Verifikation ist abgeschlossen.
Viel Erfolg beim Traden
Dein freundliches DFX Team
Bitcoiners by heart ♥️
", + "title": "Verifikation erfolgreich" } }, "stakingRef": { diff --git a/src/shared/i18n/en/mail.json b/src/shared/i18n/en/mail.json index 8bfb6f0ea1..7119c473eb 100644 --- a/src/shared/i18n/en/mail.json +++ b/src/shared/i18n/en/mail.json @@ -19,6 +19,11 @@ "salutation": "Your online identification has failed", "body": "

We have noticed that your online identification has failed. However, we have already unlocked video identification for you.
Please continue by clicking on the refresh button in the limit section on the payment page (Buy, Sell & Staking) or here.

Take the final step and start working on your financial freedom today

Your DFX Team
Bitcoiners by heart ♥

", "title": "Online identification failed" + }, + "success": { + "salutation": "Verification successful", + "body": "
Your verification is complete.
Happy Trading
Your DFX Team
Bitcoiners by heart ♥️
", + "title": "Verification successful" } }, "stakingRef": { diff --git a/src/shared/i18n/es/mail.json b/src/shared/i18n/es/mail.json index b5dff3dd69..b73d183065 100644 --- a/src/shared/i18n/es/mail.json +++ b/src/shared/i18n/es/mail.json @@ -19,6 +19,11 @@ "salutation": "Tu identificación online ha fallado", "body": "

Nos hemos dado cuenta de que tu identificación online ha fallado. De todas formas, hemos desbloquado la identificación por video para ti.
Por favor, continúa apretando el botón de refresco en la sección \"límite\" en la página de pago (Compra, Vende y Staking) o aquí.

Da el último paso y empieza a crear tu libertad financiera hoy

Tu Equipo DFX
Bitcoiners de corazón ♥

", "title": "Tu identificación online ha fallado" + }, + "success": { + "salutation": "Verificación exitosa", + "body": "
Su verificación está completa.
¡Que disfrutes al comerciar!
Tu Equipo DFX
Bitcoiners by heart ♥️
", + "title": "Verificación exitosa" } }, "stakingRef": { diff --git a/src/shared/i18n/fr/mail.json b/src/shared/i18n/fr/mail.json index 5ee6325488..7ea41b50a8 100644 --- a/src/shared/i18n/fr/mail.json +++ b/src/shared/i18n/fr/mail.json @@ -19,6 +19,11 @@ "salutation": "Votre identification en ligne a échoué", "body": "

Nous avons remarqué que votre identification en ligne a échoué. Nous avons cependant déjà débloqué l'identification vidéo pour vous.
Veuillez continuer en cliquant sur le bouton d'actualisation dans la section Limites de la page de paiement (Achat, Vente & Staking) ou ici.

Franchissez le dernier pas et développez votre liberté financière dès aujourd'hui

Votre équipe DFX
Bitcoiners de coeur ♥

", "title": "Votre identification en ligne a échoué" + }, + "success": { + "salutation": "Vérification réussie", + "body": "
Votre vérification est terminée.
Bon trading
Votre équipe DFX
Bitcoiners by heart ♥️
", + "title": "Vérification réussie" } }, "stakingRef": { diff --git a/src/shared/i18n/it/mail.json b/src/shared/i18n/it/mail.json index 585f3d9441..6cc4ddf2a3 100644 --- a/src/shared/i18n/it/mail.json +++ b/src/shared/i18n/it/mail.json @@ -19,6 +19,11 @@ "salutation": "La tua identificazione online non è riuscita", "body": "

Abbiamo notato che la sua identificazione online è fallita. Tuttavia, abbiamo già sbloccato l'identificazione video per te.
Si prega di continuare cliccando sul pulsante di aggiornamento nella sezione dei limiti della pagina di pagamento (Compra, Vendi e Staking) o qui.

Fai il passo finale e inizia a lavorare sulla tua libertà finanziaria oggi stesso

Tuo DFX team
Bitcoiners by heart ♥

", "title": "La tua identificazione online non è riuscita" + }, + "success": { + "salutation": "Verifica riuscita", + "body": "
La verifica è stata completata.
Buon trading
Tuo DFX team
Bitcoiners by heart ♥️
", + "title": "Verifica riuscita" } }, "stakingRef": { diff --git a/src/shared/i18n/pt/mail.json b/src/shared/i18n/pt/mail.json index 8bfb6f0ea1..7119c473eb 100644 --- a/src/shared/i18n/pt/mail.json +++ b/src/shared/i18n/pt/mail.json @@ -19,6 +19,11 @@ "salutation": "Your online identification has failed", "body": "

We have noticed that your online identification has failed. However, we have already unlocked video identification for you.
Please continue by clicking on the refresh button in the limit section on the payment page (Buy, Sell & Staking) or here.

Take the final step and start working on your financial freedom today

Your DFX Team
Bitcoiners by heart ♥

", "title": "Online identification failed" + }, + "success": { + "salutation": "Verification successful", + "body": "
Your verification is complete.
Happy Trading
Your DFX Team
Bitcoiners by heart ♥️
", + "title": "Verification successful" } }, "stakingRef": { diff --git a/src/user/models/kyc/kyc-process.service.ts b/src/user/models/kyc/kyc-process.service.ts index 936fe78a9f..b62dcf2dc7 100644 --- a/src/user/models/kyc/kyc-process.service.ts +++ b/src/user/models/kyc/kyc-process.service.ts @@ -1,5 +1,4 @@ import { Injectable, ServiceUnavailableException } from '@nestjs/common'; -import { UserRole } from 'src/shared/auth/user-role.enum'; import { SpiderDataRepository } from 'src/user/models/spider-data/spider-data.repository'; import { KycInProgress, KycState, KycStatus, UserData } from 'src/user/models/user-data/user-data.entity'; import { KycDocument, KycDocuments, InitiateResponse } from '../../services/spider/dto/spider.dto'; @@ -7,15 +6,16 @@ import { AccountType } from 'src/user/models/user-data/account-type.enum'; import { MailService } from 'src/shared/services/mail.service'; import { IdentResultDto } from 'src/user/models/ident/dto/ident-result.dto'; import { DocumentState, SpiderService } from 'src/user/services/spider/spider.service'; -import { UserDataService } from '../user-data/user-data.service'; +import { UserRole } from 'src/shared/auth/user-role.enum'; +import { UserRepository } from '../user/user.repository'; @Injectable() export class KycProcessService { constructor( - private readonly userDataService: UserDataService, private readonly spiderDataRepo: SpiderDataRepository, private readonly spiderService: SpiderService, private readonly mailService: MailService, + private readonly userRepo: UserRepository, ) {} // --- GENERAL METHODS --- // @@ -51,6 +51,12 @@ export class KycProcessService { const initiateData = await this.spiderService.initiateIdentification(userData.id, identType); userData.spiderData = await this.updateSpiderData(userData, initiateData); } + if (status === KycStatus.MANUAL) + await this.mailService.sendTranslatedMail({ + userData: userData, + translationKey: 'mail.kyc.success', + params: {}, + }); return this.updateKycStatus(userData, status); } @@ -99,7 +105,8 @@ export class KycProcessService { userData = await this.storeChatbotResult(userData); - const isVipUser = await this.userDataService.hasRole(userData.id, UserRole.VIP); + const isVipUser = await this.hasRole(userData.id, UserRole.VIP); + return isVipUser ? await this.goToStatus(userData, KycStatus.VIDEO_ID) : await this.goToStatus(userData, KycStatus.ONLINE_ID); @@ -179,6 +186,10 @@ export class KycProcessService { } // --- HELPER METHODS --- // + private async hasRole(userDataId: number, role: UserRole): Promise { + return await this.userRepo.findOne({ where: { userData: { id: userDataId }, role } }).then((u) => u != null); + } + private async updateSpiderData(userData: UserData, initiateData: InitiateResponse) { const sessionData = await this.getSessionData(userData, initiateData); diff --git a/src/user/models/kyc/kyc.service.ts b/src/user/models/kyc/kyc.service.ts index 908d6fbaec..cbf6600526 100644 --- a/src/user/models/kyc/kyc.service.ts +++ b/src/user/models/kyc/kyc.service.ts @@ -83,7 +83,7 @@ export class KycService { } async updateKycData(code: string, data: KycUserDataDto, userId?: number): Promise { - const user = await this.getUser(code, userId); + let user = await this.getUser(code, userId); const isPersonalAccount = (data.accountType ?? user.accountType) === AccountType.PERSONAL; // check countries @@ -102,7 +102,7 @@ export class KycService { data.organizationCountry = null; } - await this.userDataService.updateSpiderIfNeeded(user, data); + user = await this.userDataService.updateSpiderIfNeeded(user, data); const updatedUser = await this.userDataRepo.save({ ...user, ...data }); diff --git a/src/user/models/user-data/user-data.service.ts b/src/user/models/user-data/user-data.service.ts index fe523d5ae1..81bb1c633c 100644 --- a/src/user/models/user-data/user-data.service.ts +++ b/src/user/models/user-data/user-data.service.ts @@ -1,9 +1,4 @@ -import { - BadRequestException, - ConflictException, - Injectable, - NotFoundException, -} from '@nestjs/common'; +import { BadRequestException, ConflictException, Injectable, NotFoundException } from '@nestjs/common'; import { UpdateUserDataDto } from './dto/update-user-data.dto'; import { UserDataRepository } from './user-data.repository'; import { KycInProgress, KycState, UserData } from './user-data.entity'; @@ -20,6 +15,7 @@ import { UserRepository } from '../user/user.repository'; import { SpiderApiService } from 'src/user/services/spider/spider-api.service'; import { Util } from 'src/shared/util'; import { Cron, CronExpression } from '@nestjs/schedule'; +import { KycProcessService } from '../kyc/kyc-process.service'; @Injectable() export class UserDataService { @@ -32,6 +28,7 @@ export class UserDataService { private readonly fiatService: FiatService, private readonly spiderService: SpiderService, private readonly spiderApiService: SpiderApiService, + private readonly kycProcessService: KycProcessService, ) {} async getUserDataByUser(userId: number): Promise { @@ -66,7 +63,7 @@ export class UserDataService { let userData = await this.userDataRepo.findOne(userDataId); if (!userData) throw new NotFoundException('User data not found'); - userData = await this.updateUserSettings(userData, dto); + userData = await this.updateSpiderIfNeeded(userData, dto); if (dto.countryId) { userData.country = await this.countryService.getCountry(dto.countryId); @@ -78,10 +75,6 @@ export class UserDataService { if (!userData.organizationCountry) throw new BadRequestException('Country not found'); } - if (dto.kycStatus && !dto.kycState) { - dto.kycState = KycState.NA; - } - if (dto.mainBankDataId) { userData.mainBankData = await this.bankDataRepo.findOne(dto.mainBankDataId); if (!userData.mainBankData) throw new BadRequestException('Bank data not found'); @@ -104,9 +97,8 @@ export class UserDataService { ); } - if (dto.kycStatus && userData.kycStatus != dto.kycStatus) { - userData.kycStatusChangeDate = new Date(); - } + if (dto.kycStatus && userData.kycStatus != dto.kycStatus) + userData = await this.kycProcessService.goToStatus(userData, dto.kycStatus); return await this.userDataRepo.save({ ...userData, ...dto }); } @@ -125,12 +117,12 @@ export class UserDataService { } // update spider - await this.updateSpiderIfNeeded(user, dto) + user = await this.updateSpiderIfNeeded(user, dto); return this.userDataRepo.save({ ...user, ...dto }); } - async updateSpiderIfNeeded(userData: UserData, dto: UpdateUserDto) { + async updateSpiderIfNeeded(userData: UserData, dto: UpdateUserDto): Promise { if ((dto.phone && dto.phone != userData.phone) || (dto.mail && dto.mail != userData.mail)) { await this.spiderService.updateCustomer(userData.id, { telephones: dto.phone ? [dto.phone.replace('+', '').split(' ').join('')] : undefined, @@ -141,6 +133,8 @@ export class UserDataService { userData.kycState = KycState.FAILED; } } + + return userData; } // --- VOLUMES --- // @@ -203,10 +197,6 @@ export class UserDataService { await this.updateVolumes(slaveId); } - async hasRole(userDataId: number, role: UserRole): Promise { - return await this.userRepo.findOne({ where: { userData: { id: userDataId }, role } }).then((u) => u != null); - } - async getAllUserDataWithEmptyFileId(): Promise { const userDataList = await this.userDataRepo.find({ where: { kycFileId: MoreThan(0) } }); const idList = [];