125 lines
3.4 KiB
JavaScript
125 lines
3.4 KiB
JavaScript
/**
|
|
* Auth Feature - Database
|
|
* Creates and drops zen_auth_* tables.
|
|
*/
|
|
|
|
import { query, tableExists } from '@zen/core/database';
|
|
import { done, warn } from '@zen/core/shared/logger';
|
|
import { createTables as createUserCoreTables, dropTables as dropUserCoreTables } from '../../core/users/db.js';
|
|
|
|
const AUTH_TABLES = [
|
|
{
|
|
name: 'zen_auth_users',
|
|
sql: `
|
|
CREATE TABLE zen_auth_users (
|
|
id text NOT NULL PRIMARY KEY,
|
|
name text NOT NULL,
|
|
email text NOT NULL UNIQUE,
|
|
email_verified boolean NOT NULL DEFAULT false,
|
|
image text,
|
|
created_at timestamptz DEFAULT CURRENT_TIMESTAMP NOT NULL,
|
|
updated_at timestamptz DEFAULT CURRENT_TIMESTAMP NOT NULL,
|
|
role text DEFAULT 'user' CHECK (role IN ('admin', 'user'))
|
|
)
|
|
`
|
|
},
|
|
{
|
|
name: 'zen_auth_sessions',
|
|
sql: `
|
|
CREATE TABLE zen_auth_sessions (
|
|
id text NOT NULL PRIMARY KEY,
|
|
expires_at timestamptz NOT NULL,
|
|
token text NOT NULL UNIQUE,
|
|
created_at timestamptz DEFAULT CURRENT_TIMESTAMP NOT NULL,
|
|
updated_at timestamptz NOT NULL,
|
|
ip_address text,
|
|
user_agent text,
|
|
user_id text NOT NULL REFERENCES zen_auth_users (id) ON DELETE CASCADE
|
|
)
|
|
`
|
|
},
|
|
{
|
|
name: 'zen_auth_accounts',
|
|
sql: `
|
|
CREATE TABLE zen_auth_accounts (
|
|
id text NOT NULL PRIMARY KEY,
|
|
account_id text NOT NULL,
|
|
provider_id text NOT NULL,
|
|
user_id text NOT NULL REFERENCES zen_auth_users (id) ON DELETE CASCADE,
|
|
access_token text,
|
|
refresh_token text,
|
|
id_token text,
|
|
access_token_expires_at timestamptz,
|
|
refresh_token_expires_at timestamptz,
|
|
scope text,
|
|
password text,
|
|
created_at timestamptz DEFAULT CURRENT_TIMESTAMP NOT NULL,
|
|
updated_at timestamptz NOT NULL
|
|
)
|
|
`
|
|
},
|
|
{
|
|
name: 'zen_auth_verifications',
|
|
sql: `
|
|
CREATE TABLE zen_auth_verifications (
|
|
id text NOT NULL PRIMARY KEY,
|
|
identifier text NOT NULL,
|
|
value text NOT NULL,
|
|
token text NOT NULL,
|
|
expires_at timestamptz NOT NULL,
|
|
created_at timestamptz DEFAULT CURRENT_TIMESTAMP NOT NULL,
|
|
updated_at timestamptz DEFAULT CURRENT_TIMESTAMP NOT NULL
|
|
)
|
|
`
|
|
}
|
|
];
|
|
|
|
/**
|
|
* Create all authentication tables.
|
|
* @returns {Promise<{ created: string[], skipped: string[] }>}
|
|
*/
|
|
export async function createTables() {
|
|
const created = [];
|
|
const skipped = [];
|
|
|
|
for (const table of AUTH_TABLES) {
|
|
const exists = await tableExists(table.name);
|
|
|
|
if (!exists) {
|
|
await query(table.sql);
|
|
created.push(table.name);
|
|
done(`Created table: ${table.name}`);
|
|
} else {
|
|
skipped.push(table.name);
|
|
}
|
|
}
|
|
|
|
// Create role/permission tables and seed defaults
|
|
const coreResult = await createUserCoreTables();
|
|
created.push(...coreResult.created);
|
|
skipped.push(...coreResult.skipped);
|
|
|
|
return { created, skipped };
|
|
}
|
|
|
|
/**
|
|
* Drop all authentication tables in reverse dependency order.
|
|
* @returns {Promise<void>}
|
|
*/
|
|
export async function dropTables() {
|
|
const dropOrder = [...AUTH_TABLES].reverse().map(t => t.name);
|
|
|
|
warn('Dropping all Zen authentication tables...');
|
|
|
|
for (const tableName of dropOrder) {
|
|
const exists = await tableExists(tableName);
|
|
if (exists) {
|
|
await query(`DROP TABLE IF EXISTS "${tableName}" CASCADE`);
|
|
done(`Dropped table: ${tableName}`);
|
|
}
|
|
}
|
|
|
|
await dropUserCoreTables();
|
|
done('All authentication tables dropped');
|
|
}
|