From 27ecbc40b3f661623812d9933caf01344f16e6e1 Mon Sep 17 00:00:00 2001 From: Matt Date: Wed, 4 Mar 2026 20:26:34 +0100 Subject: [PATCH] fix: lock down application form when intake round is not active getConfig now throws FORBIDDEN when round is not ROUND_ACTIVE, preventing the form from loading entirely. Also blocks draft saving when round is inactive. Defense-in-depth: submit already rejected inactive rounds, this adds the frontend gate. Co-Authored-By: Claude Opus 4.6 --- src/server/routers/application.ts | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/server/routers/application.ts b/src/server/routers/application.ts index 999cef3..4c61516 100644 --- a/src/server/routers/application.ts +++ b/src/server/routers/application.ts @@ -150,6 +150,14 @@ export const applicationRouter = router({ isOpen = program.status === 'ACTIVE' } + // Block access entirely when applications are not open + if (!isOpen) { + throw new TRPCError({ + code: 'FORBIDDEN', + message: 'Applications are not currently open. The submission period has not started or has ended.', + }) + } + const wizardConfig = parseWizardConfig(program.settingsJson) return { @@ -200,6 +208,14 @@ export const applicationRouter = router({ const roundProgram = round.competition.program const isOpen = round.status === 'ROUND_ACTIVE' + // Block access entirely when the intake round is not active + if (!isOpen) { + throw new TRPCError({ + code: 'FORBIDDEN', + message: 'Applications are not currently open. The submission period has not started or has ended.', + }) + } + const roundWizardConfig = parseWizardConfig(roundProgram.settingsJson) const { settingsJson: _s, ...programData } = roundProgram @@ -608,6 +624,7 @@ export const applicationRouter = router({ where: { slug: input.roundSlug }, select: { id: true, + status: true, competition: { select: { programId: true } }, configJson: true, }, @@ -620,6 +637,14 @@ export const applicationRouter = router({ }) } + // Block draft saving when intake round is not active + if (round.status !== 'ROUND_ACTIVE') { + throw new TRPCError({ + code: 'FORBIDDEN', + message: 'Applications are not currently open.', + }) + } + const roundConfig = (round.configJson as Record) || {} if (roundConfig.drafts_enabled === false) { throw new TRPCError({