mirror of
https://github.com/OpenSignLabs/OpenSign.git
synced 2026-09-11 12:17:41 +02:00
add createdocument with template Id
This commit is contained in:
@@ -0,0 +1 @@
|
|||||||
|
v1.1.1-beta
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ import multer from 'multer';
|
|||||||
// import fs from 'node:fs';
|
// import fs from 'node:fs';
|
||||||
import updateDocument from './routes/updateDocument.js';
|
import updateDocument from './routes/updateDocument.js';
|
||||||
import deleteDocument from './routes/deleteDocument.js';
|
import deleteDocument from './routes/deleteDocument.js';
|
||||||
// import createDocumentWithTemplate from './routes/CreateDocumentWithTemplate.js';
|
import createDocumentWithTemplate from './routes/CreateDocumentWithTemplate.js';
|
||||||
|
|
||||||
dotenv.config();
|
dotenv.config();
|
||||||
const storage = multer.memoryStorage();
|
const storage = multer.memoryStorage();
|
||||||
@@ -49,7 +49,8 @@ app.get('/contactlist', getContactList);
|
|||||||
app.post('/createdocument', upload.array('file', 1), createDocument);
|
app.post('/createdocument', upload.array('file', 1), createDocument);
|
||||||
|
|
||||||
// create Document with templateId
|
// create Document with templateId
|
||||||
// app.post('/createdocument/:template_id', createDocumentWithTemplate);
|
app.post('/createdocument/:template_id', createDocumentWithTemplate);
|
||||||
|
|
||||||
// get Document on the basis of id
|
// get Document on the basis of id
|
||||||
app.get('/document/:document_id', getDocument);
|
app.get('/document/:document_id', getDocument);
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,98 @@
|
|||||||
|
const randomId = () => Math.floor(1000 + Math.random() * 9000);
|
||||||
|
export default async function createDocumentWithTemplate(request, response) {
|
||||||
|
const signers = request.body.Signers;
|
||||||
|
const folderId = request.body.FolderId;
|
||||||
|
const templateId = request.params.template_id;
|
||||||
|
const url = process.env.SERVER_URL;
|
||||||
|
try {
|
||||||
|
const reqToken = request.headers['x-api-token'];
|
||||||
|
if (!reqToken) {
|
||||||
|
return response.status(400).json({ error: 'Please Provide API Token' });
|
||||||
|
}
|
||||||
|
const tokenQuery = new Parse.Query('appToken');
|
||||||
|
tokenQuery.equalTo('token', reqToken);
|
||||||
|
const token = await tokenQuery.first({ useMasterKey: true });
|
||||||
|
if (token !== undefined) {
|
||||||
|
// Valid Token then proceed request
|
||||||
|
const userPtr = token.get('userId');
|
||||||
|
|
||||||
|
const templateQyuery = new Parse.Query('contracts_Template');
|
||||||
|
const templateRes = await templateQyuery.get(templateId, { useMasterKey: true });
|
||||||
|
if (templateRes) {
|
||||||
|
const template = JSON.parse(JSON.stringify(templateRes));
|
||||||
|
if (template?.Placeholders?.length > 0) {
|
||||||
|
let isValid = template?.Placeholders?.length <= signers?.length;
|
||||||
|
let updateSigners = template?.Placeholders?.every(y =>
|
||||||
|
signers?.some(x => x.Role === y.Role)
|
||||||
|
);
|
||||||
|
if (isValid && updateSigners) {
|
||||||
|
const folderPtr = {
|
||||||
|
__type: 'Pointer',
|
||||||
|
className: 'contracts_Document',
|
||||||
|
objectId: folderId,
|
||||||
|
};
|
||||||
|
const template = JSON.parse(JSON.stringify(templateRes));
|
||||||
|
const object = new Parse.Object('contracts_Document');
|
||||||
|
object.set('Name', template.Name);
|
||||||
|
if (template?.Note) {
|
||||||
|
object.set('Note', template.Note);
|
||||||
|
}
|
||||||
|
if (template?.Description) {
|
||||||
|
object.set('Description', template.Description);
|
||||||
|
}
|
||||||
|
if (template?.Signers) {
|
||||||
|
object.set('Signers', template?.Signers);
|
||||||
|
}
|
||||||
|
object.set('URL', template.URL);
|
||||||
|
object.set('CreatedBy', template.CreatedBy);
|
||||||
|
object.set('ExtUserPtr', template.ExtUserPtr);
|
||||||
|
if (signers) {
|
||||||
|
const placeholders = template?.Placeholders?.map(placeholder => {
|
||||||
|
let matchingSigner = signers.find(y => y.Role === placeholder.Role);
|
||||||
|
if (matchingSigner) {
|
||||||
|
return {
|
||||||
|
...placeholder,
|
||||||
|
email: matchingSigner.Email,
|
||||||
|
signerObjId: '',
|
||||||
|
signerPtr: {},
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
...placeholder,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
console.log('placeholders ', placeholders);
|
||||||
|
object.set('Placeholders', placeholders);
|
||||||
|
}
|
||||||
|
if (folderId) {
|
||||||
|
object.set('Folder', folderPtr);
|
||||||
|
}
|
||||||
|
const newACL = new Parse.ACL();
|
||||||
|
newACL.setPublicReadAccess(false);
|
||||||
|
newACL.setPublicWriteAccess(false);
|
||||||
|
newACL.setReadAccess(userPtr.id, true);
|
||||||
|
newACL.setWriteAccess(userPtr.id, true);
|
||||||
|
object.setACL(newACL);
|
||||||
|
const res = await object.save(null, { useMasterKey: true });
|
||||||
|
return response.json({ objectId: res.id, url: url });
|
||||||
|
} else {
|
||||||
|
return response.status(400).json({ error: 'Please provide signers properly!' });
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return response.status(400).json({ error: 'Please setup template properly!' });
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return response.status(404).json({ error: 'Invalid template id!' });
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return response.status(405).json({ error: 'Invalid API Token!' });
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log('err ', err);
|
||||||
|
if (err.code === 101) {
|
||||||
|
return response.status(404).json({ error: 'Invalid template id!' });
|
||||||
|
}
|
||||||
|
return response.status(400).json({ error: 'Something went wrong!' });
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -10,6 +10,7 @@ import LegaDrive from "./Component/LegaDrive/LegaDrive";
|
|||||||
import PageNotFound from "./Component/PageNotFound";
|
import PageNotFound from "./Component/PageNotFound";
|
||||||
import TemplatePlaceHolder from "./Component/TemplatePlaceholder";
|
import TemplatePlaceHolder from "./Component/TemplatePlaceholder";
|
||||||
import Parse from "parse";
|
import Parse from "parse";
|
||||||
|
import GuestLogin from "./premitives/GuestLogin";
|
||||||
Parse.serverURL = localStorage.getItem("baseUrl");
|
Parse.serverURL = localStorage.getItem("baseUrl");
|
||||||
Parse.initialize(localStorage.getItem("parseAppId"));
|
Parse.initialize(localStorage.getItem("parseAppId"));
|
||||||
// `AppRoutes` is used to define route path of app and
|
// `AppRoutes` is used to define route path of app and
|
||||||
@@ -50,6 +51,8 @@ function AppRoutes() {
|
|||||||
<Route path="/legadrive" element={<LegaDrive />} />
|
<Route path="/legadrive" element={<LegaDrive />} />
|
||||||
{/* Page Not Found */}
|
{/* Page Not Found */}
|
||||||
<Route path="/template/:templateId" element={<TemplatePlaceHolder />} />
|
<Route path="/template/:templateId" element={<TemplatePlaceHolder />} />
|
||||||
|
<Route path="/guestlogin" element={<GuestLogin />} />
|
||||||
|
|
||||||
<Route path="*" element={<PageNotFound />} />
|
<Route path="*" element={<PageNotFound />} />
|
||||||
</Routes>
|
</Routes>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -0,0 +1,294 @@
|
|||||||
|
import React, { useState } from "react";
|
||||||
|
import ModalUi from './ModalUi'
|
||||||
|
import "../css/LoginPage.css";
|
||||||
|
import loader from "../assests/loader2.gif";
|
||||||
|
import axios from "axios";
|
||||||
|
import { useParams } from "react-router-dom";
|
||||||
|
import { themeColor } from "../utils/ThemeColor/backColor";
|
||||||
|
import { useEffect } from "react";
|
||||||
|
import { useNavigate } from "react-router-dom";
|
||||||
|
import GuestSign from "./GuestSign";
|
||||||
|
|
||||||
|
function GuestLogin({children, userdetails}) {
|
||||||
|
const { id, userMail, contactBookId, serverUrl } = useParams();
|
||||||
|
let navigate = useNavigate();
|
||||||
|
const [email, setEmail] = useState(userMail || "prafull.navkar@nxglabs.com");
|
||||||
|
const [OTP, setOTP] = useState("");
|
||||||
|
const [EnterOTP, setEnterOtp] = useState(false);
|
||||||
|
const [loading, setLoading] = useState(false);
|
||||||
|
const [isLoading, setIsLoading] = useState(true);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
handleServerUrl();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
//function generate serverUrl and parseAppId from url and save it in local storage
|
||||||
|
const handleServerUrl = () => {
|
||||||
|
//split url in array from '&'
|
||||||
|
localStorage.clear();
|
||||||
|
// const checkSplit = serverUrl?.split("&");
|
||||||
|
// const server = checkSplit?.[0];
|
||||||
|
// const parseId = checkSplit?.[1];
|
||||||
|
// const appName = checkSplit?.[2];
|
||||||
|
|
||||||
|
// const newServer = server.replaceAll("%2F", "/");
|
||||||
|
// localStorage.setItem("baseUrl", newServer);
|
||||||
|
// localStorage.setItem("parseAppId", parseId);
|
||||||
|
// localStorage.setItem("_appName", appName);
|
||||||
|
|
||||||
|
localStorage.setItem("baseUrl", "https://staging-app.opensignlabs.com/api/app/");
|
||||||
|
localStorage.setItem("parseAppId", "opensignstgn");
|
||||||
|
localStorage.setItem("_appName", "contracts");
|
||||||
|
setIsLoading(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleChange = (event) => {
|
||||||
|
const { value } = event.target;
|
||||||
|
setOTP(value);
|
||||||
|
};
|
||||||
|
|
||||||
|
//send email OTP function
|
||||||
|
const SendOtp = async (e) => {
|
||||||
|
const serverUrl =
|
||||||
|
localStorage.getItem("baseUrl") && localStorage.getItem("baseUrl");
|
||||||
|
const parseId =
|
||||||
|
localStorage.getItem("parseAppId") && localStorage.getItem("parseAppId");
|
||||||
|
if (serverUrl && localStorage) {
|
||||||
|
setLoading(true);
|
||||||
|
e.preventDefault();
|
||||||
|
setEmail(email);
|
||||||
|
|
||||||
|
try {
|
||||||
|
let url = `${serverUrl}functions/SendOTPMailV1/`;
|
||||||
|
const headers = {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
"X-Parse-Application-Id": parseId
|
||||||
|
};
|
||||||
|
let body = {
|
||||||
|
email: email.toString()
|
||||||
|
};
|
||||||
|
let Otp = await axios.post(url, body, { headers: headers });
|
||||||
|
|
||||||
|
if (Otp) {
|
||||||
|
setLoading(false);
|
||||||
|
setEnterOtp(true);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
alert("something went wrong!");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
alert("something went wrong!");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//verify OTP send on via email
|
||||||
|
const VerifyOTP = async (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
const serverUrl =
|
||||||
|
localStorage.getItem("baseUrl") && localStorage.getItem("baseUrl");
|
||||||
|
const parseId =
|
||||||
|
localStorage.getItem("parseAppId") && localStorage.getItem("parseAppId");
|
||||||
|
if (OTP) {
|
||||||
|
setLoading(true);
|
||||||
|
try {
|
||||||
|
let url = `${serverUrl}functions/AuthLoginAsMail/`;
|
||||||
|
const headers = {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
"X-Parse-Application-Id": parseId
|
||||||
|
};
|
||||||
|
let body = {
|
||||||
|
email: email,
|
||||||
|
otp: OTP
|
||||||
|
};
|
||||||
|
let user = await axios.post(url, body, { headers: headers });
|
||||||
|
if (user.data.result === "Invalid Otp") {
|
||||||
|
alert("Invalid Otp");
|
||||||
|
setLoading(false);
|
||||||
|
} else if (user.data.result === "user not found!") {
|
||||||
|
alert("User not found!");
|
||||||
|
setLoading(false);
|
||||||
|
} else {
|
||||||
|
let _user = user.data.result;
|
||||||
|
const parseId = localStorage.getItem("parseAppId");
|
||||||
|
localStorage.setItem("UserInformation", JSON.stringify(_user));
|
||||||
|
localStorage.setItem(
|
||||||
|
`Parse/${parseId}/currentUser`,
|
||||||
|
JSON.stringify(_user)
|
||||||
|
);
|
||||||
|
localStorage.setItem("username", _user.name);
|
||||||
|
localStorage.setItem("accesstoken", _user.sessionToken);
|
||||||
|
//save isGuestSigner true in local to handle login flow header in mobile view
|
||||||
|
localStorage.setItem("isGuestSigner", true);
|
||||||
|
setLoading(false);
|
||||||
|
// uKymQWaYL6
|
||||||
|
navigate(
|
||||||
|
`/loadmf/signmicroapp/recipientSignPdf/${id}/${contactBookId}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} catch (error) {}
|
||||||
|
} else {
|
||||||
|
alert("Please Enter OTP!");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div style={{ padding: "2rem" }}>
|
||||||
|
<ModalUi isOpen>
|
||||||
|
<>
|
||||||
|
{isLoading ? (
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
display: "flex",
|
||||||
|
justifyContent: "center",
|
||||||
|
alignItems: "center",
|
||||||
|
height: "100vh",
|
||||||
|
flexDirection: "column"
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
alt="no img"
|
||||||
|
src={loader}
|
||||||
|
style={{ width: "80px", height: "80px" }}
|
||||||
|
/>
|
||||||
|
<span style={{ fontSize: "13px", color: "gray" }}>
|
||||||
|
{isLoading.message}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
margin: "10px",
|
||||||
|
border: "0.5px solid #c5c7c9",
|
||||||
|
padding: "30px",
|
||||||
|
boxShadow: "rgba(99, 99, 99, 0.2) 0px 2px 8px 0px"
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div className="main_head">
|
||||||
|
<div className="main-logo">
|
||||||
|
<img
|
||||||
|
alt="sign img"
|
||||||
|
src="https://qikinnovation.ams3.digitaloceanspaces.com/logo.png"
|
||||||
|
width="100%"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{!EnterOTP ? (
|
||||||
|
<div >
|
||||||
|
<div >
|
||||||
|
<span className="welcomeText">Welcome Back !</span>
|
||||||
|
<br />
|
||||||
|
<span className="KNLO">
|
||||||
|
Verification code is sent to your email
|
||||||
|
</span>
|
||||||
|
<div className="card card-box" style={{ borderRadius: "0px" }}>
|
||||||
|
<div className="card-body">
|
||||||
|
<input
|
||||||
|
type="email"
|
||||||
|
name="mobile"
|
||||||
|
value={email}
|
||||||
|
disabled
|
||||||
|
className="loginInput"
|
||||||
|
/>
|
||||||
|
<br />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="btnContainer">
|
||||||
|
{loading ? (
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
style={{
|
||||||
|
background: themeColor(),
|
||||||
|
color: "white"
|
||||||
|
}}
|
||||||
|
className="verifyBtn"
|
||||||
|
disabled
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
className="spinner-border spinner-border-sm "
|
||||||
|
role="status"
|
||||||
|
aria-hidden="true"
|
||||||
|
></span>
|
||||||
|
Loading...
|
||||||
|
</button>
|
||||||
|
) : (
|
||||||
|
<button
|
||||||
|
className="verifyBtn"
|
||||||
|
style={{
|
||||||
|
background: themeColor(),
|
||||||
|
color: "white",
|
||||||
|
marginLeft: "0px !important"
|
||||||
|
}}
|
||||||
|
onClick={(e) => SendOtp(e)}
|
||||||
|
>
|
||||||
|
Send OTP
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<div >
|
||||||
|
<div >
|
||||||
|
<span className="welcomeText">Welcome Back !</span>
|
||||||
|
<br />
|
||||||
|
<span className="KNLO">You will get a OTP via Email</span>
|
||||||
|
<div className="card card-box">
|
||||||
|
<div className="card-body">
|
||||||
|
<label>Enter Verification Code</label>
|
||||||
|
<input
|
||||||
|
type="number"
|
||||||
|
className="loginInput"
|
||||||
|
name="OTP"
|
||||||
|
value={OTP}
|
||||||
|
onChange={handleChange}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<br />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
{loading ? (
|
||||||
|
<button
|
||||||
|
style={{
|
||||||
|
background: themeColor(),
|
||||||
|
color: "white"
|
||||||
|
}}
|
||||||
|
className="verifyBtn"
|
||||||
|
type="button"
|
||||||
|
disabled
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
className="spinner-border spinner-border-sm "
|
||||||
|
role="status"
|
||||||
|
aria-hidden="true"
|
||||||
|
></span>
|
||||||
|
Loading...
|
||||||
|
</button>
|
||||||
|
) : (
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={(e) => VerifyOTP(e)}
|
||||||
|
style={{
|
||||||
|
background: themeColor(),
|
||||||
|
color: "white"
|
||||||
|
}}
|
||||||
|
className="verifyBtn"
|
||||||
|
>
|
||||||
|
Verify
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
</ModalUi>
|
||||||
|
<div><GuestSign /></div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default GuestLogin;
|
||||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user