import { defineStore } from 'pinia' import { type Router } from 'vue-router' interface AuthState { user: User | null isAuthenticated: boolean } interface User { id: number email: string [key: string]: any // Add more fields as needed } export const useAuthStore = defineStore('auth', { state: (): AuthState => { const storedState = localStorage.getItem('authState') return storedState ? JSON.parse(storedState) : { user: null, isAuthenticated: false, } }, actions: { async setCsrfToken(): Promise { await fetch('http://localhost:8000/api/set-csrf-token', { method: 'GET', credentials: 'include', }) }, async login(email: string, password: string, router: Router | null = null): Promise { const response = await fetch('http://localhost:8000/api/login', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-CSRFToken': getCSRFToken(), }, body: JSON.stringify({ email, password, }), credentials: 'include', }) const data = await response.json() if (data.success) { this.isAuthenticated = true this.saveState() if (router) { await router.push({ name: 'home', }) } } else { this.user = null this.isAuthenticated = false this.saveState() } }, async logout(router: Router | null = null): Promise { try { const response = await fetch('http://localhost:8000/api/logout', { method: 'POST', headers: { 'X-CSRFToken': getCSRFToken(), }, credentials: 'include', }) if (response.ok) { this.user = null this.isAuthenticated = false this.saveState() if (router) { await router.push({ name: 'login', }) } } } catch (error) { console.error('Logout failed', error) throw error } }, async fetchUser(): Promise { try { const response = await fetch('http://localhost:8000/api/user', { credentials: 'include', headers: { 'Content-Type': 'application/json', 'X-CSRFToken': getCSRFToken(), }, }) if (response.ok) { const data: User = await response.json() this.user = data this.isAuthenticated = true } else { this.user = null this.isAuthenticated = false } } catch (error) { console.error('Failed to fetch user', error) this.user = null this.isAuthenticated = false } this.saveState() }, saveState(): void { /* We save state to local storage to keep the state when the user reloads the page. This is a simple way to persist state. For a more robust solution, use pinia-persistent-state. */ localStorage.setItem( 'authState', JSON.stringify({ user: this.user, isAuthenticated: this.isAuthenticated, }), ) }, }, }) export function getCSRFToken(): string { /* We get the CSRF token from the cookie to include in our requests. This is necessary for CSRF protection in Django. */ const name = 'csrftoken' let cookieValue: string | null = null if (document.cookie && document.cookie !== '') { const cookies = document.cookie.split(';') for (let i = 0; i < cookies.length; i++) { const cookie = cookies[i].trim() if (cookie.substring(0, name.length + 1) === name + '=') { cookieValue = decodeURIComponent(cookie.substring(name.length + 1)) break } } } if (cookieValue === null) { throw new Error('Missing CSRF cookie.') } return cookieValue }