From 33e893ec587eeb11cf578c7c9a048001dc8326eb Mon Sep 17 00:00:00 2001 From: Maieul BOYER Date: Wed, 13 Aug 2025 19:15:27 +0200 Subject: [PATCH] feat(wip): ... --- src/@shared/package.json | 1 + src/@shared/src/database/index.ts | 19 ++++++++--------- src/@shared/src/database/init.dbml | 2 +- src/@shared/src/database/init.sql | 18 ++++------------ src/@shared/src/database/mixin/_base.ts | 1 + src/@shared/src/database/mixin/user.ts | 28 ++++++++++++++++++++++--- src/package.json | 4 +++- src/pnpm-workspace.yaml | 5 +++++ 8 files changed, 49 insertions(+), 29 deletions(-) diff --git a/src/@shared/package.json b/src/@shared/package.json index 18fb06d..6a31bd4 100644 --- a/src/@shared/package.json +++ b/src/@shared/package.json @@ -13,6 +13,7 @@ "better-sqlite3": "^11.10.0", "fastify": "^5.0.0", "fastify-plugin": "^5.0.1", + "joi": "^18.0.0", "uuidv7": "^1.0.2" }, "devDependencies": { diff --git a/src/@shared/src/database/index.ts b/src/@shared/src/database/index.ts index 925dd5b..84ff4b2 100644 --- a/src/@shared/src/database/index.ts +++ b/src/@shared/src/database/index.ts @@ -1,5 +1,5 @@ import fp from 'fastify-plugin' -import { FastifyInstance } from 'fastify' +import { FastifyInstance, FastifyPluginAsync } from 'fastify' import { Base } from "./mixin/_base"; import { UserDb } from "./mixin/user"; @@ -18,16 +18,15 @@ declare module 'fastify' { } } -export type DatabaseOption = { - path: string; -}; - -export const useDatabase = fp(async function( +export const useDatabase = fp(async function( f: FastifyInstance, - _options: DatabaseOption) { - f.log.info("Database has been hooked up to fastify ?!"); - f.log.warn("TODO: actually hook up database to fastify..."); - f.decorate('db', new Database(_options.path)); + _options: {}) { + + let path = process.env.DATABASE_DIR; + if (path === null || path === undefined) + throw "env `DATABASE_DIR` not defined"; + f.log.info(`Opening database with path: ${path}/database.db`) + f.decorate('db', new Database(`${path}/database.db`)); }); export default useDatabase; diff --git a/src/@shared/src/database/init.dbml b/src/@shared/src/database/init.dbml index 2fc5971..490b50e 100644 --- a/src/@shared/src/database/init.dbml +++ b/src/@shared/src/database/init.dbml @@ -35,7 +35,7 @@ Table auth { Table session { id integer [PK, not null, increment] - cookie text [PK, unique, not null] + cookie text [unique, not null] userid integer [ref: > user.id, not null] createAt text [not null] userAgent text [not null] diff --git a/src/@shared/src/database/init.sql b/src/@shared/src/database/init.sql index 36f5257..eeabdf2 100644 --- a/src/@shared/src/database/init.sql +++ b/src/@shared/src/database/init.sql @@ -5,28 +5,18 @@ CREATE TABLE IF NOT EXISTS user ( ); CREATE TABLE IF NOT EXISTS auth ( id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, - provider INTEGER NOT NULL, + provider TEXT NOT NULL, user INTEGER NOT NULL, oauth2_user TEXT NOT NULL UNIQUE, - FOREIGN KEY(provider) REFERENCES provider(id), FOREIGN KEY(user) REFERENCES user(id) ); -CREATE TABLE IF NOT EXISTS provider ( - id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, - name TEXT PRIMARY KEY NOT NULL, - displayName TEXT NOT NULL, - secret TEXT NOT NULL, - token_url TEXT NOT NULL, - auth_url TEXT NOT NULL, - me_url TEXT NOT NULL -); CREATE TABLE IF NOT EXISTS session ( id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, - cookie TEXT PRIMARY KEY NOT NULL UNIQUE, + cookie TEXT NOT NULL UNIQUE, userid INTEGER NOT NULL, createAt TEXT NOT NULL, userAgent TEXT NOT NULL, reason INTEGER, - FOREIGN KEY(userid) REFERENCES user(id), - FOREIGN KEY(reason) REFERENCES provider(id) + FOREIGN KEY(userid) REFERENCES user(id) ); + diff --git a/src/@shared/src/database/mixin/_base.ts b/src/@shared/src/database/mixin/_base.ts index 959c3e3..a82056d 100644 --- a/src/@shared/src/database/mixin/_base.ts +++ b/src/@shared/src/database/mixin/_base.ts @@ -10,6 +10,7 @@ export type MixinBase = new (...args: any[]) => { db: sqlite.Database, } & T; +export type SqliteReturn = object | undefined; // Only way to use the database. Everything must be done through this. // Prefer to use prepared statement `using this.db.prepare` diff --git a/src/@shared/src/database/mixin/user.ts b/src/@shared/src/database/mixin/user.ts index 26f14b9..4738a35 100644 --- a/src/@shared/src/database/mixin/user.ts +++ b/src/@shared/src/database/mixin/user.ts @@ -1,8 +1,16 @@ //import sqlite from "better-sqlite3" -import { MixinBase } from "./_base" +import Joi from "joi" +import { MixinBase, SqliteReturn } from "./_base" // never use this directly +const schema = Joi.object({ + id: Joi.number(), + name: Joi.string(), + password: Joi.string().optional().allow(null), + salt: Joi.string().optional().allow(null), +}) + export const UserDb = function (Base: TBase) { return class extends Base { @@ -13,15 +21,29 @@ export const UserDb = function (Base: TBase) { } private userFromRow(row: any): User { - throw "TODO: User from Row" + const v = Joi.attempt(row, schema); + return { + id: v.id as UserId, + name: v.name || null, + password: v.password || null, + salt: v.salt, + } } public getUser(id: UserId): User | null { - return null + return this.getUserFromRawId(id); } + + public getUserFromRawId(id: number): User | null { + let res = this.prepare('SELECT * FROM user WHERE id = ?').get(id) as SqliteReturn; + if (res === null || res === undefined) return null; + return this.userFromRow(res); + } + public setUser(id: UserId, partialUser: Partial>): User | null { return null } + } } diff --git a/src/package.json b/src/package.json index 4a833ee..7676ba3 100644 --- a/src/package.json +++ b/src/package.json @@ -14,6 +14,8 @@ }, "devDependencies": { "rimraf": "^5.0.1" + }, + "dependencies": { + "bindings": "^1.5.0" } } - diff --git a/src/pnpm-workspace.yaml b/src/pnpm-workspace.yaml index e485db3..44e6126 100644 --- a/src/pnpm-workspace.yaml +++ b/src/pnpm-workspace.yaml @@ -2,3 +2,8 @@ packages: - ./* nodeLinker: hoisted + +onlyBuiltDependencies: + - better-sqlite3 + - esbuild + - sharp