Auth
This commit is contained in:
@@ -1,13 +1,15 @@
|
||||
|
||||
import {UserContext} from "./UserContext.ts";
|
||||
import {useContext} from "react";
|
||||
import {UserContextType} from "../../types/users.ts";
|
||||
|
||||
|
||||
|
||||
export function useUser() {
|
||||
export function useUser(): undefined| UserContextType {
|
||||
const context = useContext(UserContext);
|
||||
if (!context) {
|
||||
throw new Error('useUser must be used within a UserProvider');
|
||||
console.error('useUser must be used within a UserProvider');
|
||||
return undefined;
|
||||
}
|
||||
return context;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,5 @@
|
||||
import {Account} from "../../types/users.ts";
|
||||
import {UserContextType} from "../../types/users.ts";
|
||||
import {createContext} from "react";
|
||||
|
||||
export type UserContextType = {
|
||||
user: Account | undefined;
|
||||
login: (userData: Account) => void;
|
||||
logout: () => void;
|
||||
};
|
||||
|
||||
export const UserContext = createContext<UserContextType | undefined>(undefined);
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
import React, {ReactNode, useEffect, useState} from 'react';
|
||||
import {Account} from '../../types/users.ts';
|
||||
import {Account, JwtTokenResponse, TokenObtainPair} from '../../types/users.ts';
|
||||
import {UserContext} from "./UserContext.ts";
|
||||
import {refreshToken, verifyToken, login as apiLogin} from "../../API/users.ts";
|
||||
import {getFetch} from "../../API/common.ts";
|
||||
import {deleteCookie, getCookie, setCookie} from "../cookies.ts";
|
||||
|
||||
|
||||
export function UserProvider({ children }: { children: ReactNode }) {
|
||||
@@ -8,27 +11,87 @@ export function UserProvider({ children }: { children: ReactNode }) {
|
||||
const storedUser = localStorage.getItem('user');
|
||||
return storedUser ? JSON.parse(storedUser) : undefined;
|
||||
});
|
||||
const [tokens, setTokens] = useState<JwtTokenResponse | undefined>(() => {
|
||||
const accessToken = getCookie('access_token');
|
||||
const refreshToken = getCookie('refresh_token');
|
||||
return accessToken && refreshToken ? { access: accessToken, refresh: refreshToken } : undefined;
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (tokens?.access) {
|
||||
// Устанавливаем куки для токенов
|
||||
setCookie('access_token', tokens.access, 7);
|
||||
setCookie('refresh_token', tokens.refresh, 7);
|
||||
fetchCurrentUser().then(userData => setUser(userData));
|
||||
} else {
|
||||
// Удаляем куки, если токены отсутствуют
|
||||
deleteCookie('access_token');
|
||||
deleteCookie('refresh_token');
|
||||
}
|
||||
}, [tokens]);
|
||||
|
||||
useEffect(() => {
|
||||
console.log(user)
|
||||
if (user) {
|
||||
localStorage.setItem('user', JSON.stringify(user));
|
||||
document.cookie = `user=${encodeURIComponent(JSON.stringify(user))}; path=/;`;
|
||||
} else {
|
||||
localStorage.removeItem('user');
|
||||
document.cookie = 'user=; path=/; expires=Thu, 01 Jan 1970 00:00:00 UTC;';
|
||||
}
|
||||
}, [user]);
|
||||
|
||||
const login = (userData: Account) => {
|
||||
setUser(userData);
|
||||
|
||||
const fetchCurrentUser = async (): Promise<Account | undefined> => {
|
||||
let response = await getFetch(`/users/auth/users/me/`);
|
||||
if (!response.success){
|
||||
return undefined;
|
||||
}
|
||||
|
||||
response = await getFetch(`/users/auth/users/${(response.body as Account).id}/`);
|
||||
|
||||
if (response.success){
|
||||
return response.body as Account
|
||||
}
|
||||
// if (response?.success && response.body) {
|
||||
// return response.body as Account; // Возвращаем данные о пользователе
|
||||
// }
|
||||
return undefined;
|
||||
};
|
||||
|
||||
const logout = () => {
|
||||
setUser(undefined);
|
||||
const handleLogin = async (credentials: TokenObtainPair) => {
|
||||
const tokens = await apiLogin(credentials);
|
||||
if (tokens) {
|
||||
setTokens(tokens);
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
const handleLogout = () => {
|
||||
setUser(undefined);
|
||||
setTokens(undefined);
|
||||
};
|
||||
|
||||
const validateToken = async () => {
|
||||
if (tokens?.access) {
|
||||
const isValid = await verifyToken({ token: tokens.access });
|
||||
if (!isValid && tokens.refresh) {
|
||||
const newTokens = await refreshToken({ refresh: tokens.refresh });
|
||||
if (newTokens) {
|
||||
setTokens(newTokens);
|
||||
} else {
|
||||
handleLogout();
|
||||
}
|
||||
} else if (!isValid) {
|
||||
handleLogout();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
validateToken().then();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<UserContext.Provider value={{ user, login, logout }}>
|
||||
<UserContext.Provider value={{ user, login: handleLogin, logout: handleLogout }}>
|
||||
{children}
|
||||
</UserContext.Provider>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user