UNPKG

@paroicms/server

Version:
154 lines 5.44 kB
import { ApiError } from "@paroicms/public-server-lib"; import { type } from "arktype"; import { AccountPreferencesAT } from "../../common/data-format.js"; import { appConf } from "../../context.js"; import { comparePassword } from "../../helpers/passwordEncrypt-helper.js"; import { devAccountId, getDevAccount, getPlatformAdminAccount, isDevAccountId, parsePlatformAdminAccountId, } from "../../helpers/special-account.helpers.js"; import { generateAdminToken } from "../../protected-site/protected-access-token.js"; import { findAccountByEmail, findAccountByIdAndEmail } from "../account/account.queries.js"; import { generateAccessToken, verifyAccessToken, verifyPlatformToken, } from "./auth.helper.js"; const JwtPayloadAT = type({ id: "string", email: "string", "+": "reject", }); export async function loginUser(siteContext, options) { const { user, defaultLanguage } = options; let account; if (appConf.devAccount?.email === user.email) { account = validateDevAccount({ user, devAccount: appConf.devAccount, }); } else { account = await validateUser(siteContext, user); } if (!account) { return { message: "Unauthorized", statusCode: 401, }; } const parsedPreferences = account.preferences ? AccountPreferencesAT.assert(account.preferences) : undefined; const adminToken = await generateAdminToken(); return { id: account.id, email: account.email, language: parsedPreferences?.language ?? defaultLanguage, name: account.name, token: generateAccessToken({ email: account.email, id: account.id, fqdn: siteContext.fqdn, }), adminToken, }; } export async function getVerifiedAccountFromToken(siteContext, options) { const { token, defaultLanguage } = options; let payload; try { payload = verifyAccessToken(token); if (payload.fqdn !== siteContext.fqdn) { throw new ApiError("Not the right token", 403); } let account; const parsedPlatformAccountId = parsePlatformAdminAccountId(payload.id); if (isDevAccountId(payload.id)) { account = getDevAccount(payload.id); } else if (parsedPlatformAccountId) { account = getPlatformAdminAccount(parsedPlatformAccountId); } else { const validated = JwtPayloadAT.assert(payload); account = await findAccountByIdAndEmail(siteContext, validated); } const parsedPreferences = account.preferences ? AccountPreferencesAT.assert(account.preferences) : undefined; const adminToken = await generateAdminToken(); return { email: account.email, id: account.id, language: parsedPreferences?.language ?? defaultLanguage, name: account.name, token, adminToken, }; } catch { if (payload) { siteContext.logger.warn(`Invalid token: ${JSON.stringify(payload)}`); } return { statusCode: 401, message: "Unauthorized", }; } } export async function loginByPlatformToken(siteContext, options) { try { const { token, defaultLanguage } = options; const payload = verifyPlatformToken(token); let account; const platAdmAccountIndex = (appConf.platformAdminAccounts ?? []).findIndex((account) => account.email === payload.email); if (platAdmAccountIndex !== -1) { account = getPlatformAdminAccount({ index: platAdmAccountIndex }); } else { const foundAccount = await findAccountByEmail(siteContext, payload.email); if (!foundAccount) { throw new ApiError("Account not found", 404); } account = foundAccount; } const parsedPreferences = account.preferences ? AccountPreferencesAT.assert(JSON.parse(account.preferences)) : undefined; const adminToken = await generateAdminToken(); return { id: account.id, email: payload.email, language: parsedPreferences?.language ?? defaultLanguage, name: account.name, token: generateAccessToken({ email: payload.email, id: account.id, fqdn: siteContext.fqdn, }), adminToken, }; } catch (error) { siteContext.logger.error(error); return { statusCode: 401, message: "Invalid account", }; } } async function validateUser(siteContext, { email, password }) { const user = await findAccountByEmail(siteContext, email); let samePassword = false; if (user?.passwordHash) { samePassword = await comparePassword(password, user.passwordHash); } const canPass = user?.passwordHash && samePassword; if (!canPass) return; return user; } function validateDevAccount({ user, devAccount, }) { if (user.email !== devAccount.email || user.password !== devAccount.password) return; const { password, ...others } = devAccount; return { ...others, id: devAccountId, }; } //# sourceMappingURL=auth.service.js.map