67 lines
2.1 KiB
TypeScript
67 lines
2.1 KiB
TypeScript
import { randomUUID } from 'node:crypto'
|
|
import Database from 'better-sqlite3'
|
|
import { config } from './config.js'
|
|
|
|
// better-auth scrypt hash for the password "test" (salt:hash, self-contained).
|
|
// Every e2e user gets this credential so `I login as "<email>"` works.
|
|
export const TEST_PASSWORD = 'test'
|
|
const TEST_PASSWORD_HASH =
|
|
'0b27de3eeeab546bf7bce4a94511417b:9f68ffc9cd63e21104cd033699ac9c695ddcb4cb982ea30def1b12751de1012aa12de46cd17c1e4c79276299dc8498e7d177ee59156ab7833d1d026e9d9647b6'
|
|
|
|
/** Open a short-lived connection to the e2e SQLite file the backend serves. */
|
|
export function openDb(): Database.Database {
|
|
const db = new Database(config.dbFile)
|
|
db.pragma('foreign_keys = ON')
|
|
db.pragma('busy_timeout = 5000')
|
|
return db
|
|
}
|
|
|
|
/**
|
|
* Ensure a better-auth user exists with the given roles and a credential
|
|
* account (password "test"). Idempotent — updates roles if the user exists.
|
|
* Returns the user id.
|
|
*/
|
|
export function ensureUser(email: string, roles: string[] = []): string {
|
|
const db = openDb()
|
|
try {
|
|
const existing = db
|
|
.prepare('SELECT id FROM user WHERE email = ?')
|
|
.get(email) as { id: string } | undefined
|
|
|
|
if (existing) {
|
|
db.prepare('UPDATE user SET member_roles = ? WHERE id = ?').run(
|
|
JSON.stringify(roles),
|
|
existing.id
|
|
)
|
|
return existing.id
|
|
}
|
|
|
|
const id = randomUUID()
|
|
db.prepare(
|
|
`INSERT INTO user (id, email, name, display_name, email_verified, member_roles)
|
|
VALUES (?, ?, ?, ?, 1, ?)`
|
|
).run(id, email, email, email, JSON.stringify(roles))
|
|
db.prepare(
|
|
`INSERT INTO account (id, account_id, provider_id, user_id, password)
|
|
VALUES (?, ?, 'credential', ?, ?)`
|
|
).run(randomUUID(), id, id, TEST_PASSWORD_HASH)
|
|
return id
|
|
} finally {
|
|
db.close()
|
|
}
|
|
}
|
|
|
|
/** Look up a user id by email. Throws if not found. */
|
|
export function getUserId(email: string): string {
|
|
const db = openDb()
|
|
try {
|
|
const row = db
|
|
.prepare('SELECT id FROM user WHERE email = ?')
|
|
.get(email) as { id: string } | undefined
|
|
if (!row) throw new Error(`User ${email} not found in e2e DB`)
|
|
return row.id
|
|
} finally {
|
|
db.close()
|
|
}
|
|
}
|