From 3ada54294ec58698043bca71bd5ccd9ecf2dcbdc Mon Sep 17 00:00:00 2001 From: adjoly Date: Mon, 30 Jun 2025 22:51:02 +0200 Subject: [PATCH] =?UTF-8?q?=E3=80=8C=E2=9C=A8=E3=80=8D=20feat:=20working?= =?UTF-8?q?=20/login=20and=20/check=20(only=20for=20testing=20purposes)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 1 + pnpm-lock.yaml | 11 ++++++++ src/api/auth/default.js | 60 +++++++++++++++++++++++++++++++++-------- 3 files changed, 61 insertions(+), 11 deletions(-) diff --git a/package.json b/package.json index cb61f23..05f5b05 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,6 @@ { "dependencies": { + "@fastify/cookie": "^11.0.2", "@fastify/env": "^5.0.2", "@fastify/jwt": "^9.1.0", "@tailwindcss/vite": "^4.1.11", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6361bfb..4394802 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,6 +8,9 @@ importers: .: dependencies: + '@fastify/cookie': + specifier: ^11.0.2 + version: 11.0.2 '@fastify/env': specifier: ^5.0.2 version: 5.0.2 @@ -199,6 +202,9 @@ packages: '@fastify/ajv-compiler@4.0.2': resolution: {integrity: sha512-Rkiu/8wIjpsf46Rr+Fitd3HRP+VsxUFDDeag0hs9L0ksfnwx2g7SPQQTFL0E8Qv+rfXzQOxBJnjUB9ITUDjfWQ==} + '@fastify/cookie@11.0.2': + resolution: {integrity: sha512-GWdwdGlgJxyvNv+QcKiGNevSspMQXncjMZ1J8IvuDQk0jvkzgWWZFNC2En3s+nHndZBGV8IbLwOI/sxCZw/mzA==} + '@fastify/deepmerge@2.0.2': resolution: {integrity: sha512-3wuLdX5iiiYeZWP6bQrjqhrcvBIf0NHbQH1Ur1WbHvoiuTYUEItgygea3zs8aHpiitn0lOB8gX20u1qO+FDm7Q==} @@ -1107,6 +1113,11 @@ snapshots: ajv-formats: 3.0.1(ajv@8.17.1) fast-uri: 3.0.6 + '@fastify/cookie@11.0.2': + dependencies: + cookie: 1.0.2 + fastify-plugin: 5.0.1 + '@fastify/deepmerge@2.0.2': {} '@fastify/env@5.0.2': diff --git a/src/api/auth/default.js b/src/api/auth/default.js index 3be430d..64891c1 100644 --- a/src/api/auth/default.js +++ b/src/api/auth/default.js @@ -1,4 +1,5 @@ import fastifyJWT from '@fastify/jwt'; +import fastifyCookie from '@fastify/cookie'; import sqlite from 'node:sqlite'; import bcrypt from 'bcrypt'; const database = new sqlite.DatabaseSync(':memory:'); @@ -19,7 +20,7 @@ function prepareDB() { prepareDB() const userCheck = database.prepare('SELECT EXISTS (SELECT 1 FROM credentials WHERE username = ?);'); -const userQuery = database.prepare('SELECT username, passwordHash FROM credentials WHERE username = ?;'); +const passwordQuery = database.prepare('SELECT passwordHash FROM credentials WHERE username = ?;'); const userAdd = database.prepare('INSERT INTO credentials (username, passwordHash) VALUES (?, ?)'); /** @@ -47,15 +48,17 @@ export default async function(fastify, options) { fastify.register(fastifyJWT, { secret: '12345', cookie: { - cookieName: 'refreshToken' + cookieName: 'token', }, sign: { expiresIn: '100000m' } }); + fastify.register(fastifyCookie); fastify.decorate("authenticate", async function(request, reply) { try { + fastify.log.info(request.headers.cookie); await request.jwtVerify(); } catch (err) { reply.code(401).send({ error: 'Unauthorized' }); @@ -63,18 +66,53 @@ export default async function(fastify, options) { }); fastify.post('/login', async (request, reply) => { - /** @type {{ user: string, password: string }} */ - const { user, password } = request.body; + try { + /** @type {{ user: string, password: string }} */ + const { user, password } = request.body; + request.headers.cookie + + if (!checkUser(user)) { + return reply.code(400).send({ error: "User does not exist" }); + } + + const query = passwordQuery.get(user); + const hash = query?.passwordHash; + + if (!hash) { + return reply.code(500).send({ error: "Password hash not found" }); + } + + const compare = await bcrypt.compare(password, hash); + + if (!compare) { + return reply.code(401).send({ error: "Incorrect password" }); + } + + const token = fastify.jwt.sign({ user }); + + return reply + .setCookie('token', token, { + httpOnly: true, + path: '/', + secure: false, + sameSite: 'lax', + }) + .code(200) + .send({ msg: "Login successful" }); + } catch (err) { + fastify.log.error(err); + return reply.code(500).send({ error: "Internal server error" }); + } }); fastify.post('/register', async (request, reply) => { try { /** @type {{ username: string, password: string }} */ - const { username, password } = request.body; + const { user, password } = request.body; - if (!isValidString(username) || !isValidString(password)) { + if (!isValidString(user) || !isValidString(password)) { return reply.code(400).send({ error: 'Invalid username or password' }); - } else if (checkUser(username) === true) { + } else if (checkUser(user) === true) { return reply.code(400).send({ error: "User already exist" }); } else if (password.length <= 8) { return reply.code(400).send({ error: "Password too short" }); @@ -83,15 +121,15 @@ export default async function(fastify, options) { } const hash = await bcrypt.hash(password, saltRounds); - userAdd.run(username, hash); + userAdd.run(user, hash); return reply.code(200).send({ msg: 'Register successfuly' }); } catch (err) { fastify.log.error(err); - return reply.code(500).send(); + return reply.code(500).send({ error: "Internal server error" }); } }); - fastify.get('/check', { preHandler: [fastify.authenticate] }, async (request) => { - return reply.code(200).send(); + fastify.get('/check', { preHandler: [fastify.authenticate] }, async (request, reply) => { + return reply.code(200).send({ msg: "workinggg" }); }); }