All files / features/auth authSlice.tsx

81.81% Statements 18/22
0% Branches 0/2
57.14% Functions 4/7
85% Lines 17/20

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97                                                      5x                     5x                       13x 13x 13x 13x                 1x 1x     8x 8x 8x 8x         5x               5x 79x         5x           5x    
import {createSlice, type PayloadAction} from '@reduxjs/toolkit';
import type {RootState} from '../../store/store.tsx';
 
// ============================================================================
// Types
// ============================================================================
 
export type UserRole = 'admin' | 'super_admin' | 'investor';
 
export interface User {
	userId: number;
	username: string;
	email: string;
	role: UserRole;
}
 
interface AuthState {
	user: User | null;
	accessToken: string | null;
	refreshToken: string | null;
	isAuthenticated: boolean;
}
 
// ============================================================================
// Initial State
// ============================================================================
 
const initialState: AuthState = {
	user: null,
	accessToken: null,
	refreshToken: null,
	isAuthenticated: false
};
 
// ============================================================================
// Slice
// ============================================================================
 
export const authSlice = createSlice({
	name: 'auth',
	initialState,
	reducers: {
		setCredentials: (
			state,
			action: PayloadAction<{
				user: User;
				accessToken: string;
				refreshToken: string;
			}>
		) => {
			state.user = action.payload.user;
			state.accessToken = action.payload.accessToken;
			state.refreshToken = action.payload.refreshToken;
			state.isAuthenticated = true;
		},
		setTokens: (
			state,
			action: PayloadAction<{
				accessToken: string;
				refreshToken: string;
			}>
		) => {
			state.accessToken = action.payload.accessToken;
			state.refreshToken = action.payload.refreshToken;
		},
		logout: (state) => {
			state.user = null;
			state.accessToken = null;
			state.refreshToken = null;
			state.isAuthenticated = false;
		}
	}
});
 
export const {setCredentials, setTokens, logout} = authSlice.actions;
 
export default authSlice.reducer;
 
// ============================================================================
// Selectors
// ============================================================================
 
export const selectCurrentUser = (state: RootState): User | null => state.auth.user;
export const selectIsAuthenticated = (state: RootState): boolean => state.auth.isAuthenticated;
//export const selectAccessToken = (state: RootState): string | null => state.auth.accessToken;
//export const selectRefreshToken = (state: RootState): string | null => state.auth.refreshToken;
 
// Helper to check admin access (includes super_admin)
export const selectIsAdmin = (state: RootState): boolean => {
	const role = state.auth.user?.role;
	return role === 'admin' || role === 'super_admin';
};
 
// Helper to check super admin access only
export const selectIsSuperAdmin = (state: RootState): boolean => {
	return state.auth.user?.role === 'super_admin';
};