fix: final review pass — email collision, orphaned-run loop, null confidence guards
- changeEmail validates and refuses an address another account owns (users.email is UNIQUE; a collision was a 500 inside the settings form). - /app/[id] no longer redirects a 'running' row to itself; it renders what exists and says the run was interrupted. - ScoreBar / OptionRow / VerdictBlock survive null numbers from the model instead of throwing and losing the block (seen live: '[openui] runtime/render-error: Component ScoreBar render failed'). - drop the ad-hoc render-debug scripts now that Playwright covers the browser. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.7
parent
07dd3d6bf8
commit
5160a00db5
+11
-1
@@ -1,5 +1,5 @@
|
||||
import { randomBytes, scryptSync, createHash, timingSafeEqual } from "node:crypto";
|
||||
import { createUser, userByEmail, userEmail, putSession, sessionUserId, dropSession, getSettings } from "./db.ts";
|
||||
import { createUser, userByEmail, userEmail, putSession, sessionUserId, dropSession, getSettings, db } from "./db.ts";
|
||||
|
||||
export const SESSION_COOKIE = "qai_s";
|
||||
export const SESSION_DAYS = 30;
|
||||
@@ -34,6 +34,16 @@ export function signUpNewUser(email: string, password: string): { ok: true; id:
|
||||
// request-scoped binding must not be touched at import time.
|
||||
const jar = async () => (await import("next/headers")).cookies();
|
||||
|
||||
export function changeEmail(userId: string, email: string): { ok: true } | { ok: false; error: string } {
|
||||
const e = email.trim().toLowerCase();
|
||||
if (!emailOk(e)) return { ok: false, error: "Enter a valid email address." };
|
||||
const taken = userByEmail(e);
|
||||
if (taken && taken.id !== userId) return { ok: false, error: "That email already has an account." };
|
||||
// users.email is UNIQUE: without this check a collision is a 500 inside the settings form.
|
||||
if (!taken) db.prepare("UPDATE users SET email = ? WHERE id = ?").run(e, userId);
|
||||
return { ok: true };
|
||||
}
|
||||
|
||||
export async function startSession(userId: string) {
|
||||
const token = randomBytes(32).toString("hex");
|
||||
putSession(hashToken(token), userId, Date.now() + SESSION_DAYS * 864e5);
|
||||
|
||||
Reference in New Issue
Block a user