Preprod (#176)
This commit is contained in:
commit
0f05ce8c8e
@ -45,6 +45,7 @@
|
|||||||
"@mailchimp/mailchimp_transactional": "^1.0.50",
|
"@mailchimp/mailchimp_transactional": "^1.0.50",
|
||||||
"@pinata/sdk": "^2.1.0",
|
"@pinata/sdk": "^2.1.0",
|
||||||
"@prisma/client": "^4.11.0",
|
"@prisma/client": "^4.11.0",
|
||||||
|
"@sentry/node": "^7.91.0",
|
||||||
"adm-zip": "^0.5.10",
|
"adm-zip": "^0.5.10",
|
||||||
"axios": "^1.6.2",
|
"axios": "^1.6.2",
|
||||||
"bcrypt": "^5.1.1",
|
"bcrypt": "^5.1.1",
|
||||||
@ -57,7 +58,7 @@
|
|||||||
"file-type-checker": "^1.0.8",
|
"file-type-checker": "^1.0.8",
|
||||||
"fp-ts": "^2.16.1",
|
"fp-ts": "^2.16.1",
|
||||||
"jsonwebtoken": "^9.0.0",
|
"jsonwebtoken": "^9.0.0",
|
||||||
"le-coffre-resources": "git@github.com:smart-chain-fr/leCoffre-resources.git#v2.104",
|
"le-coffre-resources": "git@github.com:smart-chain-fr/leCoffre-resources.git#v2.106",
|
||||||
"module-alias": "^2.2.2",
|
"module-alias": "^2.2.2",
|
||||||
"monocle-ts": "^2.3.13",
|
"monocle-ts": "^2.3.13",
|
||||||
"multer": "^1.4.5-lts.1",
|
"multer": "^1.4.5-lts.1",
|
||||||
|
@ -56,7 +56,7 @@ export default class CustomersController extends ApiController {
|
|||||||
/**
|
/**
|
||||||
* @description Create a new customer
|
* @description Create a new customer
|
||||||
*/
|
*/
|
||||||
@Post("/api/v1/notary/customers", [authHandler, ruleHandler])
|
@Post("/api/v1/admin/customers", [authHandler, ruleHandler])
|
||||||
protected async post(req: Request, response: Response) {
|
protected async post(req: Request, response: Response) {
|
||||||
try {
|
try {
|
||||||
//init IUser resource with request body values
|
//init IUser resource with request body values
|
||||||
@ -69,6 +69,8 @@ export default class CustomersController extends ApiController {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!customerEntity.contact?.cell_phone_number) return;
|
||||||
|
|
||||||
const customers = await this.customersService.get({
|
const customers = await this.customersService.get({
|
||||||
where: {
|
where: {
|
||||||
contact: { email: customerEntity.contact?.email },
|
contact: { email: customerEntity.contact?.email },
|
||||||
|
@ -35,7 +35,7 @@ export default class AuthController extends ApiController {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.httpSuccess(response, {
|
this.httpSuccess(response, {
|
||||||
partialPhoneNumber: res.customer.contact?.cell_phone_number.replace(/\s/g, "").slice(-4),
|
partialPhoneNumber: res.customer.contact?.cell_phone_number?.replace(/\s/g, "").slice(-4),
|
||||||
totpCodeUid: res.totpCode.uid,
|
totpCodeUid: res.totpCode.uid,
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@ -58,7 +58,7 @@ export default class AuthController extends ApiController {
|
|||||||
this.httpNotFoundRequest(response, "Customer not found");
|
this.httpNotFoundRequest(response, "Customer not found");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.httpSuccess(response, { partialPhoneNumber: customer.contact?.cell_phone_number.replace(/\s/g, "").slice(-4) });
|
this.httpSuccess(response, { partialPhoneNumber: customer.contact?.cell_phone_number?.replace(/\s/g, "").slice(-4) });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error instanceof SmsNotExpiredError) {
|
if (error instanceof SmsNotExpiredError) {
|
||||||
this.httpTooEarlyRequest(response, error.message);
|
this.httpTooEarlyRequest(response, error.message);
|
||||||
@ -229,7 +229,7 @@ export default class AuthController extends ApiController {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.httpSuccess(response, {
|
this.httpSuccess(response, {
|
||||||
partialPhoneNumber: res.customer.contact?.cell_phone_number.replace(/\s/g, "").slice(-4),
|
partialPhoneNumber: res.customer.contact?.cell_phone_number?.replace(/\s/g, "").slice(-4),
|
||||||
totpCodeUid: res.totpCode.uid,
|
totpCodeUid: res.totpCode.uid,
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
@ -5,11 +5,14 @@ import { Service } from "typedi";
|
|||||||
import AuthService, { IUserJwtPayload } from "@Services/common/AuthService/AuthService";
|
import AuthService, { IUserJwtPayload } from "@Services/common/AuthService/AuthService";
|
||||||
|
|
||||||
import IdNotService from "@Services/common/IdNotService/IdNotService";
|
import IdNotService from "@Services/common/IdNotService/IdNotService";
|
||||||
|
import WhitelistService from "@Services/common/WhitelistService/WhitelistService";
|
||||||
|
import User from "le-coffre-resources/dist/SuperAdmin";
|
||||||
|
import UsersService from "@Services/super-admin/UsersService/UsersService";
|
||||||
|
|
||||||
@Controller()
|
@Controller()
|
||||||
@Service()
|
@Service()
|
||||||
export default class UserController extends ApiController {
|
export default class UserController extends ApiController {
|
||||||
constructor(private authService: AuthService, private idNotService: IdNotService) {
|
constructor(private authService: AuthService, private idNotService: IdNotService, private whitelistService: WhitelistService, private userService: UsersService) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -25,17 +28,40 @@ export default class UserController extends ApiController {
|
|||||||
if (!code) throw new Error("code is required");
|
if (!code) throw new Error("code is required");
|
||||||
|
|
||||||
const idNotToken = await this.idNotService.getIdNotToken(code);
|
const idNotToken = await this.idNotService.getIdNotToken(code);
|
||||||
|
|
||||||
if(!idNotToken) {
|
if(!idNotToken) {
|
||||||
this.httpValidationError(response, "IdNot token undefined");
|
this.httpValidationError(response, "IdNot token undefined");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const user = await this.idNotService.getOrCreateUser(idNotToken);
|
const user = await this.idNotService.getOrCreateUser(idNotToken);
|
||||||
|
|
||||||
if(!user) {
|
if(!user) {
|
||||||
this.httpUnauthorized(response);
|
this.httpUnauthorized(response, "Email not found");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
await this.idNotService.updateUser(user.uid);
|
|
||||||
|
//Whitelist feature
|
||||||
|
//Get user with contact
|
||||||
|
const prismaUser = await this.userService.getByUid(user.uid, {contact: true });
|
||||||
|
if (!prismaUser) {
|
||||||
|
this.httpNotFoundRequest(response, "user not found");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Hydrate user to be able to use his contact
|
||||||
|
const userHydrated = User.hydrate<User>(prismaUser, { strategy: "excludeAll" });
|
||||||
|
|
||||||
|
//Check if user is whitelisted
|
||||||
|
const isWhitelisted = await this.whitelistService.getByEmail(userHydrated.contact!.email);
|
||||||
|
|
||||||
|
//If not whitelisted, return 409 Not whitelisted
|
||||||
|
if (!isWhitelisted) {
|
||||||
|
this.httpNotWhitelisted(response);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.idNotService.updateUser(user.uid);
|
||||||
await this.idNotService.updateOffice(user.office_uid);
|
await this.idNotService.updateOffice(user.office_uid);
|
||||||
|
|
||||||
const payload = await this.authService.getUserJwtPayload(user.idNot);
|
const payload = await this.authService.getUserJwtPayload(user.idNot);
|
||||||
|
@ -68,6 +68,8 @@ export default class CustomersController extends ApiController {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!customerEntity.contact?.cell_phone_number) return;
|
||||||
|
|
||||||
const customers = await this.customersService.get({
|
const customers = await this.customersService.get({
|
||||||
where: {
|
where: {
|
||||||
contact: { email: customerEntity.contact?.email },
|
contact: { email: customerEntity.contact?.email },
|
||||||
|
@ -57,7 +57,7 @@ export default class CustomersController extends ApiController {
|
|||||||
/**
|
/**
|
||||||
* @description Create a new customer
|
* @description Create a new customer
|
||||||
*/
|
*/
|
||||||
@Post("/api/v1/notary/customers", [authHandler, ruleHandler])
|
@Post("/api/v1/super-admin/customers", [authHandler, ruleHandler])
|
||||||
protected async post(req: Request, response: Response) {
|
protected async post(req: Request, response: Response) {
|
||||||
try {
|
try {
|
||||||
//init IUser resource with request body values
|
//init IUser resource with request body values
|
||||||
@ -70,6 +70,8 @@ export default class CustomersController extends ApiController {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!customerEntity.contact?.cell_phone_number) return;
|
||||||
|
|
||||||
const customers = await this.customersService.get({
|
const customers = await this.customersService.get({
|
||||||
where: {
|
where: {
|
||||||
contact: { email: customerEntity.contact?.email },
|
contact: { email: customerEntity.contact?.email },
|
||||||
|
@ -13,7 +13,7 @@ export default function authHandler(req: Request, response: Response, next: Next
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const authService = Container.get(AuthService);
|
const authService = Container.get(AuthService);
|
||||||
authService.verifyAccessToken(token, (err, userPayload) => {
|
authService.verifyAccessToken(token, (err, userPayload) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
response.status(HttpCodes.UNAUTHORIZED).send("Error while verifying token");
|
response.status(HttpCodes.UNAUTHORIZED).send("Error while verifying token");
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import HttpException from "@Common/system/controller-pattern/exceptions/HttpException";
|
import HttpException from "@Common/system/controller-pattern/exceptions/HttpException";
|
||||||
import HttpCodes from "@Common/system/controller-pattern/HttpCodes";
|
import HttpCodes from "@Common/system/controller-pattern/HttpCodes";
|
||||||
import { NextFunction, Request, Response } from "express";
|
import { NextFunction, Request, Response } from "express";
|
||||||
|
import * as Sentry from "@sentry/node";
|
||||||
|
|
||||||
export default function errorHandler(error: any, req: Request, response: Response, next: NextFunction) {
|
export default function errorHandler(error: any, req: Request, response: Response, next: NextFunction) {
|
||||||
const errorStatus: number = error["status"];
|
const errorStatus: number = error["status"];
|
||||||
@ -15,6 +16,18 @@ export default function errorHandler(error: any, req: Request, response: Respons
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const transaction = Sentry.startTransaction({
|
||||||
|
op: "Crashed Application",
|
||||||
|
name: "Crashed Application",
|
||||||
|
});
|
||||||
|
|
||||||
|
if (error instanceof Error) {
|
||||||
|
Sentry.captureException(error.stack);
|
||||||
|
} else {
|
||||||
|
Sentry.captureException(error);
|
||||||
|
}
|
||||||
|
transaction.finish();
|
||||||
|
|
||||||
if (error instanceof HttpException) {
|
if (error instanceof HttpException) {
|
||||||
response.status(error.httpCode).send(error.message);
|
response.status(error.httpCode).send(error.message);
|
||||||
return;
|
return;
|
||||||
|
@ -0,0 +1,2 @@
|
|||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "contacts" ALTER COLUMN "cell_phone_number" DROP NOT NULL;
|
@ -0,0 +1,16 @@
|
|||||||
|
-- CreateTable
|
||||||
|
CREATE TABLE "whitelist" (
|
||||||
|
"uid" TEXT NOT NULL,
|
||||||
|
"email" VARCHAR(255) NOT NULL,
|
||||||
|
"active" BOOLEAN NOT NULL DEFAULT true,
|
||||||
|
"created_at" TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
"updated_at" TIMESTAMP(3),
|
||||||
|
|
||||||
|
CONSTRAINT "whitelist_pkey" PRIMARY KEY ("uid")
|
||||||
|
);
|
||||||
|
|
||||||
|
-- CreateIndex
|
||||||
|
CREATE UNIQUE INDEX "whitelist_uid_key" ON "whitelist"("uid");
|
||||||
|
|
||||||
|
-- CreateIndex
|
||||||
|
CREATE UNIQUE INDEX "whitelist_email_key" ON "whitelist"("email");
|
@ -37,7 +37,7 @@ model Contacts {
|
|||||||
last_name String @db.VarChar(255)
|
last_name String @db.VarChar(255)
|
||||||
email String @db.VarChar(255)
|
email String @db.VarChar(255)
|
||||||
phone_number String? @db.VarChar(50)
|
phone_number String? @db.VarChar(50)
|
||||||
cell_phone_number String @db.VarChar(50)
|
cell_phone_number String? @db.VarChar(50)
|
||||||
civility ECivility @default(MALE)
|
civility ECivility @default(MALE)
|
||||||
address Addresses? @relation(fields: [address_uid], references: [uid], onDelete: Cascade)
|
address Addresses? @relation(fields: [address_uid], references: [uid], onDelete: Cascade)
|
||||||
address_uid String? @unique @db.VarChar(255)
|
address_uid String? @unique @db.VarChar(255)
|
||||||
@ -72,6 +72,15 @@ model Users {
|
|||||||
@@map("users")
|
@@map("users")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
model Whitelist {
|
||||||
|
uid String @id @unique @default(uuid())
|
||||||
|
email String @unique @db.VarChar(255)
|
||||||
|
active Boolean @default(true)
|
||||||
|
created_at DateTime? @default(now())
|
||||||
|
updated_at DateTime? @updatedAt
|
||||||
|
@@map("whitelist")
|
||||||
|
}
|
||||||
|
|
||||||
model Offices {
|
model Offices {
|
||||||
uid String @id @unique @default(uuid())
|
uid String @id @unique @default(uuid())
|
||||||
idNot String @unique @db.VarChar(255)
|
idNot String @unique @db.VarChar(255)
|
||||||
|
@ -56,7 +56,7 @@ export default class UsersRepository extends BaseRepository {
|
|||||||
last_name: user.contact!.last_name,
|
last_name: user.contact!.last_name,
|
||||||
email: user.contact!.email,
|
email: user.contact!.email,
|
||||||
phone_number: user.contact?.phone_number,
|
phone_number: user.contact?.phone_number,
|
||||||
cell_phone_number: user.contact!.cell_phone_number,
|
cell_phone_number: user.contact!.cell_phone_number || null,
|
||||||
civility: ECivility[user.contact?.civility as keyof typeof ECivility],
|
civility: ECivility[user.contact?.civility as keyof typeof ECivility],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
39
src/common/repositories/WhitelistRepository.ts
Normal file
39
src/common/repositories/WhitelistRepository.ts
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
import Database from "@Common/databases/database";
|
||||||
|
import BaseRepository from "@Repositories/BaseRepository";
|
||||||
|
import { Service } from "typedi";
|
||||||
|
import { Prisma } from "prisma/prisma-client";
|
||||||
|
|
||||||
|
@Service()
|
||||||
|
export default class WhitelistRepository extends BaseRepository {
|
||||||
|
constructor(private database: Database) {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
protected get model() {
|
||||||
|
return this.database.getClient().whitelist;
|
||||||
|
}
|
||||||
|
protected get instanceDb() {
|
||||||
|
return this.database.getClient();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description : Find many whitelist
|
||||||
|
*/
|
||||||
|
public async findMany(query: Prisma.WhitelistFindManyArgs) {
|
||||||
|
query.take = Math.min(query.take || this.defaultFetchRows, this.maxFetchRows);
|
||||||
|
return this.model.findMany(query);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description : find unique by email
|
||||||
|
*/
|
||||||
|
public async findOneByEmail(email: string) {
|
||||||
|
return this.model.findUnique({
|
||||||
|
where: {
|
||||||
|
email: email,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -48,6 +48,10 @@ export default abstract class BaseController {
|
|||||||
return this.httpResponse(response, HttpCodes.FORBIDDEN, responseData);
|
return this.httpResponse(response, HttpCodes.FORBIDDEN, responseData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected httpNotWhitelisted(response: Response, responseData: IResponseData = "Not whitelisted") {
|
||||||
|
return this.httpResponse(response, HttpCodes.VALIDATION_ERROR, responseData);
|
||||||
|
}
|
||||||
|
|
||||||
protected httpResponse(response: Response, httpCode: HttpCodes, responseData: IResponseData = {}) {
|
protected httpResponse(response: Response, httpCode: HttpCodes, responseData: IResponseData = {}) {
|
||||||
if (responseData instanceof Error) {
|
if (responseData instanceof Error) {
|
||||||
throw responseData;
|
throw responseData;
|
||||||
|
@ -8,12 +8,13 @@ import bodyParser from "body-parser";
|
|||||||
import errorHandler from "@App/middlewares/ErrorHandler";
|
import errorHandler from "@App/middlewares/ErrorHandler";
|
||||||
import { BackendVariables } from "@Common/config/variables/Variables";
|
import { BackendVariables } from "@Common/config/variables/Variables";
|
||||||
import multer from "multer";
|
import multer from "multer";
|
||||||
|
import "../sentry.config";
|
||||||
|
|
||||||
const storage = multer.memoryStorage();
|
const storage = multer.memoryStorage();
|
||||||
|
|
||||||
(async () => {
|
(async () => {
|
||||||
try {
|
try {
|
||||||
const variables = await Container.get(BackendVariables).validate();
|
const variables = await Container.get(BackendVariables).validate();
|
||||||
const port = variables.APP_PORT;
|
const port = variables.APP_PORT;
|
||||||
const rootUrl = variables.APP_ROOT_URL;
|
const rootUrl = variables.APP_ROOT_URL;
|
||||||
const label = variables.APP_LABEL ?? "Unknown Service";
|
const label = variables.APP_LABEL ?? "Unknown Service";
|
||||||
|
16
src/sentry.config.ts
Normal file
16
src/sentry.config.ts
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import { BackendVariables } from "@Common/config/variables/Variables";
|
||||||
|
import * as Sentry from "@sentry/node";
|
||||||
|
import Container from "typedi";
|
||||||
|
|
||||||
|
const variables = Container.get(BackendVariables);
|
||||||
|
|
||||||
|
Sentry.init({
|
||||||
|
dsn: "https://ca6a89e8b480c814e1b5828b8412c681@o4506382103281664.ingest.sentry.io/4506399972130816",
|
||||||
|
|
||||||
|
// We recommend adjusting this value in production, or using tracesSampler
|
||||||
|
// for finer control
|
||||||
|
tracesSampleRate: 1.0,
|
||||||
|
environment: variables.ENV,
|
||||||
|
});
|
||||||
|
|
||||||
|
Sentry.setTag("service", "leCoffre-back");
|
@ -120,10 +120,7 @@ export default class IdNotService extends BaseService {
|
|||||||
redirect_uri: this.variables.IDNOT_REDIRECT_URL,
|
redirect_uri: this.variables.IDNOT_REDIRECT_URL,
|
||||||
code: code,
|
code: code,
|
||||||
grant_type: "authorization_code",
|
grant_type: "authorization_code",
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log(this.variables.IDNOT_BASE_URL + this.variables.IDNOT_CONNEXION_URL + "?" + query);
|
|
||||||
|
|
||||||
const token = await fetch(this.variables.IDNOT_BASE_URL + this.variables.IDNOT_CONNEXION_URL + "?" + query, { method: "POST" });
|
const token = await fetch(this.variables.IDNOT_BASE_URL + this.variables.IDNOT_CONNEXION_URL + "?" + query, { method: "POST" });
|
||||||
if(token.status !== 200) console.error(await token.text());
|
if(token.status !== 200) console.error(await token.text());
|
||||||
|
|
||||||
@ -362,6 +359,10 @@ export default class IdNotService extends BaseService {
|
|||||||
updated_at: null,
|
updated_at: null,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if(!userToAdd.contact.email) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
let userHydrated = User.hydrate<User>(userToAdd);
|
let userHydrated = User.hydrate<User>(userToAdd);
|
||||||
const user = await this.userService.create(userHydrated);
|
const user = await this.userService.create(userHydrated);
|
||||||
|
@ -27,7 +27,6 @@ export default class OvhService extends BaseService {
|
|||||||
console.error('Error sending Ovh Sms');
|
console.error('Error sending Ovh Sms');
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
console.log('SMS sent successfully via Ovh');
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -21,7 +21,6 @@ export default class SmsFactorService extends BaseService {
|
|||||||
{},
|
{},
|
||||||
)
|
)
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
console.log("SMS sent successfully via Sms Factor");
|
|
||||||
return true;
|
return true;
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
|
14
src/services/common/WhitelistService/WhitelistService.ts
Normal file
14
src/services/common/WhitelistService/WhitelistService.ts
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import WhitelistRepository from "@Repositories/WhitelistRepository";
|
||||||
|
import BaseService from "@Services/BaseService";
|
||||||
|
import { Service } from "typedi";
|
||||||
|
|
||||||
|
@Service()
|
||||||
|
export default class WhitelistService extends BaseService {
|
||||||
|
constructor(private whitelistRepository: WhitelistRepository) {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async getByEmail(email: string): Promise<any> {
|
||||||
|
return this.whitelistRepository.findOneByEmail(email);
|
||||||
|
}
|
||||||
|
}
|
@ -12,43 +12,43 @@ import SmsFactorService from "@Services/common/SmsFactorService/SmsFactorService
|
|||||||
|
|
||||||
export class SmsNotExpiredError extends Error {
|
export class SmsNotExpiredError extends Error {
|
||||||
constructor() {
|
constructor() {
|
||||||
super("SMS code not expired");
|
super("Code déjà envoyé");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class TotpCodeExpiredError extends Error {
|
export class TotpCodeExpiredError extends Error {
|
||||||
constructor() {
|
constructor() {
|
||||||
super("Totp code not found or expired");
|
super("Code non trouvé ou expiré, veuillez raffraîchir la page");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class InvalidTotpCodeError extends Error {
|
export class InvalidTotpCodeError extends Error {
|
||||||
constructor() {
|
constructor() {
|
||||||
super("Invalid Totp code");
|
super("Code invalide");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class NotRegisteredCustomerError extends Error {
|
export class NotRegisteredCustomerError extends Error {
|
||||||
constructor() {
|
constructor() {
|
||||||
super("Customer not registered");
|
super("Ce client n'existe pas");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class InvalidPasswordError extends Error {
|
export class InvalidPasswordError extends Error {
|
||||||
constructor() {
|
constructor() {
|
||||||
super("Invalid password");
|
super("Mot de passe incorrect");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class PasswordAlreadySetError extends Error {
|
export class PasswordAlreadySetError extends Error {
|
||||||
constructor() {
|
constructor() {
|
||||||
super("Password already set");
|
super("Le mot de passe a déjà été défini");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class TooSoonForNewCode extends Error {
|
export class TooSoonForNewCode extends Error {
|
||||||
constructor() {
|
constructor() {
|
||||||
super("You need to wait at least 30 seconds before asking for a new code");
|
super("Vous devez attendre 30 secondes avant de pouvoir demander un nouveau code");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@Service()
|
@Service()
|
||||||
@ -110,7 +110,7 @@ export default class CustomersService extends BaseService {
|
|||||||
const totpCode = await this.saveTotpPin(customer, totpPin, new Date(now + 5 * 60 * 1000), reason);
|
const totpCode = await this.saveTotpPin(customer, totpPin, new Date(now + 5 * 60 * 1000), reason);
|
||||||
if (!totpCode) return null;
|
if (!totpCode) return null;
|
||||||
// 5: Send the SMS code to the customer
|
// 5: Send the SMS code to the customer
|
||||||
if(this.variables.ENV !== 'dev') await this.sendSmsCodeToCustomer(totpPin, customer);
|
if (this.variables.ENV !== "dev") await this.sendSmsCodeToCustomer(totpPin, customer);
|
||||||
return {
|
return {
|
||||||
customer,
|
customer,
|
||||||
totpCode: TotpCodesResource.hydrate<TotpCodesResource>({
|
totpCode: TotpCodesResource.hydrate<TotpCodesResource>({
|
||||||
@ -162,7 +162,7 @@ export default class CustomersService extends BaseService {
|
|||||||
await this.saveTotpPin(customer, totpPin, new Date(now + 5 * 60000), TotpCodesReasons.RESET_PASSWORD);
|
await this.saveTotpPin(customer, totpPin, new Date(now + 5 * 60000), TotpCodesReasons.RESET_PASSWORD);
|
||||||
|
|
||||||
// 5: Send the SMS code to the customer
|
// 5: Send the SMS code to the customer
|
||||||
if(this.variables.ENV !== 'dev') await this.sendSmsCodeToCustomer(totpPin, customer);
|
if (this.variables.ENV !== "dev") await this.sendSmsCodeToCustomer(totpPin, customer);
|
||||||
return customer;
|
return customer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -292,7 +292,7 @@ export default class CustomersService extends BaseService {
|
|||||||
const totpCode = await this.saveTotpPin(customer, totpPin, new Date(now + 5 * 60 * 1000), totpCodeToResend.reason!, true);
|
const totpCode = await this.saveTotpPin(customer, totpPin, new Date(now + 5 * 60 * 1000), totpCodeToResend.reason!, true);
|
||||||
|
|
||||||
// 7: Send the SMS code to the customer
|
// 7: Send the SMS code to the customer
|
||||||
if(this.variables.ENV !== 'dev') await this.sendSmsCodeToCustomer(totpPin, customer);
|
if (this.variables.ENV !== "dev") await this.sendSmsCodeToCustomer(totpPin, customer);
|
||||||
return { customer, totpCode };
|
return { customer, totpCode };
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -356,14 +356,13 @@ export default class CustomersService extends BaseService {
|
|||||||
|
|
||||||
private async sendSmsCodeToCustomer(totpPin: number, customer: Customer) {
|
private async sendSmsCodeToCustomer(totpPin: number, customer: Customer) {
|
||||||
const message = "Votre code de vérification LEcoffre.io est : " + totpPin.toString();
|
const message = "Votre code de vérification LEcoffre.io est : " + totpPin.toString();
|
||||||
|
|
||||||
// Sélectionnez le fournisseur de SMS en fonction de la variable d'environnement
|
// Sélectionnez le fournisseur de SMS en fonction de la variable d'environnement
|
||||||
//const selectedProvider = this.variables.SMS_PROVIDER === "OVH" ? this.ovhService : this.smsFactorService;
|
//const selectedProvider = this.variables.SMS_PROVIDER === "OVH" ? this.ovhService : this.smsFactorService;
|
||||||
|
|
||||||
// Envoi du SMS
|
// Envoi du SMS
|
||||||
if (!customer.contact?.cell_phone_number) return;
|
if (!customer.contact?.cell_phone_number) return;
|
||||||
let success = await this.ovhService.sendSms(customer.contact?.cell_phone_number, message);
|
let success = await this.ovhService.sendSms(customer.contact?.cell_phone_number, message);
|
||||||
|
|
||||||
|
|
||||||
// Si l'envoi échoue, basculez automatiquement sur le second fournisseur
|
// Si l'envoi échoue, basculez automatiquement sur le second fournisseur
|
||||||
if (!success) {
|
if (!success) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user