Files
vibedns/web/templates/pages/account.html
T
2026-08-16 21:18:45 -05:00

128 lines
4.8 KiB
HTML

{{define "content"}}
{{$a := .Data.Admin}}
<h1 class="page-title mb-1">Account</h1>
<p class="text-body-secondary mb-4">The single administrator account for this server.</p>
{{template "settingsnav" dict "Subnav" "account"}}
<div class="row g-3">
<div class="col-12 col-lg-7">
<div class="card">
<div class="card-header">Change credentials</div>
<div class="card-body">
{{if $a.MustChangePassword}}
<div class="alert alert-warning d-flex align-items-start gap-2">
<i class="bi bi-shield-exclamation mt-1"></i>
<div>
This account still uses the password that was generated and printed at first
startup. Set your own before exposing the interface to anyone else.
</div>
</div>
{{end}}
<form method="post" action="/account" autocomplete="off">
<input type="hidden" name="_csrf" value="{{.CSRF}}">
<div class="mb-3">
<label class="form-label" for="currentPassword">
Current password <span class="text-danger">*</span>
</label>
<input type="password" class="form-control" id="currentPassword" name="current_password"
required autocomplete="current-password">
<div class="form-text">
Always required, even for a username change. Browsers replay HTTP Basic
credentials automatically, so proving you know the password is what
distinguishes you from a hijacked tab.
</div>
</div>
<hr>
<div class="mb-3">
<label class="form-label" for="newUsername">Username</label>
<input type="text" class="form-control" id="newUsername" name="username"
value="{{$a.Username}}" autocomplete="username">
<div class="form-text">Letters, digits and the characters . - _ @</div>
</div>
<div class="mb-3">
<label class="form-label" for="newPassword">New password</label>
<input type="password" class="form-control" id="newPassword" name="new_password"
autocomplete="new-password" minlength="12">
<div class="form-text">
At least 12 characters. Leave blank to keep the current password.
Stored as an Argon2id hash, never in plain text.
</div>
</div>
<div class="mb-3">
<label class="form-label" for="confirmPassword">Confirm new password</label>
<input type="password" class="form-control" id="confirmPassword" name="confirm_password"
autocomplete="new-password">
</div>
<div class="alert alert-info small">
<i class="bi bi-info-circle me-1"></i>
After saving, your browser will prompt for the new credentials. The old password
stops working immediately.
</div>
<button type="submit" class="btn btn-primary">
<i class="bi bi-check-lg me-1"></i>Save credentials
</button>
</form>
</div>
</div>
</div>
<div class="col-12 col-lg-5">
<div class="card mb-3">
<div class="card-header">Account details</div>
<div class="card-body">
<dl class="row mb-0 small">
<dt class="col-5 text-body-secondary">Username</dt>
<dd class="col-7 mono">{{$a.Username}}</dd>
<dt class="col-5 text-body-secondary">Created</dt>
<dd class="col-7">{{datetime $a.CreatedAt}}</dd>
<dt class="col-5 text-body-secondary">Last updated</dt>
<dd class="col-7">{{datetime $a.UpdatedAt}}</dd>
<dt class="col-5 text-body-secondary">Last sign-in</dt>
<dd class="col-7">
{{if $a.LastLoginAt}}{{datetime $a.LastLoginAt}}{{else}}never{{end}}
</dd>
<dt class="col-5 text-body-secondary">Password</dt>
<dd class="col-7">
<span class="badge text-bg-success">Argon2id</span>
</dd>
</dl>
</div>
</div>
<div class="card">
<div class="card-header">How authentication works</div>
<div class="card-body small text-body-secondary">
<p>
The management interface uses HTTP Basic authentication over a single
administrator account. There is no session cookie to steal, but browsers do
replay the credentials on every request, so state-changing requests additionally
carry a signed CSRF token.
</p>
<p>
Repeated failed sign-ins from one address are locked out for a few minutes.
</p>
<p class="mb-0">
For automation, use an <a href="/settings/api">API token</a> rather than the
administrator password: tokens are individually revocable and carry no ability to
change credentials.
</p>
</div>
</div>
</div>
</div>
{{end}}