internal/oidcprovider/login.html
Ref: Size: 1.7 KiB History
<!doctype html>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Sign in</title>
<style>
body { font: 15px/1.5 system-ui, sans-serif; background: #f6f7f9; color: #1a1a1a;
display: flex; min-height: 100vh; margin: 0; align-items: center; justify-content: center; }
form { background: #fff; padding: 2rem; border-radius: 8px; box-shadow: 0 1px 4px rgba(0,0,0,.1);
width: 20rem; box-sizing: border-box; }
h1 { font-size: 1.1rem; margin: 0 0 1rem; }
label { display: block; margin: .75rem 0 .25rem; font-size: .85rem; color: #555; }
input { width: 100%; padding: .5rem; box-sizing: border-box; border: 1px solid #ccc; border-radius: 4px; }
button { margin-top: 1.25rem; width: 100%; padding: .55rem; border: 0; border-radius: 4px;
background: #1a1a1a; color: #fff; font-size: .95rem; cursor: pointer; }
.error { margin-top: .75rem; color: #b00020; font-size: .85rem; }
</style>
<!--
Plain HTML, no JavaScript: a cookie-jar HTTP client drives the same form as a
human. The action posts back to the exact URL that served this page (the
authorize endpoint with the original raw query) so a headless CI client only
needs to POST email+password to the URL it just fetched โ load-bearing for CI
(spec ยง2.1). Field names email/password are a stable contract.
-->
<form method="post" action="{{.Action}}">
<h1>Sign in to eitri</h1>
<label for="email">Email</label>
<input id="email" name="email" type="email" autocomplete="username" autofocus>
<label for="password">Password</label>
<input id="password" name="password" type="password" autocomplete="current-password">
{{if .Error}}<div class="error">{{.Error}}</div>{{end}}
<button type="submit">Sign in</button>
</form>