diff --git a/muxplex/auth.py b/muxplex/auth.py
index 91c049c..d440d33 100644
--- a/muxplex/auth.py
+++ b/muxplex/auth.py
@@ -206,12 +206,6 @@ class AuthMiddleware(BaseHTTPMiddleware):
return await call_next(request)
_log.warning("federation: rejected Bearer from %s", client_host)
- # 4b. X-Muxplex-Token header (for cross-origin federation)
- token_header = request.headers.get("x-muxplex-token")
- if token_header:
- if verify_session_cookie(self.secret, token_header, self.ttl_seconds):
- return await call_next(request)
-
# 5. Authorization: Basic header
auth_header = request.headers.get("authorization", "")
if auth_header.lower().startswith("basic "):
diff --git a/muxplex/frontend/app.js b/muxplex/frontend/app.js
index eec9b7b..8dcd570 100644
--- a/muxplex/frontend/app.js
+++ b/muxplex/frontend/app.js
@@ -168,32 +168,13 @@ function isMobile() {
}
// ─── Fetch wrapper ────────────────────────────────────────────────────────────
-async function api(method, path, body, baseUrl) {
+async function api(method, path, body) {
const opts = { method, headers: {} };
if (body !== undefined) {
opts.headers['Content-Type'] = 'application/json';
opts.body = JSON.stringify(body);
}
- let url = path;
- if (baseUrl) {
- url = baseUrl.replace(/\/+$/, '') + path;
- opts.credentials = 'include';
- // Tell the remote auth middleware this is a JSON API client, not a browser
- // navigation. Without this header the middleware returns a 307 redirect to
- // /login (HTML) instead of a 401 JSON response, causing res.json() to throw
- // a SyntaxError that is misclassified as "unreachable" instead of
- // "auth_required".
- opts.headers['Accept'] = 'application/json';
- // Check for stored federation token (X-Muxplex-Token for cross-origin auth)
- try {
- var _origin = new URL(url).origin;
- var _tokens = JSON.parse(localStorage.getItem('muxplex.federation_tokens') || '{}');
- if (_tokens[_origin]) {
- opts.headers['X-Muxplex-Token'] = _tokens[_origin];
- }
- } catch (_) { /* ignore — URL parse or localStorage errors */ }
- }
- const res = await fetch(url, opts);
+ const res = await fetch(path, opts);
if (!res.ok) {
const err = new Error(`HTTP ${res.status}: ${res.statusText}`);
err.status = res.status;
@@ -203,36 +184,6 @@ async function api(method, path, body, baseUrl) {
}
// ─── Device ID ────────────────────────────────────────────────────────────────
-// ─── Federation token relay ──────────────────────────────────────────────────
-
-/**
- * Store a federation auth token for a remote origin in localStorage.
- * Keyed by origin URL in muxplex.federation_tokens.
- * Called by the postMessage listener when a login popup relays a token back.
- * @param {string} origin - The remote muxplex origin URL (e.g. 'https://host:8088')
- * @param {string} token - The session token to store
- */
-function storeFederationToken(origin, token) {
- try {
- var _ftokens = JSON.parse(localStorage.getItem('muxplex.federation_tokens') || '{}');
- _ftokens[origin] = token;
- localStorage.setItem('muxplex.federation_tokens', JSON.stringify(_ftokens));
- } catch (_) { /* blocked — ok */ }
-}
-
-// Listen for federation auth tokens relayed from login popups via postMessage.
-// When the user logs in via a popup, the popup fetches /api/auth/token and sends
-// it here, letting subsequent cross-origin API calls use X-Muxplex-Token header.
-window.addEventListener('message', function(event) {
- if (event.data && event.data.type === 'muxplex-auth-token') {
- storeFederationToken(event.data.origin, event.data.token);
- // Immediately trigger a poll so the source transitions from auth_required
- // to authenticated on the next cycle (uses the newly stored token).
- if (_pollingTimer) {
- pollSessions();
- }
- }
-});
function initDeviceId() {
const STORAGE_KEY = 'tmux-web-device-id';
@@ -549,54 +500,6 @@ function buildSidebarHTML(session, currentSession) {
);
}
-/**
- * Build the HTML string for an auth-required source tile.
- * @param {{ name: string, url: string }} source
- * @returns {string}
- */
-function buildAuthTileHTML(source) {
- const escapedName = escapeHtml(source.name || '');
- const escapedUrl = escapeHtml(source.url || '');
- return (
- '