import { defineStore } from 'pinia'; import { authService } from '~/services/auth.service'; interface User { id: string; email: string; firstName: string; lastName: string; role: 'INSTRUCTOR' | 'ADMIN' | 'STUDENT'; } export const useAuthStore = defineStore('auth', { state: () => ({ user: null as User | null, token: null as string | null, isAuthenticated: false }), getters: { isInstructor: (state) => state.user?.role === 'INSTRUCTOR', isAdmin: (state) => state.user?.role === 'ADMIN', isStudent: (state) => state.user?.role === 'STUDENT' }, actions: { async login(email: string, password: string) { try { const response = await authService.login(email, password); this.token = response.token; this.user = response.user as User; this.isAuthenticated = true; // Save to cookies const tokenCookie = useCookie('token', { maxAge: 60 * 60 * 24, // 24 hours sameSite: 'strict' }); const refreshTokenCookie = useCookie('refreshToken', { maxAge: 60 * 60 * 24 * 7, // 7 days sameSite: 'strict' }); const userCookie = useCookie('user', { maxAge: 60 * 60 * 24, // 24 hours sameSite: 'strict' }); tokenCookie.value = this.token; refreshTokenCookie.value = response.refreshToken; userCookie.value = JSON.stringify(this.user); return { token: this.token, user: this.user }; } catch (error: any) { throw error; } }, logout() { this.user = null; this.token = null; this.isAuthenticated = false; // Clear cookies const tokenCookie = useCookie('token'); const refreshTokenCookie = useCookie('refreshToken'); const userCookie = useCookie('user'); tokenCookie.value = null; refreshTokenCookie.value = null; userCookie.value = null; }, async checkAuth() { const tokenCookie = useCookie('token'); const userCookie = useCookie('user'); const refreshTokenCookie = useCookie('refreshToken'); // Case 1: Have token and user - restore auth state if (tokenCookie.value && userCookie.value) { this.token = tokenCookie.value; try { this.user = typeof userCookie.value === 'string' ? JSON.parse(userCookie.value) : userCookie.value; this.isAuthenticated = true; return; } catch (e) { // Invalid user data this.logout(); } } // Case 2: No token but have refresh token - try to refresh if (!tokenCookie.value && refreshTokenCookie.value && userCookie.value) { // Get cookie refs with options BEFORE await to maintain Nuxt context const tokenCookieWithOptions = useCookie('token', { maxAge: 60 * 60 * 24, // 24 hours sameSite: 'strict' }); const refreshTokenCookieWithOptions = useCookie('refreshToken', { maxAge: 60 * 60 * 24 * 7, // 7 days sameSite: 'strict' }); const currentRefreshToken = refreshTokenCookie.value; try { console.log('Token missing, attempting refresh...'); const newTokens = await authService.refreshToken(currentRefreshToken); // Update cookies with new tokens tokenCookieWithOptions.value = newTokens.token; refreshTokenCookieWithOptions.value = newTokens.refreshToken; this.token = newTokens.token; this.user = typeof userCookie.value === 'string' ? JSON.parse(userCookie.value) : userCookie.value; this.isAuthenticated = true; console.log('Token refreshed successfully'); } catch (e) { console.error('Token refresh failed'); this.logout(); } } } } });