mirror of
https://github.com/Sendouc/sendou.ink.git
synced 2026-03-21 18:04:39 -05:00
User middleware (#2687)
This commit is contained in:
parent
91e26948b2
commit
4fca18ac8d
|
|
@ -289,6 +289,8 @@ function wipeDB() {
|
|||
"UserFriendCode",
|
||||
"NotificationUser",
|
||||
"Notification",
|
||||
"BanLog",
|
||||
"ModNote",
|
||||
"User",
|
||||
"PlusSuggestion",
|
||||
"PlusVote",
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ export const action = async ({ request }: ActionFunctionArgs) => {
|
|||
request,
|
||||
schema: adminActionSchema,
|
||||
});
|
||||
const user = await requireUser(request);
|
||||
const user = await requireUser();
|
||||
|
||||
let message: string;
|
||||
switch (data._action) {
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import { DANGEROUS_CAN_ACCESS_DEV_CONTROLS } from "../core/dev-controls";
|
|||
|
||||
export const loader = async ({ request }: LoaderFunctionArgs) => {
|
||||
if (!DANGEROUS_CAN_ACCESS_DEV_CONTROLS) {
|
||||
const user = await requireUser(request);
|
||||
const user = await requireUser();
|
||||
requireRole(user, "STAFF");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import { z } from "zod";
|
|||
import { seed } from "~/db/seed";
|
||||
import { DANGEROUS_CAN_ACCESS_DEV_CONTROLS } from "~/features/admin/core/dev-controls";
|
||||
import { SEED_VARIATIONS } from "~/features/api-private/constants";
|
||||
import { refreshBannedCache } from "~/features/ban/core/banned.server";
|
||||
import { refreshSendouQInstance } from "~/features/sendouq/core/SendouQ.server";
|
||||
import { parseRequestPayload } from "~/utils/remix.server";
|
||||
|
||||
|
|
@ -26,6 +27,7 @@ export const action: ActionFunction = async ({ request }) => {
|
|||
|
||||
await seed(variation);
|
||||
|
||||
await refreshBannedCache();
|
||||
await refreshSendouQInstance();
|
||||
|
||||
return Response.json(null);
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ export const action = async ({ request }: ActionFunctionArgs) => {
|
|||
request,
|
||||
schema: apiActionSchema,
|
||||
});
|
||||
const user = await requireUser(request);
|
||||
const user = await requireUser();
|
||||
|
||||
const hasApiAccess = await checkUserHasApiAccess(user);
|
||||
if (!hasApiAccess) {
|
||||
|
|
|
|||
|
|
@ -1,10 +1,9 @@
|
|||
import type { LoaderFunctionArgs } from "react-router";
|
||||
import { requireUser } from "~/features/auth/core/user.server";
|
||||
import * as ApiRepository from "../ApiRepository.server";
|
||||
import { checkUserHasApiAccess } from "../core/perms";
|
||||
|
||||
export const loader = async ({ request }: LoaderFunctionArgs) => {
|
||||
const user = await requireUser(request);
|
||||
export const loader = async () => {
|
||||
const user = await requireUser();
|
||||
|
||||
const hasApiAccess = await checkUserHasApiAccess(user);
|
||||
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ import { NEW_ART_EXISTING_SEARCH_PARAM_KEY } from "../art-constants";
|
|||
import { editArtSchema, newArtSchema } from "../art-schemas.server";
|
||||
|
||||
export const action: ActionFunction = async ({ request }) => {
|
||||
const user = await requireUser(request);
|
||||
const user = await requireUser();
|
||||
requireRole(user, "ARTIST");
|
||||
|
||||
const searchParams = new URL(request.url).searchParams;
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import * as ArtRepository from "../ArtRepository.server";
|
|||
import { NEW_ART_EXISTING_SEARCH_PARAM_KEY } from "../art-constants";
|
||||
|
||||
export const loader = async ({ request }: LoaderFunctionArgs) => {
|
||||
const user = await requireUser(request);
|
||||
const user = await requireUser();
|
||||
|
||||
const artIdRaw = new URL(request.url).searchParams.get(
|
||||
NEW_ART_EXISTING_SEARCH_PARAM_KEY,
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import { associationsPage } from "~/utils/urls";
|
|||
import * as AssociationRepository from "../AssociationRepository.server";
|
||||
|
||||
export const action = async ({ request }: ActionFunctionArgs) => {
|
||||
const user = await requireUser(request);
|
||||
const user = await requireUser();
|
||||
const data = await parseRequestPayload({
|
||||
request,
|
||||
schema: createNewAssociationSchema,
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ import { assertUnreachable } from "~/utils/types";
|
|||
import * as AssociationRepository from "../AssociationRepository.server";
|
||||
|
||||
export const action = async ({ request }: ActionFunctionArgs) => {
|
||||
const user = await requireUser(request);
|
||||
const user = await requireUser();
|
||||
const data = await parseRequestPayload({
|
||||
request,
|
||||
schema: associationsPageActionSchema,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import type { LoaderFunctionArgs } from "react-router";
|
||||
import { requireUserId } from "~/features/auth/core/user.server";
|
||||
import { requireUser } from "~/features/auth/core/user.server";
|
||||
import type { SerializeFrom } from "~/utils/remix";
|
||||
import { parseSafeSearchParams } from "~/utils/remix.server";
|
||||
import { inviteCodeObject } from "~/utils/zod";
|
||||
|
|
@ -8,7 +8,7 @@ import * as AssociationRepository from "../AssociationRepository.server";
|
|||
export type AssociationsLoaderData = SerializeFrom<typeof loader>;
|
||||
|
||||
export const loader = async ({ request }: LoaderFunctionArgs) => {
|
||||
const user = await requireUserId(request);
|
||||
const user = await requireUser();
|
||||
|
||||
const associations = (
|
||||
await AssociationRepository.findByMemberUserId(user.id, {
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ import {
|
|||
SESSION_KEY,
|
||||
} from "./authenticator.server";
|
||||
import { authSessionStorage } from "./session.server";
|
||||
import { getUserId, requireUser } from "./user.server";
|
||||
import { getUser, requireUser } from "./user.server";
|
||||
|
||||
export const callbackLoader: LoaderFunction = async ({ request }) => {
|
||||
const url = new URL(request.url);
|
||||
|
|
@ -76,7 +76,7 @@ export const logInAction: ActionFunction = async ({ request }) => {
|
|||
|
||||
export const impersonateAction: ActionFunction = async ({ request }) => {
|
||||
if (!DANGEROUS_CAN_ACCESS_DEV_CONTROLS) {
|
||||
const user = await requireUser(request);
|
||||
const user = await requireUser();
|
||||
requireRole(user, "ADMIN");
|
||||
}
|
||||
|
||||
|
|
@ -163,7 +163,7 @@ export const logInViaLinkLoader: LoaderFunction = async ({ request }) => {
|
|||
request,
|
||||
schema: logInViaLinkActionSchema,
|
||||
});
|
||||
const user = await getUserId(request);
|
||||
const user = await getUser();
|
||||
|
||||
if (user) {
|
||||
throw redirect("/");
|
||||
|
|
|
|||
47
app/features/auth/core/user-context.server.ts
Normal file
47
app/features/auth/core/user-context.server.ts
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
import { AsyncLocalStorage } from "node:async_hooks";
|
||||
import { redirect } from "react-router";
|
||||
import { userIsBanned } from "~/features/ban/core/banned.server";
|
||||
import * as UserRepository from "~/features/user-page/UserRepository.server";
|
||||
import { SUSPENDED_PAGE } from "~/utils/urls";
|
||||
import { IMPERSONATED_SESSION_KEY, SESSION_KEY } from "./authenticator.server";
|
||||
import { authSessionStorage } from "./session.server";
|
||||
|
||||
export type AuthenticatedUser = NonNullable<
|
||||
Awaited<ReturnType<typeof UserRepository.findLeanById>>
|
||||
>;
|
||||
|
||||
interface UserContext {
|
||||
getUserLazy: () => Promise<AuthenticatedUser | undefined>;
|
||||
}
|
||||
|
||||
export const userAsyncLocalStorage = new AsyncLocalStorage<UserContext>();
|
||||
|
||||
export function getUserContext(): UserContext {
|
||||
const context = userAsyncLocalStorage.getStore();
|
||||
if (!context) {
|
||||
throw new Error("getUserContext called outside of user middleware context");
|
||||
}
|
||||
return context;
|
||||
}
|
||||
|
||||
export async function getUserFromRequest(
|
||||
request: Request,
|
||||
): Promise<AuthenticatedUser | undefined> {
|
||||
const session = await authSessionStorage.getSession(
|
||||
request.headers.get("Cookie"),
|
||||
);
|
||||
|
||||
const userId =
|
||||
session.get(IMPERSONATED_SESSION_KEY) ?? session.get(SESSION_KEY);
|
||||
|
||||
if (!userId) return undefined;
|
||||
|
||||
if (userIsBanned(userId)) {
|
||||
const url = new URL(request.url);
|
||||
if (url.pathname !== SUSPENDED_PAGE) {
|
||||
throw redirect(SUSPENDED_PAGE);
|
||||
}
|
||||
}
|
||||
|
||||
return UserRepository.findLeanById(userId);
|
||||
}
|
||||
34
app/features/auth/core/user-middleware.server.ts
Normal file
34
app/features/auth/core/user-middleware.server.ts
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
import {
|
||||
type AuthenticatedUser,
|
||||
getUserFromRequest,
|
||||
userAsyncLocalStorage,
|
||||
} from "./user-context.server";
|
||||
|
||||
type MiddlewareArgs = {
|
||||
request: Request;
|
||||
context: unknown;
|
||||
};
|
||||
|
||||
type MiddlewareFn = (
|
||||
args: MiddlewareArgs,
|
||||
next: () => Promise<Response>,
|
||||
) => Promise<Response>;
|
||||
|
||||
function createLazyUserGetter(
|
||||
request: Request,
|
||||
): () => Promise<AuthenticatedUser | undefined> {
|
||||
let fetchPromise: Promise<AuthenticatedUser | undefined> | undefined;
|
||||
|
||||
return () => {
|
||||
fetchPromise ??= getUserFromRequest(request);
|
||||
return fetchPromise;
|
||||
};
|
||||
}
|
||||
|
||||
export const userMiddleware: MiddlewareFn = async ({ request }, next) => {
|
||||
const context = {
|
||||
getUserLazy: createLazyUserGetter(request),
|
||||
};
|
||||
|
||||
return userAsyncLocalStorage.run(context, () => next());
|
||||
};
|
||||
|
|
@ -1,51 +1,16 @@
|
|||
import { redirect } from "react-router";
|
||||
import type { Tables } from "~/db/tables";
|
||||
import { userIsBanned } from "~/features/ban/core/banned.server";
|
||||
import * as UserRepository from "~/features/user-page/UserRepository.server";
|
||||
import { SUSPENDED_PAGE } from "~/utils/urls";
|
||||
import { IMPERSONATED_SESSION_KEY, SESSION_KEY } from "./authenticator.server";
|
||||
import { IMPERSONATED_SESSION_KEY } from "./authenticator.server";
|
||||
import { authSessionStorage } from "./session.server";
|
||||
import { type AuthenticatedUser, getUserContext } from "./user-context.server";
|
||||
|
||||
export type AuthenticatedUser = NonNullable<
|
||||
Awaited<ReturnType<typeof getUser>>
|
||||
>;
|
||||
export type { AuthenticatedUser };
|
||||
|
||||
export async function getUserId(
|
||||
request: Request,
|
||||
redirectIfBanned = true,
|
||||
): Promise<Pick<Tables["User"], "id"> | undefined> {
|
||||
const session = await authSessionStorage.getSession(
|
||||
request.headers.get("Cookie"),
|
||||
);
|
||||
|
||||
const userId =
|
||||
session.get(IMPERSONATED_SESSION_KEY) ?? session.get(SESSION_KEY);
|
||||
|
||||
if (!userId) return;
|
||||
|
||||
if (userIsBanned(userId) && redirectIfBanned) throw redirect(SUSPENDED_PAGE);
|
||||
|
||||
return { id: userId };
|
||||
export async function getUser(): Promise<AuthenticatedUser | undefined> {
|
||||
const context = getUserContext();
|
||||
return context.getUserLazy();
|
||||
}
|
||||
|
||||
export async function getUser(request: Request, redirectIfBanned = true) {
|
||||
const userId = (await getUserId(request, redirectIfBanned))?.id;
|
||||
|
||||
if (!userId) return;
|
||||
|
||||
return UserRepository.findLeanById(userId);
|
||||
}
|
||||
|
||||
export async function requireUserId(request: Request) {
|
||||
const user = await getUserId(request);
|
||||
|
||||
if (!user) throw new Response(null, { status: 401 });
|
||||
|
||||
return user;
|
||||
}
|
||||
|
||||
export async function requireUser(request: Request) {
|
||||
const user = await getUser(request);
|
||||
export async function requireUser(): Promise<AuthenticatedUser> {
|
||||
const user = await getUser();
|
||||
|
||||
if (!user) throw new Response(null, { status: 401 });
|
||||
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ export const action: ActionFunction = async ({ request, params }) => {
|
|||
schema: editBadgeActionSchema,
|
||||
});
|
||||
const badgeId = z.preprocess(actualNumber, z.number()).parse(params.id);
|
||||
const user = await requireUser(request);
|
||||
const user = await requireUser();
|
||||
|
||||
const badge = notFoundIfFalsy(await BadgeRepository.findById(badgeId));
|
||||
|
||||
|
|
|
|||
|
|
@ -3,15 +3,22 @@ import { databaseTimestampToDate } from "~/utils/dates";
|
|||
|
||||
let bannedUsers = await AdminRepository.allBannedUsers();
|
||||
|
||||
export function checkBanStatus(
|
||||
banned: number | null | undefined,
|
||||
now: Date = new Date(),
|
||||
): boolean {
|
||||
if (!banned) return false;
|
||||
if (banned === 1) return true;
|
||||
|
||||
const banExpiresAt = databaseTimestampToDate(banned);
|
||||
|
||||
return banExpiresAt > now;
|
||||
}
|
||||
|
||||
export function userIsBanned(userId: number) {
|
||||
const banStatus = bannedUsers.get(userId);
|
||||
|
||||
if (!banStatus?.banned) return false;
|
||||
if (banStatus.banned === 1) return true;
|
||||
|
||||
const banExpiresAt = databaseTimestampToDate(banStatus.banned);
|
||||
|
||||
return banExpiresAt > new Date();
|
||||
return checkBanStatus(banStatus?.banned);
|
||||
}
|
||||
|
||||
export async function refreshBannedCache() {
|
||||
|
|
|
|||
59
app/features/ban/core/banned.test.ts
Normal file
59
app/features/ban/core/banned.test.ts
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
import { describe, expect, it } from "vitest";
|
||||
import { checkBanStatus } from "./banned.server";
|
||||
|
||||
describe("checkBanStatus", () => {
|
||||
it("returns false when banned is null", () => {
|
||||
expect(checkBanStatus(null)).toBe(false);
|
||||
});
|
||||
|
||||
it("returns false when banned is undefined", () => {
|
||||
expect(checkBanStatus(undefined)).toBe(false);
|
||||
});
|
||||
|
||||
it("returns false when banned is 0", () => {
|
||||
expect(checkBanStatus(0)).toBe(false);
|
||||
});
|
||||
|
||||
it("returns true when banned is 1 (permanent ban)", () => {
|
||||
expect(checkBanStatus(1)).toBe(true);
|
||||
});
|
||||
|
||||
it("returns true when ban expires in the future", () => {
|
||||
const now = new Date("2025-01-01T12:00:00Z");
|
||||
const futureTimestamp = Math.floor(
|
||||
new Date("2025-01-01T13:00:00Z").getTime() / 1000,
|
||||
);
|
||||
|
||||
expect(checkBanStatus(futureTimestamp, now)).toBe(true);
|
||||
});
|
||||
|
||||
it("returns false when ban has expired", () => {
|
||||
const now = new Date("2025-01-01T12:00:00Z");
|
||||
const pastTimestamp = Math.floor(
|
||||
new Date("2025-01-01T11:00:00Z").getTime() / 1000,
|
||||
);
|
||||
|
||||
expect(checkBanStatus(pastTimestamp, now)).toBe(false);
|
||||
});
|
||||
|
||||
it("returns false when ban expires exactly at current time", () => {
|
||||
const now = new Date("2025-01-01T12:00:00Z");
|
||||
const exactTimestamp = Math.floor(now.getTime() / 1000);
|
||||
|
||||
expect(checkBanStatus(exactTimestamp, now)).toBe(false);
|
||||
});
|
||||
|
||||
it("returns true when ban expires 1 second in the future", () => {
|
||||
const now = new Date("2025-01-01T12:00:00Z");
|
||||
const oneSecondLater = Math.floor(now.getTime() / 1000) + 1;
|
||||
|
||||
expect(checkBanStatus(oneSecondLater, now)).toBe(true);
|
||||
});
|
||||
|
||||
it("returns false when ban expired 1 second ago", () => {
|
||||
const now = new Date("2025-01-01T12:00:00Z");
|
||||
const oneSecondEarlier = Math.floor(now.getTime() / 1000) - 1;
|
||||
|
||||
expect(checkBanStatus(oneSecondEarlier, now)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
|
@ -15,7 +15,7 @@ import { buildFiltersSearchParams } from "../builds-schemas.server";
|
|||
import { filterBuilds } from "../core/filter.server";
|
||||
|
||||
export const loader = async ({ request, params }: LoaderFunctionArgs) => {
|
||||
const user = await getUser(request);
|
||||
const user = await getUser();
|
||||
const t = await i18next.getFixedT(request, ["weapons", "common"], {
|
||||
lng: "en",
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import type { ActionFunction } from "react-router";
|
||||
import { redirect } from "react-router";
|
||||
import { requireUserId } from "~/features/auth/core/user.server";
|
||||
import { requireUser } from "~/features/auth/core/user.server";
|
||||
import * as CalendarRepository from "~/features/calendar/CalendarRepository.server";
|
||||
import {
|
||||
errorToastIfFalsy,
|
||||
|
|
@ -14,7 +14,7 @@ import { reportWinnersActionSchema } from "../calendar-schemas";
|
|||
import { canReportCalendarEventWinners } from "../calendar-utils";
|
||||
|
||||
export const action: ActionFunction = async (args) => {
|
||||
const user = await requireUserId(args.request);
|
||||
const user = await requireUser();
|
||||
const params = parseParams({
|
||||
params: args.params,
|
||||
schema: idObject,
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import type { ActionFunction } from "react-router";
|
||||
import { redirect } from "react-router";
|
||||
import { z } from "zod";
|
||||
import { requireUserId } from "~/features/auth/core/user.server";
|
||||
import { requireUser } from "~/features/auth/core/user.server";
|
||||
import * as CalendarRepository from "~/features/calendar/CalendarRepository.server";
|
||||
import * as ShowcaseTournaments from "~/features/front-page/core/ShowcaseTournaments.server";
|
||||
import {
|
||||
|
|
@ -14,8 +14,8 @@ import { CALENDAR_PAGE } from "~/utils/urls";
|
|||
import { actualNumber, id } from "~/utils/zod";
|
||||
import { canDeleteCalendarEvent } from "../calendar-utils";
|
||||
|
||||
export const action: ActionFunction = async ({ params, request }) => {
|
||||
const user = await requireUserId(request);
|
||||
export const action: ActionFunction = async ({ params }) => {
|
||||
const user = await requireUser();
|
||||
const parsedParams = z
|
||||
.object({ id: z.preprocess(actualNumber, id) })
|
||||
.parse(params);
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ import { canEditCalendarEvent, regClosesAtDate } from "../calendar-utils";
|
|||
import { findValidOrganizations } from "../loaders/calendar.new.server";
|
||||
|
||||
export const action: ActionFunction = async ({ request }) => {
|
||||
const user = await requireUser(request);
|
||||
const user = await requireUser();
|
||||
|
||||
const { avatarFileName, formData } = await uploadImageIfSubmitted({
|
||||
request,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { type ActionFunctionArgs, redirect } from "react-router";
|
||||
import { requireUserId } from "~/features/auth/core/user.server";
|
||||
import { requireUser } from "~/features/auth/core/user.server";
|
||||
import { calendarFiltersSearchParamsSchema } from "~/features/calendar/calendar-schemas";
|
||||
import * as UserRepository from "~/features/user-page/UserRepository.server";
|
||||
import {
|
||||
|
|
@ -10,7 +10,7 @@ import { calendarPage } from "~/utils/urls";
|
|||
import { dayMonthYear } from "~/utils/zod";
|
||||
|
||||
export const action = async ({ request }: ActionFunctionArgs) => {
|
||||
const user = await requireUserId(request);
|
||||
const user = await requireUser();
|
||||
const data = await parseRequestPayload({
|
||||
request,
|
||||
schema: calendarFiltersSearchParamsSchema,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import type { LoaderFunctionArgs } from "react-router";
|
||||
import { requireUserId } from "~/features/auth/core/user.server";
|
||||
import { requireUser } from "~/features/auth/core/user.server";
|
||||
import * as CalendarRepository from "~/features/calendar/CalendarRepository.server";
|
||||
import {
|
||||
notFoundIfFalsy,
|
||||
|
|
@ -14,7 +14,7 @@ export const loader = async (args: LoaderFunctionArgs) => {
|
|||
params: args.params,
|
||||
schema: idObject,
|
||||
});
|
||||
const user = await requireUserId(args.request);
|
||||
const user = await requireUser();
|
||||
const event = notFoundIfFalsy(await CalendarRepository.findById(params.id));
|
||||
|
||||
unauthorizedIfFalsy(
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import { tournamentBracketsPage } from "~/utils/urls";
|
|||
import { canEditCalendarEvent } from "../calendar-utils";
|
||||
|
||||
export const loader = async ({ request }: LoaderFunctionArgs) => {
|
||||
const user = await requireUser(request);
|
||||
const user = await requireUser();
|
||||
requireRole(user, "CALENDAR_EVENT_ADDER");
|
||||
|
||||
const url = new URL(request.url);
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ import * as CalendarEvent from "../core/CalendarEvent";
|
|||
export type CalendarLoaderData = SerializeFrom<typeof loader>;
|
||||
|
||||
export const loader = async (args: LoaderFunctionArgs) => {
|
||||
const user = await getUser(args.request);
|
||||
const user = await getUser();
|
||||
const parsed = parseSafeSearchParams({
|
||||
request: args.request,
|
||||
schema: dayMonthYear,
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
import cachified from "@epic-web/cachified";
|
||||
import type { LoaderFunctionArgs } from "react-router";
|
||||
import type { Tables } from "~/db/tables";
|
||||
import { getUserId } from "~/features/auth/core/user.server";
|
||||
import { getUser } from "~/features/auth/core/user.server";
|
||||
import * as Changelog from "~/features/front-page/core/Changelog.server";
|
||||
import { cachedFullUserLeaderboard } from "~/features/leaderboards/core/leaderboards.server";
|
||||
import * as LeaderboardRepository from "~/features/leaderboards/LeaderboardRepository.server";
|
||||
|
|
@ -10,8 +9,8 @@ import { cache, IN_MILLISECONDS, ttl } from "~/utils/cache.server";
|
|||
import { discordAvatarUrl, teamPage, userPage } from "~/utils/urls";
|
||||
import * as ShowcaseTournaments from "../core/ShowcaseTournaments.server";
|
||||
|
||||
export const loader = async ({ request }: LoaderFunctionArgs) => {
|
||||
const user = await getUserId(request);
|
||||
export const loader = async () => {
|
||||
const user = await getUser();
|
||||
|
||||
const [tournaments, changelog, leaderboards] = await Promise.all([
|
||||
ShowcaseTournaments.frontPageTournamentsByUserId(user?.id ?? null),
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import * as ImageRepository from "../ImageRepository.server";
|
|||
import { validateImageSchema } from "../upload-schemas.server";
|
||||
|
||||
export const action: ActionFunction = async ({ request }) => {
|
||||
const user = await requireUser(request);
|
||||
const user = await requireUser();
|
||||
requireRole(user, "STAFF");
|
||||
|
||||
const data = await parseRequestPayload({
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ import { MAX_UNVALIDATED_IMG_COUNT } from "../upload-constants";
|
|||
import { requestToImgType } from "../upload-utils";
|
||||
|
||||
export const action = async ({ request }: ActionFunctionArgs) => {
|
||||
const user = await requireUser(request);
|
||||
const user = await requireUser();
|
||||
|
||||
const validatedType = requestToImgType(request);
|
||||
errorToastIfFalsy(validatedType, "Invalid image type");
|
||||
|
|
|
|||
|
|
@ -1,10 +1,9 @@
|
|||
import type { LoaderFunctionArgs } from "react-router";
|
||||
import { requireUser } from "~/features/auth/core/user.server";
|
||||
import { requireRole } from "~/modules/permissions/guards.server";
|
||||
import * as ImageRepository from "../ImageRepository.server";
|
||||
|
||||
export const loader = async ({ request }: LoaderFunctionArgs) => {
|
||||
const user = await requireUser(request);
|
||||
export const loader = async () => {
|
||||
const user = await requireUser();
|
||||
requireRole(user, "STAFF");
|
||||
|
||||
return {
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import * as ImageRepository from "../ImageRepository.server";
|
|||
import { requestToImgType } from "../upload-utils";
|
||||
|
||||
export const loader = async ({ request }: LoaderFunctionArgs) => {
|
||||
const user = await requireUser(request);
|
||||
const user = await requireUser();
|
||||
const validatedType = requestToImgType(request);
|
||||
|
||||
if (!validatedType) {
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ import {
|
|||
} from "../queries/XPLeaderboard.server";
|
||||
|
||||
export const loader = async ({ request }: LoaderFunctionArgs) => {
|
||||
const user = await getUser(request);
|
||||
const user = await getUser();
|
||||
const unvalidatedType = new URL(request.url).searchParams.get(
|
||||
TYPE_SEARCH_PARAM_KEY,
|
||||
);
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import * as LFGRepository from "../LFGRepository.server";
|
|||
import { LFG, TEAM_POST_TYPES, TIMEZONES } from "../lfg-constants";
|
||||
|
||||
export const action = async ({ request }: ActionFunctionArgs) => {
|
||||
const user = await requireUser(request);
|
||||
const user = await requireUser();
|
||||
const data = await parseRequestPayload({
|
||||
request,
|
||||
schema,
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import { _action, id } from "~/utils/zod";
|
|||
import * as LFGRepository from "../LFGRepository.server";
|
||||
|
||||
export const action = async ({ request }: ActionFunctionArgs) => {
|
||||
const user = await requireUser(request);
|
||||
const user = await requireUser();
|
||||
const data = await parseRequestPayload({
|
||||
request,
|
||||
schema,
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import { id } from "~/utils/zod";
|
|||
import * as LFGRepository from "../LFGRepository.server";
|
||||
|
||||
export const loader = async ({ request }: LoaderFunctionArgs) => {
|
||||
const user = await requireUser(request);
|
||||
const user = await requireUser();
|
||||
|
||||
const userProfileData = await UserRepository.findProfileByIdentifier(
|
||||
String(user.id),
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
import type { LoaderFunctionArgs } from "react-router";
|
||||
import { getUser } from "~/features/auth/core/user.server";
|
||||
import * as Seasons from "~/features/mmr/core/Seasons";
|
||||
import type { TieredSkill } from "~/features/mmr/tiered.server";
|
||||
|
|
@ -6,8 +5,8 @@ import { userSkills } from "~/features/mmr/tiered.server";
|
|||
import type { Unpacked } from "~/utils/types";
|
||||
import * as LFGRepository from "../LFGRepository.server";
|
||||
|
||||
export const loader = async ({ request }: LoaderFunctionArgs) => {
|
||||
const user = await getUser(request);
|
||||
export const loader = async () => {
|
||||
const user = await getUser();
|
||||
const posts = await LFGRepository.posts(user);
|
||||
|
||||
return {
|
||||
|
|
|
|||
|
|
@ -1,9 +1,8 @@
|
|||
import type { LoaderFunctionArgs } from "react-router";
|
||||
import { requireUserId } from "~/features/auth/core/user.server";
|
||||
import { requireUser } from "~/features/auth/core/user.server";
|
||||
import * as NotificationRepository from "../NotificationRepository.server";
|
||||
|
||||
export const loader = async ({ request }: LoaderFunctionArgs) => {
|
||||
const user = await requireUserId(request);
|
||||
export const loader = async () => {
|
||||
const user = await requireUser();
|
||||
|
||||
return {
|
||||
notifications: await NotificationRepository.findByUserId(user.id),
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
import type { ActionFunctionArgs } from "react-router";
|
||||
import { requireUserId } from "~/features/auth/core/user.server";
|
||||
import { requireUser } from "~/features/auth/core/user.server";
|
||||
import { parseRequestPayload } from "~/utils/remix.server";
|
||||
import * as NotificationRepository from "../NotificationRepository.server";
|
||||
import { markAsSeenActionSchema } from "../notifications-schemas";
|
||||
|
||||
export const action = async ({ request }: ActionFunctionArgs) => {
|
||||
const user = await requireUserId(request);
|
||||
const user = await requireUser();
|
||||
const data = await parseRequestPayload({
|
||||
request,
|
||||
schema: markAsSeenActionSchema,
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import * as NotificationRepository from "../NotificationRepository.server";
|
|||
import { subscribeSchema } from "../notifications-schemas";
|
||||
|
||||
export const action = async ({ request }: ActionFunctionArgs) => {
|
||||
const user = await requireUser(request);
|
||||
const user = await requireUser();
|
||||
const data = await parseRequestPayload({
|
||||
request,
|
||||
schema: subscribeSchema,
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ export const action = async ({ request }: ActionFunctionArgs) => {
|
|||
request,
|
||||
schema: followUpCommentActionSchema,
|
||||
});
|
||||
const user = await requireUser(request);
|
||||
const user = await requireUser();
|
||||
|
||||
const votingMonthYear = rangeToMonthYear(
|
||||
badRequestIfFalsy(nextNonCompletedVoting(new Date())),
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ import {
|
|||
} from "../plus-suggestions-utils";
|
||||
|
||||
export const action: ActionFunction = async ({ request }) => {
|
||||
const user = await requireUser(request);
|
||||
const user = await requireUser();
|
||||
|
||||
const data = await parseRequestPayload({
|
||||
request,
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ export const action: ActionFunction = async ({ request }) => {
|
|||
request,
|
||||
schema: suggestionActionSchema,
|
||||
});
|
||||
const user = await requireUser(request);
|
||||
const user = await requireUser();
|
||||
|
||||
const votingMonthYear = rangeToMonthYear(
|
||||
badRequestIfFalsy(nextNonCompletedVoting(new Date())),
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ import { PLUS_UPVOTE } from "../plus-voting-constants";
|
|||
import { votingActionSchema } from "../plus-voting-schemas";
|
||||
|
||||
export const action: ActionFunction = async ({ request }) => {
|
||||
const user = await requireUser(request);
|
||||
const user = await requireUser();
|
||||
const data = await parseRequestPayload({
|
||||
request,
|
||||
schema: votingActionSchema,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
import type { LoaderFunctionArgs } from "react-router";
|
||||
import type { UserWithPlusTier } from "~/db/tables";
|
||||
import { getUser } from "~/features/auth/core/user.server";
|
||||
import { lastCompletedVoting } from "~/features/plus-voting/core";
|
||||
|
|
@ -7,8 +6,8 @@ import { isSupporter } from "~/modules/permissions/utils";
|
|||
import invariant from "~/utils/invariant";
|
||||
import { roundToNDecimalPlaces } from "~/utils/number";
|
||||
|
||||
export const loader = async ({ request }: LoaderFunctionArgs) => {
|
||||
const user = await getUser(request);
|
||||
export const loader = async () => {
|
||||
const user = await getUser();
|
||||
const results = await PlusVotingRepository.resultsByMonthYear(
|
||||
lastCompletedVoting(new Date()),
|
||||
);
|
||||
|
|
|
|||
|
|
@ -33,8 +33,8 @@ export type PlusVotingLoaderData =
|
|||
};
|
||||
};
|
||||
|
||||
export const loader: LoaderFunction = async ({ request }) => {
|
||||
const user = await getUser(request);
|
||||
export const loader: LoaderFunction = async () => {
|
||||
const user = await getUser();
|
||||
|
||||
const now = new Date();
|
||||
const nextVotingRange = nextNonCompletedVoting(now);
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ export const action = async ({ request, params }: ActionFunctionArgs) => {
|
|||
const { id } = parseParams({ params, schema: idObject });
|
||||
const post = notFoundIfFalsy(await ScrimPostRepository.findById(id));
|
||||
|
||||
const user = await requireUser(request);
|
||||
const user = await requireUser();
|
||||
const data = await parseRequestPayload({
|
||||
request,
|
||||
schema: cancelScrimSchema,
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ import {
|
|||
import { serializeLutiDiv } from "../scrims-utils";
|
||||
|
||||
export const action = async ({ request }: ActionFunctionArgs) => {
|
||||
const user = await requireUser(request);
|
||||
const user = await requireUser();
|
||||
const data = await parseRequestPayload({
|
||||
request,
|
||||
schema: scrimsNewActionSchema,
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ import { generateTimeOptions } from "../scrims-utils";
|
|||
import { usersListForPost } from "./scrims.new.server";
|
||||
|
||||
export const action = async ({ request }: ActionFunctionArgs) => {
|
||||
const user = await requireUser(request);
|
||||
const user = await requireUser();
|
||||
|
||||
const data = await parseRequestPayload({
|
||||
request,
|
||||
|
|
|
|||
|
|
@ -9,8 +9,8 @@ import {
|
|||
import * as Scrim from "../core/Scrim";
|
||||
import * as ScrimPostRepository from "../ScrimPostRepository.server";
|
||||
|
||||
export const loader = async ({ request, params }: LoaderFunctionArgs) => {
|
||||
const user = await requireUser(request);
|
||||
export const loader = async ({ params }: LoaderFunctionArgs) => {
|
||||
const user = await requireUser();
|
||||
|
||||
const post = notFoundIfFalsy(
|
||||
await ScrimPostRepository.findById(Number(params.id)),
|
||||
|
|
|
|||
|
|
@ -1,13 +1,12 @@
|
|||
import type { LoaderFunctionArgs } from "react-router";
|
||||
import * as AssociationRepository from "~/features/associations/AssociationRepository.server";
|
||||
import { requireUserId } from "~/features/auth/core/user.server";
|
||||
import { requireUser } from "~/features/auth/core/user.server";
|
||||
import type { SerializeFrom } from "~/utils/remix";
|
||||
import * as TeamRepository from "../../team/TeamRepository.server";
|
||||
|
||||
export type ScrimsNewLoaderData = SerializeFrom<typeof loader>;
|
||||
|
||||
export const loader = async ({ request }: LoaderFunctionArgs) => {
|
||||
const user = await requireUserId(request);
|
||||
export const loader = async () => {
|
||||
const user = await requireUser();
|
||||
|
||||
return {
|
||||
teams: await TeamRepository.teamsByMemberUserId(user.id),
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import { scrimsFiltersSearchParamsObject } from "../scrims-schemas";
|
|||
import { dividePosts } from "../scrims-utils";
|
||||
|
||||
export const loader = async ({ request }: LoaderFunctionArgs) => {
|
||||
const user = await getUser(request);
|
||||
const user = await getUser();
|
||||
|
||||
const now = new Date();
|
||||
const associations = user
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ export const action = async ({ request, params }: ActionFunctionArgs) => {
|
|||
params,
|
||||
schema: qMatchPageParamsSchema,
|
||||
}).id;
|
||||
const user = await requireUser(request);
|
||||
const user = await requireUser();
|
||||
const data = await parseRequestPayload({
|
||||
request,
|
||||
schema: matchSchema,
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@ import * as SQMatchRepository from "~/features/sendouq-match/SQMatchRepository.s
|
|||
import { notFoundIfFalsy, parseParams } from "~/utils/remix.server";
|
||||
import { qMatchPageParamsSchema } from "../q-match-schemas";
|
||||
|
||||
export const loader = async ({ params, request }: LoaderFunctionArgs) => {
|
||||
const user = await getUser(request);
|
||||
export const loader = async ({ params }: LoaderFunctionArgs) => {
|
||||
const user = await getUser();
|
||||
const matchId = parseParams({
|
||||
params,
|
||||
schema: qMatchPageParamsSchema,
|
||||
|
|
|
|||
|
|
@ -1,12 +1,11 @@
|
|||
import type { ActionFunctionArgs } from "react-router";
|
||||
import { requireUserId } from "~/features/auth/core/user.server";
|
||||
import { requireUser } from "~/features/auth/core/user.server";
|
||||
import * as QSettingsRepository from "~/features/sendouq-settings/QSettingsRepository.server";
|
||||
import { parseRequestPayload } from "~/utils/remix.server";
|
||||
import { assertUnreachable } from "~/utils/types";
|
||||
import { settingsActionSchema } from "../q-settings-schemas.server";
|
||||
|
||||
export const action = async ({ request }: ActionFunctionArgs) => {
|
||||
const user = await requireUserId(request);
|
||||
export const action = async ({ request }: { request: Request }) => {
|
||||
const user = await requireUser();
|
||||
const data = await parseRequestPayload({
|
||||
request,
|
||||
schema: settingsActionSchema,
|
||||
|
|
|
|||
|
|
@ -1,9 +1,8 @@
|
|||
import type { LoaderFunctionArgs } from "react-router";
|
||||
import { requireUserId } from "~/features/auth/core/user.server";
|
||||
import { requireUser } from "~/features/auth/core/user.server";
|
||||
import * as QSettingsRepository from "~/features/sendouq-settings/QSettingsRepository.server";
|
||||
|
||||
export const loader = async ({ request }: LoaderFunctionArgs) => {
|
||||
const user = await requireUserId(request);
|
||||
export const loader = async () => {
|
||||
const user = await requireUser();
|
||||
|
||||
return {
|
||||
settings: await QSettingsRepository.settingsByUserId(user.id),
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ import { SendouQError } from "../q-utils.server";
|
|||
// if there is a validation error the user saw stale data
|
||||
// and when we return null we just force a refresh
|
||||
export const action: ActionFunction = async ({ request }) => {
|
||||
const user = await requireUser(request);
|
||||
const user = await requireUser();
|
||||
const data = await parseRequestPayload({
|
||||
request,
|
||||
schema: lookingSchema,
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ import { preparingSchema } from "../q-schemas.server";
|
|||
export type SendouQPreparingAction = typeof action;
|
||||
|
||||
export const action = async ({ request }: ActionFunctionArgs) => {
|
||||
const user = await requireUser(request);
|
||||
const user = await requireUser();
|
||||
const data = await parseRequestPayload({
|
||||
request,
|
||||
schema: preparingSchema,
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ import { frontPageSchema } from "../q-schemas.server";
|
|||
import { userCanJoinQueueAt } from "../q-utils";
|
||||
|
||||
export const action: ActionFunction = async ({ request }) => {
|
||||
const user = await requireUser(request);
|
||||
const user = await requireUser();
|
||||
const data = await parseRequestPayload({
|
||||
request,
|
||||
schema: frontPageSchema,
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import * as PrivateUserNoteRepository from "../PrivateUserNoteRepository.server"
|
|||
import { sqRedirectIfNeeded } from "../q-utils.server";
|
||||
|
||||
export const loader = async ({ request }: LoaderFunctionArgs) => {
|
||||
const user = await requireUser(request);
|
||||
const user = await requireUser();
|
||||
|
||||
const isPreview =
|
||||
new URL(request.url).searchParams.get("preview") === "true" &&
|
||||
|
|
|
|||
|
|
@ -1,10 +1,9 @@
|
|||
import type { LoaderFunctionArgs } from "react-router";
|
||||
import { requireUserId } from "~/features/auth/core/user.server";
|
||||
import { requireUser } from "~/features/auth/core/user.server";
|
||||
import { SendouQ } from "../core/SendouQ.server";
|
||||
import { sqRedirectIfNeeded } from "../q-utils.server";
|
||||
|
||||
export const loader = async ({ request }: LoaderFunctionArgs) => {
|
||||
const user = await requireUserId(request);
|
||||
export const loader = async () => {
|
||||
const user = await requireUser();
|
||||
|
||||
const ownGroup = SendouQ.findOwnGroup(user.id);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import type { LoaderFunctionArgs } from "react-router";
|
||||
import { getUserId } from "~/features/auth/core/user.server";
|
||||
import { getUser } from "~/features/auth/core/user.server";
|
||||
import * as Seasons from "~/features/mmr/core/Seasons";
|
||||
import * as UserRepository from "~/features/user-page/UserRepository.server";
|
||||
import { SendouQ } from "../core/SendouQ.server";
|
||||
|
|
@ -7,7 +7,7 @@ import { JOIN_CODE_SEARCH_PARAM_KEY } from "../q-constants";
|
|||
import { sqRedirectIfNeeded } from "../q-utils.server";
|
||||
|
||||
export const loader = async ({ request }: LoaderFunctionArgs) => {
|
||||
const user = await getUserId(request);
|
||||
const user = await getUser();
|
||||
|
||||
const code = new URL(request.url).searchParams.get(
|
||||
JOIN_CODE_SEARCH_PARAM_KEY,
|
||||
|
|
|
|||
|
|
@ -1,12 +1,11 @@
|
|||
import type { LoaderFunctionArgs } from "react-router";
|
||||
import { requireUserId } from "~/features/auth/core/user.server";
|
||||
import { requireUser } from "~/features/auth/core/user.server";
|
||||
import * as SQGroupRepository from "~/features/sendouq/SQGroupRepository.server";
|
||||
import type { SerializeFrom } from "~/utils/remix";
|
||||
|
||||
export type TrustersLoaderData = SerializeFrom<typeof loader>;
|
||||
|
||||
export const loader = async ({ request }: LoaderFunctionArgs) => {
|
||||
const { id: userId } = await requireUserId(request);
|
||||
export const loader = async () => {
|
||||
const { id: userId } = await requireUser();
|
||||
|
||||
return {
|
||||
trusters: await SQGroupRepository.usersThatTrusted(userId),
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import { assertUnreachable } from "~/utils/types";
|
|||
import { settingsEditSchema } from "../settings-schemas";
|
||||
|
||||
export const action = async ({ request }: ActionFunctionArgs) => {
|
||||
const user = await requireUser(request);
|
||||
const user = await requireUser();
|
||||
const data = await parseRequestPayload({
|
||||
request,
|
||||
schema: settingsEditSchema,
|
||||
|
|
|
|||
|
|
@ -1,9 +1,8 @@
|
|||
import type { LoaderFunctionArgs } from "react-router";
|
||||
import { getUserId } from "~/features/auth/core/user.server";
|
||||
import { getUser } from "~/features/auth/core/user.server";
|
||||
import * as UserRepository from "~/features/user-page/UserRepository.server";
|
||||
|
||||
export const loader = async ({ request }: LoaderFunctionArgs) => {
|
||||
const user = await getUserId(request);
|
||||
export const loader = async () => {
|
||||
const user = await getUser();
|
||||
|
||||
return {
|
||||
noScreen: user
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ import { editTeamSchema, teamParamsSchema } from "../team-schemas.server";
|
|||
import { isTeamManager, isTeamOwner } from "../team-utils";
|
||||
|
||||
export const action: ActionFunction = async ({ request, params }) => {
|
||||
const user = await requireUser(request);
|
||||
const user = await requireUser();
|
||||
const { customUrl } = teamParamsSchema.parse(params);
|
||||
|
||||
const team = notFoundIfFalsy(await TeamRepository.findByCustomUrl(customUrl));
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import type { ActionFunction } from "react-router";
|
||||
import { requireUserId } from "~/features/auth/core/user.server";
|
||||
import { requireUser } from "~/features/auth/core/user.server";
|
||||
import {
|
||||
errorToastIfFalsy,
|
||||
notFoundIfFalsy,
|
||||
|
|
@ -14,7 +14,7 @@ import {
|
|||
import { isTeamMember, isTeamOwner, resolveNewOwner } from "../team-utils";
|
||||
|
||||
export const action: ActionFunction = async ({ request, params }) => {
|
||||
const user = await requireUserId(request);
|
||||
const user = await requireUser();
|
||||
const data = await parseRequestPayload({
|
||||
request,
|
||||
schema: teamProfilePageActionSchema,
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import { TEAM } from "../team-constants";
|
|||
import { teamParamsSchema } from "../team-schemas.server";
|
||||
|
||||
export const action: ActionFunction = async ({ request, params }) => {
|
||||
const user = await requireUser(request);
|
||||
const user = await requireUser();
|
||||
const { customUrl } = teamParamsSchema.parse(params);
|
||||
|
||||
const team = notFoundIfFalsy(
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import { manageRosterSchema, teamParamsSchema } from "../team-schemas.server";
|
|||
import { isTeamManager } from "../team-utils";
|
||||
|
||||
export const action: ActionFunction = async ({ request, params }) => {
|
||||
const user = await requireUser(request);
|
||||
const user = await requireUser();
|
||||
|
||||
const { customUrl } = teamParamsSchema.parse(params);
|
||||
const team = notFoundIfFalsy(await TeamRepository.findByCustomUrl(customUrl));
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import { TEAM } from "../team-constants";
|
|||
import { createTeamSchema } from "../team-schemas.server";
|
||||
|
||||
export const action: ActionFunction = async ({ request }) => {
|
||||
const user = await requireUser(request);
|
||||
const user = await requireUser();
|
||||
const data = await parseRequestPayload({
|
||||
request,
|
||||
schema: createTeamSchema,
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@ import * as TeamRepository from "../TeamRepository.server";
|
|||
import { teamParamsSchema } from "../team-schemas.server";
|
||||
import { isTeamManager } from "../team-utils";
|
||||
|
||||
export const loader = async ({ request, params }: LoaderFunctionArgs) => {
|
||||
const user = await requireUser(request);
|
||||
export const loader = async ({ params }: LoaderFunctionArgs) => {
|
||||
const user = await requireUser();
|
||||
const { customUrl } = teamParamsSchema.parse(params);
|
||||
|
||||
const team = notFoundIfFalsy(await TeamRepository.findByCustomUrl(customUrl));
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import { teamParamsSchema } from "../team-schemas.server";
|
|||
import { isTeamFull, isTeamMember } from "../team-utils";
|
||||
|
||||
export const loader = async ({ request, params }: LoaderFunctionArgs) => {
|
||||
const user = await requireUser(request);
|
||||
const user = await requireUser();
|
||||
const { customUrl } = teamParamsSchema.parse(params);
|
||||
|
||||
const team = notFoundIfFalsy(
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@ import * as TeamRepository from "../TeamRepository.server";
|
|||
import { teamParamsSchema } from "../team-schemas.server";
|
||||
import { isTeamManager } from "../team-utils";
|
||||
|
||||
export const loader = async ({ request, params }: LoaderFunctionArgs) => {
|
||||
const user = await requireUser(request);
|
||||
export const loader = async ({ params }: LoaderFunctionArgs) => {
|
||||
const user = await requireUser();
|
||||
const { customUrl } = teamParamsSchema.parse(params);
|
||||
|
||||
const team = notFoundIfFalsy(
|
||||
|
|
|
|||
|
|
@ -1,11 +1,10 @@
|
|||
import type { LoaderFunctionArgs } from "react-router";
|
||||
import * as R from "remeda";
|
||||
import type { UserWithPlusTier } from "~/db/tables";
|
||||
import { getUserId } from "~/features/auth/core/user.server";
|
||||
import { getUser } from "~/features/auth/core/user.server";
|
||||
import * as TeamRepository from "../TeamRepository.server";
|
||||
|
||||
export const loader = async ({ request }: LoaderFunctionArgs) => {
|
||||
const user = await getUserId(request);
|
||||
export const loader = async () => {
|
||||
const user = await getUser();
|
||||
|
||||
const unsortedTeams = await TeamRepository.findAllUndisbanded();
|
||||
|
||||
|
|
|
|||
|
|
@ -11,8 +11,8 @@ import {
|
|||
import { idObject } from "~/utils/zod";
|
||||
import * as XRankPlacementRepository from "../XRankPlacementRepository.server";
|
||||
|
||||
export const action = async ({ request, params }: ActionFunctionArgs) => {
|
||||
const user = await requireUser(request);
|
||||
export const action = async ({ params }: ActionFunctionArgs) => {
|
||||
const user = await requireUser();
|
||||
const { id } = parseParams({
|
||||
params,
|
||||
schema: idObject,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import type { ActionFunctionArgs } from "react-router";
|
||||
import { requireUserId } from "~/features/auth/core/user.server";
|
||||
import { requireUser } from "~/features/auth/core/user.server";
|
||||
import * as BadgeRepository from "~/features/badges/BadgeRepository.server";
|
||||
import * as CalendarRepository from "~/features/calendar/CalendarRepository.server";
|
||||
import * as Seasons from "~/features/mmr/core/Seasons";
|
||||
|
|
@ -41,7 +41,7 @@ import { tournamentBracketsPage } from "~/utils/urls";
|
|||
import { idObject } from "~/utils/zod";
|
||||
|
||||
export const action = async ({ request, params }: ActionFunctionArgs) => {
|
||||
const user = await requireUserId(request);
|
||||
const user = await requireUser();
|
||||
const { id: tournamentId } = parseParams({
|
||||
params,
|
||||
schema: idObject,
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ import {
|
|||
} from "../tournament-bracket-utils";
|
||||
|
||||
export const action: ActionFunction = async ({ params, request }) => {
|
||||
const user = await requireUser(request);
|
||||
const user = await requireUser();
|
||||
const { id: tournamentId } = parseParams({
|
||||
params,
|
||||
schema: idObject,
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ import {
|
|||
} from "../tournament-bracket-utils";
|
||||
|
||||
export const action: ActionFunction = async ({ params, request }) => {
|
||||
const user = await requireUser(request);
|
||||
const user = await requireUser();
|
||||
const { mid: matchId, id: tournamentId } = parseParams({
|
||||
params,
|
||||
schema: matchPageParamsSchema,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { type LoaderFunctionArgs, redirect } from "react-router";
|
||||
import { requireUserId } from "~/features/auth/core/user.server";
|
||||
import { requireUser } from "~/features/auth/core/user.server";
|
||||
import * as CalendarRepository from "~/features/calendar/CalendarRepository.server";
|
||||
import * as Seasons from "~/features/mmr/core/Seasons";
|
||||
import {
|
||||
|
|
@ -21,8 +21,8 @@ import { idObject } from "~/utils/zod";
|
|||
|
||||
export type FinalizeTournamentLoaderData = SerializeFrom<typeof loader>;
|
||||
|
||||
export const loader = async ({ request, params }: LoaderFunctionArgs) => {
|
||||
const user = await requireUserId(request);
|
||||
export const loader = async ({ params }: LoaderFunctionArgs) => {
|
||||
const user = await requireUser();
|
||||
const { id: tournamentId } = parseParams({
|
||||
params,
|
||||
schema: idObject,
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@ import { idObject } from "~/utils/zod";
|
|||
import type { Unwrapped } from "../../../utils/types";
|
||||
import { tournamentFromDB } from "../core/Tournament.server";
|
||||
|
||||
export const loader = async ({ request, params }: LoaderFunctionArgs) => {
|
||||
const user = await getUser(request);
|
||||
export const loader = async ({ params }: LoaderFunctionArgs) => {
|
||||
const user = await getUser();
|
||||
const { id: tournamentId } = parseParams({
|
||||
params,
|
||||
schema: idObject,
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import { organizationEditSchema } from "../tournament-organization-schemas";
|
|||
import { organizationFromParams } from "../tournament-organization-utils.server";
|
||||
|
||||
export const action = async ({ request, params }: ActionFunctionArgs) => {
|
||||
const user = await requireUser(request);
|
||||
const user = await requireUser();
|
||||
const data = await parseRequestPayload({
|
||||
request,
|
||||
schema: organizationEditSchema,
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ import { orgPageActionSchema } from "../tournament-organization-schemas";
|
|||
import { organizationFromParams } from "../tournament-organization-utils.server";
|
||||
|
||||
export const action = async ({ request, params }: ActionFunctionArgs) => {
|
||||
const user = await requireUser(request);
|
||||
const user = await requireUser();
|
||||
const organization = await organizationFromParams(params);
|
||||
const data = await parseRequestPayload({
|
||||
request,
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import { TOURNAMENT_ORGANIZATION } from "../tournament-organization-constants";
|
|||
import { newOrganizationSchema } from "../tournament-organization-schemas";
|
||||
|
||||
export const action: ActionFunction = async ({ request }) => {
|
||||
const user = await requireUser(request);
|
||||
const user = await requireUser();
|
||||
requireRole(user, "TOURNAMENT_ADDER");
|
||||
|
||||
const data = await parseRequestPayload({
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@ import * as BadgeRepository from "~/features/badges/BadgeRepository.server";
|
|||
import { requirePermission } from "~/modules/permissions/guards.server";
|
||||
import { organizationFromParams } from "../tournament-organization-utils.server";
|
||||
|
||||
export async function loader({ params, request }: LoaderFunctionArgs) {
|
||||
const user = await requireUser(request);
|
||||
export async function loader({ params }: LoaderFunctionArgs) {
|
||||
const user = await requireUser();
|
||||
const organization = await organizationFromParams(params);
|
||||
|
||||
requirePermission(organization, "EDIT", user);
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import { organizationFromParams } from "../tournament-organization-utils.server"
|
|||
export type OrganizationPageLoaderData = SerializeFrom<typeof loader>;
|
||||
|
||||
export async function loader({ params, request }: LoaderFunctionArgs) {
|
||||
const user = await getUser(request);
|
||||
const user = await getUser();
|
||||
const {
|
||||
month = new Date().getMonth(),
|
||||
year = new Date().getFullYear(),
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ import * as TournamentSubRepository from "../TournamentSubRepository.server";
|
|||
import { subSchema } from "../tournament-subs-schemas.server";
|
||||
|
||||
export const action: ActionFunction = async ({ params, request }) => {
|
||||
const user = await requireUser(request);
|
||||
const user = await requireUser();
|
||||
const data = await parseRequestPayload({
|
||||
request,
|
||||
schema: subSchema,
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ import { deleteSub } from "../queries/deleteSub.server";
|
|||
import { deleteSubSchema } from "../tournament-subs-schemas.server";
|
||||
|
||||
export const action: ActionFunction = async ({ request, params }) => {
|
||||
const user = await requireUser(request);
|
||||
const user = await requireUser();
|
||||
const { id: tournamentId } = parseParams({
|
||||
params,
|
||||
schema: idObject,
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@ import { tournamentSubsPage } from "~/utils/urls";
|
|||
import { idObject } from "~/utils/zod";
|
||||
import * as TournamentSubRepository from "../TournamentSubRepository.server";
|
||||
|
||||
export const loader = async ({ request, params }: LoaderFunctionArgs) => {
|
||||
const user = await requireUser(request);
|
||||
export const loader = async ({ params }: LoaderFunctionArgs) => {
|
||||
const user = await requireUser();
|
||||
const { id: tournamentId } = parseParams({
|
||||
params,
|
||||
schema: idObject,
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@ import { tournamentRegisterPage } from "~/utils/urls";
|
|||
import { idObject } from "~/utils/zod";
|
||||
import * as TournamentSubRepository from "../TournamentSubRepository.server";
|
||||
|
||||
export const loader = async ({ params, request }: LoaderFunctionArgs) => {
|
||||
const user = await getUser(request);
|
||||
export const loader = async ({ params }: LoaderFunctionArgs) => {
|
||||
const user = await getUser();
|
||||
const { id: tournamentId } = parseParams({
|
||||
params,
|
||||
schema: idObject,
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ import {
|
|||
} from "../tournament-utils.server";
|
||||
|
||||
export const action: ActionFunction = async ({ request, params }) => {
|
||||
const user = await requireUser(request);
|
||||
const user = await requireUser();
|
||||
const data = await parseRequestPayload({
|
||||
request,
|
||||
schema: adminActionSchema,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import type { ActionFunction } from "react-router";
|
||||
import { redirect } from "react-router";
|
||||
import { requireUserId } from "~/features/auth/core/user.server";
|
||||
import { requireUser } from "~/features/auth/core/user.server";
|
||||
import * as ShowcaseTournaments from "~/features/front-page/core/ShowcaseTournaments.server";
|
||||
import {
|
||||
clearTournamentDataCache,
|
||||
|
|
@ -31,7 +31,7 @@ export const action: ActionFunction = async ({ request, params }) => {
|
|||
params,
|
||||
schema: idObject,
|
||||
});
|
||||
const user = await requireUserId(request);
|
||||
const user = await requireUser();
|
||||
const url = new URL(request.url);
|
||||
const inviteCode = url.searchParams.get("code");
|
||||
const data = await parseRequestPayload({ request, schema: joinSchema });
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ import {
|
|||
} from "../tournament-utils.server";
|
||||
|
||||
export const action: ActionFunction = async ({ request, params }) => {
|
||||
const user = await requireUser(request);
|
||||
const user = await requireUser();
|
||||
const { avatarFileName, formData } = await uploadImageIfSubmitted({
|
||||
request,
|
||||
fileNamePrefix: "pickup-logo",
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ export const action: ActionFunction = async ({ request, params }) => {
|
|||
request,
|
||||
schema: seedsActionSchema,
|
||||
});
|
||||
const user = await requireUser(request);
|
||||
const user = await requireUser();
|
||||
const { id: tournamentId } = parseParams({
|
||||
params,
|
||||
schema: idObject,
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@ import { parseParams } from "~/utils/remix.server";
|
|||
import { idObject } from "~/utils/zod";
|
||||
import { findOwnTournamentTeam } from "../queries/findOwnTournamentTeam.server";
|
||||
|
||||
export const loader = async ({ request, params }: LoaderFunctionArgs) => {
|
||||
const user = await getUser(request);
|
||||
export const loader = async ({ params }: LoaderFunctionArgs) => {
|
||||
const user = await getUser();
|
||||
if (!user) return null;
|
||||
|
||||
const { id: tournamentId } = parseParams({
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@ import { parseParams } from "~/utils/remix.server";
|
|||
import { tournamentBracketsPage } from "~/utils/urls";
|
||||
import { idObject } from "~/utils/zod";
|
||||
|
||||
export const loader = async ({ params, request }: LoaderFunctionArgs) => {
|
||||
const user = await requireUser(request);
|
||||
export const loader = async ({ params }: LoaderFunctionArgs) => {
|
||||
const user = await requireUser();
|
||||
const { id: tournamentId } = parseParams({
|
||||
params,
|
||||
schema: idObject,
|
||||
|
|
|
|||
|
|
@ -10,8 +10,8 @@ import { streamsByTournamentId } from "../core/streams.server";
|
|||
|
||||
export type TournamentLoaderData = SerializeFrom<typeof loader>;
|
||||
|
||||
export const loader = async ({ params, request }: LoaderFunctionArgs) => {
|
||||
const user = await getUser(request);
|
||||
export const loader = async ({ params }: LoaderFunctionArgs) => {
|
||||
const user = await getUser();
|
||||
const { id: tournamentId } = parseParams({
|
||||
params,
|
||||
schema: idObject,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import type { LoaderFunctionArgs } from "react-router";
|
||||
import { getUserId } from "~/features/auth/core/user.server";
|
||||
import { getUser } from "~/features/auth/core/user.server";
|
||||
import * as TournamentRepository from "~/features/tournament/TournamentRepository.server";
|
||||
import type { SerializeFrom } from "~/utils/remix";
|
||||
import { parseSearchParams } from "~/utils/remix.server";
|
||||
|
|
@ -8,7 +8,7 @@ import { tournamentSearchSearchParamsSchema } from "../tournament-schemas.server
|
|||
export type TournamentSearchLoaderData = SerializeFrom<typeof loader>;
|
||||
|
||||
export const loader = async ({ request }: LoaderFunctionArgs) => {
|
||||
const user = await getUserId(request);
|
||||
const user = await getUser();
|
||||
if (!user) {
|
||||
return [];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import {
|
|||
import { assertUnreachable } from "~/utils/types";
|
||||
|
||||
export const action = async ({ request, params }: ActionFunctionArgs) => {
|
||||
const loggedInUser = await requireUser(request);
|
||||
const loggedInUser = await requireUser();
|
||||
|
||||
requireRole(loggedInUser, "STAFF");
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import type { ActionFunction } from "react-router";
|
||||
import * as ArtRepository from "~/features/art/ArtRepository.server";
|
||||
import { userArtPageActionSchema } from "~/features/art/art-schemas.server";
|
||||
import { requireUserId } from "~/features/auth/core/user.server";
|
||||
import { requireUser } from "~/features/auth/core/user.server";
|
||||
import { logger } from "~/utils/logger";
|
||||
import {
|
||||
errorToastIfFalsy,
|
||||
|
|
@ -11,7 +11,7 @@ import {
|
|||
import { assertUnreachable } from "~/utils/types";
|
||||
|
||||
export const action: ActionFunction = async ({ request }) => {
|
||||
const user = await requireUserId(request);
|
||||
const user = await requireUser();
|
||||
const data = await parseRequestPayload({
|
||||
request,
|
||||
schema: userArtPageActionSchema,
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ import {
|
|||
} from "~/utils/zod";
|
||||
|
||||
export const action: ActionFunction = async ({ request }) => {
|
||||
const user = await requireUser(request);
|
||||
const user = await requireUser();
|
||||
const data = await parseRequestPayload({
|
||||
request,
|
||||
schema: newBuildActionSchema,
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ import {
|
|||
} from "~/utils/zod";
|
||||
|
||||
export const action: ActionFunction = async ({ request }) => {
|
||||
const user = await requireUser(request);
|
||||
const user = await requireUser();
|
||||
const data = await parseRequestPayload({
|
||||
request,
|
||||
schema: buildsActionSchema,
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user