Files
HiveGrid-Wireframes/03 Quellen und Referenzen/hivegrid-cloud/apps/web/app/services/admin/admin-identity.server.ts
T

46 lines
1.7 KiB
TypeScript

import type { AdminPermissionName } from "@hivegrid/db/admin-permissions";
import { adminHasPermission } from "@hivegrid/db/admin-rbac.server";
import { runWithRlsContext } from "@hivegrid/db/rls-context.server";
import { NOT_FOUND_ENVELOPE } from "~/utils/errors.server";
import { getUserInfo, getValidatedServerSession } from "~/utils/session.server";
export type AdminPermissionRequirement =
| AdminPermissionName
| readonly AdminPermissionName[];
export async function requireAdminIdentityPermission(
request: Request,
permission: AdminPermissionRequirement
) {
const userInfo = await getUserInfo(request);
if (!userInfo.userId) throw Response.json(NOT_FOUND_ENVELOPE, { status: 404 });
const session = await getValidatedServerSession(request, userInfo);
if (!session || !("adminUser" in session) || session.adminUserId !== userInfo.userId) {
throw Response.json(NOT_FOUND_ENVELOPE, { status: 404 });
}
const permissions = Array.isArray(permission) ? permission : [permission];
const allowed = await runWithRlsContext(
{ userId: session.adminUserId },
async () =>
(
await Promise.all(
permissions.map((candidate) =>
adminHasPermission(session.adminUserId, candidate)
)
)
).some(Boolean)
);
if (!allowed) throw Response.json(NOT_FOUND_ENVELOPE, { status: 404 });
return session;
}
export async function runAsAdminIdentity<T>(
request: Request,
permission: AdminPermissionRequirement,
operation: (session: Awaited<ReturnType<typeof requireAdminIdentityPermission>>) => Promise<T>
): Promise<T> {
const session = await requireAdminIdentityPermission(request, permission);
return runWithRlsContext({ userId: session.adminUserId }, () => operation(session));
}