feat: add TOTP multifactor authentication
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
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);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user