User reported infinite login loop on dragonflight.live. Root cause: openresty fronts both http:// and https:// without redirecting, and a user landing on http:// gets the Set-Cookie response silently dropped — cookies are Secure-only when TRUST_PROXY=true, and the CORS allowlist refuses the http:// origin. Result: login appears to succeed, next request has no session cookie, AuthGate bounces back to login. Two defensive layers (the openresty box is not in our reach): - web-ui index.html: tiny inline redirect; if location is http://dragonflight.live, rewrite to https:// before anything else runs. Bounded to that exact hostname so local / LAN access on http://172.18.91.x stays as-is. - mam-api: emit Strict-Transport-Security on HTTPS responses when AUTH_ENABLED=true. After one successful HTTPS visit, browsers auto-upgrade future http:// requests on their own — closes the loophole even if someone bypasses the index.html JS. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
52 lines
2.3 KiB
HTML
52 lines
2.3 KiB
HTML
<!doctype html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8" />
|
|
<script>
|
|
// Force HTTPS on the public domain — Secure cookies and the CORS allowlist
|
|
// both refuse HTTP, so an http:// landing silently breaks login. Local /
|
|
// LAN hostnames keep whatever protocol they came in on.
|
|
if (location.protocol === 'http:' && location.hostname === 'dragonflight.live') {
|
|
location.replace('https:' + location.href.substring(5));
|
|
}
|
|
</script>
|
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
<title>Dragonflight · Wild Dragon Broadcast</title>
|
|
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
|
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Geist:wght@300;400;500;600;700&family=Geist+Mono:wght@400;500;600&display=swap" />
|
|
<link rel="stylesheet" href="styles.css" />
|
|
<link rel="stylesheet" href="styles-screens.css" />
|
|
<link rel="stylesheet" href="styles-asset.css" />
|
|
<link rel="stylesheet" href="styles-rest.css" />
|
|
<link rel="stylesheet" href="styles-modal.css" />
|
|
<link rel="stylesheet" href="styles-fixes.css" />
|
|
</head>
|
|
<body>
|
|
<div id="root"></div>
|
|
|
|
<script src="https://unpkg.com/react@18.3.1/umd/react.production.min.js" crossorigin="anonymous"></script>
|
|
<script src="https://unpkg.com/react-dom@18.3.1/umd/react-dom.production.min.js" crossorigin="anonymous"></script>
|
|
<script src="https://cdn.jsdelivr.net/npm/hls.js@1.5.15/dist/hls.min.js" crossorigin="anonymous"></script>
|
|
|
|
<script src="dist/data.js"></script>
|
|
<script src="dist/icons.js"></script>
|
|
<script src="dist/visuals.js"></script>
|
|
<script src="dist/shell.js"></script>
|
|
<script src="dist/auth-gate.js"></script>
|
|
<script src="dist/screens-auth.js"></script>
|
|
<script src="dist/screens-home.js"></script>
|
|
<script src="dist/screens-library.js"></script>
|
|
<script src="dist/screens-asset.js"></script>
|
|
<script src="dist/screens-projects.js"></script>
|
|
<script src="dist/screens-ingest.js"></script>
|
|
<script src="dist/screens-jobs.js"></script>
|
|
<script src="js/timecode.js"></script>
|
|
<script src="js/timeline.js"></script>
|
|
<script src="js/bmd-card.js"></script>
|
|
<script src="dist/screens-editor.js"></script>
|
|
<script src="dist/screens-admin.js"></script>
|
|
<script src="dist/modal-new-recorder.js"></script>
|
|
<script src="dist/app.js"></script>
|
|
</body>
|
|
</html>
|