wip(auth): WIP
This commit is contained in:
parent
c5dbfcad6e
commit
baf9dc54c6
5 changed files with 79 additions and 35 deletions
|
|
@ -1,26 +1,27 @@
|
||||||
// ************************************************************************** //
|
|
||||||
// //
|
|
||||||
// ::: :::::::: //
|
|
||||||
// index.ts :+: :+: :+: //
|
|
||||||
// +:+ +:+ +:+ //
|
|
||||||
// By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ //
|
|
||||||
// +#+#+#+#+#+ +#+ //
|
|
||||||
// Created: 2025/07/28 17:36:22 by maiboyer #+# #+# //
|
|
||||||
// Updated: 2025/08/03 13:36:25 by maiboyer ### ########.fr //
|
|
||||||
// //
|
|
||||||
// ************************************************************************** //
|
|
||||||
|
|
||||||
import fp from 'fastify-plugin'
|
import fp from 'fastify-plugin'
|
||||||
import { FastifyInstance } from 'fastify'
|
import { FastifyInstance } from 'fastify'
|
||||||
import sqlite from 'better-sqlite3'
|
import sqlite from 'better-sqlite3'
|
||||||
|
|
||||||
|
// @ts-ignore: this file is included using vite, typescript doesn't know how to include this...
|
||||||
import initSql from "./init.sql?raw"
|
import initSql from "./init.sql?raw"
|
||||||
import { newUUIDv7, UUIDv7 } from '@shared/uuid'
|
|
||||||
|
|
||||||
|
/**
|
||||||
export class DBUserExists extends Error {
|
* represent a unique user (by its ID.)
|
||||||
public readonly type = 'db-user-exists';
|
* Having this means that the user does exist (aka it hasn't been deleted)
|
||||||
}
|
*/
|
||||||
|
export type UserID = number & { readonly __brand: unique symbol };
|
||||||
|
/**
|
||||||
|
* The full representation of an user
|
||||||
|
*
|
||||||
|
* @property id [UserID]: The id of the user (unique)
|
||||||
|
* @property name [string]: The username of the user (unique)
|
||||||
|
* @property password [?string]: The password hash of the user (if password is defined)
|
||||||
|
*/
|
||||||
|
export type DbUser = {
|
||||||
|
readonly id: UserID,
|
||||||
|
readonly name: string,
|
||||||
|
readonly password: string | null,
|
||||||
|
};
|
||||||
|
|
||||||
// Only way to use the database. Everything must be done through this.
|
// Only way to use the database. Everything must be done through this.
|
||||||
// Prefer to use prepared statement `using this.db.prepare`
|
// Prefer to use prepared statement `using this.db.prepare`
|
||||||
|
|
@ -28,6 +29,7 @@ export class Database {
|
||||||
private db: sqlite.Database;
|
private db: sqlite.Database;
|
||||||
private st: Map<string, sqlite.Statement> = new Map();
|
private st: Map<string, sqlite.Statement> = new Map();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new instance of the database, and init it to a known state
|
* Create a new instance of the database, and init it to a known state
|
||||||
* the file ./init.sql will be ran onto the database, creating any table that might be missing
|
* the file ./init.sql will be ran onto the database, creating any table that might be missing
|
||||||
|
|
@ -66,6 +68,10 @@ export class Database {
|
||||||
this.st.set(query, st);
|
this.st.set(query, st);
|
||||||
return st;
|
return st;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getUser(user: UserID): DbUser {
|
||||||
|
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// When using .decorate you have to specify added properties for Typescript
|
// When using .decorate you have to specify added properties for Typescript
|
||||||
|
|
@ -79,11 +85,12 @@ export type DatabaseOption = {
|
||||||
path: string;
|
path: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const uDatabase = fp<DatabaseOption>(async function(
|
export const useDatabase = fp<DatabaseOption>(async function(
|
||||||
_fastify: FastifyInstance,
|
f: FastifyInstance,
|
||||||
_options: DatabaseOption) {
|
_options: DatabaseOption) {
|
||||||
console.log("Database has been hooked up to fastify ?!");
|
f.log.info("Database has been hooked up to fastify ?!");
|
||||||
|
f.log.warn("TODO: actually hook up database to fastify...");
|
||||||
});
|
});
|
||||||
|
|
||||||
export default uDatabase;
|
export default useDatabase;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ Table user {
|
||||||
|
|
||||||
Table auth {
|
Table auth {
|
||||||
id integer [PK, not null, increment]
|
id integer [PK, not null, increment]
|
||||||
provider integer [ref: > provider.id, not null]
|
provider text [not null]
|
||||||
user integer [ref: > user.id, not null]
|
user integer [ref: > user.id, not null]
|
||||||
oauth2_user text [not null, unique, Note: '''
|
oauth2_user text [not null, unique, Note: '''
|
||||||
This makes sure that an oauth2 login is the always the same `user`
|
This makes sure that an oauth2 login is the always the same `user`
|
||||||
|
|
@ -33,25 +33,13 @@ Table auth {
|
||||||
''']
|
''']
|
||||||
}
|
}
|
||||||
|
|
||||||
Table provider {
|
|
||||||
id integer [PK, not null, increment]
|
|
||||||
name text [PK, 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]
|
|
||||||
|
|
||||||
Note: "Oauth2 Providers"
|
|
||||||
}
|
|
||||||
|
|
||||||
Table session {
|
Table session {
|
||||||
id integer [PK, not null, increment]
|
id integer [PK, not null, increment]
|
||||||
cookie text [PK, unique, not null]
|
cookie text [PK, unique, not null]
|
||||||
userid integer [ref: > user.id, not null]
|
userid integer [ref: > user.id, not null]
|
||||||
createAt text [not null]
|
createAt text [not null]
|
||||||
userAgent text [not null]
|
userAgent text [not null]
|
||||||
reason integer [null, ref: > provider.id]
|
reason integer [null]
|
||||||
|
|
||||||
Note: "Every session for users"
|
Note: "Every session for users"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
7
src/@shared/src/database/users.ts
Normal file
7
src/@shared/src/database/users.ts
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
import { Database } from "@shared/database";
|
||||||
|
|
||||||
|
export type UserID = Number & { readonly __brand: unique symbol };
|
||||||
|
|
||||||
|
export async function getUser(this: Database, id: UserID) {
|
||||||
|
console.log(this);
|
||||||
|
}
|
||||||
35
src/auth/extra/providers-schema.json
Normal file
35
src/auth/extra/providers-schema.json
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"providers": {
|
||||||
|
"required": [],
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"redirect_url": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"token_url": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"client_id": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"secret_env": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"redirect_url",
|
||||||
|
"token_url",
|
||||||
|
"client_id",
|
||||||
|
"secret_env"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"providers"
|
||||||
|
]
|
||||||
|
}
|
||||||
7
src/auth/extra/providers.toml
Normal file
7
src/auth/extra/providers.toml
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
#:schema ./providers-schema.json
|
||||||
|
|
||||||
|
[providers.42]
|
||||||
|
token_url = "" # which url to use
|
||||||
|
redirect_url = "" # redirect_url
|
||||||
|
client_id = "" # the client_id for the provider
|
||||||
|
secret_env = "" # env containing the secret for the provider
|
||||||
Loading…
Add table
Add a link
Reference in a new issue