feat: forgot password (#218)

* feat: forgot password

* feat: forgot password

* fix: enable flag

---------

Co-authored-by: Quan HL <quanluuhoang8@gmail.com>
This commit is contained in:
Hoan Luu Huu
2023-05-11 08:32:14 +07:00
committed by GitHub
parent 3d9a39ac3b
commit 6cb1c50cf0
7 changed files with 90 additions and 2 deletions
+6
View File
@@ -33,6 +33,11 @@ export const DISABLE_CUSTOM_SPEECH: boolean = JSON.parse(
import.meta.env.VITE_DISABLE_CUSTOM_SPEECH || "false"
);
/** Enable Forgot Password */
export const ENABLE_FORGOT_PASSWORD: boolean = JSON.parse(
import.meta.env.VITE_ENABLE_FORGOT_PASSWORD || "false"
);
/** Disable Lcr */
export const DISABLE_LCR: boolean = JSON.parse(
import.meta.env.VITE_APP_LCR_DISABLED || "false"
@@ -230,6 +235,7 @@ export const API_CARRIERS = `${API_BASE_URL}/VoipCarriers`;
export const API_SMPP_GATEWAY = `${API_BASE_URL}/SmppGateways`;
export const API_SIP_GATEWAY = `${API_BASE_URL}/SipGateways`;
export const API_PASSWORD_SETTINGS = `${API_BASE_URL}/PasswordSettings`;
export const API_FORGOT_PASSWORD = `${API_BASE_URL}/forgot-password`;
export const API_SYSTEM_INFORMATION = `${API_BASE_URL}/SystemInformation`;
export const API_LCRS = `${API_BASE_URL}/Lcrs`;
export const API_LCR_ROUTES = `${API_BASE_URL}/LcrRoutes`;
+9
View File
@@ -17,6 +17,7 @@ import {
API_SMPP_GATEWAY,
API_SIP_GATEWAY,
API_PASSWORD_SETTINGS,
API_FORGOT_PASSWORD,
USER_ACCOUNT,
API_LOGOUT,
API_SYSTEM_INFORMATION,
@@ -63,6 +64,7 @@ import type {
Limit,
LimitCategories,
PasswordSettings,
ForgotPassword,
SystemInformation,
Lcr,
LcrRoute,
@@ -361,6 +363,13 @@ export const postPasswordSettings = (payload: Partial<PasswordSettings>) => {
);
};
export const postForgotPassword = (payload: Partial<ForgotPassword>) => {
return postFetch<EmptyResponse, Partial<ForgotPassword>>(
API_FORGOT_PASSWORD,
payload
);
};
export const postSystemInformation = (payload: Partial<SystemInformation>) => {
return postFetch<SystemInformation, Partial<SystemInformation>>(
API_SYSTEM_INFORMATION,
+4
View File
@@ -113,6 +113,10 @@ export interface PasswordSettings {
require_special_character: number;
}
export interface ForgotPassword {
email: string;
}
export interface SystemInformation {
domain_name: string;
sip_domain_name: string;
+55
View File
@@ -0,0 +1,55 @@
import React, { useState } from "react";
import { Button, H1 } from "@jambonz/ui-kit";
import { Message } from "src/components/forms";
import { postForgotPassword } from "src/api";
import { StatusCodes } from "src/api/types";
import { useNavigate } from "react-router-dom";
import { MSG_SOMETHING_WRONG } from "src/constants";
import { ROUTE_LOGIN } from "src/router/routes";
export const ForgotPassword = () => {
const [message, setMessage] = useState("");
const [email, setEmail] = useState("");
const navigate = useNavigate();
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
setMessage("");
postForgotPassword({ email })
.then((response) => {
if (response.status === StatusCodes.NO_CONTENT) {
navigate(ROUTE_LOGIN);
} else {
setMessage(MSG_SOMETHING_WRONG);
}
})
.catch((error) => {
setMessage(error.error);
});
};
return (
<>
<H1 className="h2">Forgot Password</H1>
<form className="form form--login" onSubmit={handleSubmit}>
<span>Enter your email and we will send you a password reset link</span>
<input
required
type="email"
name="email"
placeholder="Email"
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
{message && <Message message={message} />}
<Button type="submit">Send me a reset password link</Button>
</form>
</>
);
};
export default ForgotPassword;
+10 -2
View File
@@ -1,6 +1,6 @@
import React, { useEffect, useState } from "react";
import { Button, H1 } from "@jambonz/ui-kit";
import { useLocation, Navigate } from "react-router-dom";
import { useLocation, Navigate, Link } from "react-router-dom";
import { toastError, toastSuccess, useSelectState } from "src/store";
import { useAuth } from "src/router/auth";
@@ -14,8 +14,9 @@ import {
ROUTE_INTERNAL_ACCOUNTS,
ROUTE_CREATE_PASSWORD,
ROUTE_INTERNAL_APPLICATIONS,
ROUTE_FORGOT_PASSWORD,
} from "src/router/routes";
import { USER_ACCOUNT } from "src/api/constants";
import { USER_ACCOUNT, ENABLE_FORGOT_PASSWORD } from "src/api/constants";
export const Login = () => {
const { signin, authorized } = useAuth();
@@ -90,6 +91,13 @@ export const Login = () => {
/>
{message && <Message message={message} />}
<Button type="submit">Log in</Button>
{ENABLE_FORGOT_PASSWORD && (
<div>
<Link to={ROUTE_FORGOT_PASSWORD} title="Forgot Password">
<p>Forgot Password</p>
</Link>
</div>
)}
</form>
</>
);
+5
View File
@@ -6,9 +6,11 @@ import { useSelectState } from "src/store";
import { Login, Layout as LoginLayout } from "src/containers/login";
import { Layout as InternalLayout } from "src/containers/internal";
import { NotFound } from "src/containers/notfound";
import { ENABLE_FORGOT_PASSWORD } from "src/api/constants";
/** Login */
import CreatePassword from "src/containers/login/create-password";
import ForgotPassword from "src/containers/login/forgot-password";
/** Top navi */
import Users from "src/containers/internal/views/users";
@@ -59,6 +61,9 @@ export const Router = () => {
</RequireAuth>
}
/>
{ENABLE_FORGOT_PASSWORD && (
<Route path="forgot-password" element={<ForgotPassword />} />
)}
{/* 404 page not found */}
<Route path="*" element={<NotFound />} />
+1
View File
@@ -1,5 +1,6 @@
export const ROUTE_LOGIN = "/";
export const ROUTE_CREATE_PASSWORD = "/create-password";
export const ROUTE_FORGOT_PASSWORD = "/forgot-password";
export const ROUTE_INTERNAL_USERS = "/internal/users";
export const ROUTE_INTERNAL_SETTINGS = "/internal/settings";
export const ROUTE_INTERNAL_ACCOUNTS = "/internal/accounts";