diff --git a/src/api/constants.ts b/src/api/constants.ts index 706e3cc..6a9c8be 100644 --- a/src/api/constants.ts +++ b/src/api/constants.ts @@ -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`; diff --git a/src/api/index.ts b/src/api/index.ts index 2923de5..6dbf5bc 100644 --- a/src/api/index.ts +++ b/src/api/index.ts @@ -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) => { ); }; +export const postForgotPassword = (payload: Partial) => { + return postFetch>( + API_FORGOT_PASSWORD, + payload + ); +}; + export const postSystemInformation = (payload: Partial) => { return postFetch>( API_SYSTEM_INFORMATION, diff --git a/src/api/types.ts b/src/api/types.ts index 9af9f77..037d940 100644 --- a/src/api/types.ts +++ b/src/api/types.ts @@ -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; diff --git a/src/containers/login/forgot-password.tsx b/src/containers/login/forgot-password.tsx new file mode 100644 index 0000000..7aab87a --- /dev/null +++ b/src/containers/login/forgot-password.tsx @@ -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 ( + <> +

Forgot Password

+
+ Enter your email and we will send you a password reset link + setEmail(e.target.value)} + /> + + {message && } + + + + ); +}; + +export default ForgotPassword; diff --git a/src/containers/login/login.tsx b/src/containers/login/login.tsx index 7706946..46d2d61 100644 --- a/src/containers/login/login.tsx +++ b/src/containers/login/login.tsx @@ -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 && } + {ENABLE_FORGOT_PASSWORD && ( +
+ +

Forgot Password

+ +
+ )} ); diff --git a/src/router/index.tsx b/src/router/index.tsx index a35e76a..8a157f6 100644 --- a/src/router/index.tsx +++ b/src/router/index.tsx @@ -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 = () => { } /> + {ENABLE_FORGOT_PASSWORD && ( + } /> + )} {/* 404 page not found */} } /> diff --git a/src/router/routes.ts b/src/router/routes.ts index 68c3b21..7019f60 100644 --- a/src/router/routes.ts +++ b/src/router/routes.ts @@ -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";