From 5152ec0f7e7e822fc2443e8a660eb1a7f5258ee1 Mon Sep 17 00:00:00 2001 From: Nell Date: Tue, 23 Jun 2026 01:24:22 +0200 Subject: [PATCH] Init --- frontend/src/main.ts | 8 +++++-- frontend/src/stores/app.ts | 39 ++++++++++++++++++++++++++++++++- frontend/src/stores/category.ts | 13 +++++++++-- frontend/src/stores/channel.ts | 9 +++++++- frontend/src/stores/gateway.ts | 3 +++ frontend/src/stores/message.ts | 15 +++++++++++-- frontend/src/stores/server.ts | 9 +++++++- src/http/middleware.rs | 23 +++++++++++++++++++ 8 files changed, 110 insertions(+), 9 deletions(-) diff --git a/frontend/src/main.ts b/frontend/src/main.ts index f898fe4..58f7606 100644 --- a/frontend/src/main.ts +++ b/frontend/src/main.ts @@ -5,19 +5,23 @@ */ // Composables -import { createApp } from 'vue' +import {createApp} from 'vue' // Plugins -import { registerPlugins } from '@/plugins' +import {registerPlugins} from '@/plugins' // Components import App from './App.vue' // Styles import 'unfonts.css' +import {useAppStore} from "@/stores/app.ts"; const app = createApp(App) registerPlugins(app) +const appStore = useAppStore() +appStore.initialize() + app.mount('#app') diff --git a/frontend/src/stores/app.ts b/frontend/src/stores/app.ts index e1f11cb..cd73e53 100644 --- a/frontend/src/stores/app.ts +++ b/frontend/src/stores/app.ts @@ -1,9 +1,46 @@ // Utilities import {defineStore} from 'pinia' +import {useAuthStore} from "@/stores/auth.ts"; +import {useGatewayStore} from "@/stores/gateway.ts"; +import {useServerStore} from "@/stores/server.ts"; +import {useCategoryStore} from "@/stores/category.ts"; +import {useChannelStore} from "@/stores/channel.ts"; export const useAppStore = defineStore('app', { state: () => ({ baseurl: 'http://localhost:8080', }), - actions: {} + actions: { + async initialize() { + const authStore = useAuthStore() + const gatewayStore = useGatewayStore() + const serverStore = useServerStore() + const categoryStore = useCategoryStore() + const channelStore = useChannelStore() + + // Définition du trigger de chargement des données de l'application + const loadAppData = async () => { + try { + await Promise.all([ + serverStore.fetchServers(), + categoryStore.fetchCategories(), + channelStore.fetchChannels() + ]) + } catch (e) { + console.error("Erreur lors du chargement des données initiales :", e) + } + } + + // On s'abonne à l'événement de connexion de la gateway + window.addEventListener('gateway:connected', loadAppData) + + // Initialisation de l'authentification (qui lancera la connexion à la gateway) + await authStore.initialize() + + // Sécurité : si la gateway s'est déjà connectée entre-temps + if (gatewayStore.status === 'connected') { + await loadAppData() + } + } + } }); diff --git a/frontend/src/stores/category.ts b/frontend/src/stores/category.ts index 5a9c760..5070d8f 100644 --- a/frontend/src/stores/category.ts +++ b/frontend/src/stores/category.ts @@ -1,6 +1,15 @@ import {defineStore} from 'pinia' +import {useApi} from "@/composables/useApi.ts"; export const useCategoryStore = defineStore("category", { - state: () => ({}), - actions: {} + state: () => ({ + categories: [] + }), + actions: { + async fetchCategories() { + let api = useApi(); + let response = await api.get("/api/categories"); + this.categories = await response.json(); + } + } }); \ No newline at end of file diff --git a/frontend/src/stores/channel.ts b/frontend/src/stores/channel.ts index bfa569e..cf1125e 100644 --- a/frontend/src/stores/channel.ts +++ b/frontend/src/stores/channel.ts @@ -1,4 +1,5 @@ import {defineStore} from 'pinia' +import {useApi} from "@/composables/useApi.ts"; /* * This file contains the store for channels. * Centralisation des channels de l'ensemble des serveurs pour faciliter l'intéraction depuis les différents éléments du site @@ -7,5 +8,11 @@ export const useChannelStore = defineStore('channel', { state: () => ({ channels: [] }), - actions: {} + actions: { + async fetchChannels() { + let api = useApi(); + let response = await api.get("/api/channels"); + this.channels = await response.json(); + } + } }) \ No newline at end of file diff --git a/frontend/src/stores/gateway.ts b/frontend/src/stores/gateway.ts index a40655b..0decc86 100644 --- a/frontend/src/stores/gateway.ts +++ b/frontend/src/stores/gateway.ts @@ -37,6 +37,9 @@ export const useGatewayStore = defineStore('gateway', { socket.onopen = () => { this.status = 'connected' this.reconnectAttempts = 0 + + // Émission d'un événement global indiquant que la connexion est établie et prête + window.dispatchEvent(new CustomEvent('gateway:connected')) } socket.onclose = () => { diff --git a/frontend/src/stores/message.ts b/frontend/src/stores/message.ts index eb043c4..081d053 100644 --- a/frontend/src/stores/message.ts +++ b/frontend/src/stores/message.ts @@ -1,6 +1,17 @@ import {defineStore} from "pinia"; +import {useApi} from "@/composables/useApi.ts"; export const useMessageStore = defineStore("message", { - state: () => ({}), - actions: {} + state: () => ({ + messages: [] + }), + actions: { + async fetchMessages(channel_id: string) { + // todo : ici, les messages ne doivent pas être tous récupérés. Un filtre doit être appliqué. + // pour ne récupérer que les messages du channel actif + let api = useApi(); + let response = await api.get("/api/messages"); + this.messages = await response.json(); + } + } }); diff --git a/frontend/src/stores/server.ts b/frontend/src/stores/server.ts index c0811df..b4178a4 100644 --- a/frontend/src/stores/server.ts +++ b/frontend/src/stores/server.ts @@ -1,8 +1,15 @@ import {defineStore} from "pinia"; +import {useApi} from "@/composables/useApi.ts"; export const useServerStore = defineStore("server", { state: () => ({ servers: [] }), - actions: {} + actions: { + async fetchServers() { + let api = useApi(); + const response = await api.get("/api/servers"); + this.servers = await response.json(); + } + } }); \ No newline at end of file diff --git a/src/http/middleware.rs b/src/http/middleware.rs index 3f5e9c2..5af2818 100644 --- a/src/http/middleware.rs +++ b/src/http/middleware.rs @@ -149,3 +149,26 @@ pub async fn require_auth(req: Request, next: Next) -> Response { HTTPError::Unauthorized.into_response() } } + +/// Middleware de sécurité qui impose que l'utilisateur soit un Superuser (administrateur). +pub async fn require_superuser(req: Request, next: Next) -> Response { + let user_opt = req + .extensions() + .get::() + .and_then(|ctx| ctx.user.as_ref()); + + match user_opt { + Some(user) if user.is_superuser => { + // L'utilisateur est identifié ET est superuser, on continue + next.run(req).await + } + Some(_) => { + // Utilisateur connecté mais pas administrateur + HTTPError::Forbidden.into_response() + } + None => { + // Pas d'utilisateur authentifié du tout + HTTPError::Unauthorized.into_response() + } + } +}