feat(chat): join users to rooms on sign-in

This commit is contained in:
Nathnael
2026-08-17 11:33:26 +00:00
parent 00bd1250ee
commit ab734aecc3
15 changed files with 366 additions and 114 deletions

View File

@@ -1,16 +1,23 @@
<!doctype html>
<!--
Element only honours a `?loginToken=` on `/` if `mx_sso_hs_url` is already
in localStorage (element-web apps/web/src/Lifecycle.ts attemptTokenLogin,
key defined in apps/web/src/BasePlatform.ts). Normally that key is written
by Element itself at the start of an SSO redirect; freight-api's SSO
handoff skips that redirect (it already knows the homeserver), so this
page seeds the key by hand and forwards straight to the login-token URL.
Session handoff from freight-api into Element.
freight-api's chat-sso.service.ts links here as
https://chat.edr.et/sso.html?t=<login_token>&hs=<homeserver base_url>.
`hs` is passed rather than hardcoded so this file doesn't need to change if
MATRIX_PUBLIC_BASEURL ever does.
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>
@@ -19,17 +26,23 @@
</head>
<body>
<script>
var params = new URLSearchParams(window.location.search);
var token = params.get("t");
var params = new URLSearchParams(window.location.hash.slice(1));
var homeserver = params.get("hs");
if (token && homeserver) {
localStorage.setItem("mx_sso_hs_url", homeserver);
window.location.replace(
"/?loginToken=" + encodeURIComponent(token),
);
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 token. Go back to the EDR backoffice and click Chat again.";
"Missing sign-in details. Go back to the EDR backoffice and click Chat again.";
}
</script>
</body>