Simplify landing auth actions

This commit is contained in:
Meta Vens 2026-04-29 13:00:34 +01:00
commit a4833d1330
3 changed files with 20 additions and 69 deletions

View file

@ -886,11 +886,9 @@ def _landing_page_html(
}
auth_enabled = bool(auth_payload.get("enabled"))
authenticated = bool(subject_payload.get("authenticated"))
primary_href = "/app/" if authenticated or not auth_enabled else "#auth"
primary_label = "Continue to the demo" if authenticated else ("Sign in to the demo" if auth_enabled else "Open the demo")
providers = auth_payload.get("providers") if isinstance(auth_payload.get("providers"), list) else []
provider_button_html = ""
if auth_enabled and not authenticated:
header_actions_html = ""
if auth_enabled and not authenticated and providers:
fragments = []
for provider in providers:
if not isinstance(provider, dict):
@ -904,42 +902,24 @@ def _landing_page_html(
fragments.append(
f'<button class="button button-secondary" type="button" data-provider="{escaped_slug}">Login with {escaped_label}</button>'
)
provider_button_html = "".join(fragments)
hero_note = (
"Heimdall handles the provider dance, Repixelizer keeps the local verdict, and the browser mostly gets to stop couriering secrets."
if auth_enabled
else "It is not a miracle worker, and it is definitely not here to pretend it invented hand-authored pixel art from nothing."
)
auth_notice = ""
if auth_enabled and not auth_payload.get("providers"):
auth_notice = (
'<p class="copy-tag status-text" id="authNotice">Auth is enabled here, but no providers are configured yet. '
"The front door exists, but somebody still owes it an actual key.</p>"
header_actions_html = "".join(fragments)
elif authenticated:
header_actions_html = (
'<a class="button" href="/app/">Continue to the demo</a>'
'<button class="button button-secondary" id="authSignOut" type="button">Sign out</button>'
)
elif auth_enabled:
auth_notice = '<p class="copy-tag status-text" id="authNotice">Choose a provider. The main page stays put while Heimdall and the backend sort out the paperwork in another tab.</p>'
auth_state_text = (
f"Already authenticated as {subject_payload.get('displayName') or subject_payload.get('accountId') or 'a local creature'}."
if authenticated
else ""
)
else:
header_actions_html = '<a class="button" href="/app/">Open the demo</a>'
static_dir = _static_dir()
styles_path = static_dir / "styles.css"
styles_version = int(styles_path.stat().st_mtime_ns) if styles_path.exists() else 0
landing_template = (static_dir / "landing.html").read_text(encoding="utf-8")
return (
landing_template.replace("{{STYLES_VERSION}}", str(styles_version))
.replace("{{HERO_NOTE}}", html.escape(hero_note))
.replace("{{PRIMARY_HREF}}", html.escape(primary_href, quote=True))
.replace("{{PRIMARY_LABEL}}", html.escape(primary_label))
.replace("{{SIGNOUT_HIDDEN}}", "hidden" if not authenticated else "")
.replace("{{AUTH_PROVIDER_BUTTONS}}", provider_button_html)
.replace("{{AUTH_STATE_TEXT}}", html.escape(auth_state_text))
.replace("{{HEADER_ACTIONS}}", header_actions_html)
.replace("{{DEMO_LIMITS}}", html.escape(demo_limits))
.replace("{{AUTH_NOTICE}}", auth_notice)
.replace("{{AUTH_CONFIG_JSON}}", _json_html(auth_payload))
.replace("{{SESSION_SUBJECT_JSON}}", _json_html(subject_payload))
.replace("{{DEFAULT_PRIMARY_LABEL_JSON}}", _json_html(primary_label))
)

View file

@ -92,11 +92,6 @@
transform-origin: 42% 63%;
}
.landing-auth-strip {
display: grid;
gap: 10px;
}
.landing-header {
grid-template-columns: minmax(0, 1.35fr) auto minmax(280px, 0.9fr) minmax(220px, 0.65fr);
}
@ -165,13 +160,12 @@
</a>
<div class="header-instructions">
<p class="eyebrow">How to enter</p>
<p class="instruction-line">Start from this page, authenticate if enabled, then continue into the app.</p>
<p class="instruction-line">The hosted flow is a short handoff, not a separate experience.</p>
<p class="instruction-line">If auth is disabled, the demo button goes straight to the live workspace.</p>
<p class="instruction-line">Pick a provider when hosted auth is enabled.</p>
<p class="instruction-line">Otherwise, go straight to the live workspace.</p>
<p class="instruction-line">The browser is merely the courier. It should not get ideas.</p>
</div>
<div class="editor-actions">
<a class="button" href="{{PRIMARY_HREF}}" id="primaryAction">{{PRIMARY_LABEL}}</a>
<button class="button button-secondary" id="authSignOut" type="button" {{SIGNOUT_HIDDEN}}>Sign out</button>
<div class="editor-actions" id="authProviders">
{{HEADER_ACTIONS}}
</div>
</section>
<section class="hero panel-stack ui-surface ui-frame">
@ -208,13 +202,6 @@
<span>Real cells on a real lattice, ready for cleanup or export.</span>
</figure>
</div>
<div class="landing-auth-strip">
<p class="copy-tag">{{HERO_NOTE}}</p>
<div class="editor-button-group" id="authProviders">{{AUTH_PROVIDER_BUTTONS}}</div>
<p class="status-text" id="authStateLine">
{{AUTH_STATE_TEXT}}
</p>
</div>
</div>
</section>
<section class="card panel-stack ui-surface ui-frame">
@ -242,27 +229,20 @@
<p class="copy-tag status-text">
Self-hosters can still go straight to <a href="/app/">the app</a>. Hosted mode just gets a front door instead of making everyone trip over raw controls immediately.
</p>
{{AUTH_NOTICE}}
</section>
</main>
<script>
const authConfig = {{AUTH_CONFIG_JSON}};
const sessionSubject = {{SESSION_SUBJECT_JSON}};
const providerRow = document.getElementById("authProviders");
const primaryAction = document.getElementById("primaryAction");
const authStateLine = document.getElementById("authStateLine");
const authNotice = document.getElementById("authNotice");
const authNotice = null;
const signOutButton = document.getElementById("authSignOut");
const defaultPrimaryLabel = {{DEFAULT_PRIMARY_LABEL_JSON}};
let activeAttemptId = null;
function setNotice(text) {
if (authNotice) {
authNotice.textContent = text;
}
if (authStateLine) {
authStateLine.textContent = text;
}
}
function setBusy(providerSlug, busy) {
@ -272,9 +252,6 @@
for (const node of providerRow.querySelectorAll("button[data-provider]")) {
node.disabled = busy;
}
if (primaryAction && primaryAction instanceof HTMLElement) {
primaryAction.textContent = busy ? `Waiting on ${providerSlug}...` : defaultPrimaryLabel;
}
}
async function pollAttempt(attemptId, providerLabel) {
@ -363,16 +340,6 @@
}
}
if (primaryAction && authConfig.enabled && !sessionSubject.authenticated) {
primaryAction.addEventListener("click", (event) => {
event.preventDefault();
const firstProvider = Array.isArray(authConfig.providers) ? authConfig.providers[0] : null;
if (firstProvider) {
void startAuth(firstProvider);
}
});
}
if (signOutButton) {
signOutButton.addEventListener("click", async () => {
try {

View file

@ -414,6 +414,7 @@ def test_gui_hosted_root_serves_landing_page(monkeypatch, tmp_path: Path) -> Non
assert "Repixelizer hosted demo" in html
assert "Force fake pixel art back onto a real grid, then inspect each step with a full solver view." in html
assert 'href="/app/"' in html
assert "Login with Discord" not in html
def test_gui_hosted_root_renders_heimdall_login_buttons(monkeypatch, tmp_path: Path) -> None:
@ -433,6 +434,9 @@ def test_gui_hosted_root_renders_heimdall_login_buttons(monkeypatch, tmp_path: P
assert status == 200
assert "Login with Discord" in html
assert "Login with Patreon" in html
assert "Sign in to the demo" not in html
assert "Already authenticated as" not in html
assert 'href="#auth"' not in html
assert "/api/auth/heimdall/start" in html
assert "Hosted access will be gated through Heimdall once the auth pass lands." not in html