83 lines
2.1 KiB
TypeScript
83 lines
2.1 KiB
TypeScript
import { computed, ref } from "vue";
|
|
import { defineStore } from "pinia";
|
|
import apiClient from "@/api/client";
|
|
import type { AuthenticatedUser, LoginResponse } from "@/types";
|
|
|
|
const USER_STORAGE_KEY = "live-recorder-user";
|
|
const TOKEN_STORAGE_KEY = "live-recorder-token";
|
|
|
|
function readStoredValue(key: string) {
|
|
return localStorage.getItem(key) ?? sessionStorage.getItem(key);
|
|
}
|
|
|
|
function clearStoredSession() {
|
|
[localStorage, sessionStorage].forEach((storage) => {
|
|
storage.removeItem(TOKEN_STORAGE_KEY);
|
|
storage.removeItem(USER_STORAGE_KEY);
|
|
});
|
|
}
|
|
|
|
export const useAuthStore = defineStore("auth", () => {
|
|
const token = ref(readStoredValue(TOKEN_STORAGE_KEY) ?? "");
|
|
const user = ref<AuthenticatedUser | null>(
|
|
(() => {
|
|
const raw = readStoredValue(USER_STORAGE_KEY);
|
|
return raw ? (JSON.parse(raw) as AuthenticatedUser) : null;
|
|
})()
|
|
);
|
|
|
|
const isAuthenticated = computed(() => Boolean(token.value));
|
|
|
|
function persistSession(session: LoginResponse, rememberMe: boolean) {
|
|
token.value = session.token;
|
|
user.value = session.user;
|
|
clearStoredSession();
|
|
const storage = rememberMe ? localStorage : sessionStorage;
|
|
storage.setItem(TOKEN_STORAGE_KEY, session.token);
|
|
storage.setItem(USER_STORAGE_KEY, JSON.stringify(session.user));
|
|
}
|
|
|
|
function clearSession() {
|
|
token.value = "";
|
|
user.value = null;
|
|
clearStoredSession();
|
|
}
|
|
|
|
async function login(username: string, password: string, rememberMe: boolean) {
|
|
const { data } = await apiClient.post<LoginResponse>("/auth/login", {
|
|
username,
|
|
password,
|
|
rememberMe
|
|
});
|
|
|
|
persistSession(data, rememberMe);
|
|
return data;
|
|
}
|
|
|
|
async function logout() {
|
|
try {
|
|
await apiClient.post("/auth/logout");
|
|
} finally {
|
|
clearSession();
|
|
}
|
|
}
|
|
|
|
async function changePassword(currentPassword: string, newPassword: string) {
|
|
await apiClient.post("/auth/change-password", {
|
|
currentPassword,
|
|
newPassword
|
|
});
|
|
clearSession();
|
|
}
|
|
|
|
return {
|
|
token,
|
|
user,
|
|
isAuthenticated,
|
|
login,
|
|
logout,
|
|
changePassword,
|
|
clearSession
|
|
};
|
|
});
|