UNPKG

@opengis/fastify-table

Version:

core-plugins

88 lines (87 loc) 4.03 kB
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()); } }