@@ -416,21 +416,25 @@ const GITEA_REPO = import.meta.env.PUBLIC_GITEA_REPO ?? "";
groups,
raw: text,
};
})().catch(() => ( {
ok: false,
user: "",
name: "" ,
email : "",
groups: [] ,
raw : "",
}));
})().catch((err ) => {
console.warn("[proposer] whoami fetch failed", err);
return {
ok: false ,
user : "",
name: "" ,
email : "",
groups: [],
raw: "",
};
});
return _authInfoPromise;
}
// Promise unique : est-on editor ?
// ⚠️ On reste fail-closed, mais NON destructif (on ne supprime pas sur erreur réseau)
const isEditorP = giteaReady
? getAuthInfo().then((info) => info.groups.includes(PROPOSE_REQUIRED_GROUP)).catch(() => false)
? getAuthInfo().then((info) => info.groups.includes(PROPOSE_REQUIRED_GROUP))
: Promise.resolve(false);
const quoteBlock = (s) =>
@@ -501,6 +505,24 @@ const GITEA_REPO = import.meta.env.PUBLIC_GITEA_REPO ?? "";
// ==========================
const paras = Array.from(document.querySelectorAll('.reading p[id^="p-"]'));
// Petit helper : fail-closed mais réversible (hide ≠ remove)
function hidePropose(el) {
try {
el.hidden = true;
el.style.display = "none";
el.setAttribute("aria-hidden", "true");
el.setAttribute("tabindex", "-1");
} catch {}
}
function showPropose(el) {
try {
el.hidden = false;
el.style.display = "";
el.removeAttribute("aria-hidden");
el.removeAttribute("tabindex");
} catch {}
}
for (const p of paras) {
if (p.querySelector(".para-tools")) continue;
@@ -547,16 +569,16 @@ const GITEA_REPO = import.meta.env.PUBLIC_GITEA_REPO ?? "";
propose.textContent = "Proposer";
propose.setAttribute("aria-label", "Proposer une correction sur Gitea");
// ✅ fail-closed DUR : inline-style (ne peut pas être overridé par ton CSS )
propose.style.display = "none";
// ✅ fail-closed (mais NON destructif )
propose.dataset.requiresGroup = PROPOSE_REQUIRED_GROUP;
hidePropose(propose);
const raw = (p.textContent || "").trim().replace(/\s+/g, " ");
const excerpt = raw.length > 420 ? (raw.slice(0, 420) + "…") : raw;
const issueUrl = buildIssueURL(p.id, raw, excerpt);
// Lien fallback (si JS casse totalement)
// Lien fallback (si JS modal casse totalement)
propose.href = issueUrl;
// ✅ Marqueurs pour ProposeModal (interception 2 étapes)
@@ -600,16 +622,18 @@ const GITEA_REPO = import.meta.env.PUBLIC_GITEA_REPO ?? "";
}
// ✅ Après insertion : on autorise Proposer seulement si groupe editors
// - ok=false => remove (pas d’ UI “Proposer” pour les non-éditeurs)
// - erreur fetch => on garde HIDDEN (non destructif) ; un reload pourra réussir
if (giteaReady) {
isEditorP.then((ok) => {
const els = document.querySelectorAll(".para-propose");
for (const el of els) {
if (ok) el.style.display = "" ;
if (ok) showPropose(el) ;
else el.remove();
}
}).catch(() => {
// fail-closed
document.querySelectorAll(".para-propose").forEach((el) => el.remove( ));
}).catch((err ) => {
console.warn("[proposer] gate failed; keeping Proposer hidden", err);
document.querySelectorAll(".para-propose").forEach((el) => hidePropose(el ));
});
}