security hardening + drafts/attachments

This commit is contained in:
2026-02-21 19:10:56 -05:00
parent 1dc99eb681
commit a0105956e4
35 changed files with 4928 additions and 0 deletions

View File

@@ -0,0 +1,119 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Mastermind — Users</title>
<style>
body{font-family:system-ui,-apple-system,Segoe UI,Roboto,Arial,sans-serif;margin:0;background:#0b0f14;color:#e8eef7}
header{background:#111824;border-bottom:1px solid #233043;padding:14px 16px;position:sticky;top:0}
main{max-width:1100px;margin:0 auto;padding:16px}
.card{background:#111824;border:1px solid #233043;border-radius:12px;padding:14px;margin:12px 0}
a{color:#7cc4ff;text-decoration:none}
.muted{color:#a9b7c6}
table{width:100%;border-collapse:collapse}
th,td{border-bottom:1px solid #233043;padding:10px 6px;text-align:left;color:#a9b7c6;font-size:13px;vertical-align:top}
th{color:#e8eef7}
input,select{padding:10px;border-radius:10px;border:1px solid #233043;background:#0e1520;color:#e8eef7;width:100%}
button{padding:10px 12px;border-radius:10px;border:1px solid #233043;background:#1c2a3d;color:#e8eef7}
.grid{display:grid;grid-template-columns:repeat(12,1fr);gap:12px}
.col6{grid-column:span 12}
@media(min-width:900px){.col6{grid-column:span 6}}
.pill{display:inline-block;padding:2px 8px;border:1px solid #233043;border-radius:999px;font-size:12px;color:#a9b7c6}
.danger{background:#2b1216;border-color:#5a1e28}
</style>
</head>
<body>
<header>
<div style="display:flex;justify-content:space-between;align-items:center;gap:10px">
<div style="font-weight:700">User Management</div>
<div style="display:flex;gap:10px">
<a href="/">Dashboard</a>
<a href="/logout">Logout</a>
</div>
</div>
</header>
<main>
<div class="card">
<h2 style="margin:0 0 8px">Create local user</h2>
<form method="post" action="/admin/users/create" class="grid">
<div class="col6">
<label class="muted">Email</label>
<input name="email" placeholder="user@company.com" required />
</div>
<div class="col6">
<label class="muted">Display name</label>
<input name="displayName" placeholder="Jane Doe" />
</div>
<div class="col6">
<label class="muted">Role</label>
<select name="role">
<option value="apm">apm</option>
<option value="pm">pm</option>
<option value="viewer">viewer</option>
<option value="owner">owner</option>
</select>
</div>
<div class="col6">
<label class="muted">Temporary password</label>
<input name="tempPassword" placeholder="Temp password" required />
</div>
<div style="grid-column:span 12">
<button type="submit">Create user</button>
</div>
</form>
<p class="muted" style="margin-top:10px">SSO users (Google/Microsoft) will appear here after their first login.</p>
</div>
<div class="card">
<h2 style="margin:0 0 8px">Users</h2>
<table>
<thead>
<tr>
<th>Email</th>
<th>Name</th>
<th>Role</th>
<th>Status</th>
<th>Identities</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<% users.forEach(u => { %>
<tr>
<td><%= u.email || '(no email)' %></td>
<td><%= u.display_name || '' %></td>
<td><span class="pill"><%= u.role %></span></td>
<td>
<% if (u.disabled) { %>
<span class="pill danger">disabled</span>
<% } else { %>
<span class="pill">active</span>
<% } %>
</td>
<td class="muted">
<%= (u.providers || '').split(',').filter(Boolean).join(', ') %>
</td>
<td>
<form method="post" action="/admin/users/<%= u.id %>/reset" style="display:inline-block;min-width:220px">
<input name="newPassword" placeholder="New temp password" />
<button type="submit" style="margin-top:6px;width:100%">Reset local password</button>
</form>
<div style="height:8px"></div>
<form method="post" action="/admin/users/<%= u.id %>/toggle" style="display:inline-block;width:220px">
<button type="submit" style="width:100%"><%= u.disabled ? 'Enable user' : 'Disable user' %></button>
</form>
<div style="height:8px"></div>
<form method="post" action="/admin/users/<%= u.id %>/delete" onsubmit="return confirm('Delete user? This cannot be undone.');" style="display:inline-block;width:220px">
<button type="submit" style="width:100%;background:#2b1216;border-color:#5a1e28">Delete user</button>
</form>
</td>
</tr>
<% }) %>
</tbody>
</table>
</div>
</main>
</body>
</html>