From 998d7255287a4ffd9999448b0ae83adab67896df Mon Sep 17 00:00:00 2001 From: florianfederspiel Date: Tue, 6 Jan 2026 21:12:05 +0100 Subject: [PATCH] Fixed Login Allowed Workflows to be public #22 --- frontend/middleware/auth.global.ts | 36 ++++++++--- frontend/stores/auth.ts | 96 +++++++++++++++++++++++------- 2 files changed, 105 insertions(+), 27 deletions(-) diff --git a/frontend/middleware/auth.global.ts b/frontend/middleware/auth.global.ts index c03e09a..2f1c977 100644 --- a/frontend/middleware/auth.global.ts +++ b/frontend/middleware/auth.global.ts @@ -1,20 +1,42 @@ export default defineNuxtRouteMiddleware(async (to, from) => { const auth = useAuthStore() - console.log(auth) + // DEBUG: Was sieht die Middleware wirklich? + console.log("🔒 Middleware Check auf:", to.path) + console.log("👤 User Status:", auth.user ? "Eingeloggt" : "Gast") - if (auth.loading) return + // 1. Ausnahme für Workflows + // WICHTIG: Prüfen ob to.path wirklich mit /workflows beginnt + if (to.path.startsWith('/workflows')) { + console.log("✅ Zugriff erlaubt (Public Route)") + return + } + if (auth.loading) { + console.log("⏳ Auth lädt noch...") + return + } - // Wenn nicht eingeloggt → auf /login (außer er will schon dahin) - if (!auth.user && !["/login", "/password-reset"].includes(to.path)) { + // 2. Wenn nicht eingeloggt + if (!auth.user) { + // Erlaube Zugriff auf Login/Reset Seiten + if (["/login", "/password-reset"].includes(to.path)) { + return + } + + console.log("⛔ Blocked: Not logged in - Redirect to /login") return navigateTo("/login") } - // Wenn eingeloggt → von /login auf /dashboard umleiten - if (auth.user && !auth.user?.must_change_password && to.path === "/login") { + // 3. Wenn eingeloggt + if (to.path === "/login") { + if (auth.user.must_change_password) { + return navigateTo("/password-change") + } return navigateTo("/") - } else if(auth.user && auth.user.must_change_password && to.path !== "/password-change") { + } + + if (auth.user.must_change_password && to.path !== "/password-change") { return navigateTo("/password-change") } }) \ No newline at end of file diff --git a/frontend/stores/auth.ts b/frontend/stores/auth.ts index 732a6f9..308831e 100644 --- a/frontend/stores/auth.ts +++ b/frontend/stores/auth.ts @@ -24,12 +24,28 @@ export const useAuthStore = defineStore("auth", { async initStore() { console.log("Auth initStore") - await this.fetchMe() + // 1. Check: Haben wir überhaupt ein Token? + const token = useCookie("token").value + + /*if (!token) { + // Kein Token -> Wir sind fertig, User ist Gast. + this.user = null + this.loading = false + return + }*/ + + // 2. Token existiert -> Versuche User zu laden + await this.fetchMe(token) + + // Wenn fetchMe fertig ist (egal ob Erfolg oder Fehler), ladebalken weg + + + // Optional: Wenn eingeloggt, leite zur Home, falls gewünscht if(this.activeTenant > 0) { this.loading = false - - navigateTo("/") + // Hier vorsichtig sein: Nicht navigieren, wenn der User auf eine Deep-Link URL will! + // navigateTo("/") <-- Das würde ich hier evtl. sogar weglassen und der Middleware überlassen } }, @@ -39,7 +55,7 @@ export const useAuthStore = defineStore("auth", { const tempStore = useTempStore() - if(this.profile.temp_config) tempStore.setStoredTempConfig(this.profile.temp_config) + if(this.profile?.temp_config) tempStore.setStoredTempConfig(this.profile.temp_config) if(this.activeTenant > 0) { this.loading = false @@ -54,12 +70,34 @@ export const useAuthStore = defineStore("auth", { method: "POST", body: { email, password } }) + console.log("Token: " + token) + + // 1. WICHTIG: Token sofort ins Cookie schreiben, damit es persistiert wird + const tokenCookie = useCookie("token") + tokenCookie.value = token + + // 2. User Daten laden await this.fetchMe(token) + + console.log(this.user) + + // 3. WICHTIG: Jetzt explizit weiterleiten! + // Prüfen, ob der User geladen wurde + if (this.user) { + // Falls Passwort-Änderung erzwungen wird (passend zu deiner Middleware) + if (this.user.must_change_password) { + return navigateTo("/password-change") + } + + // Normaler Login -> Dashboard + return navigateTo("/") + } + } catch (e) { console.log("login error:" + e) + // Hier könnte man noch eine Fehlermeldung im UI anzeigen } - }, async logout() { @@ -67,31 +105,44 @@ export const useAuthStore = defineStore("auth", { try { await useNuxtApp().$api("/auth/logout", { method: "POST" }) } catch (e) { - console.error("Logout fehlgeschlagen:", e) + console.error("Logout API fehlgeschlagen (egal):", e) } + + // State resetten + this.resetState() + + // Token löschen + useCookie("token").value = null + + // Nur beim expliziten Logout navigieren wir + navigateTo("/login") + }, + + resetState() { this.user = null this.permissions = [] this.profile = null this.activeTenant = null this.tenants = [] - - useCookie("token").value = null - - - navigateTo("/login") + this.activeTenantData = null }, async fetchMe(jwt= null) { console.log("Auth fetchMe") const tempStore = useTempStore() + // Token aus Argument oder Cookie holen + const tokenToUse = jwt || useCookie("token").value + try { const me = await useNuxtApp().$api("/api/me", { - headers: { Authorization: `Bearer ${jwt}`, - context: { - jwt - }} + headers: { + Authorization: `Bearer ${tokenToUse}`, + context: { jwt: tokenToUse } + } }) + + // ... (Deine Logik für tenants, sorting etc. bleibt gleich) ... console.log(me) this.user = me.user this.permissions = me.permissions @@ -104,19 +155,24 @@ export const useAuthStore = defineStore("auth", { this.profile = me.profile - if(this.profile.temp_config) tempStore.setStoredTempConfig(this.profile.temp_config) + if(this.profile?.temp_config) tempStore.setStoredTempConfig(this.profile.temp_config) if(me.activeTenant > 0) { this.activeTenant = me.activeTenant this.activeTenantData = me.tenants.find(i => i.id === me.activeTenant) - - } else { - } + console.log(this) } catch (err: any) { - if (err?.response?.status === 401) this.logout() + // WICHTIG: Hier NICHT this.logout() aufrufen, weil das navigiert! + console.log("fetchMe failed (Invalid Token or Network)", err) + + // Stattdessen nur den State sauber machen und Token löschen + this.resetState() + useCookie("token").value = null + + // Wir werfen den Fehler nicht weiter, damit initStore normal durchläuft } },