This commit is contained in:
k
2026-09-22 08:29:46 +02:00
parent b5d17d8944
commit e9695c0239
8 changed files with 85 additions and 15 deletions
+6 -1
View File
@@ -187,10 +187,11 @@ export function createUser(opts: { username: string; displayName: string; avatar
return row;
}
export function updateUser(id: string, patch: { displayName?: string; avatarUrl?: string; theme?: string; email?: string; keyHash?: string }): UserRow | null {
export function updateUser(id: string, patch: { username?: string; displayName?: string; avatarUrl?: string; theme?: string; email?: string; keyHash?: string }): UserRow | null {
const d = getDb();
const sets: string[] = [];
const vals: (string | number)[] = [];
if (patch.username !== undefined) { sets.push("username = ?"); vals.push(patch.username); }
if (patch.displayName !== undefined) { sets.push("display_name = ?"); vals.push(patch.displayName); }
if (patch.avatarUrl !== undefined) { sets.push("avatar_url = ?"); vals.push(patch.avatarUrl); }
if (patch.theme !== undefined) { sets.push("theme = ?"); vals.push(patch.theme); }
@@ -199,6 +200,10 @@ export function updateUser(id: string, patch: { displayName?: string; avatarUrl?
if (sets.length > 0) {
d.query(`UPDATE users SET ${sets.join(", ")} WHERE id = ?`).run(...vals, id);
}
if (patch.username !== undefined) {
// Username is denormalized onto past reports — keep the triage list consistent.
d.query("UPDATE reports SET reporter_name = ? WHERE reporter_id = ?").run(patch.username, id);
}
return getUserById(id);
}
+10 -2
View File
@@ -622,7 +622,15 @@ const server = Bun.serve<{ ticketId: string | null; isAdmin: boolean }>({
if (path === "/api/me" && req.method === "PATCH") {
const { ok, body } = await readJson(req);
if (!ok) return json({ error: "invalid JSON" }, 400);
const patch: { displayName?: string; avatarUrl?: string; theme?: string; email?: string } = {};
const patch: { username?: string; displayName?: string; avatarUrl?: string; theme?: string; email?: string } = {};
if (body.username !== undefined) {
if (user.username === "admin") return json({ error: "the admin account cannot be renamed" }, 403);
const u = validUsername(body.username);
if (!u) return json({ error: "username: 2-32 chars [a-z0-9._-], 'admin' reserved" }, 400);
const taken = getUserByUsername(u);
if (taken && taken.id !== user.id) return json({ error: "username taken" }, 409);
patch.username = u;
}
if (body.displayName !== undefined) {
const d = cleanStr(body.displayName, 60);
if (d === null) return json({ error: "displayName: 1-60 chars" }, 400);
@@ -810,7 +818,7 @@ const server = Bun.serve<{ ticketId: string | null; isAdmin: boolean }>({
patch.avatarUrl = a;
}
if (body.theme !== undefined) {
if (!validTheme(body.theme)) return json({ error: "theme must be auto|light|dark|sunset|sunset" }, 400);
if (!validTheme(body.theme)) return json({ error: "theme must be auto|light|dark|sunset" }, 400);
patch.theme = body.theme;
}
if (body.email !== undefined) {