brewlog/templates/pages/login.html
Jon Seager 5820c162f6
fix: address static assets code review findings
- Remove dead CSS color property in .tab-mobile
- Fix design token violations (text-red-500, fallback colors)
- Add disconnectedCallback to chip-scroll, image-upload, searchable-select
- Replace innerHTML with safe DOM APIs in world-map screen reader table
- Add credentials: same-origin to WebAuthn fetch calls
- Move page-specific scripts (donut-chart, location) out of base.html
- Add client-side image resizing (1920px max dimension)
- Resize app-icon-512.png from 2048x2048 to 512x512
- Document Datastar unsafe-eval CSP requirement
- Add static asset serving tests (16 routes)
- Add e2e tests for world-map, donut-chart, chip-scroll presence
- Add cache-busting query params to all static asset URLs
2026-02-13 17:13:02 +00:00

83 lines
2.7 KiB
HTML

{% extends "base.html" %} {% import "partials/icons.html" as icons %}
{% block title %}Brewlog · Login{% endblock %}
{% block head %}
<script
defer
src="/static/js/webauthn.js?v={{ version_info.commit }}"
></script>
{% endblock %}
{% block content %}
<div class="mx-auto max-w-md">
<div class="rounded-lg border bg-surface p-6">
<h1 class="text-2xl font-semibold text-accent">Login</h1>
<p class="mt-2 text-sm text-text-secondary">
Sign in with a passkey to access the coffee log.
</p>
<div
id="login-error"
class="mt-4 hidden rounded-md bg-error-bg border border-error-border p-3 text-sm text-error-text"
role="alert"
></div>
<div
id="login-unsupported"
class="mt-4 hidden rounded-md bg-warning-bg border border-warning-border p-3 text-sm text-warning-text"
>
This browser does not support passkeys. Please use a modern browser
(Chrome, Firefox, Safari, or Edge).
</div>
<div class="mt-6">
<button
id="login-button"
type="button"
onclick="handleLogin()"
class="inline-flex w-full items-center justify-center gap-2 rounded-md bg-accent px-4 py-3 text-sm font-semibold text-accent-text transition hover:bg-accent-hover disabled:opacity-50 disabled:cursor-not-allowed"
>
{{ icons::key("h-4 w-4") }} Sign in with Passkey
</button>
<div
id="login-loading"
class="mt-4 hidden text-center text-sm text-text-muted"
>
<p>Waiting for passkey...</p>
</div>
</div>
</div>
</div>
<script>
const handleLogin = async () => {
const button = document.getElementById("login-button");
const errorDiv = document.getElementById("login-error");
const loadingDiv = document.getElementById("login-loading");
errorDiv.classList.add("hidden");
loadingDiv.classList.remove("hidden");
button.disabled = true;
const params = new URLSearchParams(window.location.search);
let queryString = "";
if (params.has("cli_callback")) {
queryString = `?${params.toString()}`;
}
try {
const result = await startPasskeyAuthentication(queryString);
window.location.href = result.redirect || "/";
} catch (err) {
errorDiv.textContent = err.message;
errorDiv.classList.remove("hidden");
loadingDiv.classList.add("hidden");
button.disabled = false;
}
};
if (!window.PublicKeyCredential) {
document.getElementById("login-button").disabled = true;
document.getElementById("login-unsupported").classList.remove("hidden");
}
</script>
{% endblock %}