diff --git a/.vscode/launch.json b/.vscode/launch.json
new file mode 100644
index 0000000..a7bef61
--- /dev/null
+++ b/.vscode/launch.json
@@ -0,0 +1,15 @@
+{
+ // Use IntelliSense to learn about possible attributes.
+ // Hover to view descriptions of existing attributes.
+ // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
+ "version": "0.2.0",
+ "configurations": [
+ {
+ "type": "chrome",
+ "request": "launch",
+ "name": "Launch Chrome against localhost",
+ "url": "http://localhost:3000",
+ "webRoot": "${workspaceFolder}/src"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/components/AutoLogoutProvider.js b/src/components/AutoLogoutProvider.js
index 166055f..6d3a425 100644
--- a/src/components/AutoLogoutProvider.js
+++ b/src/components/AutoLogoutProvider.js
@@ -5,7 +5,8 @@ import { handleLogoutFunction } from 'auth/index';
import { useDispatch } from "react-redux";
import {
isUserLoggedIn,
- isGLDLoggedIn,
+ isGLDLoggedIn,
+ isPasswordExpiry
} from "utils/Utils";
const TimerContext = createContext();
@@ -81,6 +82,9 @@ const AutoLogoutProvider = ({ children }) => {
// console.log(logoutInterval)
const interval = setInterval(async () => {
const currentTime = Date.now();
+ if (isPasswordExpiry()){
+ navigate('/user/changePassword');
+ }
// getRemainingTime();
if(state !== "Active" && lastActiveTab){
const timeElapsed = currentTime - lastRequestTime;
diff --git a/src/layout/MainLayout/Header/index.js b/src/layout/MainLayout/Header/index.js
index 9824011..7368db5 100644
--- a/src/layout/MainLayout/Header/index.js
+++ b/src/layout/MainLayout/Header/index.js
@@ -366,6 +366,13 @@ function Header(props) {
+
+
+
+
+
+
+
@@ -394,6 +401,13 @@ function Header(props) {
+
+
+
+
+
+
+
>
:
@@ -412,6 +426,13 @@ function Header(props) {
+
+
+
+
+
+
+
>
}
diff --git a/src/pages/User/ChangePasswordPage/index.js b/src/pages/User/ChangePasswordPage/index.js
index 354abd5..02dc937 100644
--- a/src/pages/User/ChangePasswordPage/index.js
+++ b/src/pages/User/ChangePasswordPage/index.js
@@ -4,11 +4,6 @@ import * as React from "react";
import * as HttpUtils from "utils/HttpUtils";
import * as UrlUtils from "utils/ApiPathConst";
import { useNavigate } from "react-router-dom";
-import { useDispatch } from "react-redux";
-import { handleLogoutFunction,
- // handleLogin
- } from 'auth/index';
-import useJwt from "auth/jwt/useJwt";
import {
Grid,
@@ -34,96 +29,41 @@ import {PNSPS_LONG_BUTTON_THEME} from "themes/buttonConst";
import {ThemeProvider} from "@emotion/react";
import {FormattedMessage, useIntl} from "react-intl";
import { EyeInvisibleOutlined, EyeOutlined } from '@ant-design/icons';
-import axios from 'axios';
-import { useParams,Link } from 'react-router-dom';
-import CancelOutlinedIcon from '@mui/icons-material/CancelOutlined';
-// import LocaleContext from "components/I18nProvider";
+import CheckCircleOutlineIcon from '@mui/icons-material/CheckCircleOutline';
+import { useDispatch } from "react-redux";
+import { handleLogoutFunction} from 'auth/index';
+import { isPasswordExpiry } from "utils/Utils";
// ==============================|| DASHBOARD - DEFAULT ||============================== //
const Index = () => {
const dispatch = useDispatch()
const navigate = useNavigate()
const [showPassword, setShowPassword] = React.useState(false);
+ const [showNewPassword, setShowNewPassword] = React.useState(false);
const [showConfirmPassword, setshowConfirmPassword] = React.useState(false);
const [isLoading, setLoding] = React.useState(true);
- const [verifyState, setVerifyState] = React.useState(null)
- const [enterUseEffect, setEnterUseEffect] = React.useState(false)
- const [username, setUsername] = React.useState("")
- // const { setLocale } = React.useContext(LocaleContext);
-
- const params = useParams()
+ const [isChanged, setIsChanged] = React.useState(false);
+
const intl = useIntl();
React.useEffect(() => {
- console.log(params);
- setEnterUseEffect(true)
+ setLoding(false)
}, []);
- React.useEffect(() => {
- // console.log("if (enterUseEffect) handleVerify()");
- if (enterUseEffect){
- handleVerify()
- }
- }, [enterUseEffect])
-
- const handleVerify = async () => {
- console.log(params);
- await axios.get(UrlUtils.GET_FORGOT_PASSWORD_VERIFY_USER_ACCOUNT, {
- params: {
- email: decodeURIComponent(params.email),
- emailVerifyHash: decodeURIComponent(params.verifyCode)
- }
- }).then(
- (response)=>{
- if (response.status === 200 && response.data) {
- console.log(response)
- setUsername(response.data.username)
- setVerifyState(true)
- } else {
- setVerifyState(false)
- }
- setLoding(false)
- }
- ).catch(error => {
- console.log(error)
- setVerifyState(false)
- setLoding(false)
- });
-
-
- }
-
- const goLogin = async (values) =>{
- dispatch(handleLogoutFunction());
+ const goLogin = (values) =>{
+ console.log(values)
HttpUtils.post({
- url: UrlUtils.POST_FORGOT_PASSWORD_NEW_PASSWORD,
+ url: UrlUtils.PATCH_CHANGE_PASSWORD,
params:{
- username: username,
- newPassword: values.password
- },
- onSuccess: () => {
- useJwt
- .login({ username: username, password: values.password })
- .then((
- // response
- ) => {
- // console.log(response)
- navigate('/forgot/password/success');
- location.reload()
- // setSumitting(false)
- })
- .catch((error) => {
- console.error(error)
- });
+ password: values.password,
+ newPassword: values.newPassword
},
- onFail: (response)=>{
- console.log("Fail");
- console.log(response);
- // window.location.assign("/iamsmart/loginFail");
+ onSuccess: function (){
+ setIsChanged(true);
},
- onError:(error)=>{
- console.log(error);
+ onError:function (error) {
+ console.log(error.response.data);
// window.location.assign("/iamsmart/loginFail");
}
});
@@ -143,6 +83,10 @@ const Index = () => {
setShowPassword(!showPassword);
};
+ const handleClickShowNewPassword = () => {
+ setShowNewPassword(!showNewPassword);
+ };
+
const handleClickShowConfirmPassword = () => {
setshowConfirmPassword(!showConfirmPassword);
};
@@ -151,6 +95,10 @@ const Index = () => {
event.preventDefault();
};
+ const handleMouseDownNewPassword = (event) => {
+ event.preventDefault();
+ };
+
const changePassword = (
// value
) => {
@@ -158,11 +106,17 @@ const Index = () => {
// setLevel(strengthColorChi(temp));
};
+ const logout = () => {
+ dispatch(handleLogoutFunction());
+ navigate('/login');
+ };
+
const formik = useFormik({
enableReinitialize: true,
initialValues: {
// username: '',
password: '',
+ newPassword: '',
confirmPassword: '',
// emailVerifyHash: '',
},
@@ -176,9 +130,16 @@ const Index = () => {
.matches(/^(?=.*[A-Z])/, { message: intl.formatMessage({id: 'atLeastOneCapLetter'})})
.matches(/^(?=.*[0-9])/, { message: intl.formatMessage({id: 'atLeast1Number'})})
.matches(/^(?=.*[!@#%&])/, { message: intl.formatMessage({id: 'atLeast1SpecialChar'})}),
+ newPassword: yup.string().min(8, intl.formatMessage({id: 'atLeast8CharPassword'}))
+ .required(intl.formatMessage({id: 'requirePassword'}))
+ .matches(/^\S*$/, { message: (intl.formatMessage({id: 'noSpacePassword'}))})
+ .matches(/^(?=.*[a-z])/, { message: intl.formatMessage({id: 'atLeastOneSmallLetter'})})
+ .matches(/^(?=.*[A-Z])/, { message: intl.formatMessage({id: 'atLeastOneCapLetter'})})
+ .matches(/^(?=.*[0-9])/, { message: intl.formatMessage({id: 'atLeast1Number'})})
+ .matches(/^(?=.*[!@#%&])/, { message: intl.formatMessage({id: 'atLeast1SpecialChar'})}),
confirmPassword: yup.string().min(8, intl.formatMessage({id: 'atLeast8CharPassword'}))
.required(intl.formatMessage({id: 'pleaseConfirmPassword'}))
- .oneOf([yup.ref('password'), null], intl.formatMessage({id: 'samePassword'})),
+ .oneOf([yup.ref('newPassword'), null], intl.formatMessage({id: 'samePassword'})),
}),
onSubmit: values => {
// console.log(values)
@@ -187,7 +148,7 @@ const Index = () => {
});
return (
- isLoading || verifyState == null ?
+ isLoading ?
@@ -199,23 +160,11 @@ const Index = () => {
-
+
- {/*
-
- */}
- {/*
- 申請公共啟事
- */}
{
border={false}
boxShadow
>
-
+ :
+
+
+ {/* */}
+
+
+
+
+
+
+
+
+
-
-
-
+
- }
-
+
+ }
+
diff --git a/src/routes/GLDUserRoutes.js b/src/routes/GLDUserRoutes.js
index b446b9f..685bfd4 100644
--- a/src/routes/GLDUserRoutes.js
+++ b/src/routes/GLDUserRoutes.js
@@ -5,7 +5,7 @@ import Loadable from 'components/Loadable';
// import MainLayout from 'layout/MainLayout';
const MainLayout = Loadable(lazy(() => import('layout/MainLayout')));
import {isGranted, isGrantedAny} from "auth/utils";
-import { isPasswordExpiry } from "utils/Utils";
+// import { isPasswordExpiry } from "utils/Utils";
// render - dashboard
const DashboardDefault = Loadable(lazy(() => import('pages/Dashboard/GLD')));
const ApplicationDetail = Loadable(lazy(() => import('pages/PublicNotice/Details_GLD')));
@@ -40,163 +40,159 @@ const GLDUserRoutes = {
path: '/',
element: ,
children: [
- (
- isPasswordExpiry()?
- {
- path: '/',
- element:
- }:
- {
- path: '/',
- element:
- }
- ),
{
- path: '/',
- children: [
- {
- path: '/dashboard',
- element:
- },
- {
- path: '/application/:id',
- element:
- },
- {
- path: '/application/search',
- element:
- },
-
- isGranted(["MAINTAIN_PAYMENT"])?
- {
- path: '/application/markAsPaid/search',
- element:
- }:{},
-
- isGrantedAny(["VIEW_PROOF","MAINTAIN_PROOF"])?{
- path: '/proof/search',
- element:
- }:{},
-
- isGranted("MAINTAIN_PROOF")?
- {
- path: '/proof/create/:id',
- element:
- }:{},
-
- isGrantedAny(["VIEW_PROOF","MAINTAIN_PROOF"])?{
- path: '/proof/reply/:id',
- element:
- }:{},
-
- isGranted(["MAINTAIN_PAYMENT"])?
- {
- path: '/paymentPage/search',
- element:
- }:{},
-
- isGranted(["MAINTAIN_PAYMENT"])?
- {
- path: '/paymentPage/details/:id',
- element:
- }:{},
-
- isGranted(["MAINTAIN_DEMANDNOTE"])?
- {
- path: '/paymentPage/createDemandNote',
- element:
- }:{},
-
- isGranted(["MAINTAIN_DEMANDNOTE"])?
- {
- path: '/paymentPage/exportGDN',
- element:
- }:{},
-
- isGrantedAny(["VIEW_DEMANDNOTE","MAINTAIN_DEMANDNOTE"])?
- {
- path: '/paymentPage/demandNote',
- element:
- }:{},
-
- isGrantedAny(["VIEW_DEMANDNOTE","MAINTAIN_DEMANDNOTE"])?
- {
- path: '/paymentPage/demandNote/details/:id',
- element:
- }:{},
-
- isGranted("MAINTAIN_RECON") ?
- {
- path: '/paymentPage/reconReport',
- element:
- }:{},
-
- isGranted("MAINTAIN_RECON") ?
- {
- path: '/gfmis/search',
- element:
- }:{},
-
-
- {
- path: '/user/profile',
- element:
- },
-
- isGranted("MAINTAIN_SETTING") ?
- {
- path: '/setting/sys',
- element:
- }:{},
-
- isGranted("MAINTAIN_ANNOUNCEMENT") ?
- {
- path: '/setting/announcement',
- element:
- }:{},
-
- isGranted("MAINTAIN_ANNOUNCEMENT")?
- {
- path: '/setting/announcement/details/:id',
- element:
- }:{},
-
- isGranted("MAINTAIN_EMAIL")?
- {
- path: '/setting/emailTemplate',
- element:
- }:{},
-
- isGranted("MAINTAIN_EMAIL")?
- {
- path: '/setting/emailTemplate/:id',
- element:
- }:{},
-
- isGranted("MAINTAIN_GAZETTE_ISSUE")?
- {
- path: '/setting/holiday',
- element:
- }:{},
-
- isGranted("MAINTAIN_GAZETTE_ISSUE")?
- {
- path: '/setting/gazetteissuepage',
- element:
- }:{},
-
- isGranted("MAINTAIN_DR")?
- {
- path: '/setting/drImport',
- element:
- }:{},
- {
- path: '/setting/auditLog',
- element:
- },
- ]
- },
-
+ path: '/',
+ element:
+ },
+ {
+ path: '/',
+ children: [
+ {
+ path: '/dashboard',
+ element:
+ },
+ {
+ path: '/application/:id',
+ element:
+ },
+ {
+ path: '/application/search',
+ element:
+ },
+
+ isGranted(["MAINTAIN_PAYMENT"])?
+ {
+ path: '/application/markAsPaid/search',
+ element:
+ }:{},
+
+ isGrantedAny(["VIEW_PROOF","MAINTAIN_PROOF"])?{
+ path: '/proof/search',
+ element:
+ }:{},
+
+ isGranted("MAINTAIN_PROOF")?
+ {
+ path: '/proof/create/:id',
+ element:
+ }:{},
+
+ isGrantedAny(["VIEW_PROOF","MAINTAIN_PROOF"])?{
+ path: '/proof/reply/:id',
+ element:
+ }:{},
+
+ isGranted(["MAINTAIN_PAYMENT"])?
+ {
+ path: '/paymentPage/search',
+ element:
+ }:{},
+
+ isGranted(["MAINTAIN_PAYMENT"])?
+ {
+ path: '/paymentPage/details/:id',
+ element:
+ }:{},
+
+ isGranted(["MAINTAIN_DEMANDNOTE"])?
+ {
+ path: '/paymentPage/createDemandNote',
+ element:
+ }:{},
+
+ isGranted(["MAINTAIN_DEMANDNOTE"])?
+ {
+ path: '/paymentPage/exportGDN',
+ element:
+ }:{},
+
+ isGrantedAny(["VIEW_DEMANDNOTE","MAINTAIN_DEMANDNOTE"])?
+ {
+ path: '/paymentPage/demandNote',
+ element:
+ }:{},
+
+ isGrantedAny(["VIEW_DEMANDNOTE","MAINTAIN_DEMANDNOTE"])?
+ {
+ path: '/paymentPage/demandNote/details/:id',
+ element:
+ }:{},
+
+ isGranted("MAINTAIN_RECON") ?
+ {
+ path: '/paymentPage/reconReport',
+ element:
+ }:{},
+
+ isGranted("MAINTAIN_RECON") ?
+ {
+ path: '/gfmis/search',
+ element:
+ }:{},
+
+
+ {
+ path: '/user/profile',
+ element:
+ },
+
+ isGranted("MAINTAIN_SETTING") ?
+ {
+ path: '/setting/sys',
+ element:
+ }:{},
+
+ isGranted("MAINTAIN_ANNOUNCEMENT") ?
+ {
+ path: '/setting/announcement',
+ element:
+ }:{},
+
+ isGranted("MAINTAIN_ANNOUNCEMENT")?
+ {
+ path: '/setting/announcement/details/:id',
+ element:
+ }:{},
+
+ isGranted("MAINTAIN_EMAIL")?
+ {
+ path: '/setting/emailTemplate',
+ element:
+ }:{},
+
+ isGranted("MAINTAIN_EMAIL")?
+ {
+ path: '/setting/emailTemplate/:id',
+ element:
+ }:{},
+
+ isGranted("MAINTAIN_GAZETTE_ISSUE")?
+ {
+ path: '/setting/holiday',
+ element:
+ }:{},
+
+ isGranted("MAINTAIN_GAZETTE_ISSUE")?
+ {
+ path: '/setting/gazetteissuepage',
+ element:
+ }:{},
+
+ isGranted("MAINTAIN_DR")?
+ {
+ path: '/setting/drImport',
+ element:
+ }:{},
+ {
+ path: '/setting/auditLog',
+ element:
+ },
+ {
+ path: '/user/changePassword',
+ element:
+ }
+ ]
+ }
]
};
diff --git a/src/routes/PublicUserRoutes.js b/src/routes/PublicUserRoutes.js
index 67c7bec..f12c742 100644
--- a/src/routes/PublicUserRoutes.js
+++ b/src/routes/PublicUserRoutes.js
@@ -4,7 +4,7 @@ import { lazy } from 'react';
import Loadable from 'components/Loadable';
// import MainLayout from 'layout/MainLayout';
const MainLayout = Loadable(lazy(() => import('layout/MainLayout')));
-import { isPasswordExpiry } from "utils/Utils";
+// import { isPasswordExpiry } from "utils/Utils";
// render - dashboard
const DashboardDefault = Loadable(lazy(() => import('pages/Dashboard/Public')));
@@ -33,24 +33,16 @@ const AnnouncementSearch = Loadable(lazy(() => import('pages/Announcement/Search
const IAmSmart_SuccessCallback = Loadable(lazy(() => import('pages/iAmSmart/SuccessCallback')));
const ChangePasswordPage = Loadable(lazy(() => import('pages/User/ChangePasswordPage')));
-
// ==============================|| MAIN ROUTING ||============================== //
const PublicDashboard = {
path: '/',
element: ,
children: [
- (
- isPasswordExpiry()?
- {
- path: '/',
- element:
- }:
- {
- path: '/',
- element:
- }
- ),
+ {
+ path: '/',
+ element:
+ },
{
path: '/',
children: [
diff --git a/src/translations/en.json b/src/translations/en.json
index 8d00780..3de08dc 100644
--- a/src/translations/en.json
+++ b/src/translations/en.json
@@ -161,6 +161,7 @@
"loginSuccessMessage2":"You are our existing user and successfully linked your existing account.
From now on, you can log in through \"iAm Smart\".",
"loginSuccessMessage3":"Continue to use e-Service",
+ "oldPassword": "Old Password",
"newPassword": "New Password",
"setNewPassword": "Please enter new password",
"forgotUserPassword": "Forgot Password",
@@ -237,6 +238,7 @@
"reset": "Reset",
"requireString": "Items marked with * must be filled in",
"confirmPassword": "Confirm password",
+ "confirmOldPassword": "Confirm old password",
"pleaseConfirmPassword": "Please confirm password",
"pleaseEnterOrgOrCompName": "Please enter the English/Chinese name of the organisation/company",
"sameAsBusinessRegistrationCert": "Same as Business Registration Certificate",
@@ -258,6 +260,7 @@
"rejectTerms": "I do not accept",
"verify": "Verify",
"verifySuccess": "Account verified successfully",
+ "passwordExpired": "Your password has expired, please change your password immediately to continue using the system.",
"verifyFail": "Verification failed, please contact the relevant system administrator for assistance.",
"validVerify": "Please enter valid verification",
"requiredValid": "Please enter valid ",
@@ -497,6 +500,7 @@
"userDetail": "User Details",
"userProfile": "My Profile",
+ "userChangePassword": "Change Password",
"primaryUser": "Primary User",
"resetAndBack": "Reset & Back",
"edit": "Edit",
diff --git a/src/translations/zh-CN.json b/src/translations/zh-CN.json
index ecb453e..45fcc81 100644
--- a/src/translations/zh-CN.json
+++ b/src/translations/zh-CN.json
@@ -188,6 +188,7 @@
"loginSuccessMessage2":"你是我们的现有用户,已成功连结现有帐户。
以后可以透过「智方便」登入。",
"loginSuccessMessage3":"继续使用e-Service",
+ "oldPassword": "旧密码",
"newPassword": "新密码",
"setNewPassword": "请输入新密码",
"forgotUserPassword": "忘记密码",
@@ -241,6 +242,7 @@
"requireDialingCode": "请输入国际区号",
"requireVerify": "请输入验证",
"verifySuccess": "帐户已成功验证。",
+ "passwordExpired": "您的密码已过期,请立即更改密码以继续使用系统。",
"verifyFail": "验证失败,请联络相关的系统管理员协助。",
"dialingCode": "国际区号",
"userFaxNumber": "传真号码",
@@ -261,6 +263,7 @@
"reset": "重置",
"requireString": "注有*的项目必须输入资料",
"confirmPassword": "确认密码",
+ "confirmOldPassword": "确认旧密码",
"pleaseConfirmPassword": "请确认密码",
"pleaseEnterOrgOrCompName": "请输入机构/公司英文名称或中文名称",
"sameAsBusinessRegistrationCert": "与商业登记证相同",
@@ -488,6 +491,7 @@
"userDetail": "用户详细信息",
"userProfile": "我的个人资料",
+ "userChangePassword": "更改密码",
"primaryUser": "主要用户",
"resetAndBack": "重置并返回",
"edit": "编辑",
diff --git a/src/translations/zh-HK.json b/src/translations/zh-HK.json
index 4bc372d..79c245c 100644
--- a/src/translations/zh-HK.json
+++ b/src/translations/zh-HK.json
@@ -188,6 +188,7 @@
"loginSuccessMessage2":"你是我們的現有用戶,已成功連結現有帳戶。
以後可以透過「智方便」登入。",
"loginSuccessMessage3":"繼續使用e-Service",
+ "oldPassword": "舊密碼",
"newPassword": "新密碼",
"setNewPassword": "請輸入新密碼",
"forgotUserPassword": "忘記密碼",
@@ -262,6 +263,7 @@
"reset": "重置",
"requireString": "註有*的項目必須輸入資料",
"confirmPassword": "確認密碼",
+ "confirmOldPassword": "確認舊密碼",
"pleaseConfirmPassword": "請確認密碼",
"pleaseEnterOrgOrCompName": "請輸入機構/公司英文名稱或中文名稱",
"sameAsBusinessRegistrationCert": "與商業登記證相同",
@@ -283,6 +285,7 @@
"rejectTerms": "我不接受",
"verify": "驗證",
"verifySuccess": "帳戶已成功驗證。",
+ "passwordExpired": "您的密碼已過期,請立即變更密碼以繼續使用系統。",
"verifyFail": "驗證失敗,請聯絡相關的系統管理員協助。",
"validVerify": "請輸入有效驗證",
"requiredValid": "請輸入有效的",
@@ -493,6 +496,7 @@
"userDetail": "使用者詳細資料",
"userProfile": "我的個人資料",
+ "userChangePassword": "更改密碼",
"primaryUser": "主要使用者",
"resetAndBack": "重置並返回",
"edit": "編輯",
diff --git a/src/utils/ApiPathConst.js b/src/utils/ApiPathConst.js
index 6772862..79fb31a 100644
--- a/src/utils/ApiPathConst.js
+++ b/src/utils/ApiPathConst.js
@@ -95,6 +95,8 @@ export const POST_FORGOT_PASSWORD_NEW_PASSWORD = apiPath+'/user/forgotPasswordNe
export const POST_FORGOT_PASSWORD_EMAIL = apiPath+'/user/sendForgotPasswordEmail';
export const POST_FORGOT_USERNAME_EMAIL = apiPath+'/user/sendForgotUserameEmail';
+export const PATCH_CHANGE_PASSWORD = apiPath+'/user/change-password';
+
//Public
export const GET_PUBLIC_ORG_USER_LIST = apiPath+'/user/listOrg';
diff --git a/src/utils/Utils.js b/src/utils/Utils.js
index f5225c7..dba3845 100644
--- a/src/utils/Utils.js
+++ b/src/utils/Utils.js
@@ -160,10 +160,10 @@ export const isPasswordExpiry = () =>{
var expirationDate = DateUtils.convertToDate(date);
if (expirationDate < currentDate) {
- console.log(true)
+ // console.log(true)
return true; // The date has expired
} else {
- console.log(false)
+ // console.log(false)
return false; // The date is still valid
}
}else{