import { execFile } from 'node:child_process'; import { promisify } from 'node:util'; import { mkdtemp, readFile, rm } from 'node:fs/promises'; import { tmpdir } from 'node:os'; import { join } from 'node:path'; import { afterEach, describe, expect, it } from 'vitest'; import { connect, type Database } from '@tursodatabase/database'; import { isFullAdministrator } from '../src/lib/server/auth/bootstrap'; const run = promisify(execFile); let directory: string | undefined; let database: Database | undefined; afterEach(async () => { await database?.close(); if (directory) await rm(directory, { recursive: true, force: true }); database = undefined; directory = undefined; }); describe('legacy administrator migration', () => { it('moves legacy administrator rows to role-admin and is repeatable', async () => { directory = await mkdtemp(join(tmpdir(), 'shd-admin-migration-')); const databasePath = join(directory, 'database.db'); database = await connect(databasePath); await database.exec(await readFile('database/schema.sql', 'utf8')); await ( await database.prepare( "INSERT INTO users(id,username,role,created_at) VALUES('legacy-admin','legacy','admin',?)", ) ).run(new Date().toISOString()); await database.close(); database = undefined; const environment = { ...process.env, TDR_DATABASE_PATH: databasePath, SKIP_DEFAULT_USERS: 'true', }; await run(process.execPath, ['scripts/db-migrate.mjs'], { cwd: process.cwd(), env: environment, }); database = await connect(databasePath); let user = await ( await database.prepare('SELECT role FROM users WHERE id=?') ).get('legacy-admin'); let relationship = await ( await database.prepare( 'SELECT role_id FROM user_roles WHERE user_id=? AND role_id=?', ) ).get('legacy-admin', 'role-admin'); expect(user.role).toBe('user'); expect(relationship.role_id).toBe('role-admin'); await database.close(); database = undefined; await run(process.execPath, ['scripts/db-migrate.mjs'], { cwd: process.cwd(), env: environment, }); database = await connect(databasePath); user = await ( await database.prepare('SELECT role FROM users WHERE id=?') ).get('legacy-admin'); relationship = await ( await database.prepare( 'SELECT COUNT(*) AS count FROM user_roles WHERE user_id=? AND role_id=?', ) ).get('legacy-admin', 'role-admin'); expect(user.role).toBe('user'); expect(Number(relationship.count)).toBe(1); expect(await isFullAdministrator(database, 'legacy-admin')).toBe(true); await ( await database.prepare( 'DELETE FROM user_roles WHERE user_id=? AND role_id=?', ) ).run('legacy-admin', 'role-admin'); expect(await isFullAdministrator(database, 'legacy-admin')).toBe(false); }); });