Simplify landing auth actions
This commit is contained in:
parent
2d5c244606
commit
a4833d1330
3 changed files with 20 additions and 69 deletions
|
|
@ -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))
|
||||
)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue