2024-12-06 10:31:24 +00:00
|
|
|
// @ts-check
|
|
|
|
|
|
|
|
const varDatabaseDbHandler = require("../../backend/varDatabaseDbHandler");
|
|
|
|
const nodemailer = require("nodemailer");
|
2024-12-10 14:10:32 +00:00
|
|
|
const http = require("http");
|
|
|
|
const getAuthCookieNames = require("../../backend/cookies/get-auth-cookie-names");
|
|
|
|
const encrypt = require("../../dsql/encrypt");
|
2024-12-11 03:45:29 +00:00
|
|
|
const serializeCookies = require("../../../utils/serialize-cookies");
|
2024-12-06 10:31:24 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* # Send Email Login Code
|
|
|
|
*
|
|
|
|
* @param {object} param
|
|
|
|
* @param {string} param.email
|
|
|
|
* @param {string} param.database
|
|
|
|
* @param {string} [param.email_login_field]
|
|
|
|
* @param {string} [param.mail_domain]
|
|
|
|
* @param {number} [param.mail_port]
|
|
|
|
* @param {string} [param.sender]
|
|
|
|
* @param {string} [param.mail_username]
|
|
|
|
* @param {string} [param.mail_password]
|
|
|
|
* @param {string} param.html
|
2024-12-06 11:55:03 +00:00
|
|
|
* @param {boolean} [param.useLocal]
|
2024-12-10 14:10:32 +00:00
|
|
|
* @param {http.ServerResponse & Object<string,any>} [param.response]
|
2024-12-11 03:45:29 +00:00
|
|
|
* @param {import("../../../../package-shared/types").CookieObject[]} [param.extraCookies]
|
2024-12-06 10:31:24 +00:00
|
|
|
*
|
2024-12-10 14:10:32 +00:00
|
|
|
* @returns {Promise<import("../../../types").SendOneTimeCodeEmailResponse>}
|
2024-12-06 10:31:24 +00:00
|
|
|
*/
|
|
|
|
module.exports = async function apiSendEmailCode({
|
|
|
|
email,
|
|
|
|
database,
|
|
|
|
email_login_field,
|
|
|
|
mail_domain,
|
|
|
|
mail_port,
|
|
|
|
sender,
|
|
|
|
mail_username,
|
|
|
|
mail_password,
|
|
|
|
html,
|
2024-12-06 11:55:03 +00:00
|
|
|
useLocal,
|
2024-12-10 14:10:32 +00:00
|
|
|
response,
|
2024-12-11 03:45:29 +00:00
|
|
|
extraCookies,
|
2024-12-06 10:31:24 +00:00
|
|
|
}) {
|
|
|
|
if (email?.match(/ /)) {
|
|
|
|
return {
|
|
|
|
success: false,
|
|
|
|
msg: "Invalid Email/Password format",
|
|
|
|
};
|
|
|
|
}
|
2024-12-10 14:10:32 +00:00
|
|
|
const createdAt = Date.now();
|
2024-12-06 10:31:24 +00:00
|
|
|
|
2024-12-06 11:55:03 +00:00
|
|
|
const foundUserQuery = `SELECT * FROM users WHERE email = ?`;
|
|
|
|
const foundUserValues = [email];
|
|
|
|
|
2024-12-08 08:58:57 +00:00
|
|
|
let foundUser = await varDatabaseDbHandler({
|
|
|
|
queryString: foundUserQuery,
|
|
|
|
queryValuesArray: foundUserValues,
|
|
|
|
database,
|
|
|
|
useLocal,
|
|
|
|
});
|
2024-12-06 10:31:24 +00:00
|
|
|
|
|
|
|
////////////////////////////////////////
|
|
|
|
////////////////////////////////////////
|
|
|
|
////////////////////////////////////////
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2024-12-10 14:10:32 +00:00
|
|
|
if (foundUser?.[0] && email_login_field) {
|
2024-12-06 10:31:24 +00:00
|
|
|
const tempCode = generateCode();
|
|
|
|
|
|
|
|
let transporter = nodemailer.createTransport({
|
|
|
|
host: mail_domain || process.env.DSQL_MAIL_HOST,
|
2024-12-10 13:09:21 +00:00
|
|
|
port: mail_port || process.env.DSQL_MAIL_PORT || 465,
|
2024-12-06 10:31:24 +00:00
|
|
|
secure: true,
|
|
|
|
auth: {
|
|
|
|
user: mail_username || process.env.DSQL_MAIL_EMAIL,
|
|
|
|
pass: mail_password || process.env.DSQL_MAIL_PASSWORD,
|
|
|
|
},
|
|
|
|
});
|
|
|
|
|
|
|
|
let mailObject = {};
|
|
|
|
|
|
|
|
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!");
|
|
|
|
|
2024-12-06 11:55:03 +00:00
|
|
|
const setTempCodeQuery = `UPDATE users SET ${email_login_field} = ? WHERE email = ?`;
|
2024-12-10 14:10:32 +00:00
|
|
|
const setTempCodeValues = [tempCode + `-${createdAt}`, email];
|
2024-12-06 10:31:24 +00:00
|
|
|
|
2024-12-08 08:58:57 +00:00
|
|
|
let setTempCode = await varDatabaseDbHandler({
|
|
|
|
queryString: setTempCodeQuery,
|
|
|
|
queryValuesArray: setTempCodeValues,
|
|
|
|
database: database,
|
|
|
|
useLocal,
|
|
|
|
});
|
2024-12-06 10:31:24 +00:00
|
|
|
|
2024-12-10 14:10:32 +00:00
|
|
|
/** @type {import("../../../types").SendOneTimeCodeEmailResponse} */
|
|
|
|
const resObject = {
|
|
|
|
success: true,
|
|
|
|
code: tempCode,
|
|
|
|
email: email,
|
|
|
|
createdAt,
|
|
|
|
msg: "Success",
|
|
|
|
};
|
|
|
|
|
|
|
|
if (response) {
|
2024-12-11 03:45:29 +00:00
|
|
|
const cookieKeyNames = getAuthCookieNames();
|
|
|
|
const oneTimeCodeCookieName = cookieKeyNames.oneTimeCodeName;
|
2024-12-10 14:10:32 +00:00
|
|
|
|
|
|
|
const encryptedPayload = encrypt({
|
|
|
|
data: JSON.stringify(resObject),
|
|
|
|
});
|
|
|
|
|
2024-12-11 03:45:29 +00:00
|
|
|
if (!encryptedPayload) {
|
|
|
|
throw new Error(
|
|
|
|
"apiSendEmailCode Error: Failed to encrypt payload"
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
/** @type {import("../../../../package-shared/types").CookieObject} */
|
|
|
|
const oneTimeCookieObject = {
|
|
|
|
name: oneTimeCodeCookieName,
|
|
|
|
value: encryptedPayload,
|
|
|
|
sameSite: "Strict",
|
|
|
|
path: "/",
|
|
|
|
httpOnly: true,
|
|
|
|
secure: true,
|
|
|
|
};
|
|
|
|
|
|
|
|
/** @type {import("../../../../package-shared/types").CookieObject[]} */
|
|
|
|
const cookiesObjectArray = extraCookies
|
|
|
|
? [...extraCookies, oneTimeCookieObject]
|
|
|
|
: [oneTimeCookieObject];
|
|
|
|
|
|
|
|
const serializedCookies = serializeCookies({
|
|
|
|
cookies: cookiesObjectArray,
|
|
|
|
});
|
|
|
|
|
|
|
|
response.setHeader("Set-Cookie", serializedCookies);
|
2024-12-10 14:10:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return resObject;
|
|
|
|
} else {
|
|
|
|
return {
|
|
|
|
success: false,
|
|
|
|
msg: "Invalid Email/Password format",
|
|
|
|
};
|
|
|
|
}
|
2024-12-06 10:31:24 +00:00
|
|
|
};
|