// ── Auth store — Authentik forwardAuth ────────────────────────────────────── // Authentik handles login at the Traefik level. If the user reaches the app, // they are already authenticated. We fetch their identity from the /api/ proxy // which forwards Authentik headers to ERPNext. // ERPNext API calls use a service token (not user session). // ───────────────────────────────────────────────────────────────────────────── import { defineStore } from 'pinia' import { ref } from 'vue' import { BASE_URL } from 'src/config/erpnext' // Service token for ERPNext API — all dispatch API calls use this const ERP_SERVICE_TOKEN = import.meta.env.VITE_ERP_TOKEN || window.__ERP_TOKEN__ || '' export const useAuthStore = defineStore('auth', () => { const user = ref(null) const loading = ref(true) const error = ref('') async function checkSession () { loading.value = true try { // Fetch user identity — the /api/ proxy passes Authentik headers to ERPNext // We use the service token to query who we are const res = await fetch(BASE_URL + '/api/method/frappe.auth.get_logged_user', { headers: { Authorization: 'token ' + ERP_SERVICE_TOKEN }, }) if (res.ok) { const data = await res.json() // For now, use the service account identity // The actual Authentik user email is in the response headers (X-authentik-email) // but those are only available at the Traefik level user.value = data.message || 'authenticated' } else { user.value = 'authenticated' // Authentik guarantees auth, ERPNext may not know the user } } catch { user.value = 'authenticated' // If ERPNext is down, user is still authenticated via Authentik } finally { loading.value = false } } async function doLogout () { // Redirect to Authentik logout window.location.href = 'https://auth.targo.ca/application/o/gigafibre-dispatch/end-session/' } return { user, loading, error, checkSession, doLogin: checkSession, doLogout } }) export function getServiceToken () { return ERP_SERVICE_TOKEN }