feat(otm): sign-in page onto the shared OTM standard (0.4.1)
Build / Build and release (push) Failing after 15s
Build / Build and release (push) Failing after 15s
Restyle login_page to the platform standard: brand (name + tagline) above one centered card, "Sign in with OTM" as the full-width primary button, and a muted Face ID/Touch ID/passkey helper line under it. 13ft has no local accounts, so there's no "Other ways to sign in" step. The fail-closed "isn't wired to OTM yet" 503 copy and the tides beacon are unchanged. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014LCQmFvKshyAJsE8C3B5ET
This commit is contained in:
+22
-8
@@ -32,7 +32,7 @@ from typing import Any, Optional
|
||||
|
||||
import requests
|
||||
|
||||
APP_VERSION = "0.4.0"
|
||||
APP_VERSION = "0.4.1"
|
||||
OTM_AUDIENCE = "app:13ft"
|
||||
OTM_BASE = os.environ.get("OTM_SSO_AUTHORIZE_BASE", "https://admin.poweredbyotm.com")
|
||||
SESSION_COOKIE = "thirteen_session"
|
||||
@@ -246,18 +246,32 @@ SSO_REASONS = {
|
||||
def login_page(next_path: str, reason: Optional[str], configured: bool) -> str:
|
||||
msg = ""
|
||||
if reason:
|
||||
msg = f'<p style="color:#b3556b">{html_mod.escape(SSO_REASONS.get(reason, "Sign-in failed."))}</p>'
|
||||
msg = f'<p style="color:#c0566e;margin:0 0 1rem;font-size:.9rem">{html_mod.escape(SSO_REASONS.get(reason, "Sign-in failed."))}</p>'
|
||||
if not configured:
|
||||
msg = '<p style="color:#b3556b">This 13ft isn\'t wired to OTM yet, so nobody can sign in. (Fails closed on purpose — it\'s a fetch proxy.)</p>'
|
||||
button = (
|
||||
f'<p><a href="{html_mod.escape(otm_sign_in_url(next_path))}" style="display:inline-block;padding:.7em 1.2em;border:1px solid currentColor;border-radius:8px;text-decoration:none;color:inherit;font-weight:600">Sign in with OTM</a></p>'
|
||||
msg = '<p style="color:#c0566e;margin:0;font-size:.9rem">This 13ft isn\'t wired to OTM yet, so nobody can sign in. (Fails closed on purpose — it\'s a fetch proxy.)</p>'
|
||||
# OTM-only app (no local accounts) — step 2's primary button is the whole
|
||||
# card, with the passkey helper line under it. There is no step 3 ("Other
|
||||
# ways to sign in"): there is no other way.
|
||||
card = msg + (
|
||||
f'<a href="{html_mod.escape(otm_sign_in_url(next_path))}" '
|
||||
'style="display:block;box-sizing:border-box;width:100%;text-align:center;padding:.85em 1.2em;'
|
||||
'margin-top:.75rem;border-radius:9px;border:1px solid var(--accent);background:var(--accent);'
|
||||
'color:var(--accent-ink);text-decoration:none;font-weight:600">Sign in with OTM</a>'
|
||||
'<p style="text-align:center;font-size:.8rem;opacity:.7;margin:.9rem 0 0">'
|
||||
'Your OTM account — Face ID, Touch ID or a passkey works there.</p>'
|
||||
if configured else ""
|
||||
)
|
||||
return (
|
||||
'<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">'
|
||||
'<title>13ft — sign in</title><style>:root{color-scheme:light dark}body{font-family:system-ui,sans-serif;max-width:28rem;margin:12vh auto;padding:0 1rem;line-height:1.5}</style></head>'
|
||||
'<body><h1>13ft</h1><p>Read the article without the cruft. Sign-in is by OTM account — one login for every OTM tool.</p>'
|
||||
f'{msg}{button}{tides_beacon()}</body></html>'
|
||||
'<title>13ft — sign in</title><style>:root{color-scheme:light dark;--accent:#3a6df0;--accent-ink:#fff}'
|
||||
'body{font-family:system-ui,sans-serif;max-width:24rem;margin:10vh auto;padding:0 1rem;line-height:1.5}'
|
||||
'.brand{text-align:center;margin:0 0 1.75rem}.brand h1{margin:0 0 .3rem;font-size:1.9rem}'
|
||||
'.brand p{margin:0;opacity:.7;font-size:.95rem}'
|
||||
'.card{border:1px solid #8884;border-radius:14px;padding:1.5rem}</style></head>'
|
||||
'<body>'
|
||||
'<div class="brand"><h1>13ft</h1><p>Read the article without the cruft.</p></div>'
|
||||
f'<div class="card">{card}</div>'
|
||||
f'{tides_beacon()}</body></html>'
|
||||
)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user