From f548aef9f0dfd030776cadd408b4b4d9ca034ec7 Mon Sep 17 00:00:00 2001 From: yuetsh <517252939@qq.com> Date: Fri, 7 Aug 2026 02:12:31 -0600 Subject: [PATCH] =?UTF-8?q?fix(=E9=98=B6=E6=AE=B53):=20=E8=A1=A5=E9=BD=90?= =?UTF-8?q?=20contestId=20=E8=84=B1=E6=95=8F=E4=B8=8E=E4=BB=93=E5=BA=93?= =?UTF-8?q?=E6=A0=B9=20.env=20=E5=8A=A0=E8=BD=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 两处是首轮六条修复的收尾,均由验证过程暴露: 1. contestId 未脱敏 —— 旧后端 SubmissionSafeModelSerializer 排除的是 info/contest/ip 三个字段,首轮只处理了 info 与 ip。 2. 根 .env 读不到 —— Bun 只自动加载 cwd 下的 .env,而启动方式 (bun run --filter '@oj2/api' dev) 会把 cwd 切到 apps/api/, 于是 .env.example 教人写在仓库根的 JUDGE_SERVER_TOKEN 静默失效, 后端降级成随机 token,判题全部卡在 PENDING。config 改为显式补读 根 .env,且只填充未设置的键(真实环境变量与 cwd 下的 .env 优先)。 Co-Authored-By: Claude Opus 5 --- apps/api/src/config.ts | 28 ++++++++++++++++++++++++++++ apps/api/src/routes/submission.ts | 4 +++- 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/apps/api/src/config.ts b/apps/api/src/config.ts index cb5b4cc..5ef24a4 100644 --- a/apps/api/src/config.ts +++ b/apps/api/src/config.ts @@ -1,4 +1,32 @@ import { randomBytes } from "node:crypto" +import { readFileSync } from "node:fs" +import { resolve } from "node:path" + +/** + * Bun 只自动加载「当前工作目录」下的 .env。而本应用的启动方式(`bun run --filter '@oj2/api' dev`) + * 会把 cwd 切到 apps/api/,于是仓库根的 .env 读不到 —— 而 .env.example 恰恰教人写在根目录。 + * 这里显式补读仓库根的 .env,让文档指引真正生效,且不管从哪个目录启动都一致。 + * + * 只填充尚未设置的键:真实环境变量与 cwd 下的 .env 优先级更高,不被覆盖。 + */ +function loadRepoRootEnv() { + try { + const text = readFileSync(resolve(import.meta.dir, "../../../.env"), "utf8") + for (const line of text.split("\n")) { + const trimmed = line.trim() + if (!trimmed || trimmed.startsWith("#")) continue + const eq = trimmed.indexOf("=") + if (eq <= 0) continue + const key = trimmed.slice(0, eq).trim() + if (process.env[key] !== undefined) continue + process.env[key] = trimmed.slice(eq + 1).trim().replace(/^["']|["']$/g, "") + } + } catch { + // 根目录没有 .env 是正常情况(例如生产用真实环境变量注入),静默跳过 + } +} + +loadRepoRootEnv() /** * 判题机 token。对齐旧后端 `options/options.py:93`: diff --git a/apps/api/src/routes/submission.ts b/apps/api/src/routes/submission.ts index 56e3392..3da5c05 100644 --- a/apps/api/src/routes/submission.ts +++ b/apps/api/src/routes/submission.ts @@ -209,7 +209,9 @@ async function submissionDetail(id: string, user: AuthUser) { shared: row.submission.shared, statisticInfo: objectValue(row.submission.statisticInfo), ip: full ? row.submission.ip : null, - contestId: row.submission.contestId, + // contest 也在旧后端的排除名单里(exclude 的三个字段是 info / contest / ip), + // 首轮修复只处理了 info 与 ip,这里补齐。 + contestId: full ? row.submission.contestId : null, problemId: row.submission.problemId, showLink: true, canUnshare: canViewSubmission(user, row.submission, row.problem, row.contest, false),