2 lines
3.9 KiB
HTML
2 lines
3.9 KiB
HTML
{% extends "base/layout.html" %}{% block content %}<div class="mx-auto max-w-5xl space-y-5 p-4 sm:p-6"><div class="flex items-start justify-between"><div><h1 class="text-2xl font-bold">{{ entry.title }}</h1><p class="text-sm text-slate-600">{{ client.client_name if client else 'Firm-level credential' }} · {{ entry.category|replace('_',' ')|title }}</p></div><a href="/credential-vault" class="rounded-lg border px-3 py-2">Back</a></div><div class="grid gap-4 md:grid-cols-2"><section class="rounded-xl bg-white p-5 shadow"><h2 class="font-semibold">Metadata</h2><dl class="mt-3 grid grid-cols-2 gap-3 text-sm"><dt class="text-slate-500">Portal</dt><dd>{% if entry.portal_url %}<a class="text-brand-700" href="{{ entry.portal_url }}" target="_blank" rel="noopener noreferrer">Open portal</a>{% else %}-{% endif %}</dd><dt class="text-slate-500">Reference</dt><dd>{{ entry.reference_number or '-' }}</dd><dt class="text-slate-500">Sensitivity</dt><dd>{{ entry.sensitivity|title }}</dd><dt class="text-slate-500">Rotation due</dt><dd>{{ entry.rotation_due_on or '-' }}</dd><dt class="text-slate-500">Expiry</dt><dd>{{ entry.expires_on or '-' }}</dd><dt class="text-slate-500">Status</dt><dd>{{ entry.status|title }}</dd></dl></section><section class="rounded-xl border border-amber-200 bg-amber-50 p-5"><h2 class="font-semibold">Reveal protected values</h2><p class="mt-1 text-sm text-amber-900">Re-authentication and a business reason are mandatory. The reveal is audit logged.</p><form method="post" action="/credential-vault/{{ entry.id }}/reveal" class="mt-3 space-y-3"><input type="hidden" name="csrf_token" value="{{ csrf_token }}"><input required name="reason" placeholder="Business reason" class="w-full rounded-lg border p-2"><input required type="password" name="current_password" autocomplete="current-password" placeholder="Current ERP password" class="w-full rounded-lg border p-2"><button class="rounded-lg bg-slate-900 px-4 py-2 font-semibold text-white">Reveal once</button></form></section></div>{% if can_manage %}<section class="rounded-xl bg-white p-5 shadow"><h2 class="font-semibold">Rotate credential</h2><form method="post" action="/credential-vault/{{ entry.id }}/rotate" class="mt-3 grid gap-3 sm:grid-cols-2"><input type="hidden" name="csrf_token" value="{{ csrf_token }}"><input name="username" placeholder="New username/login ID" class="rounded-lg border p-2"><input required type="password" name="secret" autocomplete="new-password" placeholder="New password/token" class="rounded-lg border p-2"><input type="password" name="additional_secret" autocomplete="new-password" placeholder="New PIN/additional secret" class="rounded-lg border p-2"><input type="date" name="rotation_due_on" class="rounded-lg border p-2"><textarea name="notes" placeholder="Encrypted notes" class="rounded-lg border p-2 sm:col-span-2"></textarea><input required name="reason" placeholder="Rotation reason" class="rounded-lg border p-2 sm:col-span-2"><button class="w-fit rounded-lg bg-brand-600 px-4 py-2 font-semibold text-white">Rotate and preserve history</button></form></section>{% endif %}<section class="rounded-xl bg-white p-5 shadow"><h2 class="font-semibold">Access audit</h2><div class="mt-3 overflow-x-auto"><table class="min-w-full text-sm"><thead><tr><th class="p-2 text-left">When</th><th class="p-2 text-left">User</th><th class="p-2 text-left">Action</th><th class="p-2 text-left">Reason</th><th class="p-2 text-left">Result</th></tr></thead><tbody>{% for log,user_row in logs %}<tr class="border-t"><td class="p-2">{{ log.created_at_utc }}</td><td class="p-2">{{ user_row.full_name or user_row.email if user_row else '-' }}</td><td class="p-2">{{ log.action|title }}</td><td class="p-2">{{ log.reason or '-' }}</td><td class="p-2">{{ 'Success' if log.success else 'Denied' }}</td></tr>{% else %}<tr><td colspan="5" class="p-4 text-slate-500">No access events.</td></tr>{% endfor %}</tbody></table></div></section></div>{% endblock %}
|