@opengis/fastify-table
Version:
core-plugins
88 lines (87 loc) • 4.03 kB
JavaScript
import path from "node:path";
import { fileURLToPath } from "url";
import { existsSync, readFileSync } from "node:fs";
import config from "../../../../../config.js";
import getTemplate from "../../../../plugins/table/funcs/getTemplate.js";
import pgClients from "../../../../plugins/pg/pgClients.js";
import { handlebars } from "../../../../helpers/index.js";
import { verify, enableSecret } from "./providers/totp.js";
import sendNotification from "../../../../plugins/auth/funcs/sendNotification.js";
const template = "recovery-codes-email-template";
const dirname = path.dirname(fileURLToPath(import.meta.url));
const defaultPt = existsSync(path.join(dirname, `../../../../templates/pt/${template}.hbs`))
? readFileSync(path.join(dirname, `../../../../templates/pt/${template}.hbs`), "utf8")
: "Recovery codes: {{{code}}}";
/**
* Перевірка двохфакторної авторизації для користувача
*
* @method POST
* @summary Перевірка двохфакторної авторизації
* @priority 3
* @alias verify
* @type api
* @tag auth
* @requires 2fa
* @param {Object} code Код, який використовується для перевірки у заданому провайдері двофакторної авторизації
* @errors 500
* @returns {Number} status Номер помилки
* @returns {String|Object} error Опис помилки
* @returns {String|Object} message Повідомлення про успішне виконання або об'єкт з параметрами
* @returns {String} redirect Шлях до переадресації
*/
export default async function verifyFunction(req, reply) {
const { pg = pgClients.client, user = {}, body = {} } = req;
const { uid, twofa, email } = user || {};
const { code } = body;
if (!twofa) {
return reply.status(400).send({ error: "2fa not enabled", code: 400 });
}
if (!config.pg) {
return reply.status(400).send({ error: "empty pg", code: 400 });
}
if (!code) {
return reply
.status(400)
.send({ error: "not enough body params: code", code: 400 });
}
try {
const { enabled } = await verify({ uid, code, pg });
await enableSecret({ pg, uid });
req.session.secondFactorPassed = true;
if (!enabled && email) {
const { recoveryCodes } = await pg
.query(`select social_auth_obj->'codesArray' as "recoveryCodes"
from admin.users_social_auth where uid=$1 and social_auth_type='TOTP'`, [uid])
?.then((el) => el.rows?.[0] || {});
const customPt = await getTemplate("pt", template);
const pt = customPt || defaultPt;
const html = await handlebars.compile(pt)({
recoveryCodes,
code: recoveryCodes,
domain: `${req.protocol || "https"}://${req.hostname}`,
});
await sendNotification({
pg,
to: email,
template: html,
title: `Recovery codes for ${req.hostname} 2-factor authentication`,
nocache: config.local || config.debug || user?.user_type?.includes?.("admin"),
});
}
const redirectUrl = req.headers?.referer?.match?.(/[?&]redirect=([^&]+)/)?.[1] || "/";
// return reply.redirect(redirectUrl.startsWith("/") ? redirectUrl : "/");
return reply
.status(200)
.send({ redirectUrl: redirectUrl.startsWith("/") ? redirectUrl : "/" });
}
catch (err) {
if ([
"Невірний код",
"Вже знаходиться у даному стані",
"Включіть двофакторну аутентифікацію",
].includes(err.message)) {
return reply.status(400).send({ error: err.message, code: 400 });
}
return reply.status(500).send(err.toString());
}
}