Skip to content

Commit 76ef4ff

Browse files
committed
Reconcile users by email to preserve approval/admin and ownership
1 parent 9145203 commit 76ef4ff

1 file changed

Lines changed: 64 additions & 0 deletions

File tree

functions/_lib/db.ts

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,68 @@ const readUserRow = async (env: Env, userId: string): Promise<UserRow | null> =>
272272
.first<UserRow>();
273273
};
274274

275+
const reconcileUserIdentityByEmail = async (env: Env, userId: string, email: string): Promise<void> => {
276+
const normalized = sanitizeEmail(email);
277+
if (!normalized) return;
278+
279+
const existing = await env.DB
280+
.prepare(
281+
`SELECT id, username, email, bio, avatar_url, is_admin, is_approved, approved_at, approved_by_user_id, created_at, updated_at
282+
FROM users
283+
WHERE lower(email) = lower(?) AND id <> ?
284+
ORDER BY is_admin DESC, is_approved DESC, created_at ASC
285+
LIMIT 1`,
286+
)
287+
.bind(normalized, userId)
288+
.first<UserRow>();
289+
if (!existing) return;
290+
291+
const now = new Date().toISOString();
292+
await env.DB
293+
.prepare(
294+
`UPDATE users
295+
SET is_admin = CASE WHEN ? = 1 THEN 1 ELSE is_admin END,
296+
is_approved = CASE WHEN ? = 1 THEN 1 ELSE is_approved END,
297+
approved_at = CASE WHEN ? = 1 THEN COALESCE(approved_at, ?) ELSE approved_at END,
298+
approved_by_user_id = CASE WHEN ? = 1 THEN COALESCE(approved_by_user_id, ?) ELSE approved_by_user_id END,
299+
updated_at = ?
300+
WHERE id = ?`,
301+
)
302+
.bind(
303+
existing.is_admin === 1 ? 1 : 0,
304+
existing.is_approved === 1 ? 1 : 0,
305+
existing.is_approved === 1 ? 1 : 0,
306+
existing.approved_at ?? now,
307+
existing.is_approved === 1 ? 1 : 0,
308+
existing.approved_by_user_id ?? existing.id,
309+
now,
310+
userId,
311+
)
312+
.run();
313+
314+
await env.DB.batch([
315+
env.DB.prepare("UPDATE sites SET owner_user_id = ? WHERE owner_user_id = ?").bind(userId, existing.id),
316+
env.DB
317+
.prepare(
318+
`UPDATE sites
319+
SET created_by_user_id = CASE WHEN created_by_user_id = ? THEN ? ELSE created_by_user_id END,
320+
last_edited_by_user_id = CASE WHEN last_edited_by_user_id = ? THEN ? ELSE last_edited_by_user_id END`,
321+
)
322+
.bind(existing.id, userId, existing.id, userId),
323+
env.DB.prepare("UPDATE simulations SET owner_user_id = ? WHERE owner_user_id = ?").bind(userId, existing.id),
324+
env.DB
325+
.prepare(
326+
`UPDATE simulations
327+
SET created_by_user_id = CASE WHEN created_by_user_id = ? THEN ? ELSE created_by_user_id END,
328+
last_edited_by_user_id = CASE WHEN last_edited_by_user_id = ? THEN ? ELSE last_edited_by_user_id END`,
329+
)
330+
.bind(existing.id, userId, existing.id, userId),
331+
env.DB.prepare("UPDATE site_roles SET user_id = ? WHERE user_id = ?").bind(userId, existing.id),
332+
env.DB.prepare("UPDATE simulation_roles SET user_id = ? WHERE user_id = ?").bind(userId, existing.id),
333+
env.DB.prepare("UPDATE resource_changes SET actor_user_id = ? WHERE actor_user_id = ?").bind(userId, existing.id),
334+
]);
335+
};
336+
275337
export const ensureUser = async (
276338
env: Env,
277339
userId: string,
@@ -326,6 +388,8 @@ export const ensureUser = async (
326388
userId,
327389
)
328390
.run();
391+
392+
await reconcileUserIdentityByEmail(env, userId, email);
329393
};
330394

331395
export const fetchUserProfile = async (env: Env, userId: string) => {

0 commit comments

Comments
 (0)