@paroicms/server
Version:
The ParoiCMS server
154 lines • 5.44 kB
JavaScript
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