Phase 1 foundation. Local auth per ADR-0006: Argon2id passwords, opaque hashed session tokens with idle/absolute expiry, CSRF token plus Origin check on cookie sessions, per-IP token bucket and per-account exponential lockout, three roles enforced by middleware, personal API tokens for noemactl. Audit log writer used by every admin mutation. API: request ids, panic recovery, strict CSP and security headers, body limits, single JSON error envelope, health/ready/status, users, sessions, tokens, audit, token-protected /metrics. UI: embedded html/template pages (login, first-run setup, dashboard, system, users, account, audit, interpretation boundary), light/dark theme, dependency-free app.js with CSRF-aware fetch and SSE helper. Binaries: noemad with graceful shutdown, migrations at start, bootstrap admin from environment, supervised background tasks; noemactl with status, migrate, user create and meaningful exit codes.
15 lines
733 B
HTML
15 lines
733 B
HTML
{{define "content"}}
|
|
<div class="card auth-card">
|
|
<div class="brand big"><span class="brand-mark" aria-hidden="true"></span>Noema</div>
|
|
<p class="muted">Sign in to the cognitive runtime.</p>
|
|
<form method="post" action="/login" class="stack">
|
|
<input type="hidden" name="_csrf" value="{{.CSRF}}">
|
|
<input type="hidden" name="next" value="{{.Data.Next}}">
|
|
<label>Username <input name="username" autocomplete="username" required autofocus></label>
|
|
<label>Password <input type="password" name="password" autocomplete="current-password" required></label>
|
|
{{with .Data.Error}}<p class="error" role="alert">{{.}}</p>{{end}}
|
|
<button class="btn btn-primary" type="submit">Sign in</button>
|
|
</form>
|
|
</div>
|
|
{{end}}
|