From 7298160c2a2606e23c363d63c99f89a0fd693e2c Mon Sep 17 00:00:00 2001 From: LiHaohua Date: Tue, 21 Jul 2026 18:01:00 +0800 Subject: [PATCH] fix(site): drop email-match preflight; attribute ownership by GitHub login MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The upload preview still blocked submissions whose deb Maintainer email was not among the user's verified GitHub emails ("提交会被拒绝"), even though the Worker and packages Actions moved to first-come-first-served ownership keyed on the uploader's GitHub login. - preview: replace the Maintainer-email match check with an uploader attribution line; block only on danger verdict, not-logged-in, or version/ ownership conflicts. - ownership/version preflight: derive the owner login from the index Maintainer noreply address (best-effort; the server re-checks uploaded_by). - my-packages: list packages owned by the logged-in login instead of by matching Maintainer email. - copy update in index.html to describe the first-come model. Co-authored-by: Cursor --- site/app.js | 34 ++++++++++++++++++---------------- site/index.html | 6 +++--- 2 files changed, 21 insertions(+), 19 deletions(-) diff --git a/site/app.js b/site/app.js index 10a6544..de82321 100644 --- a/site/app.js +++ b/site/app.js @@ -1,6 +1,6 @@ /* CardputerZero developer portal front-end. Same-origin API (see worker/). */ -import { parseDeb, compareDebVersions, extractEmail } from "/debparse.js"; +import { parseDeb, compareDebVersions, extractEmail, loginFromNoreply } from "/debparse.js"; // All decompression libraries are vendored at /vendor/ and served same-origin, // so there is zero runtime dependency on a third-party CDN (availability, @@ -198,26 +198,26 @@ async function renderPreview() { $("p-noicon").classList.remove("hidden"); } - // 邮箱归属预检 - const email = (parsed.email || "").toLowerCase(); - const mine = me && me.emails.includes(email); - $("p-emailmatch").innerHTML = mine - ? `Maintainer 邮箱与你的 GitHub 已验证邮箱匹配` - : `Maintainer 邮箱 (${email || "缺失"}) 不在你的 GitHub 已验证邮箱里 — 提交会被拒绝${me && me.is_admin ? "(你是管理员,可豁免)" : ""}`; + // 上传者归属(包名先到先得,以 GitHub 账号为准,与 deb 里的 Maintainer 邮箱无关) + $("p-emailmatch").innerHTML = me + ? `将以 @${me.login} 的身份记录为上传者` + : `请先登录 GitHub 再提交`; - // 版本 / 包名占用预检 + // 版本 / 包名占用预检(所有权按上传者 GitHub 账号先到先得) const idx = await loadIndex(); const entries = idx.get(c.Package) || []; let verState = "", verOk = true; if (!entries.length) { - verState = `新包名,首次提交后归属于你`; + verState = `新包名,首次提交后归属于你${me ? `(@${me.login})` : ""}`; } else { - const owner = extractEmail(entries[0].Maintainer || "").toLowerCase(); - const owned = me && (me.emails.includes(owner) || me.is_admin); + // 前端只能读到线上索引里的 Maintainer,尽力从 noreply 地址反推 owner; + // 服务端会按记录的 uploaded_by 权威复核。 + const ownerLogin = loginFromNoreply(entries[0].Maintainer || ""); + const owned = me && (me.is_admin || (ownerLogin && ownerLogin === me.login.toLowerCase())); const latest = entries.map((e) => e.Version).sort(compareDebVersions).pop(); - if (!owned) { + if (ownerLogin && !owned) { verOk = false; - verState = `包名已被他人占用(Maintainer: ${owner.slice(0, 2)}***),无法提交`; + verState = `包名已被 @${ownerLogin} 占用,只有其本人或管理员可以更新`; } else if (compareDebVersions(c.Version, latest) <= 0) { verOk = false; verState = `版本 ${c.Version} 不高于线上已发布的 ${latest},请提升版本号`; @@ -251,7 +251,7 @@ async function renderPreview() { $("p-scripts-box").classList.add("hidden"); } - const blocked = parsed.verdict === "danger" || (!mine && !(me && me.is_admin)) || !verOk; + const blocked = parsed.verdict === "danger" || !me || !verOk; $("submit-btn").disabled = blocked; $("submit-btn").textContent = blocked ? "存在阻断性问题,无法提交" : "提交到 AppStore"; $("preview-box").classList.remove("hidden"); @@ -292,8 +292,10 @@ async function renderMine() { const mine = []; for (const [name, entries] of idx) { for (const e of entries) { - const email = extractEmail(e.Maintainer || "").toLowerCase(); - if (me.emails.includes(email) || me.is_admin) mine.push({ name, ...e, email }); + const ownerLogin = loginFromNoreply(e.Maintainer || ""); + if (me.is_admin || (ownerLogin && ownerLogin === me.login.toLowerCase())) { + mine.push({ name, ...e, email: extractEmail(e.Maintainer || "").toLowerCase() }); + } } } if (!mine.length) { diff --git a/site/index.html b/site/index.html index 0668525..d31e8ee 100644 --- a/site/index.html +++ b/site/index.html @@ -96,8 +96,8 @@

CardputerZero 开发者中心

@@ -151,7 +151,7 @@

CardputerZero 开发者中心

包名版本Maintainer 加载中… -

列表来自线上 APT 索引,只显示 Maintainer 邮箱属于你的包。可直接下载已发布的 .deb;下架会生成移除 PR。

+

列表来自线上 APT 索引,只显示归属于你的包。可直接下载已发布的 .deb;下架会生成移除 PR。