211 lines
6.4 KiB
TypeScript
211 lines
6.4 KiB
TypeScript
import { createAsyncThunk } from '@reduxjs/toolkit';
|
|
import { apiService, LoginRequest, RegisterRequest } from '../../services/api';
|
|
import { setLoading, setError, loginSuccess, logout, setTokens, setUser } from './authSlice';
|
|
|
|
export const loginUser = createAsyncThunk(
|
|
'auth/login',
|
|
async (credentials: LoginRequest, { dispatch }) => {
|
|
try {
|
|
dispatch(setLoading(true));
|
|
dispatch(setError(null));
|
|
|
|
const response = await apiService.login(credentials);
|
|
|
|
if (response.success && response.data) {
|
|
// Check if user account is blocked
|
|
const userStatus = response.data.user.status;
|
|
if (['inactive', 'pending', 'suspended'].includes(userStatus)) {
|
|
throw new Error(`Account access blocked. Status: ${userStatus}. Please contact your vendor administrator.`);
|
|
}
|
|
|
|
// Dispatch login success (tokens will be stored in the slice)
|
|
dispatch(loginSuccess({
|
|
user: response.data.user,
|
|
token: response.data.accessToken,
|
|
refreshToken: response.data.refreshToken,
|
|
sessionId: response.data.sessionId,
|
|
}));
|
|
|
|
return response.data;
|
|
} else {
|
|
throw new Error(response.message || 'Login failed');
|
|
}
|
|
} catch (error: any) {
|
|
const errorMessage = error.message || 'Login failed. Please try again.';
|
|
dispatch(setError(errorMessage));
|
|
throw error;
|
|
} finally {
|
|
dispatch(setLoading(false));
|
|
}
|
|
}
|
|
);
|
|
|
|
export const registerUser = createAsyncThunk(
|
|
'auth/register',
|
|
async (userData: RegisterRequest, { dispatch }) => {
|
|
try {
|
|
dispatch(setLoading(true));
|
|
dispatch(setError(null));
|
|
|
|
const response = await apiService.register(userData);
|
|
|
|
if (response.success) {
|
|
return response;
|
|
} else {
|
|
throw new Error(response.message || 'Registration failed');
|
|
}
|
|
} catch (error: any) {
|
|
const errorMessage = error.message || 'Registration failed. Please try again.';
|
|
dispatch(setError(errorMessage));
|
|
throw error;
|
|
} finally {
|
|
dispatch(setLoading(false));
|
|
}
|
|
}
|
|
);
|
|
|
|
export const verifyEmail = createAsyncThunk(
|
|
'auth/verifyEmail',
|
|
async ({ email, otp }: { email: string; otp: string }, { dispatch }) => {
|
|
try {
|
|
dispatch(setLoading(true));
|
|
dispatch(setError(null));
|
|
|
|
const response = await apiService.verifyEmail(email, otp);
|
|
|
|
if (response.success) {
|
|
return response;
|
|
} else {
|
|
throw new Error(response.message || 'Email verification failed');
|
|
}
|
|
} catch (error: any) {
|
|
const errorMessage = error.message || 'Email verification failed. Please try again.';
|
|
dispatch(setError(errorMessage));
|
|
throw error;
|
|
} finally {
|
|
dispatch(setLoading(false));
|
|
}
|
|
}
|
|
);
|
|
|
|
export const resendVerificationEmail = createAsyncThunk(
|
|
'auth/resendVerification',
|
|
async (email: string, { dispatch }) => {
|
|
try {
|
|
dispatch(setLoading(true));
|
|
dispatch(setError(null));
|
|
|
|
const response = await apiService.resendVerificationEmail(email);
|
|
|
|
if (response.success) {
|
|
return response;
|
|
} else {
|
|
throw new Error(response.message || 'Failed to resend verification email');
|
|
}
|
|
} catch (error: any) {
|
|
const errorMessage = error.message || 'Failed to resend verification email. Please try again.';
|
|
dispatch(setError(errorMessage));
|
|
throw error;
|
|
} finally {
|
|
dispatch(setLoading(false));
|
|
}
|
|
}
|
|
);
|
|
|
|
export const logoutUser = createAsyncThunk(
|
|
'auth/logout',
|
|
async (_, { dispatch, getState }) => {
|
|
try {
|
|
const state = getState() as any;
|
|
const sessionId = state.auth.sessionId;
|
|
|
|
if (sessionId) {
|
|
await apiService.logout(sessionId);
|
|
}
|
|
|
|
// Dispatch logout (localStorage will be cleared in the slice)
|
|
dispatch(logout());
|
|
} catch (error) {
|
|
console.error('Logout error:', error);
|
|
// Still logout locally even if API call fails
|
|
dispatch(logout());
|
|
}
|
|
}
|
|
);
|
|
|
|
export const getCurrentUser = createAsyncThunk(
|
|
'auth/getCurrentUser',
|
|
async (_, { dispatch }) => {
|
|
try {
|
|
dispatch(setLoading(true));
|
|
dispatch(setError(null));
|
|
|
|
const response = await apiService.getCurrentUser();
|
|
|
|
if (response.success) {
|
|
// Check if user account is blocked
|
|
const userStatus = response.data.status;
|
|
if (['inactive', 'pending', 'suspended'].includes(userStatus)) {
|
|
// Force logout if account is blocked
|
|
dispatch(logout());
|
|
throw new Error(`Account access blocked. Status: ${userStatus}. Please contact your vendor administrator.`);
|
|
}
|
|
|
|
dispatch(setUser(response.data));
|
|
return response.data;
|
|
} else {
|
|
throw new Error('Failed to get current user');
|
|
}
|
|
} catch (error: any) {
|
|
const errorMessage = error.message || 'Failed to get current user';
|
|
dispatch(setError(errorMessage));
|
|
throw error;
|
|
} finally {
|
|
dispatch(setLoading(false));
|
|
}
|
|
}
|
|
);
|
|
|
|
export const refreshUserToken = createAsyncThunk(
|
|
'auth/refreshToken',
|
|
async (_, { dispatch, getState }) => {
|
|
try {
|
|
const state = getState() as any;
|
|
const refreshToken = state.auth.refreshToken;
|
|
|
|
if (!refreshToken) {
|
|
throw new Error('No refresh token available');
|
|
}
|
|
|
|
const response = await apiService.refreshToken(refreshToken);
|
|
|
|
if (response.success && response.data) {
|
|
// Check if user account is blocked (if user data is included in refresh response)
|
|
if (response.data.user) {
|
|
const userStatus = response.data.user.status;
|
|
if (['inactive', 'pending', 'suspended'].includes(userStatus)) {
|
|
// Force logout if account is blocked
|
|
dispatch(logout());
|
|
throw new Error(`Account access blocked. Status: ${userStatus}. Please contact your vendor administrator.`);
|
|
}
|
|
}
|
|
|
|
// Update tokens in store (localStorage will be updated in the slice)
|
|
dispatch(setTokens({
|
|
token: response.data.accessToken,
|
|
refreshToken: response.data.refreshToken,
|
|
sessionId: response.data.sessionId,
|
|
}));
|
|
|
|
return response.data;
|
|
} else {
|
|
throw new Error(response.message || 'Token refresh failed');
|
|
}
|
|
} catch (error: any) {
|
|
console.error('Token refresh failed:', error);
|
|
// If refresh fails, logout the user
|
|
dispatch(logoutUser());
|
|
throw error;
|
|
}
|
|
}
|
|
);
|