diff --git a/apps/OpenSign/src/App.js b/apps/OpenSign/src/App.js index deb9b19f6..e2cce85b5 100644 --- a/apps/OpenSign/src/App.js +++ b/apps/OpenSign/src/App.js @@ -17,6 +17,7 @@ import ReportMicroapp from "./components/ReportMicroapp"; import LoadMf from "./routes/LoadMf"; import GenerateToken from "./routes/GenerateToken"; import ValidateRoute from "./primitives/ValidateRoute"; +import Webhook from "./routes/Webhook"; function App() { const [isloading, setIsLoading] = useState(true); @@ -82,6 +83,7 @@ function App() { } /> } /> } /> + } /> } /> diff --git a/apps/OpenSign/src/routes/Webhook.js b/apps/OpenSign/src/routes/Webhook.js new file mode 100644 index 000000000..2c1424ec5 --- /dev/null +++ b/apps/OpenSign/src/routes/Webhook.js @@ -0,0 +1,186 @@ +import React, { useEffect, useState } from "react"; +import Title from "../components/Title"; +import axios from "axios"; +import Alert from "../primitives/Alert"; +import ModalUi from "../primitives/ModalUi"; +import { rejectBtn, submitBtn } from "../constant/const"; +import { openInNewTab } from "../constant/Utils"; +import Parse from "parse"; + +function Webhook() { + const [parseBaseUrl] = useState(localStorage.getItem("baseUrl")); + const [parseAppId] = useState(localStorage.getItem("parseAppId")); + const [webhook, setWebhook] = useState(); + const [isLoader, setIsLoader] = useState(true); + const [copied, setCopied] = useState(false); + const [isGenerate, setIsGenerate] = useState(false); + const [isErr, setIsErr] = useState(false); + const [isModal, setIsModal] = useState(false); + + useEffect(() => { + fetchWebhook(); + // eslint-disable-next-line + }, []); + + const fetchWebhook = async () => { + const email = Parse.User.current().getEmail(); + const params = { email: email }; + try { + const extRes = await Parse.Cloud.run("getUserDetails", params); + if (extRes) { + setWebhook(extRes.get("Webhook")); + } + setIsLoader(false); + } catch (err) { + setWebhook(); + setIsLoader(false); + console.log("Err", err); + } + }; + const handleSubmit = async (e) => { + e.preventDefault(); + setIsLoader(true); + setIsModal(false); + try { + const params = { url: webhook }; + const url = parseBaseUrl + "functions/savewebhook"; + const headers = { + "Content-Type": "application/json", + "X-Parse-Application-Id": parseAppId, + sessiontoken: localStorage.getItem("accesstoken") + }; + await axios.post(url, params, { headers: headers }).then((res) => { + if (res.data && res.data.result && res.data.result.Webhook) { + setWebhook(res.data.result.Webhook); + setIsGenerate(true); + setTimeout(() => { + setIsGenerate(false); + }, 1500); + setIsLoader(false); + } else { + console.error("Error while generating webhook"); + setIsLoader(false); + setIsErr(true); + setTimeout(() => { + setIsErr(false); + }, 1500); + } + }); + } catch (error) { + setIsLoader(false); + setIsErr(true); + setTimeout(() => { + setIsErr(false); + }, 1500); + + console.log("err", error); + } + }; + + const copytoclipboard = (text) => { + navigator.clipboard.writeText(text); + setCopied(true); + setTimeout(() => { + setCopied(false); + }, 1500); // Reset copied state after 1.5 seconds + }; + const handleModal = () => setIsModal(!isModal); + return ( + + + {isGenerate && <Alert type="success">Webhook added successfully!</Alert>} + {copied && <Alert type="success">Copied</Alert>} + {isErr && <Alert type="danger">Something went wrong!</Alert>} + {isLoader ? ( + <div + style={{ + height: "100vh", + display: "flex", + alignItems: "center", + justifyContent: "center" + }} + > + <div + style={{ + fontSize: "45px", + color: "#3dd3e0" + }} + className="loader-37" + ></div> + </div> + ) : ( + <div className="bg-white flex flex-col justify-center shadow rounded"> + <ul className="w-full flex flex-col p-2 text-sm"> + <li + className={`flex justify-between items-center border-t-[1px] border-gray-300 break-all py-2`} + > + <span className="w-[40%]">Webhook:</span>{" "} + <span id="token" className="w-[60%] md:text-end cursor-pointer"> + {webhook && webhook} + </span> + </li> + <li + className={`flex justify-between items-center border-y-[1px] border-gray-300 break-all py-2`} + > + <span className="w-[40%]">Application Id:</span>{" "} + <span + className="w-[60%] md:text-end cursor-pointer" + onClick={() => copytoclipboard(localStorage.getItem("AppID12"))} + > + {localStorage.getItem("AppID12")} + </span> + </li> + </ul> + <div className="flex flex-col md:flex-row items-center justify-center gap-2 pb-4"> + <button + type="button" + onClick={handleModal} + className="rounded hover:bg-[#15b4e9] border-[1px] border-[#15b4e9] text-[#15b4e9] hover:text-white px-4 py-2 text-xs md:text-base focus:outline-none" + > + {webhook ? "Update Webhook" : "Add Webhook"} + </button> + <button + type="button" + onClick={() => openInNewTab("https://docs.opensignlabs.com")} + className="rounded hover:bg-[#15b4e9] border-[1px] border-[#15b4e9] text-[#15b4e9] hover:text-white px-11 py-2 text-xs md:text-base focus:outline-none" + > + View Docs + </button> + </div> + + <ModalUi + isOpen={isModal} + title={"Regenerate Token"} + handleClose={handleModal} + > + <div className="m-[20px]"> + <div className="text-lg font-normal text-black"> + <label className="text-sm ml-2">Webhook</label> + <input + value={webhook} + onChange={(e) => setWebhook(e.target.value)} + placeholder="Enter webhook url" + className="px-3 py-2 w-full border-[1px] border-gray-300 rounded focus:outline-none text-xs" + /> + </div> + <hr className="bg-[#ccc] mt-4 " /> + <div className="flex items-center mt-3 gap-2 text-white"> + <button + onClick={handleSubmit} + className={submitBtn + "ml-[2px]"} + > + Yes + </button> + <button onClick={handleModal} className={rejectBtn}> + No + </button> + </div> + </div> + </ModalUi> + </div> + )} + </React.Fragment> + ); +} + +export default Webhook; diff --git a/apps/OpenSignServer/cloud/main.js b/apps/OpenSignServer/cloud/main.js index b6ff1ed7a..b02ac1894 100644 --- a/apps/OpenSignServer/cloud/main.js +++ b/apps/OpenSignServer/cloud/main.js @@ -21,6 +21,7 @@ import generateApiToken from './parsefunction/generateApiToken.js'; import getapitoken from './parsefunction/getapitoken.js'; import TemplateAfterSave from './parsefunction/TemplateAfterSave.js'; import GetTemplate from './parsefunction/GetTemplate.js'; +import savewebhook from './parsefunction/saveWebhook.js'; Parse.Cloud.define('AddUserToRole', addUserToGroups); Parse.Cloud.define('UserGroups', getUserGroups); @@ -41,6 +42,7 @@ Parse.Cloud.define('getReport', getReport); Parse.Cloud.define('generateapitoken', generateApiToken); Parse.Cloud.define('getapitoken', getapitoken); Parse.Cloud.define('getTemplate', GetTemplate); +Parse.Cloud.define('savewebhook', savewebhook); Parse.Cloud.afterSave('contracts_Document', DocumentAftersave); Parse.Cloud.afterSave('contracts_Contactbook', ContactbookAftersave); Parse.Cloud.afterSave('contracts_Users', ContractUsersAftersave); diff --git a/apps/OpenSignServer/cloud/parsefunction/pdf/PDF.min.js b/apps/OpenSignServer/cloud/parsefunction/pdf/PDF.min.js index b6f989cb7..3400963d3 100644 --- a/apps/OpenSignServer/cloud/parsefunction/pdf/PDF.min.js +++ b/apps/OpenSignServer/cloud/parsefunction/pdf/PDF.min.js @@ -2,7 +2,6 @@ import SignPDF from './SignPDF.min.cjs'; import fs from 'node:fs'; import axios from 'axios'; import FormData from 'form-data'; -// import plainplaceholder from './customSignPdf/plainplaceholder.min.js'; import { plainAddPlaceholder } from 'node-signpdf/dist/helpers/index.js'; const serverUrl = process.env.SERVER_URL, APPID = process.env.APP_ID, @@ -19,22 +18,22 @@ async function uploadFile(a) { console.log('err ', e), fs.unlinkSync(a); } } -async function updateDoc(t, s, r, i, n, o) { +async function updateDoc(t, s, r, i, o, n) { try { var d = { - UserPtr: { __type: 'Pointer', className: o, objectId: r }, + UserPtr: { __type: 'Pointer', className: n, objectId: r }, SignedUrl: s, Activity: 'Signed', ipAddress: i, }; let e; - var l = (e = n.AuditTrail && 0 < n.AuditTrail.length ? [...n.AuditTrail, d] : [d]).filter( + var l = (e = o.AuditTrail && 0 < o.AuditTrail.length ? [...o.AuditTrail, d] : [d]).filter( e => 'Signed' === e.Activity ); let a = !1; - !((n.Signers && 0 < n.Signers.length && l.length !== n.Signers.length) || !(a = !0)); - var p = { SignedUrl: s, AuditTrail: e, IsCompleted: a }; - await axios.put(serverUrl + '/classes/contracts_Document/' + t, p, { + !((o.Signers && 0 < o.Signers.length && l.length !== o.Signers.length) || !(a = !0)); + var c = { SignedUrl: s, AuditTrail: e, IsCompleted: a }; + await axios.put(serverUrl + '/classes/contracts_Document/' + t, c, { headers: { 'Content-Type': 'application/json', 'X-Parse-Application-Id': APPID, @@ -61,7 +60,7 @@ async function sendMail(e) { s + ' Standard is attached to this email. Kindly download the document from the attachment.</p></div> </div><div><p>This is an automated email from Open Sign. For any queries regarding this email, please contact the sender ' + t.Mail + - ' directly. If you think this email is inappropriate or spam, you may file a complaint with Open Sign <a href=www.opensignlabs.com target=_blank>here</a>.</p></div></div></body></html>' + ' directly. If you think this email is inappropriate or spam, you may file a complaint with Open Sign here.</p></div></div></body></html>', }; await axios.post(serverUrl + '/functions/sendmailv3', a, { headers: { @@ -86,7 +85,7 @@ async function sendCompletedMail(e) { s + '. Kindly download the document from the attachment.</p></div> </div><div><p>This is an automated email from Open Sign. For any queries regarding this email, please contact the sender ' + t.Mail + - ' directly. If you think this email is inappropriate or spam, you may file a complaint with Open Sign <a href=www.opensignlabs.com target=_blank>here</a>.</p></div></div></body></html>', + ' directly. If you think this email is inappropriate or spam, you may file a complaint with Open Sign here.</p></div></div></body></html>', }; await axios.post(serverUrl + '/functions/sendmailv3', a, { headers: { @@ -96,12 +95,58 @@ async function sendCompletedMail(e) { }, }); } -async function PDF(i, n) { +async function sendDoctoWebhook(t) { + var e; + t.data.ExtUserPtr?.Webhook && + ((e = { + File: t?.data?.SignedUrl, + Name: t?.data?.Name, + Note: t?.data?.Note, + Description: t?.data?.Description, + Signers: t?.data?.Signers?.map(e => e.Name), + Completed: !0, + CompletedAt: new Date(), + CreatedAt: t?.data?.createdAt, + }), + await axios + .post(t?.data?.ExtUserPtr?.Webhook, e, { headers: { 'Content-Type': 'application/json' } }) + .then(e => { + try { + console.log('res ', e); + var a = new Parse.Object('contracts_Webhook'); + a.set('Log', e?.status), + a.set('UserId', { + __type: 'Pointer', + className: '_User', + objectId: t.data.ExtUserPtr.UserId.objectId, + }), + a.save(null, { useMasterKey: !0 }); + } catch (e) { + console.log('err save in contracts_Webhook', e); + } + }) + .catch(e => { + console.log('Err send data to webhook', e); + try { + var a = new Parse.Object('contracts_Webhook'); + a.set('Log', e?.status), + a.set('UserId', { + __type: 'Pointer', + className: '_User', + objectId: t.data.ExtUserPtr.UserId.objectId, + }), + a.save(null, { useMasterKey: !0 }); + } catch (e) { + console.log('err save in contracts_Webhook', e); + } + })); +} +async function PDF(i, o) { try { i.params.sign; var e = i.params.docId, a = i.params.userId, - o = await axios.get( + n = await axios.get( serverUrl + '/classes/contracts_Document/' + e + '?include=ExtUserPtr,Signers', { headers: { @@ -121,28 +166,28 @@ async function PDF(i, n) { { var d, l, - p, - c = JSON.stringify({ objectId: a }); + c, + p = JSON.stringify({ objectId: a }); let s, r; r = a - ? (d = await axios.get(serverUrl + '/classes/contracts_Contactbook?where=' + c, { + ? (d = await axios.get(serverUrl + '/classes/contracts_Contactbook?where=' + p, { headers: { 'X-Parse-Application-Id': APPID, 'X-Parse-Session-Token': i.headers.sessiontoken, }, })).data && 0 < d.data.results.length ? ((s = d), 'contracts_Contactbook') - : ((s = await axios.get(serverUrl + '/classes/contracts_Users?where=' + c, { + : ((s = await axios.get(serverUrl + '/classes/contracts_Users?where=' + p, { headers: { 'X-Parse-Application-Id': APPID, 'X-Parse-Master-Key': masterKEY }, })), 'contracts_Users') : ((l = JSON.stringify({ UserId: { __type: 'Pointer', className: '_User', objectId: t.data.objectId }, })), - (p = await axios.get(serverUrl + '/classes/contracts_Users?where=' + l, { + (c = await axios.get(serverUrl + '/classes/contracts_Users?where=' + l, { headers: { 'X-Parse-Application-Id': APPID, 'X-Parse-Master-Key': masterKEY }, - })).data && 0 < p.data.results.length - ? ((s = p), 'contracts_Users') + })).data && 0 < c.data.results.length + ? ((s = c), 'contracts_Users') : ((s = await axios.get(serverUrl + '/classes/contracts_Contactbook?where=' + l, { headers: { 'X-Parse-Application-Id': APPID, @@ -155,8 +200,8 @@ async function PDF(i, n) { if (!i.params.pdfFile) return { status: 'error', message: 'pdf file not present!' }; { let e = Buffer.from(i.params.pdfFile, 'base64'); - var u = process.env.PFX_BASE64, - h = Buffer.from(u, 'base64'), + var h = process.env.PFX_BASE64, + u = Buffer.from(h, 'base64'), f = { UserPtr: { __type: 'Pointer', className: r, objectId: s.data.results[0].objectId }, SignedUrl: '', @@ -165,20 +210,20 @@ async function PDF(i, n) { }; let a; var y = (a = - o.data.AuditTrail && 0 < o.data.AuditTrail.length - ? [...o.data.AuditTrail, f] + n.data.AuditTrail && 0 < n.data.AuditTrail.length + ? [...n.data.AuditTrail, f] : [f]).filter(e => 'Signed' === e.Activity); let t = !1; !( - (o.data.Signers && 0 < o.data.Signers.length && y.length !== o.data.Signers.length) || + (n.data.Signers && 0 < n.data.Signers.length && y.length !== n.data.Signers.length) || !(t = !0) ); var v, P, x = `./exports/exported_file_${Math.floor(5e3 * Math.random())}.pdf`, - A = + b = (t - ? ((v = o.data.Signers?.map(e => e.Name + ' <' + e.Email + '>')), + ? ((v = n.data.Signers?.map(e => e.Name + ' <' + e.Email + '>')), (e = v && 0 < v.length ? plainAddPlaceholder({ @@ -193,38 +238,39 @@ async function PDF(i, n) { location: 'location', signatureLength: 1e4, })), - (P = await new SignPDF(e, h).signPDF()), + (P = await new SignPDF(e, u).signPDF()), fs.writeFileSync(x, P)) : fs.writeFileSync(x, e), await uploadFile(x)); - if (A && A.imageUrl) { - const n = await updateDoc( + if (b && b.imageUrl) { + const o = await updateDoc( i.params.docId, - A.imageUrl, + b.imageUrl, s.data.results[0].objectId, i.headers['x-real-ip'], - o.data, + n.data, r ); return ( sendMail({ - url: A.imageUrl, - sender: { Mail: o.data.ExtUserPtr.Email, Name: o.data.ExtUserPtr.Name }, - pdfName: o.data.Name, + url: b.imageUrl, + sender: { Mail: n.data.ExtUserPtr.Email, Name: n.data.ExtUserPtr.Name }, + pdfName: n.data.Name, receiver: g, }), - n && - n.isCompleted && - sendCompletedMail({ - url: A.imageUrl, - sender: { Mail: o.data.ExtUserPtr.Email, Name: 'Open sign' }, - pdfName: o.data.Name, - receiver: o.data.ExtUserPtr.Email, + o && + o.isCompleted && + (sendCompletedMail({ + url: b.imageUrl, + sender: { Mail: n.data.ExtUserPtr.Email, Name: 'Open sign' }, + pdfName: n.data.Name, + receiver: n.data.ExtUserPtr.Email, }), + sendDoctoWebhook(n)), fs.unlinkSync(x), console.log('New Signed PDF created called: ' + x), - 'success' === n.message - ? { status: 'success', data: A.imageUrl } + 'success' === o.message + ? { status: 'success', data: b.imageUrl } : { status: 'error', message: 'please provide required parameters!' } ); } diff --git a/apps/OpenSignServer/cloud/parsefunction/saveWebhook.js b/apps/OpenSignServer/cloud/parsefunction/saveWebhook.js new file mode 100644 index 000000000..1beff7c4b --- /dev/null +++ b/apps/OpenSignServer/cloud/parsefunction/saveWebhook.js @@ -0,0 +1,29 @@ +import axios from 'axios'; +export default async function savewebhook(request) { + const serverUrl = process.env.SERVER_URL; + try { + const userRes = await axios.get(serverUrl + '/users/me', { + headers: { + 'X-Parse-Application-Id': process.env.APP_ID, + 'X-Parse-Session-Token': request.headers['sessiontoken'], + }, + }); + const userId = userRes.data && userRes.data.objectId; + const contractuser = new Parse.Query('contracts_Users'); + contractuser.equalTo('UserId', { __type: 'Pointer', className: '_User', objectId: userId }); + const user = await contractuser.first({ useMasterKey: true }); + + if (user) { + const updateUser = new Parse.Object('contracts_Users'); + updateUser.id = user.id; + updateUser.set('Webhook', request.params.url); + const updatedRes = await updateUser.save(null, { useMasterKey: true }); + if (updatedRes) { + return { code: 200, Webhook: updatedRes.get('Webhook') }; + } + } + } catch (err) { + console.log('update user', err); + return err; + } +} diff --git a/apps/OpenSignServer/databases/migrations/20240123122932-add_webhook_menu.cjs b/apps/OpenSignServer/databases/migrations/20240123122932-add_webhook_menu.cjs new file mode 100644 index 000000000..01f30c910 --- /dev/null +++ b/apps/OpenSignServer/databases/migrations/20240123122932-add_webhook_menu.cjs @@ -0,0 +1,684 @@ +/** + * + * @param {Parse} Parse + */ +exports.up = async Parse => { + const className = 'w_menu'; + const userMenu = new Parse.Query(className); + const updateUserMenu = await userMenu.get('H9vRfEYKhT'); + updateUserMenu.set('menuItems', [ + { + icon: 'fas fa-tachometer-alt', + title: 'Dashboard', + target: '', + pageType: 'dashboard', + description: '', + objectId: '35KBoSgoAK', + }, + { + icon: 'far fa-newspaper', + title: 'New Document', + target: '_self', + pageType: null, + description: null, + objectId: null, + children: [ + { + icon: 'fas fa-pen-nib', + title: 'Sign yourself', + target: '_self', + pageType: 'form', + description: '', + objectId: 'sHAnZphf69', + }, + { + 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: 'fa-solid fa-file-contract', + title: 'Templates', + target: '_self', + pageType: 'report', + description: '', + objectId: '6TeaPr321t', + }, + { + icon: 'fas fa-folder', + title: 'OpenSign™ Drive', + target: '_self', + pageType: 'mf', + description: '', + objectId: + 'remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/legadrive', + }, + { + icon: 'fas fa-address-card', + title: 'Reports', + target: '_self', + pageType: null, + description: '', + objectId: null, + children: [ + { + icon: 'fas fa-signature', + title: 'Need your sign', + target: '_self', + pageType: 'report', + description: '', + objectId: '4Hhwbp482K', + }, + { + icon: 'fas fa-tasks', + title: 'In Progress', + target: '_self', + pageType: 'report', + description: '', + objectId: '1MwEuxLEkF', + }, + { + icon: 'fas fa-check-circle', + title: 'Completed', + target: '_self', + pageType: 'report', + description: '', + objectId: 'kQUoW4hUXz', + }, + { + icon: 'fas fa-edit', + title: 'Drafts', + target: '_self', + pageType: 'report', + description: '', + objectId: 'ByHuevtCFY', + }, + { + icon: 'fas fa-times-circle', + title: 'Declined', + target: '_self', + pageType: 'report', + description: '', + objectId: 'UPr2Fm5WY3', + }, + { + icon: 'fas fa-hourglass-end', + title: 'Expired', + target: '_self', + pageType: 'report', + description: '', + objectId: 'zNqBHXHsYH', + }, + { + icon: 'fa-solid fa-address-book', + title: 'Contactbook', + target: '_self', + pageType: 'report', + description: '', + objectId: '5KhaPr482K', + }, + ], + }, + { + icon: 'fas fa-cog', + title: 'Settings', + target: '_self', + pageType: null, + description: '', + objectId: null, + children: [ + { + icon: 'fas fa-pen-fancy', + title: 'My Signature', + target: '_self', + pageType: 'mf', + description: '', + objectId: + 'remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/managesign', + }, + { + icon: 'fa-solid fa-key', + title: 'API Token', + target: '_self', + pageType: 'generatetoken', + description: '', + objectId: '', + }, + { + icon: 'fa-solid fa-globe', + title: 'Webhook', + target: '_self', + pageType: 'webhook', + description: '', + objectId: '', + }, + ], + }, + ]); + + const AdminMenu = new Parse.Query(className); + const updateAdminMenu = await AdminMenu.get('VPh91h0ZHk'); + updateAdminMenu.set('menuItems', [ + { + icon: 'fas fa-tachometer-alt', + title: 'Dashboard', + target: '', + pageType: 'dashboard', + description: '', + objectId: '35KBoSgoAK', + }, + { + icon: 'far fa-newspaper', + title: 'New Document', + target: '_self', + pageType: null, + description: null, + objectId: null, + children: [ + { + icon: 'fas fa-pen-nib', + title: 'Sign yourself', + target: '_self', + pageType: 'form', + description: '', + objectId: 'sHAnZphf69', + }, + { + 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: 'fa-solid fa-file-contract', + title: 'Templates', + target: '_self', + pageType: 'report', + description: '', + objectId: '6TeaPr321t', + }, + { + icon: 'fas fa-folder', + title: 'OpenSign™ Drive', + target: '_self', + pageType: 'mf', + description: '', + objectId: + 'remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/legadrive', + }, + { + icon: 'fas fa-address-card', + title: 'Reports', + target: '_self', + pageType: null, + description: '', + objectId: null, + children: [ + { + icon: 'fas fa-signature', + title: 'Need your sign', + target: '_self', + pageType: 'report', + description: '', + objectId: '4Hhwbp482K', + }, + { + icon: 'fas fa-tasks', + title: 'In Progress', + target: '_self', + pageType: 'report', + description: '', + objectId: '1MwEuxLEkF', + }, + { + icon: 'fas fa-check-circle', + title: 'Completed', + target: '_self', + pageType: 'report', + description: '', + objectId: 'kQUoW4hUXz', + }, + { + icon: 'fas fa-edit', + title: 'Drafts', + target: '_self', + pageType: 'report', + description: '', + objectId: 'ByHuevtCFY', + }, + { + icon: 'fas fa-times-circle', + title: 'Declined', + target: '_self', + pageType: 'report', + description: '', + objectId: 'UPr2Fm5WY3', + }, + { + icon: 'fas fa-hourglass-end', + title: 'Expired', + target: '_self', + pageType: 'report', + description: '', + objectId: 'zNqBHXHsYH', + }, + { + icon: 'fa-solid fa-address-book', + title: 'Contactbook', + target: '_self', + pageType: 'report', + description: '', + objectId: '5KhaPr482K', + }, + ], + }, + { + icon: 'fas fa-cog', + title: 'Settings', + target: '_self', + pageType: null, + description: '', + objectId: null, + children: [ + { + icon: 'fas fa-pen-fancy', + title: 'My Signature', + target: '_self', + pageType: 'mf', + description: '', + objectId: + 'remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/managesign', + }, + { + icon: 'far fa-user', + title: 'Add User', + target: '_self', + pageType: 'form', + description: '', + objectId: 'lM0xRnM3iE', + }, + { + icon: 'fa-solid fa-key', + title: 'API Token', + target: '_self', + pageType: 'generatetoken', + description: '', + objectId: '', + }, + { + icon: 'fa-solid fa-globe', + title: 'Webhook', + target: '_self', + pageType: 'webhook', + description: '', + objectId: '', + }, + ], + }, + ]); + // TODO: Set the schema here + // Example: + // schema.addString('name').addNumber('cash'); + const batch = [updateUserMenu, updateAdminMenu]; + return Parse.Object.saveAll(batch, { useMasterKey: true }); +}; + +/** + * + * @param {Parse} Parse + */ +exports.down = async Parse => { + // TODO: set className here + const className = 'w_menu'; + const userMenu = new Parse.Query(className); + const revertUserMenu = await userMenu.get('H9vRfEYKhT'); + revertUserMenu.set('menuItems', [ + { + icon: 'fas fa-tachometer-alt', + title: 'Dashboard', + target: '', + pageType: 'dashboard', + description: '', + objectId: '35KBoSgoAK', + }, + { + icon: 'far fa-newspaper', + title: 'New Document', + target: '_self', + pageType: null, + description: null, + objectId: null, + children: [ + { + icon: 'fas fa-pen-nib', + title: 'Sign yourself', + target: '_self', + pageType: 'form', + description: '', + objectId: 'sHAnZphf69', + }, + { + 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: 'fa-solid fa-file-contract', + title: 'Templates', + target: '_self', + pageType: 'report', + description: '', + objectId: '6TeaPr321t', + }, + { + icon: 'fas fa-folder', + title: 'OpenSign™ Drive', + target: '_self', + pageType: 'mf', + description: '', + objectId: + 'remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/legadrive', + }, + { + icon: 'fas fa-address-card', + title: 'Reports', + target: '_self', + pageType: null, + description: '', + objectId: null, + children: [ + { + icon: 'fas fa-signature', + title: 'Need your sign', + target: '_self', + pageType: 'report', + description: '', + objectId: '4Hhwbp482K', + }, + { + icon: 'fas fa-tasks', + title: 'In Progress', + target: '_self', + pageType: 'report', + description: '', + objectId: '1MwEuxLEkF', + }, + { + icon: 'fas fa-check-circle', + title: 'Completed', + target: '_self', + pageType: 'report', + description: '', + objectId: 'kQUoW4hUXz', + }, + { + icon: 'fas fa-edit', + title: 'Drafts', + target: '_self', + pageType: 'report', + description: '', + objectId: 'ByHuevtCFY', + }, + { + icon: 'fas fa-times-circle', + title: 'Declined', + target: '_self', + pageType: 'report', + description: '', + objectId: 'UPr2Fm5WY3', + }, + { + icon: 'fas fa-hourglass-end', + title: 'Expired', + target: '_self', + pageType: 'report', + description: '', + objectId: 'zNqBHXHsYH', + }, + { + icon: 'fa-solid fa-address-book', + title: 'Contactbook', + target: '_self', + pageType: 'report', + description: '', + objectId: '5KhaPr482K', + }, + ], + }, + { + icon: 'fas fa-cog', + title: 'Settings', + target: '_self', + pageType: null, + description: '', + objectId: null, + children: [ + { + icon: 'fas fa-pen-fancy', + title: 'My Signature', + target: '_self', + pageType: 'mf', + description: '', + objectId: + 'remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/managesign', + }, + { + icon: 'fa-solid fa-key', + title: 'API Token', + target: '_self', + pageType: 'generatetoken', + description: '', + objectId: '', + }, + ], + }, + ]); + + const adminMenu = new Parse.Query(className); + const revertAdminMenu = await adminMenu.get('VPh91h0ZHk'); + revertAdminMenu.set('menuItems', [ + { + icon: 'fas fa-tachometer-alt', + title: 'Dashboard', + target: '', + pageType: 'dashboard', + description: '', + objectId: '35KBoSgoAK', + }, + { + icon: 'far fa-newspaper', + title: 'New Document', + target: '_self', + pageType: null, + description: null, + objectId: null, + children: [ + { + icon: 'fas fa-pen-nib', + title: 'Sign yourself', + target: '_self', + pageType: 'form', + description: '', + objectId: 'sHAnZphf69', + }, + { + 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: 'fa-solid fa-file-contract', + title: 'Templates', + target: '_self', + pageType: 'report', + description: '', + objectId: '6TeaPr321t', + }, + { + icon: 'fas fa-folder', + title: 'OpenSign™ Drive', + target: '_self', + pageType: 'mf', + description: '', + objectId: + 'remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/legadrive', + }, + { + icon: 'fas fa-address-card', + title: 'Reports', + target: '_self', + pageType: null, + description: '', + objectId: null, + children: [ + { + icon: 'fas fa-signature', + title: 'Need your sign', + target: '_self', + pageType: 'report', + description: '', + objectId: '4Hhwbp482K', + }, + { + icon: 'fas fa-tasks', + title: 'In Progress', + target: '_self', + pageType: 'report', + description: '', + objectId: '1MwEuxLEkF', + }, + { + icon: 'fas fa-check-circle', + title: 'Completed', + target: '_self', + pageType: 'report', + description: '', + objectId: 'kQUoW4hUXz', + }, + { + icon: 'fas fa-edit', + title: 'Drafts', + target: '_self', + pageType: 'report', + description: '', + objectId: 'ByHuevtCFY', + }, + { + icon: 'fas fa-times-circle', + title: 'Declined', + target: '_self', + pageType: 'report', + description: '', + objectId: 'UPr2Fm5WY3', + }, + { + icon: 'fas fa-hourglass-end', + title: 'Expired', + target: '_self', + pageType: 'report', + description: '', + objectId: 'zNqBHXHsYH', + }, + { + icon: 'fa-solid fa-address-book', + title: 'Contactbook', + target: '_self', + pageType: 'report', + description: '', + objectId: '5KhaPr482K', + }, + ], + }, + { + icon: 'fas fa-cog', + title: 'Settings', + target: '_self', + pageType: null, + description: '', + objectId: null, + children: [ + { + icon: 'fas fa-pen-fancy', + title: 'My Signature', + target: '_self', + pageType: 'mf', + description: '', + objectId: + 'remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/managesign', + }, + { + icon: 'far fa-user', + title: 'Add User', + target: '_self', + pageType: 'form', + description: '', + objectId: 'lM0xRnM3iE', + }, + { + icon: 'fa-solid fa-key', + title: 'API Token', + target: '_self', + pageType: 'generatetoken', + description: '', + objectId: '', + }, + ], + }, + ]); + // TODO: Set the schema here + // Example: + // schema.addString('name').addNumber('cash'); + const batch = [revertUserMenu, revertAdminMenu]; + return Parse.Object.saveAll(batch, { useMasterKey: true }); +};