Add admin identity module: better-auth, per-app permissions, invitations (#12)
Jenkins Production Deployment
Jenkins Production Deployment
Reviewed-on: #12 Co-authored-by: Patrick Müller <mail@pmueller.me> Co-committed-by: Patrick Müller <mail@pmueller.me>
This commit was merged in pull request #12.
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
import * as dotenv from 'dotenv';
|
||||
import mysql from 'mysql2';
|
||||
import {Kysely, MysqlDialect} from 'kysely';
|
||||
import {AdminDatabase} from './admin.schema.js';
|
||||
import logger from '../../middleware/logger.js';
|
||||
|
||||
dotenv.config();
|
||||
|
||||
/**
|
||||
* The admin module is the one place in this API that does not use the
|
||||
* `mariadb` driver: better-auth talks to the database through Kysely, whose
|
||||
* MySQL dialect expects a mysql2 pool. The other domains keep their own
|
||||
* `mariadb` pools (see Feedback.db.ts) - this is an addition, not a migration.
|
||||
*
|
||||
* The pool is the callback-style `mysql2` one, NOT `mysql2/promise`: Kysely's
|
||||
* MysqlDialect calls `pool.getConnection((err, conn) => ...)`. The promise
|
||||
* wrapper ignores that callback and returns a Promise instead, so every query
|
||||
* through Kysely would hang forever with no error - which is exactly what it
|
||||
* did until the integration tests caught it.
|
||||
*
|
||||
* timezone 'Z' matters: better-auth computes session and token expiry in UTC.
|
||||
* Without it mysql2 would write and read those DATETIMEs in the process's local
|
||||
* zone, so sessions would expire an hour early or late depending on DST.
|
||||
*/
|
||||
|
||||
export namespace NachklangAdminDB {
|
||||
export const pool = mysql.createPool({
|
||||
host: process.env.DB_HOST,
|
||||
user: process.env.DB_USER,
|
||||
password: process.env.DB_PASSWORD,
|
||||
database: process.env.ADMIN_DB,
|
||||
// The other modules' pools default to 3306. This one is configurable so
|
||||
// the integration tests can point at a throwaway container on another
|
||||
// port without touching a developer's real .env.
|
||||
port: parseInt(process.env.DB_PORT || '3306', 10),
|
||||
connectionLimit: 5,
|
||||
timezone: 'Z'
|
||||
});
|
||||
|
||||
// mysql2 emits connection trouble as an event on the pool, not only as a
|
||||
// rejected query. Without a listener Node turns that into an
|
||||
// uncaughtException, so a database restart would take the whole API - and
|
||||
// with it the calendar, feedback and tickets domains - down with it.
|
||||
// Individual queries still reject, and their callers still answer 500.
|
||||
pool.on('error', (err: unknown) => {
|
||||
logger.error('Admin database pool error', {detail: (err as any)?.message});
|
||||
});
|
||||
|
||||
// Handed to better-auth as `database: {dialect, type: 'mysql'}`.
|
||||
export const dialect = new MysqlDialect({pool});
|
||||
|
||||
// Used by this module's own services for the two custom tables and for
|
||||
// permission lookups that join better-auth's `user`.
|
||||
export const db = new Kysely<AdminDatabase>({dialect});
|
||||
}
|
||||
Reference in New Issue
Block a user