146 lines
3.9 KiB
TypeScript
146 lines
3.9 KiB
TypeScript
import { Body, Controller, Get, Post, Request, Route, Security, Tags } from "tsoa";
|
|
import prisma from "../db";
|
|
import nodemailer from "nodemailer";
|
|
import { notFoundError } from "../utils/error";
|
|
import { RequestWithLineUser } from "../interfaces/user";
|
|
import HttpError from "../interfaces/http-error";
|
|
import HttpStatus from "../interfaces/http-status";
|
|
|
|
type SendEmail = {
|
|
email: string;
|
|
} & ({ legalPersonNo: string } | { citizenId: string });
|
|
|
|
type VerificationPayload = {
|
|
email: string;
|
|
otp: string;
|
|
} & ({ legalPersonNo: string } | { citizenId: string });
|
|
|
|
let emailTransport: ReturnType<(typeof nodemailer)["createTransport"]>;
|
|
|
|
@Route("/api/v1/verification")
|
|
@Tags("Verification")
|
|
export class verificationController extends Controller {
|
|
@Get()
|
|
@Security("line")
|
|
async isRegistered(@Request() req: RequestWithLineUser) {
|
|
return !!(await prisma.customerBranch.findFirst({ where: { userId: req.user.sub } }));
|
|
}
|
|
|
|
@Post("/send-otp")
|
|
public async sendOTP(@Body() body: SendEmail) {
|
|
if (
|
|
![
|
|
process.env.SMTP_HOST,
|
|
process.env.SMTP_PORT,
|
|
process.env.SMTP_USER,
|
|
process.env.SMTP_PASS,
|
|
].every(Boolean)
|
|
) {
|
|
throw new HttpError(
|
|
HttpStatus.PRECONDITION_FAILED,
|
|
"SMTP not configured",
|
|
"smtpNotConfigured",
|
|
);
|
|
}
|
|
|
|
if (!emailTransport) {
|
|
emailTransport = nodemailer.createTransport({
|
|
host: process.env.SMTP_HOST!,
|
|
port: +process.env.SMTP_PORT!,
|
|
secure: false, // true for port 465, false for other ports
|
|
auth: {
|
|
user: process.env.SMTP_USER!,
|
|
pass: process.env.SMTP_PASS!,
|
|
},
|
|
});
|
|
}
|
|
|
|
const generateOTP = Math.floor(100000 + Math.random() * 900000).toString();
|
|
const expiresTime = new Date(Date.now() + 5 * 60 * 1000);
|
|
|
|
const dataCustomerBranch = await prisma.customerBranch.findFirst({
|
|
where: {
|
|
email: body.email,
|
|
...("citizenId" in body
|
|
? {
|
|
citizenId: body.citizenId,
|
|
customer: {
|
|
customerType: "PERS",
|
|
},
|
|
}
|
|
: {
|
|
legalPersonNo: body.legalPersonNo,
|
|
customer: {
|
|
customerType: "CORP",
|
|
},
|
|
}),
|
|
},
|
|
});
|
|
|
|
if (!dataCustomerBranch) throw notFoundError("Customer Branch");
|
|
|
|
await emailTransport.sendMail({
|
|
from: process.env.SMTP_USER,
|
|
to: body.email,
|
|
subject: "Your OTP Code",
|
|
text: `Your OTP Code ${generateOTP}`,
|
|
html: `<p>Your OTP code is: <strong>${generateOTP}</strong></p>`,
|
|
});
|
|
|
|
await prisma.customerBranch.update({
|
|
where: {
|
|
id: dataCustomerBranch.id,
|
|
},
|
|
data: {
|
|
otpCode: generateOTP,
|
|
otpExpires: expiresTime,
|
|
},
|
|
});
|
|
return { message: "OTP sent successfully" };
|
|
}
|
|
|
|
@Post("/verify-otp")
|
|
@Security("line")
|
|
public async verifyOTP(@Request() req: RequestWithLineUser, @Body() body: VerificationPayload) {
|
|
const customerBranch = await prisma.customerBranch.findFirst({
|
|
where: {
|
|
email: body.email,
|
|
...("citizenId" in body
|
|
? {
|
|
citizenId: body.citizenId,
|
|
customer: {
|
|
customerType: "PERS",
|
|
},
|
|
}
|
|
: {
|
|
legalPersonNo: body.legalPersonNo,
|
|
customer: {
|
|
customerType: "CORP",
|
|
},
|
|
}),
|
|
},
|
|
});
|
|
|
|
if (!customerBranch) throw notFoundError("Customer Branch");
|
|
|
|
if (
|
|
customerBranch.otpCode &&
|
|
customerBranch.otpCode === body.otp &&
|
|
customerBranch.otpExpires &&
|
|
customerBranch.otpExpires >= new Date()
|
|
) {
|
|
const dataCustomer = await prisma.customerBranch.update({
|
|
where: {
|
|
id: customerBranch.id,
|
|
},
|
|
data: {
|
|
userId: req.user.sub,
|
|
},
|
|
});
|
|
|
|
return dataCustomer;
|
|
} else {
|
|
return "OTP ไม่ถูกต้อง";
|
|
}
|
|
}
|
|
}
|