admin-panel-front/src/features/auth/authSlice.ts
2026-08-03 14:41:19 +03:30

73 lines
2.4 KiB
TypeScript

import { createSlice, type PayloadAction } from '@reduxjs/toolkit';
import type { AuthState, LoginSuccessPayload } from '@/features/auth/authTypes';
import { STORAGE_KEYS } from '@/utils/storage';
import { clearAuthTokens, getAccessToken, isAccessTokenExpired, storeAuthTokens } from '@/utils/authToken';
const clearPersistedAuthState = () => {
localStorage.removeItem(STORAGE_KEYS.accessToken);
localStorage.removeItem(STORAGE_KEYS.user);
localStorage.removeItem(STORAGE_KEYS.authState);
clearAuthTokens();
};
const loadPersistedAuthState = (): AuthState => {
const loggedOutState: AuthState = { user: null, accessToken: null, isAuthenticated: false };
const storedAuth = localStorage.getItem(STORAGE_KEYS.authState);
const storedAccessToken = getAccessToken();
if (!storedAuth) {
return loggedOutState;
}
try {
const parsed = JSON.parse(storedAuth) as AuthState;
const accessToken = parsed.accessToken || storedAccessToken;
if (accessToken && parsed.user && !isAccessTokenExpired()) {
return { user: parsed.user, accessToken, isAuthenticated: true };
}
} catch {
// fall through to the logged-out default below
}
clearPersistedAuthState();
return loggedOutState;
};
const authSlice = createSlice({
name: 'auth',
initialState: loadPersistedAuthState(),
reducers: {
loginSuccess: (state, action: PayloadAction<LoginSuccessPayload>) => {
state.user = action.payload.user;
state.accessToken = action.payload.accessToken;
state.isAuthenticated = true;
localStorage.setItem(STORAGE_KEYS.accessToken, action.payload.accessToken);
localStorage.setItem(STORAGE_KEYS.user, JSON.stringify(action.payload.user));
storeAuthTokens({
access_token: action.payload.accessToken,
refresh_token: action.payload.refreshToken ?? '',
});
localStorage.setItem(
STORAGE_KEYS.authState,
JSON.stringify({
user: action.payload.user,
accessToken: action.payload.accessToken,
isAuthenticated: true,
}),
);
},
logout: (state) => {
state.user = null;
state.accessToken = null;
state.isAuthenticated = false;
clearPersistedAuthState();
},
hydrateAuth: () => loadPersistedAuthState(),
},
});
export const { loginSuccess, logout, hydrateAuth } = authSlice.actions;
export default authSlice.reducer;