92 lines
2.7 KiB
TypeScript
92 lines
2.7 KiB
TypeScript
import { defineStore } from "pinia";
|
|
import type { User, LoginPayload, RegisterPayload } from "@/services/auth";
|
|
import AuthService from "@/services/auth";
|
|
|
|
export const useAuthStore = defineStore("auth", {
|
|
state: () => ({
|
|
user: null as User | null,
|
|
token: null as string | null,
|
|
checked: false as boolean, // whether we've attempted to fetch current user
|
|
}),
|
|
getters: {
|
|
isAuthenticated: (state) => !!state.user && !!state.token,
|
|
},
|
|
actions: {
|
|
async fetchMe() {
|
|
try {
|
|
const userData = await AuthService.me();
|
|
// Validate that we actually received a user object, not HTML or other invalid data
|
|
if (
|
|
userData &&
|
|
typeof userData === "object" &&
|
|
"id" in userData &&
|
|
"email" in userData
|
|
) {
|
|
this.user = userData;
|
|
} else {
|
|
// If backend returned invalid data (like HTML), treat as unauthenticated
|
|
console.warn("Invalid user data received from /api/user:", userData);
|
|
this.user = null;
|
|
}
|
|
} catch (e) {
|
|
console.error("Error fetching user:", e);
|
|
this.user = null;
|
|
this.token = null;
|
|
} finally {
|
|
this.checked = true;
|
|
}
|
|
return this.user;
|
|
},
|
|
async login(payload: LoginPayload) {
|
|
const response = await AuthService.login(payload);
|
|
|
|
if (response.success && response.data.user && response.data.token) {
|
|
this.user = response.data.user;
|
|
this.token = response.data.token;
|
|
this.checked = true;
|
|
return this.user;
|
|
} else {
|
|
throw new Error(response.message || "Login failed");
|
|
}
|
|
},
|
|
async register(payload: RegisterPayload) {
|
|
const response = await AuthService.register(payload);
|
|
|
|
if (response.success && response.data.user && response.data.token) {
|
|
this.user = response.data.user;
|
|
this.token = response.data.token;
|
|
this.checked = true;
|
|
return this.user;
|
|
} else {
|
|
throw new Error(response.message || "Registration failed");
|
|
}
|
|
},
|
|
async logout() {
|
|
try {
|
|
await AuthService.logout();
|
|
} finally {
|
|
this.user = null;
|
|
this.token = null;
|
|
this.checked = true;
|
|
}
|
|
},
|
|
// Initialize auth state from localStorage token on app load
|
|
initializeAuth() {
|
|
const token = AuthService.getToken();
|
|
if (token) {
|
|
this.token = token;
|
|
// Optionally fetch user data if token exists
|
|
this.fetchMe().catch(() => {
|
|
// If fetching user fails, clear invalid token
|
|
this.token = null;
|
|
AuthService.logout();
|
|
});
|
|
} else {
|
|
this.checked = true;
|
|
}
|
|
},
|
|
},
|
|
});
|
|
|
|
export default useAuthStore;
|