Properly handle OPTIONS requests to public API routes (#1738)

This commit is contained in:
inkfarer
2024-05-24 21:20:07 +03:00
committed by GitHub
parent 33fcbcf7ca
commit a7a806471d
6 changed files with 36 additions and 5 deletions

View File

@@ -1,3 +1,5 @@
import { cors } from "remix-utils/cors";
const apiTokens = process.env["PUBLIC_API_TOKENS"]?.split(",") ?? [];
export function requireBearerAuth(req: Request) {
const authHeader = req.headers.get("Authorization");
@@ -9,3 +11,12 @@ export function requireBearerAuth(req: Request) {
throw new Response("Invalid token", { status: 401 });
}
}
export async function handleOptionsRequest(req: Request) {
if (req.method === "OPTIONS") {
throw await cors(req, new Response("OK", { status: 204 }), {
origin: "*",
credentials: true,
});
}
}

View File

@@ -6,7 +6,10 @@ import { id } from "~/utils/zod";
import type { GetTournamentMatchResponse } from "../schema";
import { jsonArrayFrom } from "kysely/helpers/sqlite";
import { resolveMapList } from "~/features/tournament-bracket/core/mapList.server";
import { requireBearerAuth } from "../api-public-utils.server";
import {
handleOptionsRequest,
requireBearerAuth,
} from "../api-public-utils.server";
import i18next from "~/modules/i18n/i18next.server";
import * as TournamentRepository from "~/features/tournament/TournamentRepository.server";
import { cors } from "remix-utils/cors";
@@ -16,6 +19,7 @@ const paramsSchema = z.object({
});
export const loader = async ({ params, request }: LoaderFunctionArgs) => {
await handleOptionsRequest(request);
requireBearerAuth(request);
const t = await i18next.getFixedT("en", ["game-misc"]);

View File

@@ -3,7 +3,10 @@ import { z } from "zod";
import { tournamentFromDB } from "~/features/tournament-bracket/core/Tournament.server";
import { notFoundIfFalsy, parseParams } from "~/utils/remix";
import { id } from "~/utils/zod";
import { requireBearerAuth } from "../api-public-utils.server";
import {
handleOptionsRequest,
requireBearerAuth,
} from "../api-public-utils.server";
import type { GetTournamentBracketResponse } from "../schema";
import { cors } from "remix-utils/cors";
@@ -13,6 +16,7 @@ const paramsSchema = z.object({
});
export const loader = async ({ params, request }: LoaderFunctionArgs) => {
await handleOptionsRequest(request);
requireBearerAuth(request);
const { id, bidx } = parseParams({ params, schema: paramsSchema });

View File

@@ -6,7 +6,10 @@ import { id } from "~/utils/zod";
import type { GetTournamentTeamsResponse } from "../schema";
import { databaseTimestampToDate } from "~/utils/dates";
import { jsonArrayFrom } from "kysely/helpers/sqlite";
import { requireBearerAuth } from "../api-public-utils.server";
import {
handleOptionsRequest,
requireBearerAuth,
} from "../api-public-utils.server";
import i18next from "~/modules/i18n/i18next.server";
import { cors } from "remix-utils/cors";
@@ -15,6 +18,7 @@ const paramsSchema = z.object({
});
export const loader = async ({ params, request }: LoaderFunctionArgs) => {
await handleOptionsRequest(request);
requireBearerAuth(request);
const t = await i18next.getFixedT("en", ["game-misc"]);

View File

@@ -7,7 +7,10 @@ import type { GetTournamentResponse } from "../schema";
import { databaseTimestampToDate } from "~/utils/dates";
import { HACKY_resolvePicture } from "~/features/tournament/tournament-utils";
import { jsonArrayFrom } from "kysely/helpers/sqlite";
import { requireBearerAuth } from "../api-public-utils.server";
import {
handleOptionsRequest,
requireBearerAuth,
} from "../api-public-utils.server";
import { cors } from "remix-utils/cors";
const paramsSchema = z.object({
@@ -15,6 +18,7 @@ const paramsSchema = z.object({
});
export const loader = async ({ params, request }: LoaderFunctionArgs) => {
await handleOptionsRequest(request);
requireBearerAuth(request);
const { id } = parseParams({ params, schema: paramsSchema });

View File

@@ -7,7 +7,10 @@ import type { GetUserResponse } from "../schema";
import { jsonArrayFrom } from "kysely/helpers/sqlite";
import { i18next } from "~/modules/i18n/i18next.server";
("~/modules/i18n");
import { requireBearerAuth } from "../api-public-utils.server";
import {
handleOptionsRequest,
requireBearerAuth,
} from "../api-public-utils.server";
import { cors } from "remix-utils/cors";
const paramsSchema = z.object({
@@ -15,6 +18,7 @@ const paramsSchema = z.object({
});
export const loader = async ({ params, request }: LoaderFunctionArgs) => {
await handleOptionsRequest(request);
requireBearerAuth(request);
const t = await i18next.getFixedT("en", ["weapons"]);