91 lines
2.0 KiB
TypeScript
91 lines
2.0 KiB
TypeScript
import { API_URL, decodeJWT } from "@shared";
|
|
import { makeAutoObservable, runInAction } from "mobx";
|
|
import axios, { AxiosError } from "axios";
|
|
|
|
type LoginResponse = {
|
|
token: string;
|
|
user: {
|
|
id: number;
|
|
name: string;
|
|
email: string;
|
|
is_admin: boolean;
|
|
};
|
|
};
|
|
|
|
class AuthStore {
|
|
payload: LoginResponse | null = null;
|
|
token: string | null = null;
|
|
isLoading = false;
|
|
error: string | null = null;
|
|
|
|
constructor() {
|
|
makeAutoObservable(this);
|
|
this.initialize();
|
|
}
|
|
|
|
private initialize() {
|
|
const storedToken = localStorage.getItem("token") || undefined;
|
|
const decoded = decodeJWT(storedToken);
|
|
|
|
if (decoded) {
|
|
this.payload = decoded;
|
|
} else {
|
|
this.logout();
|
|
}
|
|
}
|
|
|
|
private setAuthToken(token: string) {
|
|
localStorage.setItem("token", token);
|
|
}
|
|
|
|
login = async (email: string, password: string) => {
|
|
this.isLoading = true;
|
|
this.error = null;
|
|
|
|
try {
|
|
const response = await axios.post<LoginResponse>(
|
|
`${API_URL}/auth/login`,
|
|
{
|
|
email,
|
|
password,
|
|
}
|
|
);
|
|
|
|
const data = response.data;
|
|
|
|
runInAction(() => {
|
|
this.setAuthToken(data.token);
|
|
this.payload = response.data;
|
|
this.error = null;
|
|
});
|
|
} catch (error) {
|
|
if (error instanceof AxiosError) {
|
|
this.error =
|
|
error.response?.data?.message || "Ошибка при входе в систему";
|
|
} else {
|
|
this.error = "Неизвестная ошибка при входе в систему";
|
|
}
|
|
throw new Error(this.error ?? "Неизвестная ошибка при входе в систему");
|
|
} finally {
|
|
this.isLoading = false;
|
|
}
|
|
};
|
|
|
|
logout = () => {
|
|
localStorage.removeItem("token");
|
|
|
|
this.payload = null;
|
|
this.error = null;
|
|
};
|
|
|
|
get isAuthenticated() {
|
|
return this.payload !== null;
|
|
}
|
|
|
|
get user() {
|
|
return this.payload?.user;
|
|
}
|
|
}
|
|
|
|
export const authStore = new AuthStore();
|