2026-04-08 07:50:27 -04:00
|
|
|
import { clerkMiddleware, createRouteMatcher, clerkClient } from '@clerk/astro/server';
|
2026-02-25 18:47:33 -05:00
|
|
|
|
2026-04-08 07:50:27 -04:00
|
|
|
const isProtectedRoute = createRouteMatcher(['/pokemon']);
|
|
|
|
|
const isAdminRoute = createRouteMatcher(['/admin']);
|
2026-02-25 20:31:13 -05:00
|
|
|
|
2026-04-08 07:50:27 -04:00
|
|
|
const TARGET_ORG_ID = "org_3Baav9czkRLLlC7g89oJWqRRulK";
|
|
|
|
|
|
|
|
|
|
export const onRequest = clerkMiddleware(async (auth, context) => {
|
|
|
|
|
const { isAuthenticated, userId, redirectToSignIn, has } = auth();
|
2026-03-05 22:59:16 -05:00
|
|
|
|
|
|
|
|
if (!isAuthenticated && isProtectedRoute(context.request)) {
|
2026-04-08 07:50:27 -04:00
|
|
|
return redirectToSignIn();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ── Inventory visibility check ──────────────────────────────────────────────
|
|
|
|
|
// Resolves to true if the user belongs to the target org OR has the feature
|
|
|
|
|
const canAddInventory =
|
|
|
|
|
isAuthenticated &&
|
|
|
|
|
userId &&
|
|
|
|
|
(
|
|
|
|
|
has({ permission: "org:feature:inventory_add" }) || // Clerk feature flag
|
|
|
|
|
(await getUserOrgIds(context, userId)).includes(TARGET_ORG_ID)
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// Expose the flag to your Astro pages via locals
|
|
|
|
|
context.locals.canAddInventory = canAddInventory ?? false;
|
|
|
|
|
|
|
|
|
|
// ── Admin route guard (unchanged) ───────────────────────────────────────────
|
|
|
|
|
if (isAdminRoute(context.request)) {
|
|
|
|
|
if (!isAuthenticated || !userId) {
|
|
|
|
|
return redirectToSignIn();
|
|
|
|
|
}
|
2026-03-05 22:59:16 -05:00
|
|
|
|
2026-04-08 07:50:27 -04:00
|
|
|
try {
|
|
|
|
|
const client = await clerkClient(context);
|
|
|
|
|
const memberships = await client.organizations.getOrganizationMembershipList({
|
|
|
|
|
organizationId: TARGET_ORG_ID,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const userMembership = memberships.data.find(
|
|
|
|
|
(m) => m.publicUserData?.userId === userId
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
if (!userMembership || userMembership.role !== "org:admin") {
|
|
|
|
|
return new Response(null, { status: 404 });
|
|
|
|
|
}
|
|
|
|
|
} catch (e) {
|
|
|
|
|
console.error("Clerk membership check failed:", e);
|
|
|
|
|
return context.redirect("/");
|
|
|
|
|
}
|
2026-02-25 20:31:13 -05:00
|
|
|
}
|
|
|
|
|
});
|
2026-04-08 07:50:27 -04:00
|
|
|
|
|
|
|
|
// ── Helper: fetch all org IDs the current user belongs to ───────────────────
|
|
|
|
|
async function getUserOrgIds(context: any, userId: string): Promise<string[]> {
|
|
|
|
|
try {
|
|
|
|
|
const client = await clerkClient(context);
|
|
|
|
|
const memberships = await client.users.getOrganizationMembershipList({ userId });
|
|
|
|
|
return memberships.data.map((m) => m.organization.id);
|
|
|
|
|
} catch (e) {
|
|
|
|
|
console.error("Failed to fetch user org memberships:", e);
|
|
|
|
|
return [];
|
|
|
|
|
}
|
|
|
|
|
}
|