refactor(housekeeping): reuse request capability context
This commit is contained in:
1 parent
cc6bb9a9a3
commit
edc165ba8d
5 files changed
+134
-8
No files matched your search
@@ -1,9 +1,14 @@
|
||||
// @ts-nocheck
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import {
|
||||
anyCapability,
|
||||
type HousekeepingCapabilityContext,
|
||||
} from "@/features/housekeeping/foundation/contracts";
|
||||
import { redirectSafe } from "@/lib/foundation/security";
|
||||
import { canAccess, getAdminContext } from "@/lib/permissions";
|
||||
import { clientIp, rateLimit } from "@/lib/rate-limit";
|
||||
import {
|
||||
requireHousekeepingCapability,
|
||||
requireMod,
|
||||
requireModPermission,
|
||||
requirePermission,
|
||||
@@ -70,6 +75,23 @@ describe("requirePermission", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("requireHousekeepingCapability", () => {
|
||||
it("reuses an already-created capability context without reloading permissions", async () => {
|
||||
const context: HousekeepingCapabilityContext = {
|
||||
actor: { id: 1, username: "admin", rank: 0 },
|
||||
isSuperAdmin: false,
|
||||
has: (slug) => slug === "admin.users.view",
|
||||
hasAny: (...slugs) => slugs.includes("admin.users.view"),
|
||||
hasAll: (...slugs) => slugs.every((slug) => slug === "admin.users.view"),
|
||||
};
|
||||
|
||||
await expect(
|
||||
requireHousekeepingCapability(anyCapability("admin.users.view"), context),
|
||||
).resolves.toBe(context);
|
||||
expect(getAdminContext).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe("requireMod", () => {
|
||||
it("allows with MOD_DASHBOARD", async () => {
|
||||
vi.mocked(getAdminContext).mockResolvedValue({
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
import { authorizeHousekeeping } from "@/features/housekeeping/foundation/authorization";
|
||||
import type {
|
||||
CapabilityRequirement,
|
||||
HousekeepingCapabilityContext,
|
||||
} from "@/features/housekeeping/foundation/contracts";
|
||||
import { getHousekeepingCapabilityContext } from "@/features/housekeeping/foundation/server-capability-context";
|
||||
import { redirectSafe } from "@/lib/foundation/security";
|
||||
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
|
||||
import { clientIp, rateLimit } from "@/lib/rate-limit";
|
||||
@@ -7,6 +13,18 @@ export interface StaffUser {
|
||||
rank: number;
|
||||
username: string;
|
||||
}
|
||||
export async function requireHousekeepingCapability(
|
||||
requirement: CapabilityRequirement,
|
||||
context?: HousekeepingCapabilityContext,
|
||||
): Promise<HousekeepingCapabilityContext> {
|
||||
const capabilityContext =
|
||||
context ?? (await getHousekeepingCapabilityContext());
|
||||
const authorization = authorizeHousekeeping(capabilityContext, requirement);
|
||||
|
||||
if (!authorization.ok) redirectSafe("/admin", "/admin");
|
||||
|
||||
return capabilityContext;
|
||||
}
|
||||
|
||||
export async function requireStaff(): Promise<StaffUser> {
|
||||
const { session, permissions } = await getAdminContext();
|
||||
|
||||
Reference in new issue
Block a user