Files
2026-08-17 12:53:08 +00:00

50 lines
1.9 KiB
HTML

<!doctype html>
<!--
Session handoff from freight-api into Element.
freight-api's chat-sso.service.ts links here as
https://chat.edr.et/sso.html#hs=<homeserver>&t=<access_token>&u=<user_id>&d=<device_id>
— a fragment, not a query, so the token is never sent to a server and never
lands in an access log. location.replace() below drops this URL from history
as well, so the token does not survive the redirect.
The keys written here are the ones Element reads on startup
(element-web src/Lifecycle.ts getStoredSessionVars/getStoredToken): the token
is looked up in IndexedDB first and falls back to localStorage, which Element
then migrates into IndexedDB itself. A plaintext token is accepted —
tryDecryptToken returns a string token as-is, and only decrypts when it finds
an encrypted payload.
This replaced a ?loginToken= handoff: POST /_matrix/client/v1/login/get_token
is capped at one call per user per minute by a limiter hardcoded in Synapse,
so clicking Chat twice in a minute failed.
-->
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Signing in to EDR Chat…</title>
</head>
<body>
<script>
var params = new URLSearchParams(window.location.hash.slice(1));
var homeserver = params.get("hs");
var token = params.get("t");
var userId = params.get("u");
var deviceId = params.get("d");
if (homeserver && token && userId && deviceId) {
localStorage.setItem("mx_hs_url", homeserver);
localStorage.setItem("mx_user_id", userId);
localStorage.setItem("mx_device_id", deviceId);
localStorage.setItem("mx_access_token", token);
localStorage.setItem("mx_has_access_token", "true");
localStorage.setItem("mx_is_guest", "false");
window.location.replace("/");
} else {
document.body.textContent =
"Missing sign-in details. Go back to the EDR backoffice and click Chat again.";
}
</script>
</body>
</html>