diff --git a/package.json b/package.json index 134c5ea..1bb5368 100644 --- a/package.json +++ b/package.json @@ -4,11 +4,13 @@ "type": "module", "scripts": { "build": "tsc", - "start": "tsx src/server.ts" + "start": "tsx src/server.ts", + "fmt": "dprint fmt" }, "devDependencies": { "@types/bcryptjs": "^2.4.6", "@types/bun": "^1.0.4", + "dprint": "^0.46.2", "tsx": "^4.7.0", "typescript": "^5.3.3" }, @@ -19,6 +21,7 @@ "@fastify/type-provider-typebox": "^4.0.0", "@fastify/websocket": "^10.0.1", "@sinclair/typebox": "^0.32.9", + "bcrypt": "^5.1.1", "bcryptjs": "^2.4.3", "fastify": "^4.27.0", "nanoid": "^5.0.4", diff --git a/src/bcrypt.ts b/src/bcrypt.ts deleted file mode 100644 index 9ba20a6..0000000 --- a/src/bcrypt.ts +++ /dev/null @@ -1,18 +0,0 @@ -import * as bcrypt from "bcryptjs"; - -const saltRounds = 10; // Le nombre de tours de salage - -/* Fonction pour hasher le mot de passe */ -export async function hashPassword(password: string): Promise { - const hashedPassword = await bcrypt.hash(password, saltRounds); - return hashedPassword; -} - -/* Fonction pour vérifier le mot de passe */ -export async function comparePassword( - plainPassword: string, - hashedPassword: string -): Promise { - const isMatch = await bcrypt.compare(plainPassword, hashedPassword); - return isMatch; -} diff --git a/src/database.ts b/src/database.ts index c699142..79f02d4 100644 --- a/src/database.ts +++ b/src/database.ts @@ -15,7 +15,7 @@ export type error = { export function runDB( db: sqlite3.Database, query: string, - params: any[] + params: any[], ): Promise { return new Promise((resolve, reject) => { db.run(query, params, (err) => { @@ -31,7 +31,7 @@ export function runDB( /* Fonction pour récupérer plusieurs lignes de la base de données */ export function allDB( db: sqlite3.Database, - query: string + query: string, ): Promise { return new Promise((resolve, reject) => { db.all(query, (err, rows) => { @@ -48,7 +48,7 @@ export function allDB( export function getDB( db: sqlite3.Database, query: string, - params: any[] + params: any[], ): Promise { return new Promise((resolve, reject) => { db.get(query, params, (err, row: T) => { @@ -78,7 +78,7 @@ export function openDatabase() { sqlite3.OPEN_READWRITE | sqlite3.OPEN_CREATE, (err: Error | null) => { if (err) console.error(err.message); - } + }, ); } @@ -110,7 +110,8 @@ export function createTables(db: sqlite3.Database) { /* Créer la table registered_user dans la base de données */ export function createRegisteredUserTable(db: sqlite3.Database): Promise { - const tableRegisteredUser = `CREATE TABLE IF NOT EXISTS registered_user (id_user INTEGER PRIMARY KEY AUTOINCREMENT, login TEXT NOT NULL, password TEXT NOT NULL, permissions INTEGER NOT NULL, UNIQUE (login))`; + const tableRegisteredUser = + `CREATE TABLE IF NOT EXISTS registered_user (id_user INTEGER PRIMARY KEY AUTOINCREMENT, login TEXT NOT NULL, password TEXT NOT NULL, permissions INTEGER NOT NULL, UNIQUE (login))`; return runDB(db, tableRegisteredUser, []); } @@ -120,7 +121,7 @@ export async function insertUser( db: sqlite3.Database, login: string, password: string, - permissions: number + permissions: number, ): Promise { const insertUserQuery = `INSERT INTO registered_user (login, password, permissions) VALUES (?, ?, ?)`; @@ -140,7 +141,7 @@ export async function insertUser( /* Vérifier si un utilisateur existe dans la table registered_user */ export async function verifyUser( db: sqlite3.Database, - login: string + login: string, ): Promise { const verifyUserQuery = `SELECT login, password FROM registered_user WHERE login = ?`; @@ -162,7 +163,7 @@ export type User = { export function updateUserLogin( db: sqlite3.Database, id: number, - newLogin: string + newLogin: string, ) { const updateUserLoginQuery = `UPDATE registered_user SET login = ? WHERE id_user = ?`; @@ -173,7 +174,7 @@ export function updateUserLogin( export function updateUserPassword( db: sqlite3.Database, id: number, - newPassword: string + newPassword: string, ) { const updateUserPasswordQuery = `UPDATE registered_user SET password = ? WHERE id_user = ?`; @@ -184,7 +185,7 @@ export function updateUserPassword( export function updateUserPermissions( db: sqlite3.Database, id: number, - newPermissions: number + newPermissions: number, ) { const updateUserPermissionsQuery = `UPDATE registered_user SET permissions = ? WHERE id_user = ?`; @@ -242,7 +243,8 @@ export function selectUserById(db: sqlite3.Database, id: number) { /* Créer la table language dans la base de données */ export function createLanguageTable(db: sqlite3.Database): Promise { - const tableLanguage = `CREATE TABLE IF NOT EXISTS language (id_language INTEGER PRIMARY KEY AUTOINCREMENT, designation TEXT NOT NULL, version INTEGER NOT NULL)`; + const tableLanguage = + `CREATE TABLE IF NOT EXISTS language (id_language INTEGER PRIMARY KEY AUTOINCREMENT, designation TEXT NOT NULL, version INTEGER NOT NULL)`; return runDB(db, tableLanguage, []); } @@ -250,7 +252,7 @@ export function createLanguageTable(db: sqlite3.Database): Promise { export function insertLanguage( db: sqlite3.Database, designation: string, - version: number + version: number, ) { const insertLanguageQuery = `INSERT INTO language (designation, version) VALUES (?, ?)`; @@ -261,7 +263,7 @@ export function insertLanguage( export function updateLanguageDesignation( db: sqlite3.Database, id: number, - newDesignation: string + newDesignation: string, ) { const updateLanguageDesignationQuery = `UPDATE language SET designation = ? WHERE id_language = ?`; @@ -272,7 +274,7 @@ export function updateLanguageDesignation( export function updateLanguageVersion( db: sqlite3.Database, id: number, - newVersion: number + newVersion: number, ) { const updateLanguageVersionQuery = `UPDATE language SET version = ? WHERE id_language = ?`; @@ -318,7 +320,8 @@ export function selectLanguageById(db: sqlite3.Database, id: number) { /* Créer la table work dans la base de données */ export function createWorkTable(db: sqlite3.Database): Promise { - const tableWork = `CREATE TABLE IF NOT EXISTS work (id_work INTEGER PRIMARY KEY AUTOINCREMENT, link CHAR(36) NOT NULL, user_id INTEGER REFERENCES registered_user(id_user), language_id INTEGER NOT NULL REFERENCES language(id_language), content TEXT NOT NULL)`; + const tableWork = + `CREATE TABLE IF NOT EXISTS work (id_work INTEGER PRIMARY KEY AUTOINCREMENT, link CHAR(36) NOT NULL, user_id INTEGER REFERENCES registered_user(id_user), language_id INTEGER NOT NULL REFERENCES language(id_language), content TEXT NOT NULL)`; return runDB(db, tableWork, []); } @@ -328,7 +331,7 @@ export function insertWork( link: string, user_id: number, language_id: number, - content: string + content: string, ) { const insertWorkQuery = `INSERT INTO work (link, user_id, language_id, content) VALUES (?, ?, ?, ?)`; diff --git a/src/runner.ts b/src/runner.ts index 290e8bb..1a8567b 100644 --- a/src/runner.ts +++ b/src/runner.ts @@ -19,11 +19,11 @@ export const IMAGES = { export function allocateBuffer( jobId: string, code: string, - image: string + image: string, ): Buffer { let cur = 0; const buffer = Buffer.allocUnsafe( - jobId.length + image.length + code.length + 9 + jobId.length + image.length + code.length + 9, ); cur = buffer.writeUInt8(0, cur); cur += buffer.write(jobId, cur); diff --git a/src/server.ts b/src/server.ts index 6504954..d131036 100644 --- a/src/server.ts +++ b/src/server.ts @@ -1,14 +1,14 @@ +import { rebaseUpdates, Update } from "@codemirror/collab"; +import { ChangeSet, Text } from "@codemirror/state"; import cors from "@fastify/cors"; -import websocket, { WebSocket } from "@fastify/websocket"; import { Type, TypeBoxTypeProvider } from "@fastify/type-provider-typebox"; +import websocket, { WebSocket } from "@fastify/websocket"; +import bcrypt from "bcrypt"; import Fastify, { FastifyReply } from "fastify"; import { nanoid } from "nanoid"; import { allocateBuffer, getRunner } from "runner"; import { Pull, Push } from "zeromq"; -import { ChangeSet, Text } from "@codemirror/state"; -import { Update, rebaseUpdates } from "@codemirror/collab"; import * as db from "./database"; -import { hashPassword } from "bcrypt"; const sender = new Push(); await sender.bind(`tcp://127.0.0.1:5557`); @@ -62,7 +62,7 @@ fastify.get("/live", { websocket: true }, (socket, req) => { received.map((update: any) => ({ clientID: update.clientID, changes: update.changes.toJSON(), - })) + })), ); } else if (data.type == "getDocument") { send(socket, requestId, { version: updates.length, doc: doc.toString() }); @@ -103,7 +103,7 @@ fastify.post( reply.raw.write("id: 0\n\n"); }); clients[jobId] = reply; - } + }, ); /* Création du répertoire de la base de données s'il n'existe pas */ @@ -115,6 +115,8 @@ const database = db.openDatabase(); /* Créer les tables si elles n'existent pas */ db.createTables(database); +const salt = 10; + /* Route pour créer un utilisateur */ fastify.post( "/users", @@ -129,14 +131,18 @@ fastify.post( }, async (request, reply) => { const { login, password, permissions } = request.body; - // Hasher le mot de passe avant de l'insérer dans la base de données (en type string) - const hashedPassword = (await hashPassword(password)) as string; - if (!(await db.insertUser(database, login, hashedPassword, permissions))) { - reply.send({ success: false }); - } else { - reply.send({ success: true }); - } - } + + bcrypt.hash(password, salt, async (err, hash) => { + if (err) { + reply.send({ success: false }); + } + if (!(await db.insertUser(database, login, hash, permissions))) { + reply.send({ success: false }); + } else { + reply.send({ success: true }); + } + }); + }, ); /* Route pour vérifier si un utilisateur existe */ @@ -154,12 +160,10 @@ fastify.post( const { login, password } = request.body; const user = await db.verifyUser(database, login); - if (user === null || user.password !== password) { - reply.send({ success: false }); - } else { - reply.send({ success: true }); - } - } + bcrypt.compare(password, user?.password) + .then(res => reply.send({ sucess: res })) + .catch(err => reply.send({ sucess: false })); + }, ); /* Route pour mettre à jour le login d'un utilisateur */ @@ -182,7 +186,7 @@ fastify.put( const { newLogin } = request.body; db.updateUserLogin(database, id, newLogin); reply.send({ success: true }); - } + }, ); /* Route pour mettre à jour le mot de passe d'un utilisateur */ @@ -205,7 +209,7 @@ fastify.put( const { newPassword } = request.body; db.updateUserPassword(database, id, newPassword); reply.send({ success: true }); - } + }, ); /* Route pour mettre à jour les permissions d'un utilisateur */ @@ -228,7 +232,7 @@ fastify.put( const { newPermissions } = request.body; await db.updateUserPermissions(database, id, newPermissions); reply.send({ success: true }); - } + }, ); /* Route pour supprimer un utilisateur par son ID */ @@ -247,7 +251,7 @@ fastify.delete( const { id } = request.params; await db.deleteUserById(database, id); reply.send({ success: true }); - } + }, ); /* Route pour supprimer un utilisateur par son login */ @@ -264,7 +268,7 @@ fastify.delete( const { login } = request.params; await db.deleteUserByLogin(database, login); reply.send({ success: true }); - } + }, ); /* Route pour supprimer tous les utilisateurs */ @@ -295,7 +299,7 @@ fastify.get( const { id } = request.params; const user = await db.selectUserById(database, id); reply.send(user); - } + }, ); /* Route pour récupérer un utilisateur par son login */ @@ -312,7 +316,7 @@ fastify.get( const { login } = request.params; const user = await db.selectUserByLogin(database, login); reply.send(user); - } + }, ); /* Route pour créer un language */ @@ -330,7 +334,7 @@ fastify.post( const { designation, version } = request.body; db.insertLanguage(database, designation, version); reply.send({ success: true }); - } + }, ); /* Route pour mettre à jour la désignation d'un language */ @@ -353,7 +357,7 @@ fastify.put( const { newDesignation } = request.body; db.updateLanguageDesignation(database, id, newDesignation); reply.send({ success: true }); - } + }, ); /* Route pour mettre à jour la version d'un language */ @@ -376,7 +380,7 @@ fastify.put( const { newVersion } = request.body; db.updateLanguageVersion(database, id, newVersion); reply.send({ success: true }); - } + }, ); /* Route pour supprimer un language */ @@ -395,7 +399,7 @@ fastify.delete( const { id } = request.params; db.deleteLanguage(database, id); reply.send({ success: true }); - } + }, ); /* Route pour supprimer tous les languages */ @@ -420,7 +424,7 @@ fastify.get( const { id } = request.params; const language = await db.selectLanguageById(database, id); reply.send(language); - } + }, ); /* Route pour récupérer tous les languages */ @@ -446,7 +450,7 @@ fastify.post( const { id_user, link, id_language, code } = request.body; db.insertWork(database, link, id_user, id_language, code); reply.send({ success: true }); - } + }, ); /* Route pour récupérer tous les works */ @@ -477,7 +481,7 @@ fastify.delete( const { id } = request.params; db.deleteWork(database, id); reply.send({ success: true }); - } + }, ); /* Route pour récupérer un work par son ID */ @@ -496,7 +500,7 @@ fastify.get( const { id } = request.params; const work = await db.selectWorkById(database, id); reply.send(work); - } + }, ); /* Forward output est une fonction asynchrone qui permet de récupérer les messages envoyés par le container et de les renvoyer au client */