fix: idor checks on all exposed endpoints
This commit is contained in:
@@ -2,11 +2,12 @@ import { json, error } from '@sveltejs/kit';
|
||||
import { db } from '$lib/server/db';
|
||||
import { mappool, mappoolSlot } from '$lib/server/db/schema';
|
||||
import { eq } from 'drizzle-orm';
|
||||
import { requireAuth, requireOwnerOrAdmin } from '$lib/server/permissions';
|
||||
import type { RequestHandler } from './$types';
|
||||
|
||||
// Get a mappool with its slots
|
||||
export const GET: RequestHandler = async ({ params, locals }) => {
|
||||
if (!locals.user) error(401, 'Not logged in');
|
||||
requireAuth(locals);
|
||||
|
||||
const pool = await db.query.mappool.findFirst({
|
||||
where: eq(mappool.id, params.id)
|
||||
@@ -24,7 +25,17 @@ export const GET: RequestHandler = async ({ params, locals }) => {
|
||||
|
||||
// Delete a mappool
|
||||
export const DELETE: RequestHandler = async ({ params, locals }) => {
|
||||
if (!locals.user) error(401, 'Not logged in');
|
||||
const pool = await db.query.mappool.findFirst({
|
||||
where: eq(mappool.id, params.id)
|
||||
});
|
||||
|
||||
if (!pool) error(404, 'Mappool not found');
|
||||
|
||||
requireOwnerOrAdmin(
|
||||
locals,
|
||||
pool.createdBy,
|
||||
'Only the mappool creator or an admin can delete this'
|
||||
);
|
||||
|
||||
await db.delete(mappool).where(eq(mappool.id, params.id));
|
||||
return json({ ok: true });
|
||||
|
||||
@@ -1,13 +1,19 @@
|
||||
import { json, error } from '@sveltejs/kit';
|
||||
import { db } from '$lib/server/db';
|
||||
import { mappoolSlot } from '$lib/server/db/schema';
|
||||
import { mappool, mappoolSlot } from '$lib/server/db/schema';
|
||||
import { eq, and } from 'drizzle-orm';
|
||||
import { getBeatmap } from '$lib/server/osu/api';
|
||||
import { requireOwnerOrAdmin } from '$lib/server/permissions';
|
||||
import type { RequestHandler } from './$types';
|
||||
|
||||
// Add a slot to a mappool
|
||||
export const POST: RequestHandler = async ({ params, request, locals }) => {
|
||||
if (!locals.user) error(401, 'Not logged in');
|
||||
const pool = await db.query.mappool.findFirst({
|
||||
where: eq(mappool.id, params.id)
|
||||
});
|
||||
|
||||
if (!pool) error(404, 'Mappool not found');
|
||||
|
||||
requireOwnerOrAdmin(locals, pool.createdBy, 'Only the mappool creator or an admin can add slots');
|
||||
|
||||
const { beatmapId, category, mods } = await request.json();
|
||||
|
||||
|
||||
@@ -1,11 +1,22 @@
|
||||
import { json, error } from '@sveltejs/kit';
|
||||
import { db } from '$lib/server/db';
|
||||
import { mappoolSlot } from '$lib/server/db/schema';
|
||||
import { mappool, mappoolSlot } from '$lib/server/db/schema';
|
||||
import { eq } from 'drizzle-orm';
|
||||
import { requireOwnerOrAdmin } from '$lib/server/permissions';
|
||||
import type { RequestHandler } from './$types';
|
||||
|
||||
export const DELETE: RequestHandler = async ({ params, locals }) => {
|
||||
if (!locals.user) error(401, 'Not logged in');
|
||||
const pool = await db.query.mappool.findFirst({
|
||||
where: eq(mappool.id, params.id)
|
||||
});
|
||||
|
||||
if (!pool) error(404, 'Mappool not found');
|
||||
|
||||
requireOwnerOrAdmin(
|
||||
locals,
|
||||
pool.createdBy,
|
||||
'Only the mappool creator or an admin can delete slots'
|
||||
);
|
||||
|
||||
await db.delete(mappoolSlot).where(eq(mappoolSlot.id, params.slotId));
|
||||
return json({ ok: true });
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
// src/routes/api/matches/[id]/lobby/+server.ts
|
||||
import { json, error } from '@sveltejs/kit';
|
||||
import { moveToLobby } from '$lib/server/match/engine';
|
||||
import { requireRole } from '$lib/server/permissions';
|
||||
import type { RequestHandler } from './$types';
|
||||
|
||||
export const POST: RequestHandler = async ({ params, request, locals }) => {
|
||||
if (!locals.user) error(401, 'Not logged in');
|
||||
requireRole(locals, 'referee', 'Only referees or admins can move matches to lobby');
|
||||
|
||||
const body = await request.json().catch(() => ({}));
|
||||
|
||||
|
||||
@@ -1,14 +1,30 @@
|
||||
// src/routes/api/matches/[id]/pick/+server.ts
|
||||
import { json, error } from '@sveltejs/kit';
|
||||
import { pickMap } from '$lib/server/match/engine';
|
||||
import { requireAuth, hasRole } from '$lib/server/permissions';
|
||||
import { getMatchFull } from '$lib/server/match/helpers';
|
||||
import type { RequestHandler } from './$types';
|
||||
|
||||
export const POST: RequestHandler = async ({ params, request, locals }) => {
|
||||
if (!locals.user) error(401, 'Not logged in');
|
||||
const user = requireAuth(locals);
|
||||
|
||||
const { participantId, mappoolSlotId } = await request.json();
|
||||
if (!participantId || !mappoolSlotId) {
|
||||
error(400, 'participantId and mappoolSlotId required');
|
||||
const { mappoolSlotId } = await request.json();
|
||||
if (!mappoolSlotId) {
|
||||
error(400, 'mappoolSlotId required');
|
||||
}
|
||||
|
||||
const match = await getMatchFull(params.id);
|
||||
|
||||
// Find the participant linked to the authenticated user
|
||||
const participant = match.participants.find((p) => p.players.some((pl) => pl.userId === user.id));
|
||||
|
||||
if (!participant && !hasRole(user.role, 'referee')) {
|
||||
error(403, 'You are not a participant in this match');
|
||||
}
|
||||
|
||||
const participantId = participant?.id;
|
||||
if (!participantId) {
|
||||
error(400, 'Could not resolve participant');
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
@@ -1,14 +1,30 @@
|
||||
// src/routes/api/matches/[id]/roll/+server.ts
|
||||
import { json, error } from '@sveltejs/kit';
|
||||
import { submitRoll } from '$lib/server/match/engine';
|
||||
import { requireAuth, hasRole } from '$lib/server/permissions';
|
||||
import { getMatchFull } from '$lib/server/match/helpers';
|
||||
import type { RequestHandler } from './$types';
|
||||
|
||||
export const POST: RequestHandler = async ({ params, request, locals }) => {
|
||||
if (!locals.user) error(401, 'Not logged in');
|
||||
const user = requireAuth(locals);
|
||||
|
||||
const { participantId, value } = await request.json();
|
||||
if (!participantId || value == null) {
|
||||
error(400, 'participantId and value required');
|
||||
const { value } = await request.json();
|
||||
if (value == null) {
|
||||
error(400, 'value required');
|
||||
}
|
||||
|
||||
const match = await getMatchFull(params.id);
|
||||
|
||||
// Find the participant linked to the authenticated user
|
||||
const participant = match.participants.find((p) => p.players.some((pl) => pl.userId === user.id));
|
||||
|
||||
if (!participant && !hasRole(user.role, 'referee')) {
|
||||
error(403, 'You are not a participant in this match');
|
||||
}
|
||||
|
||||
const participantId = participant?.id;
|
||||
if (!participantId) {
|
||||
error(400, 'Could not resolve participant');
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
// src/routes/api/matches/[id]/rolling/+server.ts
|
||||
import { json, error } from '@sveltejs/kit';
|
||||
import { moveToRolling } from '$lib/server/match/engine';
|
||||
import { requireRole } from '$lib/server/permissions';
|
||||
import type { RequestHandler } from './$types';
|
||||
|
||||
export const POST: RequestHandler = async ({ params, locals }) => {
|
||||
if (!locals.user) error(401, 'Not logged in');
|
||||
requireRole(locals, 'referee', 'Only referees or admins can move matches to rolling');
|
||||
|
||||
try {
|
||||
const m = await moveToRolling(params.id);
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
// src/routes/api/matches/[id]/score/+server.ts
|
||||
import { json, error } from '@sveltejs/kit';
|
||||
import { submitGameScores } from '$lib/server/match/engine';
|
||||
import { requireRole } from '$lib/server/permissions';
|
||||
import type { RequestHandler } from './$types';
|
||||
|
||||
export const POST: RequestHandler = async ({ request, locals }) => {
|
||||
if (!locals.user) error(401, 'Not logged in');
|
||||
requireRole(locals, 'referee', 'Only referees or admins can submit scores');
|
||||
|
||||
const { matchGameId, scores } = await request.json();
|
||||
if (!matchGameId || !scores?.length) {
|
||||
|
||||
Reference in New Issue
Block a user