Add 'apps/web/' from commit '1e7174fa604b11e7c3983cd8ad01c596f6e77e96'

git-subtree-dir: apps/web
git-subtree-mainline: 068a51b46b
git-subtree-split: 1e7174fa60
This commit is contained in:
2026-08-16 21:42:59 -04:00
350 changed files with 62192 additions and 0 deletions
+82
View File
@@ -0,0 +1,82 @@
import { and, asc, eq, ne, sql } from "drizzle-orm";
import { db } from "~/server/db";
import { users } from "~/server/db/schema";
/** Seeded in drizzle/0014_seed_demo_account.sql for App Store review. */
export const DEMO_USER_EMAIL = "demo@example.com";
export const DEMO_USER_ID = "a0000000-0000-4000-8000-000000000001";
const FIRST_USER_ADMIN_LOCK_KEY = 0x62656e76;
type DbTx = Pick<typeof db, "execute" | "select" | "query" | "update">;
export function isDemoUser(user: {
email?: string | null;
id?: string | null;
}): boolean {
const email = user.email?.toLowerCase();
return email === DEMO_USER_EMAIL || user.id === DEMO_USER_ID;
}
function nonDemoUserConditions() {
return and(ne(users.email, DEMO_USER_EMAIL), ne(users.id, DEMO_USER_ID));
}
async function acquireFirstUserAdminLock(tx: DbTx): Promise<void> {
await tx.execute(
sql`SELECT pg_advisory_xact_lock(${FIRST_USER_ADMIN_LOCK_KEY})`,
);
}
/**
* Role for a user about to be inserted. Call inside a transaction before insert.
*/
export async function resolveNewUserRole(tx: DbTx): Promise<"admin" | "user"> {
await acquireFirstUserAdminLock(tx);
const [result] = await tx
.select({ count: sql<number>`count(*)::int` })
.from(users)
.where(nonDemoUserConditions());
return (result?.count ?? 0) === 0 ? "admin" : "user";
}
/**
* Promote the first non-demo user to admin after Better Auth creates them (OAuth, etc.).
* Safe under concurrent sign-ups: only one non-demo admin is ever assigned.
*/
export async function promoteFirstRealUserIfNeeded(userId: string): Promise<void> {
await db.transaction(async (tx) => {
await acquireFirstUserAdminLock(tx);
const user = await tx.query.users.findFirst({
where: eq(users.id, userId),
columns: { id: true, email: true, role: true },
});
if (!user || isDemoUser(user)) {
return;
}
const [adminResult] = await tx
.select({ count: sql<number>`count(*)::int` })
.from(users)
.where(and(nonDemoUserConditions(), eq(users.role, "admin")));
if ((adminResult?.count ?? 0) > 0) {
return;
}
const [firstRealUser] = await tx
.select({ id: users.id })
.from(users)
.where(nonDemoUserConditions())
.orderBy(asc(users.createdAt))
.limit(1);
if (firstRealUser?.id === userId) {
await tx.update(users).set({ role: "admin" }).where(eq(users.id, userId));
}
});
}