mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-19 22:30:31 +00:00
fix: auth pages errors handler
This commit is contained in:
@@ -24,7 +24,7 @@ export class AuthSendResetPasswordService {
|
|||||||
|
|
||||||
@Inject(SystemUser.name)
|
@Inject(SystemUser.name)
|
||||||
private readonly systemUserModel: typeof SystemUser,
|
private readonly systemUserModel: typeof SystemUser,
|
||||||
) {}
|
) { }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends the given email reset password email.
|
* Sends the given email reset password email.
|
||||||
@@ -33,8 +33,9 @@ export class AuthSendResetPasswordService {
|
|||||||
async sendResetPassword(email: string): Promise<void> {
|
async sendResetPassword(email: string): Promise<void> {
|
||||||
const user = await this.systemUserModel
|
const user = await this.systemUserModel
|
||||||
.query()
|
.query()
|
||||||
.findOne({ email })
|
.findOne({ email });
|
||||||
.throwIfNotFound();
|
|
||||||
|
if (!user) return;
|
||||||
|
|
||||||
const token: string = uniqid();
|
const token: string = uniqid();
|
||||||
|
|
||||||
@@ -48,10 +49,8 @@ export class AuthSendResetPasswordService {
|
|||||||
this.deletePasswordResetToken(email);
|
this.deletePasswordResetToken(email);
|
||||||
|
|
||||||
// Creates a new password reset row with unique token.
|
// Creates a new password reset row with unique token.
|
||||||
const passwordReset = await this.resetPasswordModel.query().insert({
|
await this.resetPasswordModel.query().insert({ email, token });
|
||||||
email,
|
|
||||||
token,
|
|
||||||
});
|
|
||||||
// Triggers sent reset password event.
|
// Triggers sent reset password event.
|
||||||
await this.eventPublisher.emitAsync(events.auth.sendResetPassword, {
|
await this.eventPublisher.emitAsync(events.auth.sendResetPassword, {
|
||||||
user,
|
user,
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
import { ClsService } from 'nestjs-cls';
|
import { ClsService } from 'nestjs-cls';
|
||||||
import { Inject, Injectable, UnauthorizedException } from '@nestjs/common';
|
import { Inject, Injectable } from '@nestjs/common';
|
||||||
import { JwtService } from '@nestjs/jwt';
|
import { JwtService } from '@nestjs/jwt';
|
||||||
import { SystemUser } from '@/modules/System/models/SystemUser';
|
import { SystemUser } from '@/modules/System/models/SystemUser';
|
||||||
import { ModelObject } from 'objection';
|
import { ModelObject } from 'objection';
|
||||||
import { JwtPayload } from '../Auth.interfaces';
|
import { JwtPayload } from '../Auth.interfaces';
|
||||||
|
import { InvalidEmailPasswordException } from '../exceptions/InvalidEmailPassword.exception';
|
||||||
|
import { UserNotFoundException } from '../exceptions/UserNotFound.exception';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class AuthSigninService {
|
export class AuthSigninService {
|
||||||
@@ -12,7 +14,7 @@ export class AuthSigninService {
|
|||||||
private readonly systemUserModel: typeof SystemUser,
|
private readonly systemUserModel: typeof SystemUser,
|
||||||
private readonly jwtService: JwtService,
|
private readonly jwtService: JwtService,
|
||||||
private readonly clsService: ClsService,
|
private readonly clsService: ClsService,
|
||||||
) {}
|
) { }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validates the given email and password.
|
* Validates the given email and password.
|
||||||
@@ -32,14 +34,10 @@ export class AuthSigninService {
|
|||||||
.findOne({ email })
|
.findOne({ email })
|
||||||
.throwIfNotFound();
|
.throwIfNotFound();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
throw new UnauthorizedException(
|
throw new InvalidEmailPasswordException(email);
|
||||||
`There isn't any user with email: ${email}`,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
if (!(await user.checkPassword(password))) {
|
if (!(await user.checkPassword(password))) {
|
||||||
throw new UnauthorizedException(
|
throw new InvalidEmailPasswordException(email);
|
||||||
`Wrong password for user with email: ${email}`,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
return user;
|
return user;
|
||||||
}
|
}
|
||||||
@@ -61,9 +59,7 @@ export class AuthSigninService {
|
|||||||
this.clsService.set('tenantId', user.tenantId);
|
this.clsService.set('tenantId', user.tenantId);
|
||||||
this.clsService.set('userId', user.id);
|
this.clsService.set('userId', user.id);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw new UnauthorizedException(
|
throw new UserNotFoundException(String(payload.sub));
|
||||||
`There isn't any user with email: ${payload.sub}`,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
return payload;
|
return payload;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ export class AuthSignupService {
|
|||||||
|
|
||||||
@Inject(SystemUser.name)
|
@Inject(SystemUser.name)
|
||||||
private readonly systemUserModel: typeof SystemUser,
|
private readonly systemUserModel: typeof SystemUser,
|
||||||
) {}
|
) { }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Registers a new tenant with user from user input.
|
* Registers a new tenant with user from user input.
|
||||||
@@ -121,7 +121,6 @@ export class AuthSignupService {
|
|||||||
const isAllowedDomain = signupRestrictions.allowedDomains.some(
|
const isAllowedDomain = signupRestrictions.allowedDomains.some(
|
||||||
(domain) => emailDomain === domain,
|
(domain) => emailDomain === domain,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!isAllowedEmail && !isAllowedDomain) {
|
if (!isAllowedEmail && !isAllowedDomain) {
|
||||||
throw new ServiceError(
|
throw new ServiceError(
|
||||||
ERRORS.SIGNUP_RESTRICTED_NOT_ALLOWED,
|
ERRORS.SIGNUP_RESTRICTED_NOT_ALLOWED,
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
import { UnauthorizedException } from '@nestjs/common';
|
||||||
|
import { ERRORS } from '../Auth.constants';
|
||||||
|
|
||||||
|
export class InvalidEmailPasswordException extends UnauthorizedException {
|
||||||
|
constructor(email: string) {
|
||||||
|
super({
|
||||||
|
statusCode: 401,
|
||||||
|
error: 'Unauthorized',
|
||||||
|
message: `Invalid email or password for ${email}`,
|
||||||
|
code: ERRORS.INVALID_DETAILS,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
import { UnauthorizedException } from '@nestjs/common';
|
||||||
|
import { ERRORS } from '../Auth.constants';
|
||||||
|
|
||||||
|
export class UserNotFoundException extends UnauthorizedException {
|
||||||
|
constructor(identifier: string) {
|
||||||
|
super({
|
||||||
|
statusCode: 401,
|
||||||
|
error: 'Unauthorized',
|
||||||
|
message: `User not found: ${identifier}`,
|
||||||
|
code: ERRORS.USER_NOT_FOUND,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -17,12 +17,11 @@ import { TenantUser } from '../Tenancy/TenancyModels/models/TenantUser.model';
|
|||||||
@Injectable()
|
@Injectable()
|
||||||
export class AuthorizationGuard implements CanActivate {
|
export class AuthorizationGuard implements CanActivate {
|
||||||
constructor(
|
constructor(
|
||||||
private reflector: Reflector,
|
|
||||||
private readonly clsService: ClsService,
|
private readonly clsService: ClsService,
|
||||||
|
|
||||||
@Inject(TenantUser.name)
|
@Inject(TenantUser.name)
|
||||||
private readonly tenantUserModel: TenantModelProxy<typeof TenantUser>,
|
private readonly tenantUserModel: TenantModelProxy<typeof TenantUser>,
|
||||||
) {}
|
) { }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if the user has the required abilities to access the route
|
* Checks if the user has the required abilities to access the route
|
||||||
@@ -31,7 +30,7 @@ export class AuthorizationGuard implements CanActivate {
|
|||||||
*/
|
*/
|
||||||
async canActivate(context: ExecutionContext): Promise<boolean> {
|
async canActivate(context: ExecutionContext): Promise<boolean> {
|
||||||
const request = context.switchToHttp().getRequest<Request>();
|
const request = context.switchToHttp().getRequest<Request>();
|
||||||
const { tenantId, user } = request as any;
|
const { user } = request as any;
|
||||||
|
|
||||||
if (ABILITIES_CACHE.has(user.id)) {
|
if (ABILITIES_CACHE.has(user.id)) {
|
||||||
(request as any).ability = ABILITIES_CACHE.get(user.id);
|
(request as any).ability = ABILITIES_CACHE.get(user.id);
|
||||||
@@ -40,7 +39,6 @@ export class AuthorizationGuard implements CanActivate {
|
|||||||
(request as any).ability = ability;
|
(request as any).ability = ability;
|
||||||
ABILITIES_CACHE.set(user.id, ability);
|
ABILITIES_CACHE.set(user.id, ability);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,13 +32,11 @@ export default function Login() {
|
|||||||
email: values.crediential,
|
email: values.crediential,
|
||||||
password: values.password,
|
password: values.password,
|
||||||
}).catch(({ response }) => {
|
}).catch(({ response }) => {
|
||||||
const {
|
const { data: error } = response;
|
||||||
data: { errors },
|
const toastMessages = transformLoginErrorsToToasts(error);
|
||||||
} = response;
|
|
||||||
const toastBuilders = transformLoginErrorsToToasts(errors);
|
|
||||||
|
|
||||||
toastBuilders.forEach((builder) => {
|
toastMessages.forEach((toastMessage) => {
|
||||||
Toaster.show(builder);
|
Toaster.show(toastMessage);
|
||||||
});
|
});
|
||||||
setSubmitting(false);
|
setSubmitting(false);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ export default function SendResetPassword() {
|
|||||||
// Handle form submitting.
|
// Handle form submitting.
|
||||||
const handleSubmit = (values, { setSubmitting }) => {
|
const handleSubmit = (values, { setSubmitting }) => {
|
||||||
sendResetPasswordMutate({ email: values.crediential })
|
sendResetPasswordMutate({ email: values.crediential })
|
||||||
.then((response) => {
|
.then(() => {
|
||||||
AppToaster.show({
|
AppToaster.show({
|
||||||
message: intl.get('check_your_email_for_a_link_to_reset'),
|
message: intl.get('check_your_email_for_a_link_to_reset'),
|
||||||
intent: Intent.SUCCESS,
|
intent: Intent.SUCCESS,
|
||||||
@@ -43,20 +43,9 @@ export default function SendResetPassword() {
|
|||||||
history.push('/auth/login');
|
history.push('/auth/login');
|
||||||
setSubmitting(false);
|
setSubmitting(false);
|
||||||
})
|
})
|
||||||
.catch(
|
.catch(() => {
|
||||||
({
|
setSubmitting(false);
|
||||||
response: {
|
});
|
||||||
data: { errors },
|
|
||||||
},
|
|
||||||
}) => {
|
|
||||||
const toastBuilders = transformSendResetPassErrorsToToasts(errors);
|
|
||||||
|
|
||||||
toastBuilders.forEach((builder) => {
|
|
||||||
AppToaster.show(builder);
|
|
||||||
});
|
|
||||||
setSubmitting(false);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -82,11 +71,17 @@ function SendResetPasswordFooterLinks() {
|
|||||||
<AuthFooterLinks>
|
<AuthFooterLinks>
|
||||||
{!signupDisabled && (
|
{!signupDisabled && (
|
||||||
<AuthFooterLink>
|
<AuthFooterLink>
|
||||||
<T id={'dont_have_an_account'} /> <Link to={'/auth/register'}><T id={'sign_up'} /></Link>
|
<T id={'dont_have_an_account'} />{' '}
|
||||||
|
<Link to={'/auth/register'}>
|
||||||
|
<T id={'sign_up'} />
|
||||||
|
</Link>
|
||||||
</AuthFooterLink>
|
</AuthFooterLink>
|
||||||
)}
|
)}
|
||||||
<AuthFooterLink>
|
<AuthFooterLink>
|
||||||
<T id={'return_to'} /> <Link to={'/auth/login'}><T id={'sign_in'} /></Link>
|
<T id={'return_to'} />{' '}
|
||||||
|
<Link to={'/auth/login'}>
|
||||||
|
<T id={'sign_in'} />
|
||||||
|
</Link>
|
||||||
</AuthFooterLink>
|
</AuthFooterLink>
|
||||||
</AuthFooterLinks>
|
</AuthFooterLinks>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -13,12 +13,17 @@ export function AuthenticationLoadingOverlay() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const AuthOverlayRoot = styled.div`
|
const AuthOverlayRoot = styled.div`
|
||||||
|
--x-color-background: rgba(252, 253, 255, 0.5);
|
||||||
|
|
||||||
|
.bp4-dark & {
|
||||||
|
--x-color-background: rgba(37, 42, 49, 0.60);
|
||||||
|
}
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
background: rgba(252, 253, 255, 0.5);
|
background: var(--x-color-background);
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
`;
|
`;
|
||||||
|
|||||||
@@ -45,10 +45,10 @@ export const InviteAcceptSchema = Yup.object().shape({
|
|||||||
password: Yup.string().min(4).required().label(intl.get('password')),
|
password: Yup.string().min(4).required().label(intl.get('password')),
|
||||||
});
|
});
|
||||||
|
|
||||||
export const transformSendResetPassErrorsToToasts = (errors) => {
|
export const transformSendResetPassErrorsToToasts = (error) => {
|
||||||
const toastBuilders = [];
|
const toastBuilders = [];
|
||||||
|
|
||||||
if (errors.find((e) => e.type === 'EMAIL.NOT.REGISTERED')) {
|
if (error.code === ERRORS.EMAIL_NOT_REGISTERED) {
|
||||||
toastBuilders.push({
|
toastBuilders.push({
|
||||||
message: intl.get('we_couldn_t_find_your_account_with_that_email'),
|
message: intl.get('we_couldn_t_find_your_account_with_that_email'),
|
||||||
intent: Intent.DANGER,
|
intent: Intent.DANGER,
|
||||||
@@ -57,38 +57,26 @@ export const transformSendResetPassErrorsToToasts = (errors) => {
|
|||||||
return toastBuilders;
|
return toastBuilders;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const transformLoginErrorsToToasts = (errors) => {
|
export const transformLoginErrorsToToasts = (error) => {
|
||||||
const toastBuilders = [];
|
const toastBuilders = [];
|
||||||
|
|
||||||
if (errors.find((e) => e.type === LOGIN_ERRORS.INVALID_DETAILS)) {
|
if (error.code === LOGIN_ERRORS.INVALID_DETAILS) {
|
||||||
toastBuilders.push({
|
toastBuilders.push({
|
||||||
message: intl.get('email_and_password_entered_did_not_match'),
|
message: intl.get('email_and_password_entered_did_not_match'),
|
||||||
intent: Intent.DANGER,
|
intent: Intent.DANGER,
|
||||||
});
|
});
|
||||||
}
|
} else if (error.code === LOGIN_ERRORS.USER_INACTIVE) {
|
||||||
if (errors.find((e) => e.type === LOGIN_ERRORS.USER_INACTIVE)) {
|
|
||||||
toastBuilders.push({
|
toastBuilders.push({
|
||||||
message: intl.get('the_user_has_been_suspended_from_admin'),
|
message: intl.get('the_user_has_been_suspended_from_admin'),
|
||||||
intent: Intent.DANGER,
|
intent: Intent.DANGER,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (errors.find((e) => e.type === LOGIN_ERRORS.LOGIN_TO_MANY_ATTEMPTS)) {
|
|
||||||
toastBuilders.push({
|
|
||||||
message: intl.get('your_account_has_been_locked'),
|
|
||||||
intent: Intent.DANGER,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return toastBuilders;
|
return toastBuilders;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const transformRegisterErrorsToForm = (errors) => {
|
export const transformRegisterErrorsToForm = (errors) => {
|
||||||
const formErrors = {};
|
const formErrors = {};
|
||||||
|
|
||||||
if (errors.some((e) => e.type === REGISTER_ERRORS.PHONE_NUMBER_EXISTS)) {
|
|
||||||
formErrors.phone_number = intl.get(
|
|
||||||
'the_phone_number_already_used_in_another_account',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (errors.some((e) => e.type === REGISTER_ERRORS.EMAIL_EXISTS)) {
|
if (errors.some((e) => e.type === REGISTER_ERRORS.EMAIL_EXISTS)) {
|
||||||
formErrors.email = intl.get('the_email_already_used_in_another_account');
|
formErrors.email = intl.get('the_email_already_used_in_another_account');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
--x-border-color: #E1E1E1;
|
--x-border-color: #E1E1E1;
|
||||||
--x-color-placeholder-text: #738091;
|
--x-color-placeholder-text: #738091;
|
||||||
|
|
||||||
.bp4-dark & {
|
:global(.bp4-dark) & {
|
||||||
--x-border-color: rgba(225, 225, 225, 0.15);
|
--x-border-color: rgba(225, 225, 225, 0.15);
|
||||||
--x-color-placeholder-text: rgba(225, 225, 225, 0.65);
|
--x-color-placeholder-text: rgba(225, 225, 225, 0.65);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,7 +53,6 @@ export function CompanyLogoUpload({
|
|||||||
const [initialLocalPreview, setInitialLocalPreview] = useState<string | null>(
|
const [initialLocalPreview, setInitialLocalPreview] = useState<string | null>(
|
||||||
initialPreview || null,
|
initialPreview || null,
|
||||||
);
|
);
|
||||||
|
|
||||||
const openRef = useRef<() => void>(null);
|
const openRef = useRef<() => void>(null);
|
||||||
|
|
||||||
const handleRemove = () => {
|
const handleRemove = () => {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// @ts-nocheck
|
// @ts-nocheck
|
||||||
import { useMutation } from 'react-query';
|
import { useMutation } from 'react-query';
|
||||||
import { batch } from 'react-redux';
|
import { batch } from 'react-redux';
|
||||||
import useApiRequest from '../useRequest';
|
import useApiRequest, { useAuthApiRequest } from '../useRequest';
|
||||||
import { setCookie } from '../../utils';
|
import { setCookie } from '../../utils';
|
||||||
import { useRequestQuery } from '../useQueryRequest';
|
import { useRequestQuery } from '../useQueryRequest';
|
||||||
import t from './types';
|
import t from './types';
|
||||||
@@ -40,7 +40,7 @@ export function setAuthLoginCookies(data) {
|
|||||||
* Authentication login.
|
* Authentication login.
|
||||||
*/
|
*/
|
||||||
export const useAuthLogin = (props) => {
|
export const useAuthLogin = (props) => {
|
||||||
const apiRequest = useApiRequest();
|
const apiRequest = useAuthApiRequest();
|
||||||
|
|
||||||
const setAuthToken = useSetAuthToken();
|
const setAuthToken = useSetAuthToken();
|
||||||
const setOrganizationId = useSetOrganizationId();
|
const setOrganizationId = useSetOrganizationId();
|
||||||
@@ -49,7 +49,6 @@ export const useAuthLogin = (props) => {
|
|||||||
const setLocale = useSetLocale();
|
const setLocale = useSetLocale();
|
||||||
|
|
||||||
return useMutation((values) => apiRequest.post(AuthRoute.Signin, values), {
|
return useMutation((values) => apiRequest.post(AuthRoute.Signin, values), {
|
||||||
select: (res) => res.data,
|
|
||||||
onSuccess: (res) => {
|
onSuccess: (res) => {
|
||||||
// Set authentication cookies.
|
// Set authentication cookies.
|
||||||
setAuthLoginCookies(res.data);
|
setAuthLoginCookies(res.data);
|
||||||
@@ -75,7 +74,7 @@ export const useAuthLogin = (props) => {
|
|||||||
* Authentication register.
|
* Authentication register.
|
||||||
*/
|
*/
|
||||||
export const useAuthRegister = (props) => {
|
export const useAuthRegister = (props) => {
|
||||||
const apiRequest = useApiRequest();
|
const apiRequest = useAuthApiRequest();
|
||||||
|
|
||||||
return useMutation(
|
return useMutation(
|
||||||
(values) => apiRequest.post(AuthRoute.Signup, values),
|
(values) => apiRequest.post(AuthRoute.Signup, values),
|
||||||
@@ -87,7 +86,7 @@ export const useAuthRegister = (props) => {
|
|||||||
* Authentication send reset password.
|
* Authentication send reset password.
|
||||||
*/
|
*/
|
||||||
export const useAuthSendResetPassword = (props) => {
|
export const useAuthSendResetPassword = (props) => {
|
||||||
const apiRequest = useApiRequest();
|
const apiRequest = useAuthApiRequest();
|
||||||
|
|
||||||
return useMutation(
|
return useMutation(
|
||||||
(values) => apiRequest.post(AuthRoute.SendResetPassword, values),
|
(values) => apiRequest.post(AuthRoute.SendResetPassword, values),
|
||||||
@@ -99,7 +98,7 @@ export const useAuthSendResetPassword = (props) => {
|
|||||||
* Authentication reset password.
|
* Authentication reset password.
|
||||||
*/
|
*/
|
||||||
export const useAuthResetPassword = (props) => {
|
export const useAuthResetPassword = (props) => {
|
||||||
const apiRequest = useApiRequest();
|
const apiRequest = useAuthApiRequest();
|
||||||
|
|
||||||
return useMutation(
|
return useMutation(
|
||||||
([token, values]) => apiRequest.post(`auth/reset/${token}`, values),
|
([token, values]) => apiRequest.post(`auth/reset/${token}`, values),
|
||||||
@@ -129,7 +128,7 @@ export const useAuthMetadata = (props = {}) => {
|
|||||||
* Resend the mail of signup verification.
|
* Resend the mail of signup verification.
|
||||||
*/
|
*/
|
||||||
export const useAuthSignUpVerifyResendMail = (props) => {
|
export const useAuthSignUpVerifyResendMail = (props) => {
|
||||||
const apiRequest = useApiRequest();
|
const apiRequest = useAuthApiRequest();
|
||||||
|
|
||||||
return useMutation(
|
return useMutation(
|
||||||
() => apiRequest.post(AuthRoute.SignupVerifyResend),
|
() => apiRequest.post(AuthRoute.SignupVerifyResend),
|
||||||
@@ -146,7 +145,7 @@ interface AuthSignUpVerifyValues {
|
|||||||
* Signup verification.
|
* Signup verification.
|
||||||
*/
|
*/
|
||||||
export const useAuthSignUpVerify = (props) => {
|
export const useAuthSignUpVerify = (props) => {
|
||||||
const apiRequest = useApiRequest();
|
const apiRequest = useAuthApiRequest();
|
||||||
|
|
||||||
return useMutation(
|
return useMutation(
|
||||||
(values: AuthSignUpVerifyValues) =>
|
(values: AuthSignUpVerifyValues) =>
|
||||||
|
|||||||
@@ -120,3 +120,35 @@ export default function useApiRequest() {
|
|||||||
[http],
|
[http],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function useAuthApiRequest() {
|
||||||
|
const http = React.useMemo(() => {
|
||||||
|
// Axios instance.
|
||||||
|
return axios.create();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return React.useMemo(
|
||||||
|
() => ({
|
||||||
|
http,
|
||||||
|
get(resource, params) {
|
||||||
|
return http.get(`/api/${resource}`, params);
|
||||||
|
},
|
||||||
|
post(resource, params, config) {
|
||||||
|
return http.post(`/api/${resource}`, params, config);
|
||||||
|
},
|
||||||
|
update(resource, slug, params) {
|
||||||
|
return http.put(`/api/${resource}/${slug}`, params);
|
||||||
|
},
|
||||||
|
put(resource, params) {
|
||||||
|
return http.put(`/api/${resource}`, params);
|
||||||
|
},
|
||||||
|
patch(resource, params, config) {
|
||||||
|
return http.patch(`/api/${resource}`, params, config);
|
||||||
|
},
|
||||||
|
delete(resource, params) {
|
||||||
|
return http.delete(`/api/${resource}`, params);
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
[http],
|
||||||
|
);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user