Checkpoint: password reset, rule expiry, migrations
- Self-service and admin password-change endpoints
(PUT /v1/auth/password, PUT /v1/accounts/{id}/password)
- Policy rule time-scoped expiry (not_before / expires_at)
with migration 000006 and engine filtering
- golang-migrate integration; embedded SQL migrations
- PolicyRecord fieldalignment lint fix
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
47
web/templates/fragments/password_reset_form.html
Normal file
47
web/templates/fragments/password_reset_form.html
Normal file
@@ -0,0 +1,47 @@
|
||||
{{define "password_reset_form"}}
|
||||
<form id="password-reset-form"
|
||||
hx-put="/accounts/{{.Account.UUID}}/password"
|
||||
hx-target="#password-reset-section"
|
||||
hx-swap="innerHTML"
|
||||
hx-headers='{"X-CSRF-Token": "{{.CSRFToken}}"}'
|
||||
onsubmit="return mciasPwConfirm(this)">
|
||||
<div class="form-group">
|
||||
<label for="new_password">New Password</label>
|
||||
<input type="password" id="new_password" name="new_password"
|
||||
class="form-control" autocomplete="new-password"
|
||||
placeholder="Minimum 12 characters" required minlength="12">
|
||||
</div>
|
||||
<div class="form-group" style="margin-top:.5rem">
|
||||
<label for="confirm_password">Confirm Password</label>
|
||||
<input type="password" id="confirm_password" name="confirm_password"
|
||||
class="form-control" autocomplete="new-password"
|
||||
placeholder="Repeat new password" required minlength="12">
|
||||
</div>
|
||||
<div id="pw-reset-error" role="alert"
|
||||
style="display:none;color:var(--color-danger,#c0392b);font-size:.85rem;margin-top:.35rem"></div>
|
||||
<button type="submit" class="btn btn-danger btn-sm" style="margin-top:.75rem">
|
||||
Reset Password
|
||||
</button>
|
||||
</form>
|
||||
<script>
|
||||
function mciasPwConfirm(form) {
|
||||
var pw = form.querySelector('#new_password').value;
|
||||
var cfm = form.querySelector('#confirm_password').value;
|
||||
var err = form.querySelector('#pw-reset-error');
|
||||
if (pw !== cfm) {
|
||||
err.textContent = 'Passwords do not match.';
|
||||
err.style.display = 'block';
|
||||
return false;
|
||||
}
|
||||
err.style.display = 'none';
|
||||
return true;
|
||||
}
|
||||
</script>
|
||||
{{end}}
|
||||
|
||||
{{define "password_reset_result"}}
|
||||
{{if .Flash}}
|
||||
<div class="alert alert-success" role="alert">{{.Flash}}</div>
|
||||
{{end}}
|
||||
{{template "password_reset_form" .}}
|
||||
{{end}}
|
||||
@@ -72,6 +72,16 @@
|
||||
Owner must match subject (self-service rules only)
|
||||
</label>
|
||||
</div>
|
||||
<div style="display:grid;grid-template-columns:1fr 1fr;gap:.5rem;margin-bottom:.5rem">
|
||||
<div>
|
||||
<label class="text-small text-muted">Not before (UTC, optional)</label>
|
||||
<input class="form-control" type="datetime-local" name="not_before" style="font-size:.85rem">
|
||||
</div>
|
||||
<div>
|
||||
<label class="text-small text-muted">Expires at (UTC, optional)</label>
|
||||
<input class="form-control" type="datetime-local" name="expires_at" style="font-size:.85rem">
|
||||
</div>
|
||||
</div>
|
||||
<button class="btn btn-sm btn-secondary" type="submit">Create Rule</button>
|
||||
</form>
|
||||
{{end}}
|
||||
|
||||
@@ -4,6 +4,15 @@
|
||||
<td class="text-small">{{.Priority}}</td>
|
||||
<td>
|
||||
<strong>{{.Description}}</strong>
|
||||
{{if .IsExpired}}<span class="badge" style="background:#dc2626;color:#fff;margin-left:.4rem">expired</span>{{end}}
|
||||
{{if .IsPending}}<span class="badge" style="background:#d97706;color:#fff;margin-left:.4rem">scheduled</span>{{end}}
|
||||
{{if or .NotBefore .ExpiresAt}}
|
||||
<div class="text-small text-muted" style="margin-top:.2rem">
|
||||
{{if .NotBefore}}Not before: {{.NotBefore}}{{end}}
|
||||
{{if and .NotBefore .ExpiresAt}} · {{end}}
|
||||
{{if .ExpiresAt}}Expires: {{.ExpiresAt}}{{end}}
|
||||
</div>
|
||||
{{end}}
|
||||
<details style="margin-top:.25rem">
|
||||
<summary class="text-small text-muted" style="cursor:pointer">Show rule JSON</summary>
|
||||
<pre style="font-size:.75rem;background:#f8fafc;padding:.5rem;border-radius:4px;overflow:auto;margin-top:.25rem">{{.RuleJSON}}</pre>
|
||||
|
||||
Reference in New Issue
Block a user