diff --git a/.env.example b/.env.example index 304a913..f6d25ac 100644 --- a/.env.example +++ b/.env.example @@ -11,7 +11,8 @@ GRAPH_PORT=3000 ELK_PORT=5601 -GOOGLE_CALLBACK_URL=https://localhost:8443/api/v1 +# the url to which the user will be redirected when it logs with google +CALLBACK_REDIR=http://localhost:3000 GOOGLE_CLIENT_SECRET=susAF GOOGLE_CLIENT_ID=Really @@ -25,4 +26,6 @@ SMTP_AUTH_USERNAME= SMTP_AUTH_PASSWORD= EMAIL_TO= +USER_URL= +AUTH_URL= CORS_ORIGIN= diff --git a/doc/auth/logout.md b/doc/auth/logout.md new file mode 100644 index 0000000..98b6edc --- /dev/null +++ b/doc/auth/logout.md @@ -0,0 +1,24 @@ +# Logout + +Available endpoints: +- GET `/logout` + +Common return: +- 500 with response +```json +{ + "error": "Internal server error" +} +``` + +## GET `/logout` + +Used to logout the client (it just delete the cookie) + +Returns: +- 200 with response and clear cookie +```json +{ + "msg": "Logout successful" +} +``` diff --git a/doc/auth/me.md b/doc/auth/me.md index 4c907e2..26a2e15 100644 --- a/doc/auth/me.md +++ b/doc/auth/me.md @@ -3,3 +3,9 @@ GET `/me` Inputs : just need the JWT cookie Returns the user of the account + +``` +{ + user: ":userId" +} +``` diff --git a/docker/api-base/compose.yml b/docker/api-base/compose.yml index fa6d469..bed06c8 100644 --- a/docker/api-base/compose.yml +++ b/docker/api-base/compose.yml @@ -30,7 +30,7 @@ services: - back environment: - TZ=Europe/Paris - - GOOGLE_CALLBACK_URL=${GOOGLE_CALLBACK_URL} + - GOOGLE_CALLBACK_URL=${AUTH_URL} - GOOGLE_CLIENT_ID=${GOOGLE_CLIENT_ID} - GOOGLE_CLIENT_SECRET=${GOOGLE_CLIENT_SECRET} - API_TARGET=auth diff --git a/docker/front/Dockerfile b/docker/front/Dockerfile index b8f2ce2..36fc0e5 100644 --- a/docker/front/Dockerfile +++ b/docker/front/Dockerfile @@ -13,6 +13,9 @@ RUN cd /build \ FROM node:lts-alpine AS builder-vite +ARG VITE_USER_URL +ARG VITE_AUTH_URL + RUN npm install -g pnpm WORKDIR /app @@ -24,8 +27,8 @@ RUN pnpm install --frozen-lockfile COPY vite.config.js tailwind.config.js ./ COPY src ./src -RUN pnpm vite build - +RUN VITE_USER_URL=${VITE_USER_URL} VITE_AUTH_URL=${VITE_AUTH_URL}\ + pnpm vite build FROM alpine:3.22 diff --git a/docker/front/compose.yml b/docker/front/compose.yml index 72b2b67..134b29d 100644 --- a/docker/front/compose.yml +++ b/docker/front/compose.yml @@ -4,6 +4,9 @@ services: build: dockerfile: docker/front/Dockerfile context: ../../ + args: + - VITE_USER_URL=${USER_URL} + - VITE_AUTH_URL=${AUTH_URL} environment: - TZ=Europe/Paris networks: diff --git a/src/api/auth/default.js b/src/api/auth/default.js index 63b9888..56ebf62 100644 --- a/src/api/auth/default.js +++ b/src/api/auth/default.js @@ -11,6 +11,7 @@ import { gRegisterCallback } from './gRegisterCallback.js'; import { totpSetup } from './totpSetup.js'; import { totpDelete } from './totpDelete.js'; import { totpVerify } from './totpVerify.js'; +import { logout } from './logout.js'; const saltRounds = 10; export const appName = process.env.APP_NAME || 'knl_meowscendence'; @@ -114,4 +115,6 @@ export default async function(fastify, options) { } } }, async (request, reply) => { return register(request, reply, saltRounds, fastify); }); + + fastify.get('/logout', {}, async (request, reply) => { return logout(reply, fastify); }) } diff --git a/src/api/auth/gLogCallback.js b/src/api/auth/gLogCallback.js index 975b7d6..6b3c78b 100644 --- a/src/api/auth/gLogCallback.js +++ b/src/api/auth/gLogCallback.js @@ -37,7 +37,7 @@ export async function gLogCallback(request, reply, fastify) { return reply.code(400).send({ error: "User does not exist" }); } - const token = fastify.jwt.sign(user); + const token = fastify.jwt.sign({ user: user.username}); return reply .setCookie('token', token, { @@ -45,9 +45,7 @@ export async function gLogCallback(request, reply, fastify) { path: '/', secure: env !== 'development', sameSite: 'lax', - }) - .code(200) - .send({ msg: "Login successful" }); + }).redirect(process.env.CALLBACK_REDIR); } catch (error) { fastify.log.error(error); reply.code(500).send({ error: 'Internal server error' }); diff --git a/src/api/auth/gRegisterCallback.js b/src/api/auth/gRegisterCallback.js index f79542f..217fae5 100644 --- a/src/api/auth/gRegisterCallback.js +++ b/src/api/auth/gRegisterCallback.js @@ -1,6 +1,7 @@ import axios from 'axios' import authDB from '../../utils/authDB.js'; +import { authUserCreate } from '../../utils/authUserCreate.js'; var env = process.env.NODE_ENV || 'development'; @@ -46,7 +47,9 @@ export async function gRegisterCallback(request, reply, fastify) { authDB.addUser(user.username, ''); - const token = fastify.jwt.sign(user); + authUserCreate(user.username, fastify) + + const token = fastify.jwt.sign({ user: user.username}); return reply .setCookie('token', token, { @@ -54,9 +57,7 @@ export async function gRegisterCallback(request, reply, fastify) { path: '/', secure: env !== 'development', sameSite: 'lax', - }) - .code(200) - .send({ msg: "Register successful" }); + }).redirect(process.env.CALLBACK_REDIR); } catch (error) { fastify.log.error(error); reply.code(500).send({ error: 'Internal server error' }); diff --git a/src/api/auth/logout.js b/src/api/auth/logout.js new file mode 100644 index 0000000..b3c57ef --- /dev/null +++ b/src/api/auth/logout.js @@ -0,0 +1,18 @@ +/** + * @async + * @param {import("fastify").FastifyReply} reply + * @param {import("fastify").FastifyInstance} fastify + * + * @returns {import("fastify").FastifyReply} + */ +export async function logout(reply, fastify) { + try { + return reply + .code(200) + .clearCookie("token") + .send({ msg: "Logout successful" }); + } catch { + fastify.log.error(err); + return reply.code(500).send({ error: "Internal server error" }); + } +} diff --git a/src/api/auth/register.js b/src/api/auth/register.js index 7463452..5e10ff1 100644 --- a/src/api/auth/register.js +++ b/src/api/auth/register.js @@ -2,6 +2,7 @@ import bcrypt from 'bcrypt'; import { isValidString } from '../../utils/authUtils.js'; import authDB from '../../utils/authDB.js'; +import { authUserCreate } from '../../utils/authUserCreate.js'; var env = process.env.NODE_ENV || 'development'; @@ -36,6 +37,8 @@ export async function register(request, reply, saltRounds, fastify) { const hash = await bcrypt.hash(password, saltRounds); authDB.addUser(user, hash); + authUserCreate(user, fastify) + const token = fastify.jwt.sign({ user }); return reply diff --git a/src/utils/authUserCreate.js b/src/utils/authUserCreate.js new file mode 100644 index 0000000..e8a6771 --- /dev/null +++ b/src/utils/authUserCreate.js @@ -0,0 +1,24 @@ +import axios from 'axios'; + +/** + * @param {string} username + * @param {import('fastify').FastifyInstance} fastify + */ +export async function authUserCreate(username, fastify) { + const payload = { + displayName: username, + }; + const cookie = fastify.jwt.sign({ user: "admin" }); + + const url = process.env.USER_URL || "http://localhost:3002" + + await axios.post( + url + "/users/" + username, + payload, + { + headers: { + 'Cookie': 'token=' + cookie, + }, + } + ); +}