brackt/app/lib/auth.ts

56 lines
1.5 KiB
TypeScript

import { getAuth } from "@clerk/react-router/server";
import type { database } from "~/database/context";
import { eq, and } from "drizzle-orm";
import * as schema from "~/database/schema";
import type { LoaderFunctionArgs } from "react-router";
type Db = ReturnType<typeof database>;
/**
* Verifies the request has an authenticated user who is either a commissioner
* or a team owner in the given league/season. Throws Response on failure.
*
* @param unauthMessage - 401 message when not logged in
* @param unauthorizedMessage - 403 message when logged in but not a member
*/
export async function requireLeagueAccess(
args: LoaderFunctionArgs,
{
leagueId,
seasonId,
db,
unauthMessage = "You must be logged in",
unauthorizedMessage = "You do not have access to this league",
}: {
leagueId: string;
seasonId: string;
db: Db;
unauthMessage?: string;
unauthorizedMessage?: string;
}
): Promise<void> {
const { userId } = await getAuth(args);
if (!userId) {
throw new Response(unauthMessage, { status: 401 });
}
const [commissioner, team] = await Promise.all([
db.query.commissioners.findFirst({
where: and(
eq(schema.commissioners.leagueId, leagueId),
eq(schema.commissioners.userId, userId)
),
}),
db.query.teams.findFirst({
where: and(
eq(schema.teams.seasonId, seasonId),
eq(schema.teams.ownerId, userId)
),
}),
]);
if (!commissioner && !team) {
throw new Response(unauthorizedMessage, { status: 403 });
}
}