Init
This commit is contained in:
@@ -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')
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -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 = () => {
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -149,3 +149,26 @@ pub async fn require_auth(req: Request<Body>, 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<Body>, next: Next) -> Response {
|
||||
let user_opt = req
|
||||
.extensions()
|
||||
.get::<RequestContext>()
|
||||
.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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user