import varDatabaseDbHandler from "../../backend/varDatabaseDbHandler"; import nodemailer, { SendMailOptions } from "nodemailer"; import http from "http"; import getAuthCookieNames from "../../backend/cookies/get-auth-cookie-names"; import encrypt from "../../dsql/encrypt"; import serializeCookies from "../../../utils/serialize-cookies"; import { SendOneTimeCodeEmailResponse } from "../../../types"; type Param = { email: string; database: string; email_login_field?: string; mail_domain?: string; mail_port?: number; sender?: string; mail_username?: string; mail_password?: string; html: string; useLocal?: boolean; response?: http.ServerResponse & { [s: string]: any }; extraCookies?: import("../../../../package-shared/types").CookieObject[]; }; /** * # Send Email Login Code */ export default async function apiSendEmailCode({ email, database, email_login_field, mail_domain, mail_port, sender, mail_username, mail_password, html, useLocal, response, extraCookies, }: Param): Promise { if (email?.match(/ /)) { return { success: false, msg: "Invalid Email/Password format", }; } const createdAt = Date.now(); const foundUserQuery = `SELECT * FROM users WHERE email = ?`; const foundUserValues = [email]; let foundUser = await varDatabaseDbHandler({ queryString: foundUserQuery, queryValuesArray: foundUserValues, database, useLocal, }); //////////////////////////////////////// //////////////////////////////////////// //////////////////////////////////////// if (!foundUser || !foundUser[0]) { return { success: false, msg: "No user found", }; } function generateCode() { const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; let code = ""; for (let i = 0; i < 8; i++) { code += chars[Math.floor(Math.random() * chars.length)]; } return code; } if (foundUser?.[0] && email_login_field) { const tempCode = generateCode(); let transporter = nodemailer.createTransport({ host: mail_domain || process.env.DSQL_MAIL_HOST, port: mail_port ? mail_port : process.env.DSQL_MAIL_PORT ? Number(process.env.DSQL_MAIL_PORT) : 465, secure: true, auth: { user: mail_username || process.env.DSQL_MAIL_EMAIL, pass: mail_password || process.env.DSQL_MAIL_PASSWORD, }, }); let mailObject: SendMailOptions = {}; mailObject["from"] = `"Datasquirel SSO" <${ sender || "support@datasquirel.com" }>`; mailObject["sender"] = sender || "support@datasquirel.com"; mailObject["to"] = email; mailObject["subject"] = "One Time Login Code"; mailObject["html"] = html.replace(/{{code}}/, tempCode); const info = await transporter.sendMail(mailObject); if (!info?.accepted) throw new Error("Mail not Sent!"); const setTempCodeQuery = `UPDATE users SET ${email_login_field} = ? WHERE email = ?`; const setTempCodeValues = [tempCode + `-${createdAt}`, email]; let setTempCode = await varDatabaseDbHandler({ queryString: setTempCodeQuery, queryValuesArray: setTempCodeValues, database: database, useLocal, }); /** @type {import("../../../types").SendOneTimeCodeEmailResponse} */ const resObject: import("../../../types").SendOneTimeCodeEmailResponse = { success: true, code: tempCode, email: email, createdAt, msg: "Success", }; if (response) { const cookieKeyNames = getAuthCookieNames(); const oneTimeCodeCookieName = cookieKeyNames.oneTimeCodeName; const encryptedPayload = encrypt({ data: JSON.stringify(resObject), }); if (!encryptedPayload) { throw new Error( "apiSendEmailCode Error: Failed to encrypt payload" ); } /** @type {import("../../../../package-shared/types").CookieObject} */ const oneTimeCookieObject: import("../../../../package-shared/types").CookieObject = { name: oneTimeCodeCookieName, value: encryptedPayload, sameSite: "Strict", path: "/", httpOnly: true, secure: true, }; /** @type {import("../../../../package-shared/types").CookieObject[]} */ const cookiesObjectArray: import("../../../../package-shared/types").CookieObject[] = extraCookies ? [...extraCookies, oneTimeCookieObject] : [oneTimeCookieObject]; const serializedCookies = serializeCookies({ cookies: cookiesObjectArray, }); response.setHeader("Set-Cookie", serializedCookies); } return resObject; } else { return { success: false, msg: "Invalid Email/Password format", }; } }