mirror of
https://github.com/OpenSignLabs/OpenSign.git
synced 2026-08-17 21:25:54 +02:00
add session validation, updated migration script and minor ui changes
This commit is contained in:
@@ -15,6 +15,7 @@ import ForgetPassword from "./routes/ForgetPassword";
|
||||
import ChangePassword from "./routes/ChangePassword";
|
||||
import ReportMicroapp from "./components/ReportMicroapp";
|
||||
import LoadMf from "./routes/LoadMf";
|
||||
import ValidateRoute from "./layout/ValidateRoute";
|
||||
|
||||
function App() {
|
||||
const [isloading, setIsLoading] = useState(true);
|
||||
@@ -58,8 +59,24 @@ function App() {
|
||||
) : (
|
||||
<BrowserRouter>
|
||||
<Routes>
|
||||
<Route exact path="/" element={<Login />} />
|
||||
<Route exact path="/signup" element={<Signup />} />
|
||||
<Route
|
||||
exact
|
||||
path="/"
|
||||
element={
|
||||
<ValidateRoute>
|
||||
<Login />
|
||||
</ValidateRoute>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
exact
|
||||
path="/signup"
|
||||
element={
|
||||
<ValidateRoute>
|
||||
<Signup />
|
||||
</ValidateRoute>
|
||||
}
|
||||
/>
|
||||
<Route exact path="/loadmf/:remoteApp/*" element={<LoadMf />} />
|
||||
<Route exact path="/forgetpassword" element={<ForgetPassword />} />
|
||||
{process.env.REACT_APP_ENABLE_SUBSCRIPTION && (
|
||||
|
||||
@@ -7,10 +7,35 @@ import Tour from "reactour";
|
||||
import axios from "axios";
|
||||
import { useSelector } from "react-redux";
|
||||
import Parse from "parse";
|
||||
import ModalUi from "../primitives/ModalUi";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
|
||||
const HomeLayout = ({ children }) => {
|
||||
const navigate = useNavigate();
|
||||
const { width } = useWindowSize();
|
||||
const [isOpen, setIsOpen] = useState(true);
|
||||
const arr = useSelector((state) => state.TourSteps);
|
||||
const [isUserValid, setIsUserValid] = useState(true);
|
||||
|
||||
useEffect(() => {
|
||||
(async () => {
|
||||
try {
|
||||
// Use the session token to validate the user
|
||||
const userQuery = new Parse.Query(Parse.User);
|
||||
const user = await userQuery.get(Parse.User.current().id, {
|
||||
sessionToken: localStorage.getItem("accesstoken")
|
||||
});
|
||||
if (user) {
|
||||
setIsUserValid(true);
|
||||
} else {
|
||||
setIsUserValid(false);
|
||||
}
|
||||
} catch (error) {
|
||||
// Session token is invalid or there was an error
|
||||
setIsUserValid(false);
|
||||
}
|
||||
})();
|
||||
}, []);
|
||||
|
||||
// reactour state
|
||||
const [isCloseBtn, setIsCloseBtn] = useState(true);
|
||||
@@ -19,7 +44,7 @@ const HomeLayout = ({ children }) => {
|
||||
const [tourConfigs, setTourConfigs] = useState([]);
|
||||
|
||||
const showSidebar = () => {
|
||||
setIsOpen(value => !value);
|
||||
setIsOpen((value) => !value);
|
||||
};
|
||||
useEffect(() => {
|
||||
if (width && width <= 768) {
|
||||
@@ -28,9 +53,7 @@ const HomeLayout = ({ children }) => {
|
||||
}, [width]);
|
||||
|
||||
useEffect(() => {
|
||||
if (localStorage.getItem("domain") === "sign" && arr && arr.length > 0) {
|
||||
handleDynamicSteps();
|
||||
} else if (
|
||||
if (
|
||||
localStorage.getItem("domain") === "contracts" &&
|
||||
arr &&
|
||||
arr.length > 0
|
||||
@@ -153,32 +176,58 @@ const HomeLayout = ({ children }) => {
|
||||
setIsOpen(false);
|
||||
}
|
||||
};
|
||||
|
||||
const handleLoginBtn = () => {
|
||||
Parse.User.logOut();
|
||||
navigate("/", { replace: true });
|
||||
};
|
||||
return (
|
||||
<div>
|
||||
<div className="sticky top-0 z-50">
|
||||
<Header showSidebar={showSidebar} />
|
||||
</div>
|
||||
<div className="flex md:flex-row flex-col z-50">
|
||||
<Sidebar isOpen={isOpen} closeSidebar={closeSidebar} />
|
||||
{isUserValid ? (
|
||||
<>
|
||||
<div className="flex md:flex-row flex-col z-50">
|
||||
<Sidebar isOpen={isOpen} closeSidebar={closeSidebar} />
|
||||
|
||||
<div className="relative h-screen flex flex-col justify-between w-full overflow-y-auto">
|
||||
<div className="bg-[#eef1f5] p-3">{children}</div>
|
||||
<div className="z-30">
|
||||
<Footer />
|
||||
<div className="relative h-screen flex flex-col justify-between w-full overflow-y-auto">
|
||||
<div className="bg-[#eef1f5] p-3">{children}</div>
|
||||
<div className="z-30">
|
||||
<Footer />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Tour
|
||||
onRequestClose={closeTour}
|
||||
steps={tourConfigs}
|
||||
isOpen={isTour}
|
||||
closeWithMask={false}
|
||||
disableKeyboardNavigation={["esc"]}
|
||||
// disableInteraction={true}
|
||||
scrollOffset={-100}
|
||||
rounded={5}
|
||||
showCloseButton={isCloseBtn}
|
||||
/>
|
||||
<Tour
|
||||
onRequestClose={closeTour}
|
||||
steps={tourConfigs}
|
||||
isOpen={isTour}
|
||||
closeWithMask={false}
|
||||
disableKeyboardNavigation={["esc"]}
|
||||
// disableInteraction={true}
|
||||
scrollOffset={-100}
|
||||
rounded={5}
|
||||
showCloseButton={isCloseBtn}
|
||||
/>
|
||||
</>
|
||||
) : (
|
||||
<ModalUi
|
||||
title={"Session Expired"}
|
||||
headColor={"#dc3545"}
|
||||
isOpen={true}
|
||||
showClose={false}
|
||||
>
|
||||
<div className="flex flex-col justify-center items-center py-5 gap-5">
|
||||
<p className="text-xl font-semibold ">Your Session has Expired.</p>
|
||||
<button
|
||||
onClick={handleLoginBtn}
|
||||
className="text-base px-3 py-1.5 rounded shadow-md text-white bg-[#1ab6ce]"
|
||||
>
|
||||
Login
|
||||
</button>
|
||||
</div>
|
||||
</ModalUi>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
import React, { useEffect } from "react";
|
||||
import Parse from "parse";
|
||||
|
||||
const ValidateRoute = ({ children }) => {
|
||||
useEffect(() => {
|
||||
(async () => {
|
||||
try {
|
||||
// Use the session token to validate the user
|
||||
const userQuery = new Parse.Query(Parse.User);
|
||||
const user = await userQuery.get(Parse.User.current().id, {
|
||||
sessionToken: localStorage.getItem("accesstoken")
|
||||
});
|
||||
if (!user) {
|
||||
Parse.User.logOut();
|
||||
}
|
||||
} catch (error) {
|
||||
// Session token is invalid or there was an error
|
||||
Parse.User.logOut();
|
||||
}
|
||||
})();
|
||||
}, []);
|
||||
return <div>{children}</div>;
|
||||
};
|
||||
|
||||
export default ValidateRoute;
|
||||
@@ -1,21 +1,35 @@
|
||||
import React from "react";
|
||||
const ModalUi = ({ children, title, isOpen, handleClose }) => {
|
||||
|
||||
const ModalUi = ({
|
||||
children,
|
||||
title,
|
||||
isOpen,
|
||||
headColor,
|
||||
handleClose,
|
||||
showHeader = true,
|
||||
showClose = true
|
||||
}) => {
|
||||
return (
|
||||
<>
|
||||
{isOpen && (
|
||||
<div className="fixed z-[999] top-0 left-0 w-[100%] h-[100%] bg-black bg-opacity-[75%]">
|
||||
<div className="fixed z-[1000] top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 text-sm bg-white rounded shadow-md max-h-90 md:min-w-[500px] overflow-y-auto hide-scrollbar">
|
||||
<div className="flex justify-between bg-[#32a3ac] rounded-t items-center py-[10px] px-[20px] text-white">
|
||||
<div className="text-[1.2rem] font-normal">{title}</div>
|
||||
{showHeader && (
|
||||
<div
|
||||
className="text-[1.5rem] cursor-pointer"
|
||||
onClick={() => handleClose && handleClose()}
|
||||
className="flex justify-between rounded-t items-center py-[15px] px-[20px] text-white"
|
||||
style={{ background: headColor ? headColor : "#32a3ac" }}
|
||||
>
|
||||
×
|
||||
<div className="text-[1.2rem] font-normal">{title}</div>
|
||||
{showClose && (
|
||||
<div
|
||||
className="text-[1.5rem] cursor-pointer"
|
||||
onClick={() => handleClose && handleClose()}
|
||||
>
|
||||
×
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div >{children}</div>
|
||||
)}
|
||||
<div>{children}</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -32,7 +32,7 @@ exports.up = async Parse => {
|
||||
objectId: 'sHAnZphf69',
|
||||
},
|
||||
{
|
||||
icon: 'fas fa-file-signature',
|
||||
icon: 'fa-solid fa-paper-plane',
|
||||
title: 'Request signatures',
|
||||
target: '_self',
|
||||
pageType: 'form',
|
||||
@@ -50,7 +50,7 @@ exports.up = async Parse => {
|
||||
],
|
||||
},
|
||||
{
|
||||
icon: 'fas fa-file-signature',
|
||||
icon: 'fa-solid fa-file-contract',
|
||||
title: 'Templates',
|
||||
target: '_self',
|
||||
pageType: 'report',
|
||||
@@ -181,23 +181,30 @@ exports.up = async Parse => {
|
||||
objectId: 'sHAnZphf69',
|
||||
},
|
||||
{
|
||||
icon: 'fas fa-file-signature',
|
||||
icon: 'fa-solid fa-paper-plane',
|
||||
title: 'Request signatures',
|
||||
target: '_self',
|
||||
pageType: 'form',
|
||||
description: '',
|
||||
objectId: '8mZzFxbG1z',
|
||||
},
|
||||
{
|
||||
icon: 'fas fa-file-signature',
|
||||
title: 'New template',
|
||||
target: '_self',
|
||||
pageType: 'form',
|
||||
description: '',
|
||||
objectId: 'template',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
icon: 'fas fa-folder',
|
||||
title: 'OpenSignDrive™',
|
||||
icon: 'fa-solid fa-file-contract',
|
||||
title: 'Templates',
|
||||
target: '_self',
|
||||
pageType: 'mf',
|
||||
pageType: 'report',
|
||||
description: '',
|
||||
objectId:
|
||||
'remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/legadrive',
|
||||
objectId: '6TeaPr321t',
|
||||
},
|
||||
{
|
||||
icon: 'fas fa-address-card',
|
||||
|
||||
@@ -43,7 +43,7 @@ const EditTemplate = ({ template, onSuccess }) => {
|
||||
fontWeight: "700"
|
||||
}}
|
||||
>
|
||||
file selected : {template.URL?.split("/")[3]?.split("_")[1]}
|
||||
{template.URL?.split("/")[3]?.split("_")[1]}
|
||||
</div>
|
||||
</div>
|
||||
<div className="form-section">
|
||||
|
||||
@@ -10,12 +10,12 @@ const LinkUserModal = (props) => {
|
||||
details={props.handleAddUser}
|
||||
closePopup={props.closePopup}
|
||||
/>
|
||||
<div style={{ display: "flex", alignItems: "center", gap: 5, margin:"0px 25px" }}>
|
||||
<div style={{ display: "flex", alignItems: "center", gap: 5, margin:"0 30%", color:"#808080" }}>
|
||||
<span
|
||||
style={{
|
||||
height: 1,
|
||||
width: "100%",
|
||||
backgroundColor: "grey"
|
||||
backgroundColor: "#ccc"
|
||||
}}
|
||||
></span>
|
||||
<span>or</span>
|
||||
@@ -23,7 +23,7 @@ const LinkUserModal = (props) => {
|
||||
style={{
|
||||
height: 1,
|
||||
width: "100%",
|
||||
backgroundColor: "grey"
|
||||
backgroundColor: "#ccc"
|
||||
}}
|
||||
></span>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.addusercontainer {
|
||||
height: 100%;
|
||||
padding: 20px;
|
||||
padding: 10px 20px 10px 20px;
|
||||
}
|
||||
|
||||
.loaderdiv {
|
||||
|
||||
@@ -87,10 +87,9 @@ const SelectSigners = (props) => {
|
||||
/>
|
||||
</div>
|
||||
{isError ? <p style={{color:'red', fontSize: "12px", margin:"5px"}}>Please select signer</p>: <p style={{color:'transparent', fontSize: "12px", margin:"5px"}}>.</p>}
|
||||
|
||||
<div >
|
||||
<div>
|
||||
<button className="submitbutton" onClick={() => handleAdd()}>
|
||||
Add Signer
|
||||
Submit
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user