fediverse-sse.js
66 lignes · 2550 octets
// RFC 0023 Slice B iter. 3 — Server-Sent Events listener for the // fediverse login flow. Loaded from the `login_waiting.html` template. // // ANSSI FUI-CSP-1: previously an inline <script>, externalised so the // global Content-Security-Policy can drop `script-src 'unsafe-inline'` // for this template. The challenge_id is passed via a `data-*` // attribute on the script tag itself. (function () { var script = document.getElementById("fediverse-sse-script"); if (!script) { return; } var challengeId = script.getAttribute("data-challenge-id"); if (!challengeId) { return; } var sse = new EventSource("/login/fediverse/sse/" + challengeId); sse.addEventListener("status", function (ev) { var payload; try { payload = JSON.parse(ev.data); } catch (_err) { return; } var state = payload.state; if (state === "approved") { // L'IdP a approuvé : appeler /api/v1/auth/login/fediverse/consume/{id} // qui pose le cookie JWT remote, puis redirection /home. fetch("/api/v1/auth/login/fediverse/consume/" + challengeId, { method: "POST", credentials: "same-origin", }) .then(function (r) { if (r.ok) { window.location.href = "/home"; } else { window.location.href = "/login/fediverse/error?reason=unknown"; } }) .catch(function () { window.location.href = "/login/fediverse/error?reason=unknown"; }); sse.close(); } else if (state === "rejected") { sse.close(); window.location.href = "/login/fediverse/error?reason=rejected"; } else if (state === "expired") { sse.close(); window.location.href = "/login/fediverse/error?reason=timeout"; } else if (state === "consumed") { sse.close(); window.location.href = "/home"; } // state === "pending" → rien à faire, on attend le prochain poll. }); sse.onerror = function () { // Connexion perdue ; le serveur va relancer mais on protège // l'UX si le navigateur abandonne après plusieurs tentatives. sse.close(); setTimeout(function () { window.location.href = "/login/fediverse/error?reason=timeout"; }, 30000); }; })();
GitRust