diff --git a/apps/web/app/(sidebar)/scout/actions/submitForm.ts b/apps/web/app/(sidebar)/scout/actions/submitForm.ts index 78fbd2c..c92ca9e 100644 --- a/apps/web/app/(sidebar)/scout/actions/submitForm.ts +++ b/apps/web/app/(sidebar)/scout/actions/submitForm.ts @@ -1,8 +1,8 @@ "use server"; +import { StandFormData, standFormSchema } from "../data/schema"; import { _getTeamsInMatch, TeamInMatch } from "./teamsInMatch"; import { StandFormSubmissionErrors } from "./utils"; -import { StandFormData, standFormSchema } from "../data/schema"; import { createServerAction, @@ -10,7 +10,7 @@ import { ServerActionErrorWithCustomData } from "@/lib/actions/actions-utils"; import { auth } from "@/lib/auth"; -import { AuthErrors, isSessionAuthorized } from "@/lib/auth/utils"; +import { AuthErrors, checkSession } from "@/lib/auth/utils"; import { db } from "@/lib/database"; import { match, @@ -103,15 +103,15 @@ async function insertStandForm( async function _submitStandForm(data: StandFormData) { const session = await auth(); + if (!session) throw new ServerActionError(AuthErrors.UNAUTHORIZED); + const { success, data: validatedData } = standFormSchema.safeParse(data); if (!success) { throw new ServerActionError("Invalid form data"); } - if (!session || !isSessionAuthorized(UserRole.USER, session)) { - throw new ServerActionError(AuthErrors.UNAUTHORIZED); - } + await checkSession(UserRole.USER, session); const teamMatches = await _getTeamsInMatch(data.match_detail.match_number); diff --git a/apps/web/lib/auth/utils.ts b/apps/web/lib/auth/utils.ts index 8a70245..edf6b36 100644 --- a/apps/web/lib/auth/utils.ts +++ b/apps/web/lib/auth/utils.ts @@ -1,9 +1,9 @@ import { auth } from "./auth"; -import { UserRole } from "@/lib/database/schema"; -import { redirect } from "next/navigation"; +import { UserRole, userRoleOrdering } from "@/lib/database/schema"; import { Session } from "next-auth"; import { DiscordProfile } from "next-auth/providers/discord"; +import { redirect } from "next/navigation"; const YETI_GUILD_ID = "408711970305474560"; const AVALANCHE_GUILD_ID = "1241008226598649886"; @@ -81,7 +81,7 @@ export function redirectError(error: AuthErrors) { } function roleIndex(userRole: UserRole) { - return Object.values(UserRole).indexOf(userRole); + return userRoleOrdering.indexOf(userRole); } export function isSessionAuthorized(requiredRole: UserRole, session: Session) { diff --git a/apps/web/lib/database/schema.ts b/apps/web/lib/database/schema.ts index f072eb2..2413210 100644 --- a/apps/web/lib/database/schema.ts +++ b/apps/web/lib/database/schema.ts @@ -20,9 +20,6 @@ import { } from "drizzle-orm/pg-core"; import type { AdapterAccountType } from "next-auth/adapters"; - -// the order of this enum is important and is used -// to check permissions for a user to access resources export enum UserRole { ADMIN = "admin", USER = "user", @@ -30,6 +27,9 @@ export enum UserRole { BANISHED = "banished", } +// ordering of user roles from most to least permissive +export const userRoleOrdering: UserRole[] = [UserRole.ADMIN, UserRole.USER, UserRole.GUEST, UserRole.BANISHED]; + export const userRoleEnum = pgEnum("user_role", enumToPgEnum(UserRole)); export const users = pgTable("user", {