Files
HiveGrid-Wireframes/hivegrid-cloud/apps/web/app/utils/loaders.middleware.ts
T

115 lines
4.4 KiB
TypeScript

import { getTenantUserType } from "./db/tenants.db.server";
import { getTenantIdFromUrl, resolveTenantLookupSource } from "./services/.server/urlService";
import { getUserInfo } from "./session.server";
import { db } from "./db.server";
import { getUserRoleInTenant } from "./db/permissions/userRoles.db.server";
import { Params } from "react-router";
import { DefaultAppRoles } from "~/application/dtos/shared/DefaultAppRoles";
import { loadRequiredWebConfig } from "@toolctrl/config";
import { getHostRoutingContextFromRequest } from "./app/HostRouting.server";
const webConfig = loadRequiredWebConfig();
export type AuthErrorCode = "UNAUTHORIZED" | "FORBIDDEN";
export function authErrorEnvelope(code: AuthErrorCode, messageKey: string) {
return { error: { code, messageKey } };
}
const UNAUTHORIZED_ENVELOPE = authErrorEnvelope("UNAUTHORIZED", "errors.unauthorized");
const FORBIDDEN_ADMINS_ONLY_ENVELOPE = authErrorEnvelope("FORBIDDEN", "errors.adminsOnly");
export async function requireAuth({ request, params, adminOnly }: { request: Request; params: { tenant?: string }; adminOnly?: boolean }) {
const userInfo = await getUserInfo(request);
const hostContext = getHostRoutingContextFromRequest(request);
if (hostContext === "admin") {
return await requireSuperAdmin({ request });
}
const tenantLookupSource = resolveTenantLookupSource({ request, params });
if (tenantLookupSource.source === "app-route-param") {
const tenantId = await getTenantIdFromUrl({ tenant: tenantLookupSource.tenant });
if (!userInfo.userId || !tenantId) {
throw Response.json(UNAUTHORIZED_ENVELOPE, { status: 401 });
}
const member = await getTenantUserType(userInfo.userId, tenantId);
if (!member) {
const isSuperAdmin = await getIsSuperAdminByUserId(userInfo.userId);
if (!isSuperAdmin) {
throw Response.json(UNAUTHORIZED_ENVELOPE, { status: 401 });
}
}
}
if (adminOnly) {
const isSuperUserOrAdmin = await getIsSuperUserOrAdmin({ request, params });
if (!isSuperUserOrAdmin && webConfig.nodeEnv !== "development") {
throw Response.json(FORBIDDEN_ADMINS_ONLY_ENVELOPE, { status: 401 });
}
}
return { ...userInfo };
}
export async function requireSuperAdmin({ request }: { request: Request }) {
const userInfo = await getUserInfo(request);
if (!userInfo.userId) {
throw Response.json(UNAUTHORIZED_ENVELOPE, { status: 401 });
}
const isSuperAdmin = await db.adminUser.findUnique({ where: { userId: userInfo.userId } });
if (!isSuperAdmin) {
throw Response.json(UNAUTHORIZED_ENVELOPE, { status: 401 });
}
return { ...userInfo, isSuperAdmin };
}
export async function getIsSuperUserOrAdmin({ request, params }: { request: Request; params: Params }) {
const { userId } = await getUserInfo(request);
const tenantId = await getTenantIdFromUrl(params);
if (!userId || !tenantId) return false;
const isSuperAdmin = await getIsSuperAdmin({ request });
if (isSuperAdmin) return true;
const isSuperUser = await getUserRoleInTenant(userId, tenantId, DefaultAppRoles.SuperUser);
if (isSuperUser) return true;
const isAdmin = await getUserRoleInTenant(userId, tenantId, DefaultAppRoles.Admin);
if (isAdmin) return true;
return false;
}
export async function getIsSuperUserOrAdminByIds({ userId, tenantId }: { userId: string; tenantId: string }) {
if (!userId || !tenantId) return false;
const isSuperAdmin = await db.adminUser.findUnique({ where: { userId: userId } });
if (isSuperAdmin) return true;
const isSuperUser = await getUserRoleInTenant(userId, tenantId, DefaultAppRoles.SuperUser);
if (isSuperUser) return true;
const isAdmin = await getUserRoleInTenant(userId, tenantId, DefaultAppRoles.Admin);
if (isAdmin) return true;
return false;
}
export async function getIsSuperAdmin({ request }: { request: Request }) {
const { userId } = await getUserInfo(request);
if (!userId) return false;
return getIsSuperAdminByUserId(userId);
}
export async function getIsSuperAdminByUserId(userId: string) {
if (!userId) return false;
const isSuperAdmin = await db.adminUser.findUnique({ where: { userId } });
return !!isSuperAdmin;
}
export async function requireSuperUserOrAdmin({ request, params }: { request: Request; params: Params }) {
const isSuperUserOrAdmin = await getIsSuperUserOrAdmin({ request, params });
if (!isSuperUserOrAdmin) {
throw Response.json(UNAUTHORIZED_ENVELOPE, { status: 401 });
}
return true;
}