refactor(auth): update AuthContext for new API structure
- Remove login logic from context (moved to custom hook) - Add restoreSession functionality - Update state management for new auth response structure - Add permission checking by ID and title - Manage access_token and refresh_token separately
This commit is contained in:
parent
d45f588fa7
commit
7ec69a67e7
|
|
@ -1,18 +1,20 @@
|
|||
import { createContext, useContext, useReducer, useEffect } from 'react';
|
||||
import { AuthState, User } from '../types';
|
||||
import { AuthState, AdminUser, Permission } from '../types/auth';
|
||||
import toast from 'react-hot-toast';
|
||||
|
||||
interface AuthContextType extends AuthState {
|
||||
login: (email: string, password: string) => Promise<boolean>;
|
||||
logout: () => void;
|
||||
hasPermission: (permission: number) => boolean;
|
||||
hasPermission: (permissionId: number) => boolean;
|
||||
hasPermissionByTitle: (title: string) => boolean;
|
||||
restoreSession: () => void;
|
||||
}
|
||||
|
||||
const AuthContext = createContext<AuthContextType | undefined>(undefined);
|
||||
|
||||
type AuthAction =
|
||||
| { type: 'LOGIN_SUCCESS'; payload: { user: User; token: string } }
|
||||
| { type: 'LOGIN_SUCCESS'; payload: { user: AdminUser; permissions: Permission[]; allPermissions: Permission[]; token: string; refreshToken: string } }
|
||||
| { type: 'LOGOUT' }
|
||||
| { type: 'RESTORE_SESSION'; payload: { user: User; token: string } };
|
||||
| { type: 'RESTORE_SESSION'; payload: { user: AdminUser; permissions: Permission[]; allPermissions: Permission[]; token: string; refreshToken: string } };
|
||||
|
||||
const authReducer = (state: AuthState, action: AuthAction): AuthState => {
|
||||
switch (action.type) {
|
||||
|
|
@ -20,22 +22,28 @@ const authReducer = (state: AuthState, action: AuthAction): AuthState => {
|
|||
return {
|
||||
isAuthenticated: true,
|
||||
user: action.payload.user,
|
||||
permissions: action.payload.user.permissions,
|
||||
permissions: action.payload.permissions,
|
||||
allPermissions: action.payload.allPermissions,
|
||||
token: action.payload.token,
|
||||
refreshToken: action.payload.refreshToken,
|
||||
};
|
||||
case 'LOGOUT':
|
||||
return {
|
||||
isAuthenticated: false,
|
||||
user: null,
|
||||
permissions: [],
|
||||
allPermissions: [],
|
||||
token: null,
|
||||
refreshToken: null,
|
||||
};
|
||||
case 'RESTORE_SESSION':
|
||||
return {
|
||||
isAuthenticated: true,
|
||||
user: action.payload.user,
|
||||
permissions: action.payload.user.permissions,
|
||||
permissions: action.payload.permissions,
|
||||
allPermissions: action.payload.allPermissions,
|
||||
token: action.payload.token,
|
||||
refreshToken: action.payload.refreshToken,
|
||||
};
|
||||
default:
|
||||
return state;
|
||||
|
|
@ -46,77 +54,76 @@ const initialState: AuthState = {
|
|||
isAuthenticated: false,
|
||||
user: null,
|
||||
permissions: [],
|
||||
allPermissions: [],
|
||||
token: null,
|
||||
refreshToken: null,
|
||||
};
|
||||
|
||||
export const AuthProvider = ({ children }: { children: React.ReactNode }) => {
|
||||
const [state, dispatch] = useReducer(authReducer, initialState);
|
||||
|
||||
useEffect(() => {
|
||||
const restoreSession = () => {
|
||||
const token = localStorage.getItem('admin_token');
|
||||
const refreshToken = localStorage.getItem('admin_refresh_token');
|
||||
const userStr = localStorage.getItem('admin_user');
|
||||
const permissionsStr = localStorage.getItem('admin_permissions');
|
||||
const allPermissionsStr = localStorage.getItem('admin_all_permissions');
|
||||
|
||||
if (token && userStr) {
|
||||
if (token && userStr && permissionsStr) {
|
||||
try {
|
||||
const user = JSON.parse(userStr);
|
||||
dispatch({ type: 'RESTORE_SESSION', payload: { user, token } });
|
||||
} catch (error) {
|
||||
localStorage.removeItem('admin_token');
|
||||
localStorage.removeItem('admin_user');
|
||||
}
|
||||
}
|
||||
}, []);
|
||||
|
||||
const login = async (email: string, password: string): Promise<boolean> => {
|
||||
try {
|
||||
const mockUser: User = {
|
||||
id: '1',
|
||||
name: 'مدیر کل',
|
||||
email: email,
|
||||
role: 'admin',
|
||||
permissions: [1, 2, 3, 4, 5, 10, 15, 20, 22, 25, 30],
|
||||
status: 'active',
|
||||
createdAt: new Date().toISOString(),
|
||||
lastLogin: new Date().toISOString(),
|
||||
};
|
||||
|
||||
const mockToken = 'mock-jwt-token-' + Date.now();
|
||||
|
||||
if (email === 'admin@test.com' && password === 'admin123') {
|
||||
localStorage.setItem('admin_token', mockToken);
|
||||
localStorage.setItem('admin_user', JSON.stringify(mockUser));
|
||||
const permissions = JSON.parse(permissionsStr);
|
||||
const allPermissions = allPermissionsStr ? JSON.parse(allPermissionsStr) : [];
|
||||
|
||||
dispatch({
|
||||
type: 'LOGIN_SUCCESS',
|
||||
payload: { user: mockUser, token: mockToken }
|
||||
});
|
||||
|
||||
return true;
|
||||
type: 'RESTORE_SESSION',
|
||||
payload: {
|
||||
user,
|
||||
permissions,
|
||||
allPermissions,
|
||||
token,
|
||||
refreshToken: refreshToken || ''
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Login error:', error);
|
||||
return false;
|
||||
localStorage.removeItem('admin_token');
|
||||
localStorage.removeItem('admin_refresh_token');
|
||||
localStorage.removeItem('admin_user');
|
||||
localStorage.removeItem('admin_permissions');
|
||||
localStorage.removeItem('admin_all_permissions');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
restoreSession();
|
||||
}, []);
|
||||
|
||||
const logout = () => {
|
||||
localStorage.removeItem('admin_token');
|
||||
localStorage.removeItem('admin_refresh_token');
|
||||
localStorage.removeItem('admin_user');
|
||||
localStorage.removeItem('admin_permissions');
|
||||
localStorage.removeItem('admin_all_permissions');
|
||||
dispatch({ type: 'LOGOUT' });
|
||||
toast.success('خروج موفقیتآمیز بود');
|
||||
};
|
||||
|
||||
const hasPermission = (permission: number): boolean => {
|
||||
return state.permissions.includes(permission);
|
||||
const hasPermission = (permissionId: number): boolean => {
|
||||
return state.permissions.some(permission => permission.id === permissionId);
|
||||
};
|
||||
|
||||
const hasPermissionByTitle = (title: string): boolean => {
|
||||
return state.permissions.some(permission => permission.title === title);
|
||||
};
|
||||
|
||||
return (
|
||||
<AuthContext.Provider value={{
|
||||
...state,
|
||||
login,
|
||||
logout,
|
||||
hasPermission,
|
||||
hasPermissionByTitle,
|
||||
restoreSession,
|
||||
}}>
|
||||
{children}
|
||||
</AuthContext.Provider>
|
||||
|
|
|
|||
Loading…
Reference in New Issue