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