handleDelete(item)}
- className="bg-[#1ab6ce] rounded-sm shadow-md text-[12px] font-semibold uppercase text-white py-1.5 px-3 focus:outline-none"
+ className="px-4 py-1.5 text-white rounded shadow-md text-center focus:outline-none "
+ style={{ backgroundColor: modalSubmitBtnColor }}
>
Yes
No
@@ -371,7 +374,7 @@ const ReportTable = ({
)}
{heading.includes("Folder") && (
- {item?.Folder?.Name || "OpenSignDrive"}
+ {item?.Folder?.Name || "OpenSign⢠Drive"}
)}
diff --git a/apps/OpenSign/src/primitives/TemplateForm.js b/apps/OpenSign/src/primitives/TemplateForm.js
deleted file mode 100644
index 5fa592870..000000000
--- a/apps/OpenSign/src/primitives/TemplateForm.js
+++ /dev/null
@@ -1,336 +0,0 @@
-import React, { useState } from "react";
-import sanitizeFileName from "./sanitizeFileName";
-import Parse from "parse";
-import DropboxChooser from "../components/fields/DropboxChoose";
-import Alert from "./Alert";
-import SelectFolder from "../components/fields/SelectFolder";
-// import SignersInput from "../components/fields/SignersInput";
-import Title from "../components/Title";
-import { useNavigate } from "react-router-dom";
-import { templateCls } from "../constant/const";
-
-const TemplateForm = () => {
- const navigate = useNavigate();
- const [signers, setSigners] = useState([]);
- const [folder, setFolder] = useState({ ObjectId: "", Name: "" });
- const [formData, setFormData] = useState({
- Name: "",
- Description: "",
- Note: "Please review and sign this document"
- });
- const [fileupload, setFileUpload] = useState([]);
- const [fileload, setfileload] = useState(false);
- const [percentage, setpercentage] = useState(0);
- const [isAlert, setIsAlert] = useState(false);
- const [isSubmit, setIsSubmit] = useState(false);
- const [isErr, setIsErr] = useState("");
- const handleStrInput = (e) => {
- setFormData({ ...formData, [e.target.name]: e.target.value });
- };
-
- const handleFileInput = (e) => {
- setpercentage(0);
- try {
- let files = e.target.files;
- if (typeof files[0] !== "undefined") {
- const mb = Math.round(files[0].bytes / Math.pow(1024, 2));
- if (mb > 10) {
- alert(
- `The selected file size is too large. Please select a file less than ${Math.round(
- 10
- )} MB`
- );
- return;
- }
-
- handleFileUpload(files[0]);
- } else {
- alert("Please select file.");
- return false;
- }
- } catch (error) {
- alert(error.message);
- return false;
- }
- };
-
- const handleFileUpload = async (file) => {
- Parse.serverURL = process.env.REACT_APP_SERVERURL;
- Parse.initialize(process.env.REACT_APP_APPID);
- setfileload(true);
- const fileName = file.name;
- const name = sanitizeFileName(fileName);
- const pdfFile = file;
- const parseFile = new Parse.File(name, pdfFile);
-
- try {
- const response = await parseFile.save({
- progress: (progressValue, loaded, total, { type }) => {
- if (type === "upload" && progressValue !== null) {
- const percentCompleted = Math.round((loaded * 100) / total);
- setpercentage(percentCompleted);
- }
- }
- });
-
- // The response object will contain information about the uploaded file
- // You can access the URL of the uploaded file using response.url()
- setFileUpload(response.url());
- setfileload(false);
- if (response.url()) {
- return response.url();
- }
- } catch (error) {
- setfileload(false);
- setpercentage(0);
- console.error("Error uploading file:", error);
- }
- };
-
- const dropboxSuccess = async (files) => {
- setfileload(true);
- const file = files[0];
- const url = file.link;
- const mb = Math.round(file.bytes / Math.pow(1024, 2));
-
- if (mb > 10) {
- setTimeout(() => {
- alert(
- `The selected file size is too large. Please select a file less than 10 MB`
- );
- }, 500);
- return;
- } else {
- const name = sanitizeFileName(file.name);
-
- const parseFile = new Parse.File(name, { uri: url });
-
- try {
- const response = await parseFile.save({
- progress: (progressValue, loaded, total, { type }) => {
- if (type === "upload" && progressValue !== null) {
- const percentCompleted = Math.round((loaded * 100) / total);
- setpercentage(percentCompleted);
- }
- }
- });
- setFileUpload(response.url());
- setfileload(false);
-
- if (response.url()) {
- return response.url();
- }
- } catch (error) {
- setfileload(false);
- setpercentage(0);
- console.error("Error uploading file:", error);
- }
- }
- };
- const dropboxCancel = async () => {};
- const handleSubmit = async (e) => {
- e.preventDefault();
- setIsSubmit(true);
- try {
- const currentUser = Parse.User.current();
- const template = new Parse.Object(templateCls);
- Object.entries(formData).forEach((item) =>
- template.set(item[0], item[1])
- );
- template.set("URL", fileupload);
- template.set("CreatedBy", Parse.User.createWithoutData(currentUser.id));
- if (folder && folder.ObjectId) {
- template.set("Folder", {
- __type: "Pointer",
- className: templateCls,
- objectId: folder.ObjectId
- });
- }
- if (signers && signers.length > 0) {
- template.set("Signers", signers);
- }
- const ExtCls = JSON.parse(localStorage.getItem("Extand_Class"));
- template.set("ExtUserPtr", {
- __type: "Pointer",
- className: "contracts_Users",
- objectId: ExtCls[0].objectId
- });
-
- const res = await template.save();
- if (res) {
- setSigners([]);
- setFolder({ ObjectId: "", Name: "" });
- setFormData({
- Name: "",
- Description: "",
- Note: ""
- });
- setFileUpload([]);
- setpercentage(0);
- navigate(
- "/asmf/remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/template/" +
- res.id
- );
- }
- } catch (err) {
- console.log("err ", err);
- setIsErr(true);
- } finally {
- setIsAlert(true);
- setTimeout(() => {
- setIsAlert(false);
- }, 1000);
- setIsSubmit(false);
- }
- };
-
- const handleFolder = (data) => {
- setFolder(data);
- };
- // const handleSigners = (data) => {
- // if (data && data.length > 0) {
- // const updateSigners = data.map((x) => ({
- // __type: "Pointer",
- // className: "contracts_Contactbook",
- // objectId: x
- // }));
- // setSigners(updateSigners);
- // }
- // };
-
- const handleReset = () => {
- setSigners([]);
- setFolder({ ObjectId: "", Name: "" });
- setFormData({
- Name: "",
- Description: "",
- Note: ""
- });
- setFileUpload([]);
- setpercentage(0);
- };
- return (
-
-
- {isAlert && (
-
- {isErr
- ? "Something went wrong please try again!"
- : "Template created successfully!"}
-
- )}
-
-
- );
-};
-
-export default TemplateForm;
diff --git a/apps/OpenSign/src/primitives/Validate.js b/apps/OpenSign/src/primitives/Validate.js
new file mode 100644
index 000000000..86993d8b3
--- /dev/null
+++ b/apps/OpenSign/src/primitives/Validate.js
@@ -0,0 +1,57 @@
+import React, { useState, useEffect } from "react";
+import Parse from "parse";
+import { Outlet, useNavigate, useLocation } from "react-router-dom";
+import ModalUi from "./ModalUi";
+const Validate = () => {
+ const navigate = useNavigate();
+ const location = useLocation();
+ 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);
+ }
+ })();
+ }, []);
+ const handleLoginBtn = () => {
+ try {
+ Parse.User.logOut();
+ } catch (err) {
+ console.log("err ", err);
+ } finally {
+ localStorage.removeItem("accesstoken");
+ navigate("/", { replace: true, state: { from: location } });
+ }
+ };
+ return isUserValid ? (
+
+
+
+ ) : (
+
+
+
Your session has expired.
+
+ Login
+
+
+
+ );
+};
+
+export default Validate;
diff --git a/apps/OpenSign/src/primitives/ValidateRoute.js b/apps/OpenSign/src/primitives/ValidateRoute.js
index 62202dfe6..9c4f01e07 100644
--- a/apps/OpenSign/src/primitives/ValidateRoute.js
+++ b/apps/OpenSign/src/primitives/ValidateRoute.js
@@ -1,7 +1,7 @@
import React, { useEffect } from "react";
import Parse from "parse";
-
-const ValidateRoute = ({ children }) => {
+import { Outlet } from "react-router-dom";
+const ValidateRoute = () => {
useEffect(() => {
(async () => {
try {
@@ -28,7 +28,7 @@ const ValidateRoute = ({ children }) => {
localStorage.removeItem("accesstoken");
}
};
- return {children}
;
+ return { }
;
};
export default ValidateRoute;
diff --git a/apps/OpenSign/src/redux/actions/index.js b/apps/OpenSign/src/redux/actions/index.js
index afec8161d..3e9e2816a 100644
--- a/apps/OpenSign/src/redux/actions/index.js
+++ b/apps/OpenSign/src/redux/actions/index.js
@@ -124,8 +124,7 @@ export const login = (username, password) => async (dispatch) => {
const currentUser = Parse.User.current();
await Parse.Cloud.run("getUserDetails", {
email: currentUser.get("email")
- })
- .then(
+ }).then(
(results) => {
let userinfo = results.toJSON();
if (userinfo.TenantId) {
@@ -215,95 +214,10 @@ export const fetchRoleEnum = (name) => async (dispatch) => {
dispatch({ type: "FETCH_ROLE", payload: response });
};
-export const setEnableCart = (val) => async (dispatch) => {
- dispatch({
- type: "ENABLE_CART",
- payload: val
- });
-};
-
-export const setCartUpdateData = (val) => async (dispatch) => {
- dispatch({
- type: "UPDATE_CART",
- payload: val
- });
-};
-
-export const addItemsToCart = (val) => async (dispatch) => {
- dispatch({
- type: "ADD_CART",
- payload: val
- });
-};
-
-export const clearCartData = () => async (dispatch) => {
- dispatch({
- type: "CLEAR_CART",
- payload: []
- });
-};
-
-export const SaveMultipleCart = (val) => async (dispatch) => {
- dispatch({
- type: "MULTI_CART",
- payload: val
- });
-};
-
-export const removeFromCart = (val) => async (dispatch) => {
- dispatch({
- type: "REMOVE_CART",
- payload: val
- });
-};
-
-export const onChangeLevel1Dropdown = (id, name) => async (dispatch) => {
- localStorage.setItem(`_dd${name}`, id);
- let _data = { [name]: `${id}` };
- dispatch({ type: "Level1_Dropdown", payload: _data });
-};
-
-export const onChangeLevel2Dropdown = (id, name) => async (dispatch) => {
- localStorage.setItem(`_dd${name}`, id);
- let _data = { [name]: `${id}` };
- dispatch({ type: "Level2_Dropdown", payload: _data });
-};
-
-export const onChangeLevel3Dropdown = (id, name) => async (dispatch) => {
- localStorage.setItem(`_dd${name}`, id);
- let _data = { [name]: `${id}` };
- dispatch({ type: "Level3_Dropdown", payload: _data });
-};
-
-export const removeState = () => async (dispatch) => {
- dispatch({ type: "REMOVE_STATE", payload: {} });
-};
-export const removeLevel2State = () => async (dispatch) => {
- dispatch({ type: "removeLevel2", payload: {} });
-};
-
-export const removeLevel3State = () => async (dispatch) => {
- dispatch({ type: "removeLevel3", payload: {} });
-};
-
export const showTenantName = (name) => async (dispatch) => {
dispatch({ type: "SHOW_TENANT", payload: name || null });
};
-export const saveDependantDDValue = (id, value) => async (dispatch) => {
- let _data = { [`${id}_dd`]: value };
- dispatch({ type: "SAVE_DEPENDANTDD", payload: _data });
-};
-
-export const removeDependantDDValue = (id, value) => async (dispatch) => {
- let _data = { [`${id}_dd`]: value };
- dispatch({ type: "REMOVE_DEPENDANTDD", payload: _data });
-};
-
-export const remove_AlldependantDD = () => async (dispatch) => {
- dispatch({ type: "REMOVE_ALLDEPENDANTDD", payload: {} });
-};
-
export const save_tourSteps = (steps) => async (dispatch) => {
dispatch({ type: "SAVE_TOURSTEPS", payload: steps });
};
diff --git a/apps/OpenSign/src/routes/Dashboard.js b/apps/OpenSign/src/routes/Dashboard.js
index 2bc3d9bc7..e381cf364 100644
--- a/apps/OpenSign/src/routes/Dashboard.js
+++ b/apps/OpenSign/src/routes/Dashboard.js
@@ -24,7 +24,7 @@ const Dashboard = (props) => {
getDashboard(localStorage.getItem("PageLanding"));
}
} else {
- navigate("/", { replace: true });
+ navigate("/", { replace: true, state: { from: location } });
}
// eslint-disable-next-line
}, [id]);
diff --git a/apps/OpenSign/src/routes/Form.js b/apps/OpenSign/src/routes/Form.js
index 2c6c67709..8eab4b04b 100644
--- a/apps/OpenSign/src/routes/Form.js
+++ b/apps/OpenSign/src/routes/Form.js
@@ -1,1244 +1,252 @@
-import React, { Component } from "react";
-import { connect } from "react-redux";
-import {
- removeState,
- removeLevel2State,
- removeLevel3State
-} from "../redux/actions/index";
-import Engine from "json-rules-engine-simplified";
-import applyRules from "rjsf-conditionals";
-import Form from "@rjsf/core";
-import validator from "@rjsf/validator-ajv8";
-import LayoutField from "../components/fields/Rjsf-layout";
-import "../styles/form.css";
-import "../styles/toast.css";
-import Parse from "parse";
-import "../styles/loader.css";
-import TimeWidget from "../components/fields/TimeWidget";
-import axios from "axios";
+import React, { useState } from "react";
import { useNavigate, useParams } from "react-router-dom";
-import HiddenField from "../components/fields/HiddenField";
-import MultiSelectField from "../components/fields/MultiSelectField";
-import ErrorBoundary from "../components/ErrorBoundary";
-import FileUpload from "../components/fields/FileUpload";
-import TreeWidget from "../components/TreeWidget";
-import parse from "html-react-parser";
-import Title from "../components/Title";
import { formJson } from "../json/FormJson";
-import TemplateForm from "../primitives/TemplateForm";
-const widget = {
- TimeWidget: TimeWidget
-};
-const fields = () => {
- return {
- layout: LayoutField,
- FileUpload: FileUpload,
- HiddenField: HiddenField,
- MultiSelectField: MultiSelectField,
- FolderComponent: TreeWidget
- };
-};
+import AddUser from "../components/AddUser";
+import sanitizeFileName from "../primitives/sanitizeFileName";
+import Parse from "parse";
+import DropboxChooser from "../components/fields/DropboxChoose";
+import Alert from "../primitives/Alert";
+import SelectFolder from "../components/fields/SelectFolder";
+import SignersInput from "../components/fields/SignersInput";
+import Title from "../components/Title";
+import PageNotFound from "./PageNotFound";
-function FormBuilderFn(props) {
+function Form() {
const { id } = useParams();
- const navigate = useNavigate();
- if (id === "template") {
- return ;
+
+ if (id === "lM0xRnM3iE") {
+ return ;
} else {
- return (
-
- );
+ const config = formJson[id];
+ if (config) {
+ return ;
+ } else {
+ return ;
+ }
}
}
-class FormBuilder extends Component {
- state = {
- schema: {},
- ui_schema: {},
- extraActions: undefined,
- rules: [],
- isAppRequest: false,
- formData: {},
- persistentFields: [],
- successMassage: "Record inserted successfully.",
- title: "",
- active: true,
- buttons: {},
- schemaState: {},
- noValidate: false,
- liveValidate: false,
- _validate: null,
- userSchema: {},
- loading: false,
- parseBaseUrl: localStorage.getItem("baseUrl"),
- parseAppId: localStorage.getItem("parseAppId"),
- toastColor: "#5cb85c",
- toastDescription: "",
- redirect_type: "",
- redirect_id: "",
- FormACL: null,
- help: "",
- link: ""
+
+const Forms = (props) => {
+ const navigate = useNavigate();
+ const [signers, setSigners] = useState([]);
+ const [folder, setFolder] = useState({ ObjectId: "", Name: "" });
+ const [formData, setFormData] = useState({
+ Name: "",
+ Description: "",
+ Note: "Please review and sign this document",
+ TimeToCompleteDays: 15,
+ SendinOrder: "false"
+ });
+ const [fileupload, setFileUpload] = useState([]);
+ const [fileload, setfileload] = useState(false);
+ const [percentage, setpercentage] = useState(0);
+ const [isAlert, setIsAlert] = useState(false);
+ const [isSubmit, setIsSubmit] = useState(false);
+ const [isErr, setIsErr] = useState("");
+ const handleStrInput = (e) => {
+ setFormData({ ...formData, [e.target.name]: e.target.value });
};
- async getForm(id) {
- this.setState({
- loading: true
- });
+ const handleFileInput = (e) => {
+ setpercentage(0);
try {
- const results = formJson(id);
- // console.log("custom result",results)
- if (results) {
- const resultjson = results;
- if (resultjson.userSchema !== undefined) {
- this.setState({
- userSchema: resultjson.userSchema
- });
+ let files = e.target.files;
+ if (typeof files[0] !== "undefined") {
+ const mb = Math.round(files[0].bytes / Math.pow(1024, 2));
+ if (mb > 10) {
+ alert(
+ `The selected file size is too large. Please select a file less than ${Math.round(
+ 10
+ )} MB`
+ );
+ return;
}
- for (let [value] of Object.entries(resultjson.jsonSchema.properties)) {
- if (typeof value === "object") {
- for (let [k, v] of Object.entries(value)) {
- if (k === "format" && v === "date") {
- let today = new Date();
- let date =
- today.getFullYear() +
- "-" +
- ("0" + (today.getMonth() + 1)).slice(-2) +
- "-" +
- ("0" + today.getDate()).slice(-2);
- value.default = date;
- }
- if (k === "component" && v === "DateTime") {
- value.default = new Date().toISOString();
- }
- }
- }
- }
- let txt,
- link,
- successMsg,
- _rules = [],
- persistentFields = [],
- _extraActions = {};
- if (resultjson.help) {
- if (resultjson.help.htmlbody) {
- txt = resultjson.help.htmlbody;
- }
- if (resultjson.help.link) {
- link = resultjson.help.link;
- }
- }
- if (resultjson.rules) {
- _rules = resultjson.rules;
- }
- if (resultjson.persistentFields) {
- persistentFields = resultjson.persistentFields;
- }
- if (resultjson.extraActions) {
- _extraActions = this.setExtraActions(resultjson.extraActions);
- }
- if (resultjson.success_message) {
- successMsg = resultjson.success_message;
- } else {
- successMsg = this.state.successMassage;
- }
- let _jsonSchema = JSON.stringify(resultjson.jsonSchema);
- _jsonSchema = _jsonSchema.replace("#$", "$");
- _jsonSchema = _jsonSchema.replace("#*", "$");
- _jsonSchema = _jsonSchema.replace("_DOT_", ".");
- let _replaceJSONSchema = JSON.parse(_jsonSchema);
- this.setState({
- redirect_type: resultjson.success_redirect,
- redirect_id: resultjson.redirect_id,
- FormACL: resultjson.formACL,
- help: txt,
- link: link,
- persistentFields: persistentFields,
- successMassage: successMsg,
- buttons: resultjson.buttons.add,
- schemaState: _replaceJSONSchema,
- ui_schema: resultjson.uiSchema,
- rules: _rules,
- extraActions: _extraActions,
- title: resultjson.class,
- _validate: resultjson.validFunction,
- noValidate: resultjson.noValidate,
- liveValidate: resultjson.liveValidate && resultjson.liveValidate,
- loading: false
- });
- localStorage.setItem(
- "jsonschema",
- JSON.stringify(resultjson.jsonSchema)
- );
+ handleFileUpload(files[0]);
} else {
- alert("form not found");
+ alert("Please select file.");
+ return false;
}
- } catch (e) {
- if (e.message === "Invalid session token") {
- let appdata = localStorage.getItem("userSettings");
- let applogo = localStorage.getItem("appLogo");
- let appName = localStorage.getItem("appName");
- let defaultmenuid = localStorage.getItem("defaultmenuid");
- let PageLanding = localStorage.getItem("PageLanding");
- let domain = localStorage.getItem("domain");
- let _appName = localStorage.getItem("_appName");
- let baseUrl = localStorage.getItem("BaseUrl12");
- let appid = localStorage.getItem("AppID12");
- localStorage.clear();
- localStorage.setItem("appLogo", applogo);
- localStorage.setItem("appName", appName);
- localStorage.setItem("_appName", _appName);
- localStorage.setItem("defaultmenuid", defaultmenuid);
- localStorage.setItem("PageLanding", PageLanding);
- localStorage.setItem("domain", domain);
- localStorage.setItem("userSettings", appdata);
- localStorage.setItem("BaseUrl12", baseUrl);
- localStorage.setItem("AppID12", appid);
- this.props.navigate(`/`);
- }
- console.log(e.message);
- console.error("Problem", e);
- this.setState({
- loading: false
- });
- }
- }
-
- wrap = (s) => "{ return " + s + " };";
-
- // func = new Function(wrap(body));
-
- dynamicValidate = (formData, errors) => {
- try {
- let body = atob(this.state._validate);
- let res = new Function(this.wrap(body))
- .call(null)
- .call(null, formData, errors);
- return res;
} catch (error) {
- console.log(error);
+ alert(error.message);
+ return false;
}
};
- setExtraActions = (actions) => {
+ const handleFileUpload = async (file) => {
+ Parse.serverURL = process.env.REACT_APP_SERVERURL;
+ Parse.initialize(process.env.REACT_APP_APPID);
+ setfileload(true);
+ const fileName = file.name;
+ const name = sanitizeFileName(fileName);
+ const pdfFile = file;
+ const parseFile = new Parse.File(name, pdfFile);
+
try {
- let result = {};
- Object.entries(actions).forEach(([key, value]) => {
- let body = atob(value);
- let res = new Function(this.wrap(body)).call(null);
- result[key] = res;
+ const response = await parseFile.save({
+ progress: (progressValue, loaded, total, { type }) => {
+ if (type === "upload" && progressValue !== null) {
+ const percentCompleted = Math.round((loaded * 100) / total);
+ setpercentage(percentCompleted);
+ }
+ }
});
- return result;
+
+ // The response object will contain information about the uploaded file
+ // You can access the URL of the uploaded file using response.url()
+ setFileUpload(response.url());
+ setfileload(false);
+ if (response.url()) {
+ return response.url();
+ }
} catch (error) {
- console.log(error);
+ setfileload(false);
+ setpercentage(0);
+ console.error("Error uploading file:", error);
}
};
- handleSubmit = async ({ formData }) => {
- this.setState({ active: false, loading: true });
- if (
- this.state.userSchema &&
- Object.entries(this.state.userSchema).length !== 0 &&
- this.state.userSchema.constructor === Object
- ) {
- try {
- let RowData = formData;
- RowData &&
- Object.entries(RowData).forEach(([key, value]) => {
- if (typeof value === "string") {
- RowData[key] = value.trim();
- }
- });
- let UserData = {};
- let RoleField = "";
- let _scanData = this.state.schemaState;
- if (_scanData.dependencies) {
- Object.keys(_scanData.dependencies).forEach((key) => {
- if (_scanData.dependencies[key].oneOf) {
- _scanData.dependencies[key].oneOf.forEach((val) => {
- Object.keys(val.properties).forEach((k) => {
- if (typeof val.properties[k] === "object") {
- if (val.properties[k].format === "date") {
- if (RowData[k]) {
- let newdate = new Date(RowData[k]);
- RowData[k] = newdate;
- }
- }
- if (val.properties[k].component === "HtmlEditor") {
- if (RowData[k]) {
- let newHtml = RowData[k]
- .replace(/]*>/g, "")
- .replace(/<\/p>/g, " ");
- RowData[k] = newHtml;
- }
- }
- if (val.properties[k].component === "DateTime") {
- if (RowData[k]) {
- let newDate11 = new Date(RowData[k]);
- RowData[k] = newDate11;
- }
- }
- if (val.properties[k].component === "CurrencyInput") {
- if (val.properties[k].currencyColumn) {
- RowData[`${val.properties[k].currencyColumn}`] =
- val.properties[k].defaultcurrency;
- }
- }
- if (val.properties[k].type === "string") {
- if (typeof RowData[k] === "string")
- RowData[k] = RowData[k].trim();
- }
- if (val.properties[k].data !== undefined) {
- if (val.properties[k].data.isPointer) {
- let pointer = undefined;
- if (val.properties[k].data.class) {
- if (val.properties[k].data.savePointerClass) {
- if (RowData[k]) {
- pointer = {
- __type: "Pointer",
- className:
- val.properties[k].data.savePointerClass,
- objectId: RowData[k]
- };
- }
- } else {
- if (RowData[k]) {
- pointer = {
- __type: "Pointer",
- className: val.properties[k].data.class,
- objectId: RowData[k]
- };
- }
- }
- } else {
- if (RowData[k]) {
- pointer = {
- __type: "Pointer",
- className: localStorage.getItem("extended_class"),
- objectId: RowData[k]
- };
- }
- }
- RowData[k] = pointer;
- }
- if (val.properties[k].data.FolderTypeValue) {
- if (RowData[k]) {
- let obj = {
- __type: "Pointer",
- className: val.properties[k].data.ClassName,
- objectId: RowData[k]
- };
- RowData[k] = obj;
- }
- }
- }
- }
- });
- });
- }
- });
- }
- let _userScheama = this.state.userSchema;
- Object.keys(_scanData).forEach(function (key) {
- let _dd = _scanData[key];
- typeof _dd === "object" &&
- Object.keys(_dd).forEach(function (k) {
- if (_dd[k].type === "array" && _dd[k].items) {
- let _prop = _dd[k].items.properties;
-
- if (_prop && Array.isArray(RowData[k])) {
- let newRow = [];
- RowData[k].forEach((t) => {
- let _newObj = t;
- if (typeof t === "object") {
- Object.keys(_prop).forEach(function (l) {
- if (_prop[l].data && _prop[l].data.isPointer) {
- if (typeof t[l] === "object") {
- let obj = {
- __type: "Pointer",
- className: _prop[l].data.class,
- objectId: t[l].objectId
- };
- _newObj = { ..._newObj, [l]: obj };
- } else {
- let obj = {
- __type: "Pointer",
- className: _prop[l].data.class,
- objectId: t[l]
- };
- _newObj = { ..._newObj, [l]: obj };
- }
- }
- });
- }
- newRow.push(_newObj);
- });
- RowData[k] = newRow;
- }
- }
-
- if (_dd[k].component === "AutoSuggest" && _dd[k].isPointer) {
- if (RowData[k]) {
- let pointer = {
- __type: "Pointer",
- className: _dd[k].class,
- objectId: RowData[k]
- };
- RowData[k] = pointer;
- }
- }
- if (_dd[k].format === "date") {
- let newdate = new Date(RowData[k]);
- RowData[k] = newdate;
- }
- if (_dd[k].component === "CurrencyInput") {
- RowData[`${_dd[k].currencyColumn}`] = _dd[k].defaultcurrency;
- }
- if (_dd[k].component === "HtmlEditor") {
- if (RowData[k]) {
- let newHtml = RowData[k]
- .replace(/
]*>/g, "")
- .replace(/<\/p>/g, " ");
- RowData[k] = newHtml;
- }
- }
- if (_dd[k].component === "DateTime") {
- let newDate;
- if (!RowData[k]) {
- newDate = new Date();
- } else {
- newDate = new Date(RowData[k]);
- }
- RowData[k] = newDate;
- }
- if (_dd[k].data !== undefined) {
- if (_dd[k].data.isPointer) {
- let pointer = undefined;
- if (_dd[k].data.savePointerClass) {
- if (RowData[k]) {
- pointer = {
- __type: "Pointer",
- className: _dd[k].data.savePointerClass,
- objectId: RowData[k]
- };
- RowData[k] = pointer;
- }
- } else if (RowData[k]) {
- if (_dd[k].data.class) {
- pointer = {
- __type: "Pointer",
- className: _dd[k].data.class,
- objectId: RowData[k]
- };
- } else {
- pointer = {
- __type: "Pointer",
- className: localStorage.getItem("extended_class"),
- objectId: RowData[k]
- };
- }
-
- RowData[k] = pointer;
- }
- }
- if (_dd[k].data.FolderTypeValue) {
- if (RowData[k]) {
- let obj = {
- __type: "Pointer",
- className: _dd[k].data.ClassName,
- objectId: RowData[k]
- };
- RowData[k] = obj;
- }
- }
- }
- if (_dd[k].type === "string") {
- let d = RowData[k];
- if (typeof d === "string") {
- RowData[k] = d.trim();
- }
- }
- });
- });
+ const dropboxSuccess = async (files) => {
+ setfileload(true);
+ const file = files[0];
+ const url = file.link;
+ const mb = Math.round(file.bytes / Math.pow(1024, 2));
- Object.keys(_userScheama).forEach(function (kkey) {
- Object.keys(RowData).forEach(function (_k) {
- if (_userScheama[kkey].startsWith("$")) {
- let _uuu = _userScheama[kkey].replace("$", "");
- if (kkey === "Role" || kkey === "role") {
- if (RowData[_uuu] === RowData[_k]) {
- RoleField = RowData[_uuu];
- }
- } else if (_uuu === _k) {
- UserData[kkey] = RowData[_k];
- }
- } else {
- RoleField = _userScheama[kkey];
- }
- });
- });
- Parse.serverURL = this.state.parseBaseUrl;
- Parse.initialize(this.state.parseAppId);
- var _users = Parse.Object.extend("User");
- var _user = new _users();
- let _uname = UserData.name;
- _user.set("name", _uname.toString().trim());
- if (UserData.username) {
- let _u_un = UserData.username;
- _user.set("username", _u_un.toString().trim());
- if (UserData.email) {
- let _email = UserData.email;
- _user.set("email", _email.trim());
- }
- } else if (UserData.email) {
- let _email = UserData.email;
- _user.set("email", _email.trim());
- _user.set("username", _email.trim());
- } else {
- _user.set("username", UserData.phone.toString().trim());
- }
- _user.set("phone", UserData.phone);
- _user.set("password", UserData.password);
- _user.save().then(
- (u) => {
- let roleurl = `${this.state.parseBaseUrl}functions/AddUserToRole`;
- const headers = {
- "Content-Type": "application/json",
- "X-Parse-Application-Id": this.state.parseAppId,
- sessionToken: localStorage.getItem("accesstoken")
- };
- let body = {
- appName: localStorage.getItem("_appName"),
- roleName: RoleField,
- userId: u.id
- };
- axios.post(roleurl, body, { headers: headers }).then(() => {
- const currentUser = Parse.User.current();
- let _fname = this.state.title;
- var forms = Parse.Object.extend(_fname);
- var form = new forms();
- form.set(
- "CreatedBy",
- Parse.User.createWithoutData(currentUser.id)
- );
- if (localStorage.getItem("TenetId")) {
- form.set("TenantId", {
- __type: "Pointer",
- className: "partners_Tenant",
- objectId: localStorage.getItem("TenetId")
- });
- }
- form.set("UserId", u);
- form.set("UserRole", RoleField);
- if (this.state["FormACL"]) {
- let ACL = {};
- for (let [key, value] of Object.entries(
- this.state["FormACL"]
- )) {
- if (key === "*") {
- ACL[key] = value;
- }
- if (key === "#currentUser#") {
- ACL[Parse.User.current().id] = value;
- }
- if (key.startsWith("role")) {
- ACL[key] = value;
- }
- }
- form.setACL(new Parse.ACL(ACL));
- }
- form.save(RowData).then(
- () => {
- let filtered = {};
- if (this.state.redirect_type === "clearData") {
- if (
- this.state.persistentFields &&
- this.state.persistentFields.length
- ) {
- filtered = Object.keys(RowData)
- .filter((key) =>
- this.state.persistentFields.includes(key)
- )
- .reduce((obj, key) => {
- obj[key] = RowData[key];
- return obj;
- }, {});
- }
- } else {
- RowData = {};
- }
- this.setState(
- {
- formData: filtered,
- active: true,
- loading: false,
- toastColor: "#5cb85c",
- toastDescription: this.state.successMassage
- },
- () => {
- let redirect_type = this.state.redirect_type;
- let redirect_id = this.state.redirect_id;
- this.props.removeState();
- this.props.removeLevel2State();
- this.props.removeLevel3State();
- var x = document.getElementById("snackbar");
- x.className = "show";
- setTimeout(function () {
- x.className = x.className.replace("show", "");
- if (redirect_type === "Form") {
- this.props.navigate(`/form/${redirect_id}`);
- } else if (redirect_type === "Report") {
- this.props.navigate(`/report/${redirect_id}`);
- } else if (redirect_type === "Dashboard") {
- this.props.navigate(`/dashboard/${redirect_id}`);
- } else if (redirect_type === "Url") {
- window.location = redirect_id;
- } else if (redirect_type === "Microapp") {
- this.props.navigate(`/asmf/${redirect_id}`);
- }
- }, 2000);
- }
- );
- },
- (error) => {
- console.log("error", error.message);
- this.setState({
- loading: false,
- active: true,
- toastColor: "#d9534f",
- toastDescription: error.message
- });
-
- var x = document.getElementById("snackbar");
- x.className = "show";
- setTimeout(function () {
- x.className = x.className.replace("show", "");
- }, 2000);
- }
- );
- });
- },
- async (error) => {
- if (error.code === 202) {
- let params;
- if (UserData.username) {
- params = { username: UserData.username };
- } else if (UserData.email) {
- params = { email: UserData.email };
- } else {
- params = { username: UserData.phone };
- }
- const userRes = await Parse.Cloud.run("getUserId", params);
- try {
- let _emp = {
- __type: "Pointer",
- className: "_User",
- objectId: userRes.id
- };
- let roleurl = `${this.state.parseBaseUrl}functions/AddUserToRole`;
- const headers = {
- "Content-Type": "application/json",
- "X-Parse-Application-Id": this.state.parseAppId,
- sessionToken: localStorage.getItem("accesstoken")
- };
- let body = {
- appName: localStorage.getItem("_appName"),
- roleName: RoleField,
- userId: userRes.id
- };
- await axios
- .post(roleurl, body, { headers: headers })
- .then(() => {
- const currentUser = Parse.User.current();
- let _fname = this.state.title;
- var forms = Parse.Object.extend(_fname);
- var form = new forms();
- form.set(
- "CreatedBy",
- Parse.User.createWithoutData(currentUser.id)
- );
- if (localStorage.getItem("TenetId")) {
- form.set("TenantId", {
- __type: "Pointer",
- className: "partners_Tenant",
- objectId: localStorage.getItem("TenetId")
- });
- }
- form.set("UserId", _emp);
- form.set("UserRole", RoleField);
- if (this.state["FormACL"]) {
- let ACL = {};
- for (let [key, value] of Object.entries(
- this.state["FormACL"]
- )) {
- if (key === "*") {
- ACL[key] = value;
- }
- if (key === "#currentUser#") {
- ACL[Parse.User.current().id] = value;
- }
- if (key.startsWith("role")) {
- ACL[key] = value;
- }
- }
- form.setACL(new Parse.ACL(ACL));
- }
- form.save(RowData).then(
- () => {
- let filtered = {};
- if (this.state.redirect_type === "clearData") {
- if (
- this.state.persistentFields &&
- this.state.persistentFields.length
- ) {
- filtered = Object.keys(RowData)
- .filter((key) =>
- this.state.persistentFields.includes(key)
- )
- .reduce((obj, key) => {
- obj[key] = RowData[key];
- return obj;
- }, {});
- }
- } else {
- RowData = {};
- }
- this.setState(
- {
- formData: filtered,
- active: true,
- loading: false,
- toastColor: "#5cb85c",
- toastDescription: this.state.successMassage
- },
- () => {
- let redirect_type = this.state.redirect_type;
- let redirect_id = this.state.redirect_id;
- this.props.removeState();
- this.props.removeLevel2State();
- this.props.removeLevel3State();
- var x = document.getElementById("snackbar");
- x.className = "show";
- setTimeout(function () {
- x.className = x.className.replace("show", "");
- if (redirect_type === "Form") {
- this.props.navigate(`/form/${redirect_id}`);
- } else if (redirect_type === "Report") {
- this.props.navigate(`/report/${redirect_id}`);
- } else if (redirect_type === "Dashboard") {
- this.props.navigate(
- `/dashboard/${redirect_id}`
- );
- } else if (redirect_type === "Url") {
- window.location = redirect_id;
- } else if (redirect_type === "Microapp") {
- this.props.navigate(`/asmf/${redirect_id}`);
- }
- }, 2000);
- }
- );
- },
- (error) => {
- this.setState({
- loading: false,
- active: true,
- toastColor: "#d9534f",
- toastDescription: error.message
- });
-
- var x = document.getElementById("snackbar");
- x.className = "show";
- setTimeout(function () {
- x.className = x.className.replace("show", "");
- }, 2000);
- }
- );
- });
- } catch (error) {
- this.setState({
- loading: false,
- active: true,
- toastColor: "#d9534f",
- toastDescription: error.message
- });
-
- var x = document.getElementById("snackbar");
- x.className = "show";
- setTimeout(function () {
- x.className = x.className.replace("show", "");
- }, 2000);
- }
- }
- }
+ if (mb > 10) {
+ setTimeout(() => {
+ alert(
+ `The selected file size is too large. Please select a file less than 10 MB`
);
- } catch (e) {
- console.log("Problem", e.message);
- this.setState({ loading: false, active: true });
- }
+ }, 500);
+ return;
} else {
- try {
- let RowData = formData;
- let _scanData = this.state.schemaState;
- if (_scanData.dependencies) {
- Object.keys(_scanData.dependencies).forEach((key) => {
- if (_scanData.dependencies[key].oneOf) {
- _scanData.dependencies[key].oneOf.forEach((val) => {
- Object.keys(val.properties).forEach((k) => {
- if (typeof val.properties[k] === "object") {
- if (val.properties[k].format === "date") {
- if (RowData[k]) {
- let newdate = new Date(RowData[k]);
- RowData[k] = newdate;
- }
- }
- if (val.properties[k].component === "HtmlEditor") {
- if (RowData[k]) {
- let newHtml = RowData[k]
- .replace(/
]*>/g, "")
- .replace(/<\/p>/g, " ");
- RowData[k] = newHtml;
- }
- }
- if (val.properties[k].component === "DateTime") {
- if (RowData[k]) {
- let newDate11 = new Date(RowData[k]);
- RowData[k] = newDate11;
- }
- }
- if (val.properties[k].component === "CurrencyInput") {
- if (val.properties[k].currencyColumn) {
- RowData[`${val.properties[k].currencyColumn}`] =
- val.properties[k].defaultcurrency;
- }
- }
- if (val.properties[k].type === "string") {
- if (typeof RowData[k] === "string")
- RowData[k] = RowData[k].trim();
- }
- if (val.properties[k].data !== undefined) {
- if (val.properties[k].data.isPointer) {
- let pointer = undefined;
- if (val.properties[k].data.savePointerClass) {
- if (RowData[k]) {
- pointer = {
- __type: "Pointer",
- className:
- val.properties[k].data.savePointerClass,
- objectId: RowData[k]
- };
- }
- } else if (val.properties[k].data.class) {
- if (RowData[k]) {
- pointer = {
- __type: "Pointer",
- className: val.properties[k].data.class,
- objectId: RowData[k]
- };
- }
- } else {
- if (RowData[k]) {
- pointer = {
- __type: "Pointer",
- className: localStorage.getItem("extended_class"),
- objectId: RowData[k]
- };
- }
- }
-
- RowData[k] = pointer;
- }
- if (val.properties[k].data.FolderTypeValue) {
- if (RowData[k]) {
- let obj = {
- __type: "Pointer",
- className: val.properties[k].data.ClassName,
- objectId: RowData[k]
- };
- RowData[k] = obj;
- }
- }
- }
- }
- });
- });
- }
- });
- }
- Object.keys(_scanData).forEach(function (key) {
- let _dd = _scanData[key];
- if (typeof _dd === "object") {
- Object.keys(_dd).forEach(function (k) {
- if (_dd[k].type === "array" && _dd[k].items) {
- let _prop = _dd[k].items.properties;
- if (_prop && Array.isArray(RowData[k])) {
- let newRow = [];
- RowData[k].forEach((t) => {
- let _newObj = t;
- if (typeof t === "object") {
- Object.keys(_prop).forEach(function (l) {
- if (_prop[l].data && _prop[l].data.isPointer) {
- if (typeof t[l] === "object") {
- let obj = {
- __type: "Pointer",
- className: _prop[l].data.class,
- objectId: t[l].objectId
- };
- _newObj = { ..._newObj, [l]: obj };
- } else {
- let obj = {
- __type: "Pointer",
- className: _prop[l].data.class,
- objectId: t[l]
- };
- _newObj = { ..._newObj, [l]: obj };
- }
- }
- });
- }
- newRow.push(_newObj);
- });
- RowData[k] = newRow;
- }
- }
-
- if (_dd[k].component === "AutoSuggest" && _dd[k].isPointer) {
- if (RowData[k]) {
- let pointer = {
- __type: "Pointer",
- className: _dd[k].class,
- objectId: RowData[k]
- };
- RowData[k] = pointer;
- }
- }
- if (_dd[k].format === "date") {
- let newdate = new Date(RowData[k]);
- RowData[k] = newdate;
- }
- if (_dd[k].component === "HtmlEditor") {
- if (RowData[k]) {
- let newHtml = RowData[k]
- .replace(/
]*>/g, "")
- .replace(/<\/p>/g, " ");
- RowData[k] = newHtml;
- }
- }
- if (_dd[k].component === "DateTime") {
- let newDate11;
- if (!RowData[k]) {
- newDate11 = new Date();
- } else {
- newDate11 = new Date(RowData[k]);
- }
- RowData[k] = newDate11;
- }
- if (_dd[k].component === "CurrencyInput") {
- if (_dd[k].currencyColumn) {
- RowData[`${_dd[k].currencyColumn}`] = _dd[k].defaultcurrency;
- }
- }
- if (_dd[k].data !== undefined) {
- if (_dd[k].data.isPointer) {
- let pointer = undefined;
- if (RowData[k] && RowData[k] !== "Select") {
- if (_dd[k].type === "array") {
- pointer = [];
- RowData[k] &&
- RowData[k].forEach((a) => {
- let _kk = {};
- if (_dd[k].data.savePointerClass) {
- _kk = {
- __type: "Pointer",
- className: _dd[k].data.savePointerClass,
- objectId: a
- };
- } else {
- _kk = {
- __type: "Pointer",
- className: _dd[k].data.class,
- objectId: a
- };
- }
+ const name = sanitizeFileName(file.name);
- pointer.push(_kk);
- });
- } else if (_dd[k].data.class) {
- if (_dd[k].data.savePointerClass) {
- if (RowData[k]) {
- pointer = {
- __type: "Pointer",
- className: _dd[k].data.savePointerClass,
- objectId: RowData[k]
- };
- }
- } else if (RowData[k]) {
- pointer = {
- __type: "Pointer",
- className: _dd[k].data.class,
- objectId: RowData[k]
- };
- }
- } else {
- if (RowData[k]) {
- pointer = {
- __type: "Pointer",
- className: localStorage.getItem("extended_class"),
- objectId: RowData[k]
- };
- }
- }
+ const parseFile = new Parse.File(name, { uri: url });
- RowData[k] = pointer;
- }
- }
- if (_dd[k].data.FolderTypeValue) {
- if (RowData[k]) {
- let obj = {
- __type: "Pointer",
- className: _dd[k].data.ClassName,
- objectId: RowData[k]
- };
- RowData[k] = obj;
- }
- }
- }
- if (_dd[k].type === "string") {
- let d = RowData[k];
- if (typeof d === "string") {
- RowData[k] = d.trim();
- }
- }
- });
+ try {
+ const response = await parseFile.save({
+ progress: (progressValue, loaded, total, { type }) => {
+ if (type === "upload" && progressValue !== null) {
+ const percentCompleted = Math.round((loaded * 100) / total);
+ setpercentage(percentCompleted);
+ }
}
});
- Parse.serverURL = this.state.parseBaseUrl;
- Parse.initialize(this.state.parseAppId);
- const currentUser = Parse.User.current();
- let _fname = this.state.title;
- var forms = Parse.Object.extend(_fname);
-
- var form = new forms();
-
- form.set("CreatedBy", Parse.User.createWithoutData(currentUser.id));
+ setFileUpload(response.url());
+ setfileload(false);
- if (this.state["FormACL"]) {
- let ACL = {};
- for (let [key, value] of Object.entries(this.state["FormACL"])) {
- if (key === "*") {
- ACL[key] = value;
- }
- if (key === "#currentUser#") {
- ACL[Parse.User.current().id] = value;
- } else if (key.startsWith("#")) {
- let arr = key.split("#");
- let new_arr = arr.filter((x) => x !== "");
- if (new_arr.length === 2) {
- let l = RowData[new_arr[0]];
- try {
- const Agent = Parse.Object.extend(l.className);
- const qu = new Parse.Query(Agent);
- qu.equalTo("objectId", l.objectId);
- qu.include(new_arr[1]);
- await qu.first();
- } catch (err) {
- console.error("Error while fetching Agent", err.massage);
- }
- }
- }
- if (key.startsWith("role")) {
- ACL[key] = value;
- }
- }
- form.setACL(new Parse.ACL(ACL));
+ if (response.url()) {
+ return response.url();
}
-
- form.save(RowData).then(
- (form) => {
- let filtered = {};
- if (this.state.redirect_type === "clearData") {
- if (
- this.state.persistentFields &&
- this.state.persistentFields.length
- ) {
- filtered = Object.keys(RowData)
- .filter((key) => this.state.persistentFields.includes(key))
- .reduce((obj, key) => {
- obj[key] = RowData[key];
- return obj;
- }, {});
- }
- } else {
- RowData = {};
- }
-
- this.setState(
- {
- formData: filtered,
- active: true,
- loading: false,
- toastColor: "#5cb85c",
- toastDescription: this.state.successMassage
- },
- () => {
- let redirect_type = this.state.redirect_type;
- let redirect_id = this.state.redirect_id;
- var x = document.getElementById("snackbar");
- this.props.removeState();
- this.props.removeLevel2State();
- this.props.removeLevel3State();
- x.className = "show";
- setTimeout(function () {
- x.className = x.className.replace("show", "");
- }, 2000);
- if (redirect_type === "Form") {
- this.props.navigate(`/form/${redirect_id}`);
- } else if (redirect_type === "Report") {
- this.props.navigate(`/report/${redirect_id}`);
- } else if (redirect_type === "Dashboard") {
- this.props.navigate(`/dashboard/${redirect_id}`);
- } else if (redirect_type === "Url") {
- window.location = redirect_id;
- } else if (redirect_type === "Microapp") {
- window.localStorage.setItem(
- "rowlevel",
- JSON.stringify({ ...formData, ...form })
- );
- this.props.navigate(`/asmf/${redirect_id}`);
- }
- }
- );
- },
- (error) => {
- this.setState({
- loading: false,
- active: true,
- toastColor: "#d9534f",
- toastDescription: error.message
- });
-
- var x = document.getElementById("snackbar");
- x.className = "show";
- setTimeout(function () {
- x.className = x.className.replace("show", "");
- }, 2000);
- }
- );
} catch (error) {
- this.setState({
- loading: false,
- active: true,
- toastColor: "#d9534f",
- toastDescription: error.message
- });
-
- var x = document.getElementById("snackbar");
- x.className = "show";
- setTimeout(function () {
- x.className = x.className.replace("show", "");
- }, 2000);
+ setfileload(false);
+ setpercentage(0);
+ console.error("Error uploading file:", error);
}
}
};
+ const dropboxCancel = async () => {};
+ const handleSubmit = async (e) => {
+ e.preventDefault();
+ e.stopPropagation();
+ setIsSubmit(true);
+ try {
+ const currentUser = Parse.User.current();
+ const object = new Parse.Object(props.Cls);
+ object.set("Name", formData?.Name);
+ object.set("Description", formData?.Description);
+ object.set("Note", formData?.Note);
+ if (props.title === "Request Signatures") {
+ object.set(
+ "TimeToCompleteDays",
+ parseInt(formData?.TimeToCompleteDays)
+ );
+ const isChecked = formData.SendinOrder === "true" ? true : false;
+ object.set("SendinOrder", isChecked);
+ }
+ object.set("URL", fileupload);
+ object.set("CreatedBy", Parse.User.createWithoutData(currentUser.id));
+ if (folder && folder.ObjectId) {
+ object.set("Folder", {
+ __type: "Pointer",
+ className: props.Cls,
+ objectId: folder.ObjectId
+ });
+ }
+ if (signers && signers.length > 0) {
+ object.set("Signers", signers);
+ }
+ const ExtCls = JSON.parse(localStorage.getItem("Extand_Class"));
+ object.set("ExtUserPtr", {
+ __type: "Pointer",
+ className: "contracts_Users",
+ objectId: ExtCls[0].objectId
+ });
- saveUrlParamToFormdata = () => {
- let url = window.location.hash;
- let paramString = url.split("?")[1];
- let queryString = new URLSearchParams(paramString);
- let obj = {};
- for (const [key, value] of queryString.entries()) {
- obj = { ...obj, [key]: value };
+ const res = await object.save();
+ if (res) {
+ setSigners([]);
+ setFolder({ ObjectId: "", Name: "" });
+ setFormData({
+ Name: "",
+ Description: "",
+ Note: ""
+ });
+ setFileUpload([]);
+ setpercentage(0);
+ navigate(
+ `/asmf/remoteUrl=aHR0cHM6Ly9xaWstYWktb3JnLmdpdGh1Yi5pby9TaWduLU1pY3JvYXBwVjIvcmVtb3RlRW50cnkuanM=&moduleToLoad=AppRoutes&remoteName=signmicroapp/${props?.redirectRoute}/${res.id}`
+ );
+ }
+ } catch (err) {
+ console.log("err ", err);
+ setIsErr(true);
+ } finally {
+ setIsAlert(true);
+ setTimeout(() => {
+ setIsAlert(false);
+ }, 1000);
+ setIsSubmit(false);
}
- this.setState({ formData: obj });
};
- componentDidMount() {
- let url = window.location.hash;
- if (url.includes("_app")) {
- this.setState({ isAppRequest: true });
- }
- let id = this.props.id;
- this.getForm(id);
- this.saveUrlParamToFormdata();
- }
-
- UNSAFE_componentWillReceiveProps(newProps) {
- let id = newProps.id;
- this.getForm(id);
- }
-
- render() {
- if (localStorage.getItem("accesstoken") === null) {
- this.props.navigate(`/`);
+ const handleFolder = (data) => {
+ setFolder(data);
+ };
+ const handleSigners = (data) => {
+ if (data && data.length > 0) {
+ const updateSigners = data.map((x) => ({
+ __type: "Pointer",
+ className: "contracts_Contactbook",
+ objectId: x
+ }));
+ setSigners(updateSigners);
}
+ };
- let schema = this.state.schemaState;
- let uiSchema = this.state.ui_schema;
- let rules = this.state.rules;
- let extraActions = this.state.extraActions;
-
- let FormToDisplay = applyRules(
- schema,
- uiSchema,
- rules,
- Engine,
- extraActions
- )(Form);
- let formView = (
-
-
-
- {this.state.active && this.state.buttons.submitText ? (
-
- {this.state.buttons.submitText}
-
- ) : (
- this.state.buttons.submitText && (
-
- {this.state.buttons.submitText}
-
- )
- )}
-
- {this.state.buttons.resetText && (
- {
- e.preventDefault();
- this.setState({
- loading: true,
- formData: {}
- });
- setTimeout(() => {
- this.setState({ loading: false });
- }, 1000);
- }}
- type="button"
- >
- {this.state.buttons.resetText}
-
- )}
-
-
-
- );
-
- if (this.state.loading) {
- formView = (
+ const handleReset = () => {
+ setSigners([]);
+ setFolder({ ObjectId: "", Name: "" });
+ setFormData({
+ Name: "",
+ Description: "",
+ Note: ""
+ });
+ setFileUpload([]);
+ setpercentage(0);
+ };
+ return (
+
+
+ {isAlert && (
+
+ {isErr
+ ? "Something went wrong please try again!"
+ : `${props.msgVar} created successfully!`}
+
+ )}
+ {isSubmit ? (
- );
- }
- return (
-
-
-
-
-
-
-
- {this.state.help ? (
-
- ) : null}
-
{formView}
-
+ ) : (
+
- {isModal && (
-
-
-
-
-
- Additional Info
-
-
-
-
-
-
-
+
+
- )}
+
+
+ Job Title
+ *
+
+
+ setUserDetails({
+ ...userDetails,
+ Destination: e.target.value
+ })
+ }
+ required
+ />
+
+
+ handleSubmitbtn(e)}
+ style={{
+ marginRight: 10,
+ backgroundColor: modalSubmitBtnColor
+ }}
+ >
+ Login
+
+
+ Cancel
+
+
+
+
>
) : (
{
+const PageNotFound = ({ prefix }) => {
return (
@@ -10,7 +10,9 @@ const PageNotFound = () => {
404
-
Page Not Found
+
+ {prefix ? prefix : "Page"} Not Found
+
);
diff --git a/apps/OpenSign/src/routes/Pgsignup.js b/apps/OpenSign/src/routes/Pgsignup.js
index af4cc0108..f3d12437d 100644
--- a/apps/OpenSign/src/routes/Pgsignup.js
+++ b/apps/OpenSign/src/routes/Pgsignup.js
@@ -5,7 +5,7 @@ import axios from "axios";
import { fetchAppInfo, showTenantName } from "../redux/actions/index";
import { connect } from "react-redux";
import Title from "../components/Title";
-import { useNavigate } from "react-router-dom";
+import { useNavigate, useLocation } from "react-router-dom";
const appId = localStorage.getItem("AppID12");
const server = localStorage.getItem("BaseUrl12");
@@ -13,6 +13,7 @@ Parse.serverURL = server;
Parse.initialize(appId);
const PgSignUp = (props) => {
const navigate = useNavigate();
+ const location = useLocation();
const [parseBaseUrl] = useState(localStorage.getItem("BaseUrl12"));
const [parseAppId] = useState(localStorage.getItem("AppID12"));
const [formData, setFormData] = useState({
@@ -187,7 +188,7 @@ const PgSignUp = (props) => {
console.log("err ", error);
if (error.message === "Account already exists for this username.") {
alert("Account already exists!");
- navigate("/");
+ navigate("/", { replace: true });
} else {
setIsLoader(false);
alert("Something went wrong, please try again later!");
@@ -351,7 +352,7 @@ const PgSignUp = (props) => {
element.pageType
);
setIsLoader(false);
- navigate("/");
+ navigate("/", { replace: true });
} else {
extendedInfo.forEach((x) => {
if (x.TenantId) {
@@ -389,9 +390,12 @@ const PgSignUp = (props) => {
);
setIsLoader(false);
alert("Registered user successfully");
- navigate(
- `/${element.pageType}/${element.pageId}`
- );
+ const redirectUrl =
+ location?.state?.from ||
+ `/${element.pageType}/${element.pageId}`;
+
+ // Redirect to the appropriate URL after successful login
+ navigate(redirectUrl);
}
} else {
alert("Registered user successfully");
@@ -402,7 +406,12 @@ const PgSignUp = (props) => {
);
localStorage.setItem("pageType", element.pageType);
setIsLoader(false);
- navigate(`/${element.pageType}/${element.pageId}`);
+ const redirectUrl =
+ location?.state?.from ||
+ `/${element.pageType}/${element.pageId}`;
+
+ // Redirect to the appropriate URL after successful login
+ navigate(redirectUrl);
}
},
(error) => {
diff --git a/apps/OpenSign/src/routes/PlanSubscriptions.js b/apps/OpenSign/src/routes/PlanSubscriptions.js
index 00ad2fa62..db39ee465 100644
--- a/apps/OpenSign/src/routes/PlanSubscriptions.js
+++ b/apps/OpenSign/src/routes/PlanSubscriptions.js
@@ -39,7 +39,7 @@ const PlanSubscriptions = () => {
setIsLoader(false);
setYearlyVisible(false);
} else {
- navigate("/");
+ navigate("/", { replace: true });
}
// eslint-disable-next-line
}, []);
@@ -78,31 +78,6 @@ const PlanSubscriptions = () => {
id="monthlyPlans"
className={`${yearlyVisible ? "none" : "block my-2"}`}
>
- {/*
-
-
-
- Monthly
-
-
-
-
- Yearly
-
-
-
-
*/}
diff --git a/apps/OpenSign/src/routes/Report.js b/apps/OpenSign/src/routes/Report.js
index af3273095..b47be1f34 100644
--- a/apps/OpenSign/src/routes/Report.js
+++ b/apps/OpenSign/src/routes/Report.js
@@ -5,6 +5,7 @@ import axios from "axios";
import reportJson from "../json/ReportJson";
import { useParams } from "react-router-dom";
import Title from "../components/Title";
+import PageNotFound from "./PageNotFound";
const Report = () => {
const { id } = useParams();
@@ -15,7 +16,7 @@ const Report = () => {
const [heading, setHeading] = useState([]);
const [isNextRecord, setIsNextRecord] = useState(false);
const [isMoreDocs, setIsMoreDocs] = useState(true);
- const [form, setForm]= useState("")
+ const [form, setForm] = useState("");
const abortController = new AbortController();
const docPerPage = 10;
@@ -51,7 +52,7 @@ const Report = () => {
setActions(json.actions);
setHeading(json.heading);
setReportName(json.reportName);
- setForm(json.form)
+ setForm(json.form);
Parse.serverURL = localStorage.getItem("BaseUrl12");
Parse.initialize(localStorage.getItem("AppID12"));
const currentUser = Parse.User.current().id;
@@ -159,13 +160,7 @@ const Report = () => {
form={form}
/>
) : (
-
+
)}
>
)}
diff --git a/apps/OpenSign/src/routes/Webhook.js b/apps/OpenSign/src/routes/Webhook.js
new file mode 100644
index 000000000..eaaf5b226
--- /dev/null
+++ b/apps/OpenSign/src/routes/Webhook.js
@@ -0,0 +1,171 @@
+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 [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 handleModal = () => setIsModal(!isModal);
+ return (
+
+
+ {isGenerate && Webhook added successfully! }
+ {isErr && Something went wrong! }
+ {isLoader ? (
+
+ ) : (
+
+
Webhook
+
+
+ Webhook: {" "}
+
+ {webhook && webhook}
+
+
+
+
+
+ {webhook ? "Update Webhook" : "Add Webhook"}
+
+
+ openInNewTab(
+ "https://docs.opensignlabs.com/docs/API-docs/opensign-api-v-1"
+ )
+ }
+ 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
+
+
+
+
+
+
+ Webhook
+ 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"
+ />
+
+
+
+
+ Yes
+
+
+ No
+
+
+
+
+
+ )}
+
+ );
+}
+
+export default Webhook;
diff --git a/apps/OpenSign/src/styles/loader.css b/apps/OpenSign/src/styles/loader.css
index e6e1624f8..940d1c557 100644
--- a/apps/OpenSign/src/styles/loader.css
+++ b/apps/OpenSign/src/styles/loader.css
@@ -1,2215 +1,66 @@
- fieldset {
- border: 0 !important;
- margin: 0 !important;
- padding: 0 !important;
- }
-
- [class*="loader-"] {
- display: inline-block;
- width: 1em;
- height: 1em;
- color: inherit;
- vertical-align: middle;
- pointer-events: none;
- }
-
- .loader-01 {
- border: 0.2em dotted currentcolor;
- border-radius: 50%;
- -webkit-animation: 1s loader-01 linear infinite;
- animation: 1s loader-01 linear infinite;
- }
-
- @-webkit-keyframes loader-01 {
- 0% {
- -webkit-transform: rotate(0deg);
- transform: rotate(0deg);
- }
- 100% {
- -webkit-transform: rotate(360deg);
- transform: rotate(360deg);
- }
- }
-
- @keyframes loader-01 {
- 0% {
- -webkit-transform: rotate(0deg);
- transform: rotate(0deg);
- }
- 100% {
- -webkit-transform: rotate(360deg);
- transform: rotate(360deg);
- }
- }
- .loader-02 {
- border: 0.2em solid transparent;
- border-left-color: currentcolor;
- border-right-color: currentcolor;
- border-radius: 50%;
- -webkit-animation: 1s loader-02 linear infinite;
- animation: 1s loader-02 linear infinite;
- }
-
- @-webkit-keyframes loader-02 {
- 0% {
- -webkit-transform: rotate(0deg);
- transform: rotate(0deg);
- }
- 100% {
- -webkit-transform: rotate(360deg);
- transform: rotate(360deg);
- }
- }
-
- @keyframes loader-02 {
- 0% {
- -webkit-transform: rotate(0deg);
- transform: rotate(0deg);
- }
- 100% {
- -webkit-transform: rotate(360deg);
- transform: rotate(360deg);
- }
- }
- .loader-03 {
- border: 0.2em solid currentcolor;
- border-bottom-color: transparent;
- border-radius: 50%;
- -webkit-animation: 1s loader-03 linear infinite;
- animation: 1s loader-03 linear infinite;
- position: relative;
- }
-
- @-webkit-keyframes loader-03 {
- 0% {
- -webkit-transform: rotate(0deg);
- transform: rotate(0deg);
- }
- 100% {
- -webkit-transform: rotate(360deg);
- transform: rotate(360deg);
- }
- }
-
- @keyframes loader-03 {
- 0% {
- -webkit-transform: rotate(0deg);
- transform: rotate(0deg);
- }
- 100% {
- -webkit-transform: rotate(360deg);
- transform: rotate(360deg);
- }
- }
- .loader-04 {
- border: 1px solid currentcolor;
- border-radius: 50%;
- -webkit-animation: 1s loader-04 linear infinite;
- animation: 1s loader-04 linear infinite;
- position: relative;
- }
- .loader-04:before {
- content: "";
- display: block;
- width: 0;
- height: 0;
- position: absolute;
- top: -0.2em;
- left: 50%;
- border: 0.2em solid currentcolor;
- border-radius: 50%;
- }
-
- @-webkit-keyframes loader-04 {
- 0% {
- -webkit-transform: rotate(0deg);
- transform: rotate(0deg);
- }
- 100% {
- -webkit-transform: rotate(360deg);
- transform: rotate(360deg);
- }
- }
-
- @keyframes loader-04 {
- 0% {
- -webkit-transform: rotate(0deg);
- transform: rotate(0deg);
- }
- 100% {
- -webkit-transform: rotate(360deg);
- transform: rotate(360deg);
- }
- }
- .loader-05 {
- border: 0.2em solid transparent;
- border-top-color: currentcolor;
- border-radius: 50%;
- -webkit-animation: 1s loader-05 linear infinite;
- animation: 1s loader-05 linear infinite;
- position: relative;
- }
- .loader-05:before {
- content: "";
- display: block;
- width: inherit;
- height: inherit;
- position: absolute;
- top: -0.2em;
- left: -0.2em;
- border: 0.2em solid currentcolor;
- border-radius: 50%;
- opacity: 0.5;
- }
-
- @-webkit-keyframes loader-05 {
- 0% {
- -webkit-transform: rotate(0deg);
- transform: rotate(0deg);
- }
- 100% {
- -webkit-transform: rotate(360deg);
- transform: rotate(360deg);
- }
- }
-
- @keyframes loader-05 {
- 0% {
- -webkit-transform: rotate(0deg);
- transform: rotate(0deg);
- }
- 100% {
- -webkit-transform: rotate(360deg);
- transform: rotate(360deg);
- }
- }
- .loader-06 {
- border: 0.2em solid currentcolor;
- border-radius: 50%;
- -webkit-animation: loader-06 1s ease-out infinite;
- animation: loader-06 1s ease-out infinite;
- }
-
- @-webkit-keyframes loader-06 {
- 0% {
- -webkit-transform: scale(0);
- transform: scale(0);
- opacity: 0;
- }
- 50% {
- opacity: 1;
- }
- 100% {
- -webkit-transform: scale(1);
- transform: scale(1);
- opacity: 0;
- }
- }
-
- @keyframes loader-06 {
- 0% {
- -webkit-transform: scale(0);
- transform: scale(0);
- opacity: 0;
- }
- 50% {
- opacity: 1;
- }
- 100% {
- -webkit-transform: scale(1);
- transform: scale(1);
- opacity: 0;
- }
- }
- .loader-07 {
- border: 0 solid transparent;
- border-radius: 50%;
- position: relative;
- }
- .loader-07:before, .loader-07:after {
- content: "";
- border: 0.2em solid currentcolor;
- border-radius: 50%;
- width: inherit;
- height: inherit;
- position: absolute;
- top: 0;
- left: 0;
- -webkit-animation: loader-07 1s linear infinite;
- animation: loader-07 1s linear infinite;
- opacity: 0;
- }
- .loader-07:before {
- -webkit-animation-delay: 1s;
- animation-delay: 1s;
- }
- .loader-07:after {
- -webkit-animation-delay: 0.5s;
- animation-delay: 0.5s;
- }
-
- @-webkit-keyframes loader-07 {
- 0% {
- -webkit-transform: scale(0);
- transform: scale(0);
- opacity: 0;
- }
- 50% {
- opacity: 1;
- }
- 100% {
- -webkit-transform: scale(1);
- transform: scale(1);
- opacity: 0;
- }
- }
-
- @keyframes loader-07 {
- 0% {
- -webkit-transform: scale(0);
- transform: scale(0);
- opacity: 0;
- }
- 50% {
- opacity: 1;
- }
- 100% {
- -webkit-transform: scale(1);
- transform: scale(1);
- opacity: 0;
- }
- }
- .loader-08 {
- position: relative;
- }
- .loader-08:before, .loader-08:after {
- content: "";
- width: inherit;
- height: inherit;
- border-radius: 50%;
- background-color: currentcolor;
- opacity: 0.6;
- position: absolute;
- top: 0;
- left: 0;
- -webkit-animation: loader-08 2s infinite ease-in-out;
- animation: loader-08 2s infinite ease-in-out;
- }
- .loader-08:after {
- -webkit-animation-delay: -1s;
- animation-delay: -1s;
- }
-
- @-webkit-keyframes loader-08 {
- 0%,
- 100% {
- -webkit-transform: scale(0);
- transform: scale(0);
- }
- 50% {
- -webkit-transform: scale(1);
- transform: scale(1);
- }
- }
-
- @keyframes loader-08 {
- 0%,
- 100% {
- -webkit-transform: scale(0);
- transform: scale(0);
- }
- 50% {
- -webkit-transform: scale(1);
- transform: scale(1);
- }
- }
- .loader-09 {
- background-color: currentcolor;
- border-radius: 50%;
- -webkit-animation: loader-09 1s infinite ease-in-out;
- animation: loader-09 1s infinite ease-in-out;
- }
-
- @-webkit-keyframes loader-09 {
- 0% {
- -webkit-transform: scale(0);
- transform: scale(0);
- }
- 100% {
- -webkit-transform: scale(1);
- transform: scale(1);
- opacity: 0;
- }
- }
-
- @keyframes loader-09 {
- 0% {
- -webkit-transform: scale(0);
- transform: scale(0);
- }
- 100% {
- -webkit-transform: scale(1);
- transform: scale(1);
- opacity: 0;
- }
- }
- .loader-10 {
- position: relative;
- -webkit-animation: loader-10-1 2s infinite linear;
- animation: loader-10-1 2s infinite linear;
- }
- .loader-10:before, .loader-10:after {
- content: "";
- width: 0;
- height: 0;
- border: 0.5em solid currentcolor;
- display: block;
- position: absolute;
- border-radius: 100%;
- -webkit-animation: loader-10-2 2s infinite ease-in-out;
- animation: loader-10-2 2s infinite ease-in-out;
- }
- .loader-10:before {
- top: 0;
- left: 50%;
- }
- .loader-10:after {
- bottom: 0;
- right: 50%;
- -webkit-animation-delay: -1s;
- animation-delay: -1s;
- }
-
- @-webkit-keyframes loader-10-1 {
- 100% {
- -webkit-transform: rotate(360deg);
- transform: rotate(360deg);
- }
- }
-
- @keyframes loader-10-1 {
- 100% {
- -webkit-transform: rotate(360deg);
- transform: rotate(360deg);
- }
- }
- @-webkit-keyframes loader-10-2 {
- 0%,
- 100% {
- -webkit-transform: scale(0);
- transform: scale(0);
- }
- 50% {
- -webkit-transform: scale(1);
- transform: scale(1);
- }
- }
- @keyframes loader-10-2 {
- 0%,
- 100% {
- -webkit-transform: scale(0);
- transform: scale(0);
- }
- 50% {
- -webkit-transform: scale(1);
- transform: scale(1);
- }
- }
- .loader-11 {
- background-color: currentcolor;
- -webkit-animation: loader-11 1.2s infinite ease-in-out;
- animation: loader-11 1.2s infinite ease-in-out;
- }
-
- @-webkit-keyframes loader-11 {
- 0% {
- -webkit-transform: perspective(120px) rotateX(0deg) rotateY(0deg);
- transform: perspective(120px) rotateX(0deg) rotateY(0deg);
- }
- 50% {
- -webkit-transform: perspective(120px) rotateX(-180.1deg) rotateY(0deg);
- transform: perspective(120px) rotateX(-180.1deg) rotateY(0deg);
- }
- 100% {
- -webkit-transform: perspective(120px) rotateX(-180deg) rotateY(-179.9deg);
- transform: perspective(120px) rotateX(-180deg) rotateY(-179.9deg);
- }
- }
-
- @keyframes loader-11 {
- 0% {
- -webkit-transform: perspective(120px) rotateX(0deg) rotateY(0deg);
- transform: perspective(120px) rotateX(0deg) rotateY(0deg);
- }
- 50% {
- -webkit-transform: perspective(120px) rotateX(-180.1deg) rotateY(0deg);
- transform: perspective(120px) rotateX(-180.1deg) rotateY(0deg);
- }
- 100% {
- -webkit-transform: perspective(120px) rotateX(-180deg) rotateY(-179.9deg);
- transform: perspective(120px) rotateX(-180deg) rotateY(-179.9deg);
- }
- }
- .loader-12 {
- position: relative;
- }
- .loader-12:before, .loader-12:after {
- content: "";
- display: block;
- position: absolute;
- background-color: currentcolor;
- left: 50%;
- right: 0;
- top: 0;
- bottom: 50%;
- box-shadow: -0.5em 0 0 currentcolor;
- -webkit-animation: loader-12 1s linear infinite;
- animation: loader-12 1s linear infinite;
- }
- .loader-12:after {
- top: 50%;
- bottom: 0;
- -webkit-animation-delay: 0.25s;
- animation-delay: 0.25s;
- }
-
- @-webkit-keyframes loader-12 {
- 0%,
- 100% {
- box-shadow: -0.5em 0 0 transparent;
- background-color: currentcolor;
- }
- 50% {
- box-shadow: -0.5em 0 0 currentcolor;
- background-color: transparent;
- }
- }
-
- @keyframes loader-12 {
- 0%,
- 100% {
- box-shadow: -0.5em 0 0 transparent;
- background-color: currentcolor;
- }
- 50% {
- box-shadow: -0.5em 0 0 currentcolor;
- background-color: transparent;
- }
- }
- .loader-13:before,
- .loader-13:after,
- .loader-13 {
- border-radius: 50%;
- -webkit-animation-fill-mode: both;
- animation-fill-mode: both;
- -webkit-animation: loader-13 1.8s infinite ease-in-out;
- animation: loader-13 1.8s infinite ease-in-out;
- }
-
- .loader-13 {
- color: currentcolor;
- position: relative;
- -webkit-transform: translateZ(0);
- transform: translateZ(0);
- -webkit-animation-delay: -0.16s;
- animation-delay: -0.16s;
- top: -1em;
- }
- .loader-13:before {
- right: 100%;
- -webkit-animation-delay: -0.32s;
- animation-delay: -0.32s;
- }
- .loader-13:after {
- left: 100%;
- }
- .loader-13:before, .loader-13:after {
- content: "";
- display: block;
- position: absolute;
- top: 0;
- width: inherit;
- height: inherit;
- }
-
- @-webkit-keyframes loader-13 {
- 0%,
- 80%,
- 100% {
- box-shadow: 0 1em 0 -1em;
- }
- 40% {
- box-shadow: 0 1em 0 -0.2em;
- }
- }
-
- @keyframes loader-13 {
- 0%,
- 80%,
- 100% {
- box-shadow: 0 1em 0 -1em;
- }
- 40% {
- box-shadow: 0 1em 0 -0.2em;
- }
- }
- .loader-14 {
- border-radius: 50%;
- box-shadow: 0 1em 0 -0.2em currentcolor;
- position: relative;
- -webkit-animation: loader-14 0.8s ease-in-out alternate infinite;
- animation: loader-14 0.8s ease-in-out alternate infinite;
- -webkit-animation-delay: 0.32s;
- animation-delay: 0.32s;
- top: -1em;
- }
- .loader-14:after, .loader-14:before {
- content: "";
- position: absolute;
- width: inherit;
- height: inherit;
- border-radius: inherit;
- box-shadow: inherit;
- -webkit-animation: inherit;
- animation: inherit;
- }
- .loader-14:before {
- left: -1em;
- -webkit-animation-delay: 0.48s;
- animation-delay: 0.48s;
- }
- .loader-14:after {
- right: -1em;
- -webkit-animation-delay: 0.16s;
- animation-delay: 0.16s;
- }
-
- @-webkit-keyframes loader-14 {
- 0% {
- box-shadow: 0 2em 0 -0.2em currentcolor;
- }
- 100% {
- box-shadow: 0 1em 0 -0.2em currentcolor;
- }
- }
-
- @keyframes loader-14 {
- 0% {
- box-shadow: 0 2em 0 -0.2em currentcolor;
- }
- 100% {
- box-shadow: 0 1em 0 -0.2em currentcolor;
- }
- }
- .loader-15 {
- background: currentcolor;
- position: relative;
- -webkit-animation: loader-15 1s ease-in-out infinite;
- animation: loader-15 1s ease-in-out infinite;
- -webkit-animation-delay: 0.4s;
- animation-delay: 0.4s;
- width: 0.25em;
- height: 0.5em;
- margin: 0 0.5em;
- }
- .loader-15:after, .loader-15:before {
- content: "";
- position: absolute;
- width: inherit;
- height: inherit;
- background: inherit;
- -webkit-animation: inherit;
- animation: inherit;
- }
- .loader-15:before {
- right: 0.5em;
- -webkit-animation-delay: 0.2s;
- animation-delay: 0.2s;
- }
- .loader-15:after {
- left: 0.5em;
- -webkit-animation-delay: 0.6s;
- animation-delay: 0.6s;
- }
-
- @-webkit-keyframes loader-15 {
- 0%,
- 100% {
- box-shadow: 0 0 0 currentcolor, 0 0 0 currentcolor;
- }
- 50% {
- box-shadow: 0 -0.25em 0 currentcolor, 0 0.25em 0 currentcolor;
- }
- }
-
- @keyframes loader-15 {
- 0%,
- 100% {
- box-shadow: 0 0 0 currentcolor, 0 0 0 currentcolor;
- }
- 50% {
- box-shadow: 0 -0.25em 0 currentcolor, 0 0.25em 0 currentcolor;
- }
- }
- .loader-16 {
- -webkit-transform: rotateZ(45deg);
- transform: rotateZ(45deg);
- -webkit-perspective: 1000px;
- perspective: 1000px;
- border-radius: 50%;
- }
- .loader-16:before, .loader-16:after {
- content: "";
- display: block;
- position: absolute;
- top: 0;
- left: 0;
- width: inherit;
- height: inherit;
- border-radius: 50%;
- -webkit-animation: 1s spin linear infinite;
- animation: 1s spin linear infinite;
- }
- .loader-16:before {
- -webkit-transform: rotateX(70deg);
- transform: rotateX(70deg);
- }
- .loader-16:after {
- -webkit-transform: rotateY(70deg);
- transform: rotateY(70deg);
- -webkit-animation-delay: 0.4s;
- animation-delay: 0.4s;
- }
-
- @-webkit-keyframes rotate {
- 0% {
- -webkit-transform: translate(-50%, -50%) rotateZ(0deg);
- transform: translate(-50%, -50%) rotateZ(0deg);
- }
- 100% {
- -webkit-transform: translate(-50%, -50%) rotateZ(360deg);
- transform: translate(-50%, -50%) rotateZ(360deg);
- }
- }
-
- @keyframes rotate {
- 0% {
- -webkit-transform: translate(-50%, -50%) rotateZ(0deg);
- transform: translate(-50%, -50%) rotateZ(0deg);
- }
- 100% {
- -webkit-transform: translate(-50%, -50%) rotateZ(360deg);
- transform: translate(-50%, -50%) rotateZ(360deg);
- }
- }
- @-webkit-keyframes rotateccw {
- 0% {
- -webkit-transform: translate(-50%, -50%) rotate(0deg);
- transform: translate(-50%, -50%) rotate(0deg);
- }
- 100% {
- -webkit-transform: translate(-50%, -50%) rotate(-360deg);
- transform: translate(-50%, -50%) rotate(-360deg);
- }
- }
- @keyframes rotateccw {
- 0% {
- -webkit-transform: translate(-50%, -50%) rotate(0deg);
- transform: translate(-50%, -50%) rotate(0deg);
- }
- 100% {
- -webkit-transform: translate(-50%, -50%) rotate(-360deg);
- transform: translate(-50%, -50%) rotate(-360deg);
- }
- }
- @-webkit-keyframes spin {
- 0%,
- 100% {
- box-shadow: 0.2em 0px 0 0px currentcolor;
- }
- 12% {
- box-shadow: 0.2em 0.2em 0 0 currentcolor;
- }
- 25% {
- box-shadow: 0 0.2em 0 0px currentcolor;
- }
- 37% {
- box-shadow: -0.2em 0.2em 0 0 currentcolor;
- }
- 50% {
- box-shadow: -0.2em 0 0 0 currentcolor;
- }
- 62% {
- box-shadow: -0.2em -0.2em 0 0 currentcolor;
- }
- 75% {
- box-shadow: 0px -0.2em 0 0 currentcolor;
- }
- 87% {
- box-shadow: 0.2em -0.2em 0 0 currentcolor;
- }
- }
- @keyframes spin {
- 0%,
- 100% {
- box-shadow: 0.2em 0px 0 0px currentcolor;
- }
- 12% {
- box-shadow: 0.2em 0.2em 0 0 currentcolor;
- }
- 25% {
- box-shadow: 0 0.2em 0 0px currentcolor;
- }
- 37% {
- box-shadow: -0.2em 0.2em 0 0 currentcolor;
- }
- 50% {
- box-shadow: -0.2em 0 0 0 currentcolor;
- }
- 62% {
- box-shadow: -0.2em -0.2em 0 0 currentcolor;
- }
- 75% {
- box-shadow: 0px -0.2em 0 0 currentcolor;
- }
- 87% {
- box-shadow: 0.2em -0.2em 0 0 currentcolor;
- }
- }
- .loader-17 {
- position: relative;
- background-color: currentcolor;
- border-radius: 50%;
- }
- .loader-17:after, .loader-17:before {
- content: "";
- position: absolute;
- width: 0.25em;
- height: 0.25em;
- border-radius: 50%;
- opacity: 0.8;
- }
- .loader-17:after {
- left: -0.5em;
- top: -0.25em;
- background-color: currentcolor;
- -webkit-transform-origin: 0.75em 1em;
- transform-origin: 0.75em 1em;
- -webkit-animation: loader-17 1s linear infinite;
- animation: loader-17 1s linear infinite;
- opacity: 0.6;
- }
- .loader-17:before {
- left: -1.25em;
- top: -0.75em;
- background-color: currentcolor;
- -webkit-transform-origin: 1.5em 1em;
- transform-origin: 1.5em 1em;
- -webkit-animation: loader-17 2s linear infinite;
- animation: loader-17 2s linear infinite;
- }
-
- @-webkit-keyframes loader-17 {
- 0% {
- -webkit-transform: rotateZ(0deg) translate3d(0, 0, 0);
- transform: rotateZ(0deg) translate3d(0, 0, 0);
- }
- 100% {
- -webkit-transform: rotateZ(360deg) translate3d(0, 0, 0);
- transform: rotateZ(360deg) translate3d(0, 0, 0);
- }
- }
-
- @keyframes loader-17 {
- 0% {
- -webkit-transform: rotateZ(0deg) translate3d(0, 0, 0);
- transform: rotateZ(0deg) translate3d(0, 0, 0);
- }
- 100% {
- -webkit-transform: rotateZ(360deg) translate3d(0, 0, 0);
- transform: rotateZ(360deg) translate3d(0, 0, 0);
- }
- }
- .loader-18 {
- position: relative;
- }
- .loader-18:before, .loader-18:after {
- content: "";
- display: block;
- position: absolute;
- border-radius: 50%;
- border: 0.1em solid transparent;
- border-bottom-color: currentcolor;
- top: 0;
- left: 0;
- -webkit-animation: 1s loader-18 linear infinite;
- animation: 1s loader-18 linear infinite;
- }
- .loader-18:before {
- width: 1em;
- height: 1em;
- }
- .loader-18:after {
- width: 0.8em;
- height: 0.8em;
- top: 0.1em;
- left: 0.1em;
- animation-direction: reverse;
- }
-
- @-webkit-keyframes loader-18 {
- 0% {
- -webkit-transform: rotate(0deg);
- transform: rotate(0deg);
- }
- 100% {
- -webkit-transform: rotate(360deg);
- transform: rotate(360deg);
- }
- }
-
- @keyframes loader-18 {
- 0% {
- -webkit-transform: rotate(0deg);
- transform: rotate(0deg);
- }
- 100% {
- -webkit-transform: rotate(360deg);
- transform: rotate(360deg);
- }
- }
- .loader-19 {
- border-top: 0.2em solid currentcolor;
- border-right: 0.2em solid transparent;
- -webkit-animation: loader-19 1s linear infinite;
- animation: loader-19 1s linear infinite;
- border-radius: 100%;
- position: relative;
- }
-
- @-webkit-keyframes loader-19 {
- to {
- -webkit-transform: rotate(360deg);
- transform: rotate(360deg);
- }
- }
-
- @keyframes loader-19 {
- to {
- -webkit-transform: rotate(360deg);
- transform: rotate(360deg);
- }
- }
- .loader-20 {
- background-color: transparent;
- box-shadow: inset 0px 0px 0px 0.1em currentcolor;
- border-radius: 50%;
- position: relative;
- }
- .loader-20:after, .loader-20:before {
- position: absolute;
- content: "";
- background-color: currentcolor;
- top: 0.5em;
- left: 0.5em;
- height: 0.1em;
- -webkit-transform-origin: left center;
- transform-origin: left center;
- }
- .loader-20:after {
- width: 0.4em;
- -webkit-animation: loader-20 2s linear infinite;
- animation: loader-20 2s linear infinite;
- }
- .loader-20:before {
- width: 0.3em;
- -webkit-animation: loader-20 8s linear infinite;
- animation: loader-20 8s linear infinite;
- }
-
- @-webkit-keyframes loader-20 {
- 0% {
- -webkit-transform: rotate(0deg);
- transform: rotate(0deg);
- }
- 100% {
- -webkit-transform: rotate(360deg);
- transform: rotate(360deg);
- }
- }
-
- @keyframes loader-20 {
- 0% {
- -webkit-transform: rotate(0deg);
- transform: rotate(0deg);
- }
- 100% {
- -webkit-transform: rotate(360deg);
- transform: rotate(360deg);
- }
- }
- .loader-21 {
- position: relative;
- }
- .loader-21:before, .loader-21:after {
- position: absolute;
- content: "";
- }
- .loader-21:before {
- width: 80%;
- height: 80%;
- left: 10%;
- bottom: 10%;
- border-radius: 100% 100% 100% 0;
- box-shadow: 0px 0px 0px 0.1em currentcolor;
- -webkit-animation: loader-21 1s linear infinite;
- animation: loader-21 1s linear infinite;
- -webkit-transform: rotate(-46deg);
- transform: rotate(-46deg);
- }
- .loader-21:after {
- width: 1em;
- height: 0.3em;
- border-radius: 100%;
- left: 0;
- background-color: rgba(255, 255, 255, 0.2);
- bottom: -0.2em;
- z-index: -1;
- }
-
- @-webkit-keyframes loader-21 {
- 0% {
- top: 0;
- }
- 50% {
- top: -5px;
- }
- 100% {
- top: 0;
- }
- }
-
- @keyframes loader-21 {
- 0% {
- top: 0;
- }
- 50% {
- top: -5px;
- }
- 100% {
- top: 0;
- }
- }
- .loader-22 {
- border: 0.1em currentcolor solid;
- border-radius: 100%;
- position: relative;
- overflow: hidden;
- z-index: 1;
- }
- .loader-22:after, .loader-22:before {
- position: absolute;
- content: "";
- background-color: currentcolor;
- }
- .loader-22:after {
- width: 50%;
- height: 0.1em;
- left: 50%;
- top: 50%;
- -webkit-transform-origin: left center;
- transform-origin: left center;
- -webkit-animation: loader-22 2s linear infinite alternate;
- animation: loader-22 2s linear infinite alternate;
- }
- .loader-22:before {
- width: 100%;
- height: 40%;
- left: 0;
- bottom: 0;
- }
-
- @-webkit-keyframes loader-22 {
- 0% {
- -webkit-transform: rotate(-160deg);
- transform: rotate(-160deg);
- }
- 100% {
- -webkit-transform: rotate(-20deg);
- transform: rotate(-20deg);
- }
- }
-
- @keyframes loader-22 {
- 0% {
- -webkit-transform: rotate(-160deg);
- transform: rotate(-160deg);
- }
- 100% {
- -webkit-transform: rotate(-20deg);
- transform: rotate(-20deg);
- }
- }
- .loader-23 {
- height: 0.5em;
- border: 0.1em currentcolor solid;
- border-radius: 0.1em;
- position: relative;
- -webkit-animation: loader-23 5s linear infinite;
- animation: loader-23 5s linear infinite;
- }
- .loader-23:after {
- width: 0.07em;
- height: 100%;
- background-color: currentcolor;
- border-radius: 0px 0.5em 0.5em 0px;
- position: absolute;
- content: "";
- top: 0;
- left: calc(100% + 0.1em);
- }
-
- @-webkit-keyframes loader-23 {
- 0% {
- box-shadow: inset 0px 0px 0px currentcolor;
- }
- 100% {
- box-shadow: inset 1em 0px 0px currentcolor;
- }
- }
-
- @keyframes loader-23 {
- 0% {
- box-shadow: inset 0px 0px 0px currentcolor;
- }
- 100% {
- box-shadow: inset 1em 0px 0px currentcolor;
- }
- }
- .loader-24 {
- width: 0.8em;
- height: 1em;
- border: 0.1em currentcolor solid;
- border-radius: 0px 0px 0.2em 0.2em;
- position: relative;
- }
- .loader-24:after, .loader-24:before {
- position: absolute;
- content: "";
- }
- .loader-24:after {
- width: 0.2em;
- height: 50%;
- border: 0.1em currentcolor solid;
- border-left: none;
- border-radius: 0px 0.5em 0.5em 0px;
- left: calc(100% + 0.1em);
- top: 0.1em;
- }
- .loader-24:before {
- width: 0.1em;
- height: 0.3em;
- background-color: currentcolor;
- top: -0.3em;
- left: 0.05em;
- box-shadow: 0.2em 0px 0px 0px currentcolor, 0.2em -0.2em 0px 0px currentcolor, 0.4em 0px 0px 0px currentcolor;
- -webkit-animation: loader-24 1s linear infinite alternate;
- animation: loader-24 1s linear infinite alternate;
- }
-
- @-webkit-keyframes loader-24 {
- 0% {
- height: 0px;
- }
- 100% {
- height: 6px;
- }
- }
-
- @keyframes loader-24 {
- 0% {
- height: 0px;
- }
- 100% {
- height: 6px;
- }
- }
- .loader-25 {
- border: 0.1em currentcolor solid;
- position: relative;
- -webkit-animation: loader-25-1 5s linear infinite;
- animation: loader-25-1 5s linear infinite;
- }
- .loader-25:after {
- width: 0.2em;
- height: 0.2em;
- position: absolute;
- content: "";
- background-color: currentcolor;
- bottom: calc(100% + 0.2em);
- left: -0.4em;
- -webkit-animation: loader-25-2 1s ease-in-out infinite;
- animation: loader-25-2 1s ease-in-out infinite;
- }
-
- @-webkit-keyframes loader-25-1 {
- 0% {
- box-shadow: inset 0 0 0 0 currentcolor;
- }
- 100% {
- box-shadow: inset 0 -1em 0 0 currentcolor;
- }
- }
-
- @keyframes loader-25-1 {
- 0% {
- box-shadow: inset 0 0 0 0 currentcolor;
- }
- 100% {
- box-shadow: inset 0 -1em 0 0 currentcolor;
- }
- }
- @-webkit-keyframes loader-25-2 {
- 25% {
- left: calc(100% + 0.2em);
- bottom: calc(100% + 0.2em);
- }
- 50% {
- left: calc(100% + 0.2em);
- bottom: -0.4em;
- }
- 75% {
- left: -0.4em;
- bottom: -0.4em;
- }
- 100% {
- left: -0.4em;
- bottom: calc(100% + 0.2em);
- }
- }
- @keyframes loader-25-2 {
- 25% {
- left: calc(100% + 0.2em);
- bottom: calc(100% + 0.2em);
- }
- 50% {
- left: calc(100% + 0.2em);
- bottom: -0.4em;
- }
- 75% {
- left: -0.4em;
- bottom: -0.4em;
- }
- 100% {
- left: -0.4em;
- bottom: calc(100% + 0.2em);
- }
- }
- .loader-26 {
- width: 0.5em;
- height: 0.5em;
- background-color: currentcolor;
- box-shadow: 1em 0px 0px currentcolor;
- border-radius: 50%;
- -webkit-animation: loader-26 1s ease-in-out infinite alternate;
- animation: loader-26 1s ease-in-out infinite alternate;
- }
-
- @-webkit-keyframes loader-26 {
- 0% {
- opacity: 0.1;
- -webkit-transform: rotate(0deg) scale(0.5);
- transform: rotate(0deg) scale(0.5);
- }
- 100% {
- opacity: 1;
- -webkit-transform: rotate(360deg) scale(1.2);
- transform: rotate(360deg) scale(1.2);
- }
- }
-
- @keyframes loader-26 {
- 0% {
- opacity: 0.1;
- -webkit-transform: rotate(0deg) scale(0.5);
- transform: rotate(0deg) scale(0.5);
- }
- 100% {
- opacity: 1;
- -webkit-transform: rotate(360deg) scale(1.2);
- transform: rotate(360deg) scale(1.2);
- }
- }
- .loader-27 {
- box-shadow: inset 0 0 0 0.1em currentcolor;
- border-radius: 50%;
- position: relative;
- margin-left: 1.2em;
- }
- .loader-27:before {
- content: "";
- display: block;
- width: inherit;
- height: inherit;
- border-radius: 50%;
- position: absolute;
- right: 1.2em;
- top: 0;
- box-shadow: inset 0 0 0 0.1em currentcolor;
- }
- .loader-27:after {
- border: 0.2em solid currentcolor;
- box-shadow: -1.2em 0 0 0 currentcolor;
- width: 0;
- height: 0;
- border-radius: 50%;
- left: 50%;
- top: 25%;
- position: absolute;
- content: "";
- -webkit-animation: loader-27 2s linear infinite alternate;
- animation: loader-27 2s linear infinite alternate;
- }
-
- @-webkit-keyframes loader-27 {
- 0% {
- left: 0;
- }
- 100% {
- left: 0.5em;
- }
- }
-
- @keyframes loader-27 {
- 0% {
- left: 0;
- }
- 100% {
- left: 0.5em;
- }
- }
- .loader-28 {
- position: relative;
- -webkit-animation: 2s loader-28-1 infinite;
- animation: 2s loader-28-1 infinite;
- }
- .loader-28:before {
- content: "";
- display: block;
- width: inherit;
- height: inherit;
- border-radius: 80% 20%;
- border: 0.1em solid currentcolor;
- -webkit-transform: rotate(45deg);
- transform: rotate(45deg);
- border-width: 0.1em 0.05em 0.05em 0.1em;
- }
- .loader-28:after {
- content: "";
- display: block;
- width: 0.2em;
- height: 0.2em;
- position: absolute;
- top: 0.4em;
- left: 50%;
- border-radius: 50%;
- box-shadow: -0.07em 0.07em 0 0.1em currentcolor;
- -webkit-animation: 2s loader-28-2 linear infinite;
- animation: 2s loader-28-2 linear infinite;
- }
-
- @-webkit-keyframes loader-28-1 {
- 0%,
- 100% {
- -webkit-transform: scaleY(1);
- transform: scaleY(1);
- }
- 10% {
- -webkit-transform: scaleY(0);
- transform: scaleY(0);
- }
- 20% {
- -webkit-transform: scaleY(1);
- transform: scaleY(1);
- }
- }
-
- @keyframes loader-28-1 {
- 0%,
- 100% {
- -webkit-transform: scaleY(1);
- transform: scaleY(1);
- }
- 10% {
- -webkit-transform: scaleY(0);
- transform: scaleY(0);
- }
- 20% {
- -webkit-transform: scaleY(1);
- transform: scaleY(1);
- }
- }
- @-webkit-keyframes loader-28-2 {
- 0%,
- 100% {
- -webkit-transform: translateX(0);
- transform: translateX(0);
- }
- 30% {
- -webkit-transform: translateX(-100%);
- transform: translateX(-100%);
- }
- 50% {
- -webkit-transform: transalteX(200%);
- transform: transalteX(200%);
- }
- }
- @keyframes loader-28-2 {
- 0%,
- 100% {
- -webkit-transform: translateX(0);
- transform: translateX(0);
- }
- 30% {
- -webkit-transform: translateX(-100%);
- transform: translateX(-100%);
- }
- 50% {
- -webkit-transform: transalteX(200%);
- transform: transalteX(200%);
- }
- }
- .loader-29 {
- border-radius: 50%;
- box-shadow: inset 0 0 0 0.1em currentcolor, -0.5em -0.5em 0 -0.4em currentcolor, 0 -0.7em 0 -0.4em currentcolor, 0.5em -0.5em 0 -0.4em currentcolor, -0.5em 0.5em 0 -0.4em currentcolor, 0 0.7em 0 -0.4em currentcolor, 0.5em 0.5em 0 -0.4em currentcolor, -0.7em 0 0 -0.4em currentcolor, 0.7em 0 0 -0.4em currentcolor;
- -webkit-animation: 5s loader-29 linear infinite;
- animation: 5s loader-29 linear infinite;
- }
-
- @-webkit-keyframes loader-29 {
- 0% {
- -webkit-transform: rotate(0deg);
- transform: rotate(0deg);
- }
- 100% {
- -webkit-transform: rotate(360deg);
- transform: rotate(360deg);
- }
- }
-
- @keyframes loader-29 {
- 0% {
- -webkit-transform: rotate(0deg);
- transform: rotate(0deg);
- }
- 100% {
- -webkit-transform: rotate(360deg);
- transform: rotate(360deg);
- }
- }
- .loader-30 {
- border: 0.2em solid transparent;
- border-top-color: currentcolor;
- border-bottom-color: currentcolor;
- border-radius: 50%;
- position: relative;
- -webkit-animation: 1s loader-30 linear infinite;
- animation: 1s loader-30 linear infinite;
- }
- .loader-30:before, .loader-30:after {
- content: "";
- display: block;
- width: 0;
- height: 0;
- position: absolute;
- border: 0.2em solid transparent;
- border-bottom-color: currentcolor;
- }
- .loader-30:before {
- -webkit-transform: rotate(135deg);
- transform: rotate(135deg);
- right: -0.3em;
- top: -0.05em;
- }
- .loader-30:after {
- -webkit-transform: rotate(-45deg);
- transform: rotate(-45deg);
- left: -0.3em;
- bottom: -0.05em;
- }
-
- @-webkit-keyframes loader-30 {
- 0% {
- -webkit-transform: rotate(0deg);
- transform: rotate(0deg);
- }
- 100% {
- -webkit-transform: rotate(360deg);
- transform: rotate(360deg);
- }
- }
-
- @keyframes loader-30 {
- 0% {
- -webkit-transform: rotate(0deg);
- transform: rotate(0deg);
- }
- 100% {
- -webkit-transform: rotate(360deg);
- transform: rotate(360deg);
- }
- }
- .loader-31 {
- box-shadow: 0 0 2em currentcolor;
- background-color: currentcolor;
- position: relative;
- border-radius: 50%;
- -webkit-transform: rotateX(-60deg) perspective(1000px);
- transform: rotateX(-60deg) perspective(1000px);
- }
- .loader-31:before, .loader-31:after {
- content: "";
- display: block;
- position: absolute;
- top: 0;
- left: 0;
- width: inherit;
- height: inherit;
- border-radius: inherit;
- -webkit-animation: 1s loader-31 ease-out infinite;
- animation: 1s loader-31 ease-out infinite;
- }
- .loader-31:after {
- -webkit-animation-delay: 0.4s;
- animation-delay: 0.4s;
- }
-
- @-webkit-keyframes loader-31 {
- 0% {
- opacity: 1;
- -webkit-transform: rotate(0deg);
- transform: rotate(0deg);
- box-shadow: 0 0 0 -0.5em currentcolor, 0 0 0 -0.5em currentcolor, 0 0 0 -0.5em currentcolor, 0 0 0 -0.5em currentcolor, 0 0 0 -0.5em currentcolor, 0 0 0 -0.5em currentcolor, 0 0 0 -0.5em currentcolor, 0 0 0 -0.5em currentcolor;
- }
- 100% {
- opacity: 0;
- -webkit-transform: rotate(180deg);
- transform: rotate(180deg);
- box-shadow: -1em -1em 0 -0.35em currentcolor, 0 -1.5em 0 -0.35em currentcolor, 1em -1em 0 -0.35em currentcolor, -1.5em 0 0 -0.35em currentcolor, 1.5em -0 0 -0.35em currentcolor, -1em 1em 0 -0.35em currentcolor, 0 1.5em 0 -0.35em currentcolor, 1em 1em 0 -0.35em currentcolor;
- }
- }
-
- @keyframes loader-31 {
- 0% {
- opacity: 1;
- -webkit-transform: rotate(0deg);
- transform: rotate(0deg);
- box-shadow: 0 0 0 -0.5em currentcolor, 0 0 0 -0.5em currentcolor, 0 0 0 -0.5em currentcolor, 0 0 0 -0.5em currentcolor, 0 0 0 -0.5em currentcolor, 0 0 0 -0.5em currentcolor, 0 0 0 -0.5em currentcolor, 0 0 0 -0.5em currentcolor;
- }
- 100% {
- opacity: 0;
- -webkit-transform: rotate(180deg);
- transform: rotate(180deg);
- box-shadow: -1em -1em 0 -0.35em currentcolor, 0 -1.5em 0 -0.35em currentcolor, 1em -1em 0 -0.35em currentcolor, -1.5em 0 0 -0.35em currentcolor, 1.5em -0 0 -0.35em currentcolor, -1em 1em 0 -0.35em currentcolor, 0 1.5em 0 -0.35em currentcolor, 1em 1em 0 -0.35em currentcolor;
- }
- }
- .loader-32 {
- position: relative;
- border-radius: 50%;
- box-shadow: 0 0 1em 0 currentcolor, inset 0 0 1em 0 currentcolor;
- -webkit-animation: 1s loader-32 linear infinite;
- animation: 1s loader-32 linear infinite;
- }
- .loader-32:before, .loader-32:after {
- content: "";
- display: block;
- width: inherit;
- height: inherit;
- position: absolute;
- border-radius: 50%;
- }
- .loader-32:before {
- border-top: 0.2em solid currentcolor;
- border-right: 0.2em solid transparent;
- top: 0.28em;
- right: calc(50% - 0.22em);
- }
- .loader-32:after {
- border-bottom: 0.2em solid currentcolor;
- border-left: 0.2em solid transparent;
- bottom: 0.28em;
- left: calc(50% - 0.22em);
- }
-
- @-webkit-keyframes loader-32 {
- 0% {
- -webkit-transform: rotateX(-60deg) rotateZ(0deg);
- transform: rotateX(-60deg) rotateZ(0deg);
- }
- 100% {
- -webkit-transform: rotateX(-60deg) rotateZ(360deg);
- transform: rotateX(-60deg) rotateZ(360deg);
- }
- }
-
- @keyframes loader-32 {
- 0% {
- -webkit-transform: rotateX(-60deg) rotateZ(0deg);
- transform: rotateX(-60deg) rotateZ(0deg);
- }
- 100% {
- -webkit-transform: rotateX(-60deg) rotateZ(360deg);
- transform: rotateX(-60deg) rotateZ(360deg);
- }
- }
- .loader-33 {
- border-radius: 50%;
- position: relative;
- }
- .loader-33:after, .loader-33:before {
- position: absolute;
- content: "";
- }
- .loader-33:after {
- height: 0.1em;
- width: 1em;
- background-color: currentcolor;
- border-radius: 0.1em;
- bottom: 0;
- left: 0;
- -webkit-transform-origin: bottom center;
- transform-origin: bottom center;
- -webkit-animation: loader-33-1 0.8s ease-in-out infinite alternate;
- animation: loader-33-1 0.8s ease-in-out infinite alternate;
- }
- .loader-33:before {
- height: 0.2em;
- width: 0.2em;
- background-color: currentcolor;
- border-radius: 50%;
- top: 0;
- left: calc(50% - 0.1em);
- -webkit-animation: loader-33-2 0.4s ease-in-out infinite alternate;
- animation: loader-33-2 0.4s ease-in-out infinite alternate;
- }
-
- @-webkit-keyframes loader-33-2 {
- 0% {
- height: 0.24em;
- -webkit-transform: translateY(0px);
- transform: translateY(0px);
- }
- 75% {
- height: 0.2em;
- width: 0.2em;
- }
- 100% {
- height: 0.1em;
- width: 0.24em;
- -webkit-transform: translateY(0.8em);
- transform: translateY(0.8em);
- }
- }
-
- @keyframes loader-33-2 {
- 0% {
- height: 0.24em;
- -webkit-transform: translateY(0px);
- transform: translateY(0px);
- }
- 75% {
- height: 0.2em;
- width: 0.2em;
- }
- 100% {
- height: 0.1em;
- width: 0.24em;
- -webkit-transform: translateY(0.8em);
- transform: translateY(0.8em);
- }
- }
- @-webkit-keyframes loader-33-1 {
- 0% {
- -webkit-transform: rotate(-45deg);
- transform: rotate(-45deg);
- }
- 100% {
- -webkit-transform: rotate(45deg);
- transform: rotate(45deg);
- }
- }
- @keyframes loader-33-1 {
- 0% {
- -webkit-transform: rotate(-45deg);
- transform: rotate(-45deg);
- }
- 100% {
- -webkit-transform: rotate(45deg);
- transform: rotate(45deg);
- }
- }
- .loader-34 {
- position: relative;
- width: 1em;
- height: 0.5em;
- }
- .loader-34:after, .loader-34:before {
- position: absolute;
- content: "";
- height: 0.4em;
- width: 0.4em;
- top: 0;
- background-color: currentcolor;
- border-radius: 50%;
- }
- .loader-34:after {
- right: 0;
- -webkit-animation: loader-34-2 0.5s ease-in-out infinite;
- animation: loader-34-2 0.5s ease-in-out infinite;
- -webkit-animation-direction: alternate;
- animation-direction: alternate;
- }
- .loader-34:before {
- left: 0;
- -webkit-animation: loader-34-1 0.5s ease-in-out infinite;
- animation: loader-34-1 0.5s ease-in-out infinite;
- -webkit-animation-direction: alternate;
- animation-direction: alternate;
- }
-
- @-webkit-keyframes loader-34-1 {
- 0% {
- -webkit-transform: translatex(0px);
- transform: translatex(0px);
- }
- 65% {
- height: 0.4em;
- width: 0.4em;
- }
- 100% {
- height: 0.5em;
- width: 0.3em;
- -webkit-transform: translatex(0.2em);
- transform: translatex(0.2em);
- }
- }
-
- @keyframes loader-34-1 {
- 0% {
- -webkit-transform: translatex(0px);
- transform: translatex(0px);
- }
- 65% {
- height: 0.4em;
- width: 0.4em;
- }
- 100% {
- height: 0.5em;
- width: 0.3em;
- -webkit-transform: translatex(0.2em);
- transform: translatex(0.2em);
- }
- }
- @-webkit-keyframes loader-34-2 {
- 0% {
- -webkit-transform: translatex(0px);
- transform: translatex(0px);
- }
- 65% {
- height: 0.4em;
- width: 0.4em;
- }
- 100% {
- height: 0.5em;
- width: 0.3em;
- -webkit-transform: translatex(-0.2em);
- transform: translatex(-0.2em);
- }
- }
- @keyframes loader-34-2 {
- 0% {
- -webkit-transform: translatex(0px);
- transform: translatex(0px);
- }
- 65% {
- height: 0.4em;
- width: 0.4em;
- }
- 100% {
- height: 0.5em;
- width: 0.3em;
- -webkit-transform: translatex(-0.2em);
- transform: translatex(-0.2em);
- }
- }
- .loader-35 {
- margin: 0 0.5em;
- position: relative;
- }
- .loader-35:before {
- border-radius: 50%;
- background-color: currentcolor;
- -webkit-animation: loader-35 3s cubic-bezier(0.77, 0, 0.175, 1) infinite;
- animation: loader-35 3s cubic-bezier(0.77, 0, 0.175, 1) infinite;
- content: "";
- width: inherit;
- height: inherit;
- top: 0;
- left: 0;
- position: absolute;
- }
-
- @-webkit-keyframes loader-35 {
- 0% {
- -webkit-transform: translateX(0) scale(1);
- transform: translateX(0) scale(1);
- }
- 25% {
- -webkit-transform: translateX(-100%) scale(0.3);
- transform: translateX(-100%) scale(0.3);
- }
- 50% {
- -webkit-transform: translateX(0) scale(1);
- transform: translateX(0) scale(1);
- }
- 75% {
- -webkit-transform: translateX(100%) scale(0.3);
- transform: translateX(100%) scale(0.3);
- }
- 100% {
- -webkit-transform: translateX(0) scale(1);
- transform: translateX(0) scale(1);
- }
- }
-
- @keyframes loader-35 {
- 0% {
- -webkit-transform: translateX(0) scale(1);
- transform: translateX(0) scale(1);
- }
- 25% {
- -webkit-transform: translateX(-100%) scale(0.3);
- transform: translateX(-100%) scale(0.3);
- }
- 50% {
- -webkit-transform: translateX(0) scale(1);
- transform: translateX(0) scale(1);
- }
- 75% {
- -webkit-transform: translateX(100%) scale(0.3);
- transform: translateX(100%) scale(0.3);
- }
- 100% {
- -webkit-transform: translateX(0) scale(1);
- transform: translateX(0) scale(1);
- }
- }
- .loader-36 {
- position: relative;
- }
- .loader-36:before, .loader-36:after {
- content: "";
- position: absolute;
- top: 0;
- left: 0;
- }
- .loader-36:before {
- width: 1em;
- height: 1em;
- border: 0.1em solid currentcolor;
- border-radius: 50%;
- -webkit-animation: loader-36-1 1.15s infinite -0.3s;
- animation: loader-36-1 1.15s infinite -0.3s;
- }
- .loader-36:after {
- right: 0;
- bottom: 0;
- margin: auto;
- width: 0;
- height: 0;
- border: 0.1em solid currentcolor;
- border-radius: 50%;
- -webkit-transform: translate(-0.2em);
- transform: translate(-0.2em);
- -webkit-animation: loader-36-2 4.6s infinite steps(1);
- animation: loader-36-2 4.6s infinite steps(1);
- }
-
- @-webkit-keyframes loader-36-1 {
- to {
- -webkit-transform: rotateX(180deg);
- transform: rotateX(180deg);
- }
- }
-
- @keyframes loader-36-1 {
- to {
- -webkit-transform: rotateX(180deg);
- transform: rotateX(180deg);
- }
- }
- @-webkit-keyframes loader-36-2 {
- 0% {
- opacity: 0;
- }
- 25% {
- opacity: 1;
- }
- 50% {
- box-shadow: 0.2em 0 0 currentcolor;
- }
- 75% {
- box-shadow: 0.2em 0 0 currentcolor, 0.4em 0 0 currentcolor;
- }
- }
- @keyframes loader-36-2 {
- 0% {
- opacity: 0;
- }
- 25% {
- opacity: 1;
- }
- 50% {
- box-shadow: 0.2em 0 0 currentcolor;
- }
- 75% {
- box-shadow: 0.2em 0 0 currentcolor, 0.4em 0 0 currentcolor;
- }
- }
- .loader-37 {
- border-right: 0.1em solid currentcolor;
- border-radius: 100%;
- -webkit-animation: loader-37 800ms linear infinite;
- animation: loader-37 800ms linear infinite;
- }
- .loader-37:before, .loader-37:after {
- content: "";
- width: 0.8em;
- height: 0.8em;
- display: block;
- position: absolute;
- top: calc(50% - 0.4em);
- left: calc(50% - 0.4em);
- border-left: 0.08em solid currentcolor;
- border-radius: 100%;
- animation: loader-37 400ms linear infinite reverse;
- }
- .loader-37:after {
- width: 0.6em;
- height: 0.6em;
- top: calc(50% - 0.3em);
- left: calc(50% - 0.3em);
- border: 0;
- border-right: 0.05em solid currentcolor;
- -webkit-animation: none;
- animation: none;
- }
-
- @-webkit-keyframes loader-37 {
- from {
- -webkit-transform: rotate(360deg);
- transform: rotate(360deg);
- }
- to {
- -webkit-transform: rotate(0deg);
- transform: rotate(0deg);
- }
- }
-
- @keyframes loader-37 {
- from {
- -webkit-transform: rotate(360deg);
- transform: rotate(360deg);
- }
- to {
- -webkit-transform: rotate(0deg);
- transform: rotate(0deg);
- }
- }
- .loader-38 {
- height: 0.1em;
- width: 0.1em;
- box-shadow: -0.2em -0.2em 0 0.1em currentcolor, -0.2em -0.2em 0 0.1em currentcolor, -0.2em -0.2em 0 0.1em currentcolor, -0.2em -0.2em 0 0.1em currentcolor;
- -webkit-animation: loader-38 6s infinite;
- animation: loader-38 6s infinite;
- }
-
- @-webkit-keyframes loader-38 {
- 0% {
- box-shadow: -0.2em -0.2em 0 0.1em currentcolor, -0.2em -0.2em 0 0.1em currentcolor, -0.2em -0.2em 0 0.1em currentcolor, -0.2em -0.2em 0 0.1em currentcolor;
- }
- 8.33% {
- box-shadow: -0.2em -0.2em 0 0.1em currentcolor, 0.2em -0.2em 0 0.1em currentcolor, 0.2em -0.2em 0 0.1em currentcolor, 0.2em -0.2em 0 0.1em currentcolor;
- }
- 16.66% {
- box-shadow: -0.2em -0.2em 0 0.1em currentcolor, 0.2em -0.2em 0 0.1em currentcolor, 0.2em 0.2em 0 0.1em currentcolor, 0.2em 0.2em 0 0.1em currentcolor;
- }
- 24.99% {
- box-shadow: -0.2em -0.2em 0 0.1em currentcolor, 0.2em -0.2em 0 0.1em currentcolor, 0.2em 0.2em 0 0.1em currentcolor, -0.2em 0.2em 0 0.1em currentcolor;
- }
- 33.32% {
- box-shadow: -0.2em -0.2em 0 0.1em currentcolor, 0.2em -0.2em 0 0.1em currentcolor, 0.2em 0.2em 0 0.1em currentcolor, -0.2em -0.2em 0 0.1em currentcolor;
- }
- 41.65% {
- box-shadow: 0.2em -0.2em 0 0.1em currentcolor, 0.2em -0.2em 0 0.1em currentcolor, 0.2em 0.2em 0 0.1em currentcolor, 0.2em -0.2em 0 0.1em currentcolor;
- }
- 49.98% {
- box-shadow: 0.2em 0.2em 0 0.1em currentcolor, 0.2em 0.2em 0 0.1em currentcolor, 0.2em 0.2em 0 0.1em currentcolor, 0.2em 0.2em 0 0.1em currentcolor;
- }
- 58.31% {
- box-shadow: -0.2em 0.2em 0 0.1em currentcolor, -0.2em 0.2em 0 0.1em currentcolor, 0.2em 0.2em 0 0.1em currentcolor, -0.2em 0.2em 0 0.1em currentcolor;
- }
- 66.64% {
- box-shadow: -0.2em -0.2em 0 0.1em currentcolor, -0.2em -0.2em 0 0.1em currentcolor, 0.2em 0.2em 0 0.1em currentcolor, -0.2em 0.2em 0 0.1em currentcolor;
- }
- 74.97% {
- box-shadow: -0.2em -0.2em 0 0.1em currentcolor, 0.2em -0.2em 0 0.1em currentcolor, 0.2em 0.2em 0 0.1em currentcolor, -0.2em 0.2em 0 0.1em currentcolor;
- }
- 83.3% {
- box-shadow: -0.2em -0.2em 0 0.1em currentcolor, 0.2em 0.2em 0 0.1em currentcolor, 0.2em 0.2em 0 0.1em currentcolor, -0.2em 0.2em 0 0.1em currentcolor;
- }
- 91.63% {
- box-shadow: -0.2em -0.2em 0 0.1em currentcolor, -0.2em 0.2em 0 0.1em currentcolor, -0.2em 0.2em 0 0.1em currentcolor, -0.2em 0.2em 0 0.1em currentcolor;
- }
- 100% {
- box-shadow: -0.2em -0.2em 0 0.1em currentcolor, -0.2em -0.2em 0 0.1em currentcolor, -0.2em -0.2em 0 0.1em currentcolor, -0.2em -0.2em 0 0.1em currentcolor;
- }
- }
-
- @keyframes loader-38 {
- 0% {
- box-shadow: -0.2em -0.2em 0 0.1em currentcolor, -0.2em -0.2em 0 0.1em currentcolor, -0.2em -0.2em 0 0.1em currentcolor, -0.2em -0.2em 0 0.1em currentcolor;
- }
- 8.33% {
- box-shadow: -0.2em -0.2em 0 0.1em currentcolor, 0.2em -0.2em 0 0.1em currentcolor, 0.2em -0.2em 0 0.1em currentcolor, 0.2em -0.2em 0 0.1em currentcolor;
- }
- 16.66% {
- box-shadow: -0.2em -0.2em 0 0.1em currentcolor, 0.2em -0.2em 0 0.1em currentcolor, 0.2em 0.2em 0 0.1em currentcolor, 0.2em 0.2em 0 0.1em currentcolor;
- }
- 24.99% {
- box-shadow: -0.2em -0.2em 0 0.1em currentcolor, 0.2em -0.2em 0 0.1em currentcolor, 0.2em 0.2em 0 0.1em currentcolor, -0.2em 0.2em 0 0.1em currentcolor;
- }
- 33.32% {
- box-shadow: -0.2em -0.2em 0 0.1em currentcolor, 0.2em -0.2em 0 0.1em currentcolor, 0.2em 0.2em 0 0.1em currentcolor, -0.2em -0.2em 0 0.1em currentcolor;
- }
- 41.65% {
- box-shadow: 0.2em -0.2em 0 0.1em currentcolor, 0.2em -0.2em 0 0.1em currentcolor, 0.2em 0.2em 0 0.1em currentcolor, 0.2em -0.2em 0 0.1em currentcolor;
- }
- 49.98% {
- box-shadow: 0.2em 0.2em 0 0.1em currentcolor, 0.2em 0.2em 0 0.1em currentcolor, 0.2em 0.2em 0 0.1em currentcolor, 0.2em 0.2em 0 0.1em currentcolor;
- }
- 58.31% {
- box-shadow: -0.2em 0.2em 0 0.1em currentcolor, -0.2em 0.2em 0 0.1em currentcolor, 0.2em 0.2em 0 0.1em currentcolor, -0.2em 0.2em 0 0.1em currentcolor;
- }
- 66.64% {
- box-shadow: -0.2em -0.2em 0 0.1em currentcolor, -0.2em -0.2em 0 0.1em currentcolor, 0.2em 0.2em 0 0.1em currentcolor, -0.2em 0.2em 0 0.1em currentcolor;
- }
- 74.97% {
- box-shadow: -0.2em -0.2em 0 0.1em currentcolor, 0.2em -0.2em 0 0.1em currentcolor, 0.2em 0.2em 0 0.1em currentcolor, -0.2em 0.2em 0 0.1em currentcolor;
- }
- 83.3% {
- box-shadow: -0.2em -0.2em 0 0.1em currentcolor, 0.2em 0.2em 0 0.1em currentcolor, 0.2em 0.2em 0 0.1em currentcolor, -0.2em 0.2em 0 0.1em currentcolor;
- }
- 91.63% {
- box-shadow: -0.2em -0.2em 0 0.1em currentcolor, -0.2em 0.2em 0 0.1em currentcolor, -0.2em 0.2em 0 0.1em currentcolor, -0.2em 0.2em 0 0.1em currentcolor;
- }
- 100% {
- box-shadow: -0.2em -0.2em 0 0.1em currentcolor, -0.2em -0.2em 0 0.1em currentcolor, -0.2em -0.2em 0 0.1em currentcolor, -0.2em -0.2em 0 0.1em currentcolor;
- }
- }
- .loader-39 {
- position: relative;
- width: 0.15em;
- height: 0.15em;
- background-color: currentcolor;
- border-radius: 100%;
- -webkit-animation: loader-39-1 30s infinite linear;
- animation: loader-39-1 30s infinite linear;
- }
- .loader-39:before, .loader-39:after {
- content: "";
- border-radius: 100%;
- position: absolute;
- top: 50%;
- left: 50%;
- -webkit-transform: translate(-50%, -50%);
- transform: translate(-50%, -50%);
- }
- .loader-39:before {
- width: 0.3em;
- height: 1em;
- -webkit-animation: loader-39-2 0.8s linear infinite;
- animation: loader-39-2 0.8s linear infinite;
- }
- .loader-39:after {
- width: 1em;
- height: 0.3em;
- -webkit-animation: loader-39-2 1.2s linear infinite;
- animation: loader-39-2 1.2s linear infinite;
- }
-
- @-webkit-keyframes loader-39-1 {
- 0% {
- -webkit-transform: rotate(0deg);
- transform: rotate(0deg);
- }
- 100% {
- -webkit-transform: rotate(360deg);
- transform: rotate(360deg);
- }
- }
-
- @keyframes loader-39-1 {
- 0% {
- -webkit-transform: rotate(0deg);
- transform: rotate(0deg);
- }
- 100% {
- -webkit-transform: rotate(360deg);
- transform: rotate(360deg);
- }
- }
- @-webkit-keyframes loader-39-2 {
- 0% {
- box-shadow: 0.04em -0.04em 0 0.02em currentcolor;
- }
- 25% {
- box-shadow: 0.04em 0.04em 0 0.02em currentcolor;
- }
- 50% {
- box-shadow: -0.04em 0.04em 0 0.02em currentcolor;
- }
- 75% {
- box-shadow: -0.04em -0.04em 0 0.02em currentcolor;
- }
- 100% {
- box-shadow: 0.04em -0.04em 0 0.02em currentcolor;
- }
- }
- @keyframes loader-39-2 {
- 0% {
- box-shadow: 0.04em -0.04em 0 0.02em currentcolor;
- }
- 25% {
- box-shadow: 0.04em 0.04em 0 0.02em currentcolor;
- }
- 50% {
- box-shadow: -0.04em 0.04em 0 0.02em currentcolor;
- }
- 75% {
- box-shadow: -0.04em -0.04em 0 0.02em currentcolor;
- }
- 100% {
- box-shadow: 0.04em -0.04em 0 0.02em currentcolor;
- }
- }
- .loader-40 {
- border: 0.05em currentcolor solid;
- border-radius: 0.2em;
- overflow: hidden;
- position: relative;
- }
- .loader-40:after, .loader-40:before {
- content: "";
- border-radius: 50%;
- position: absolute;
- width: inherit;
- height: inherit;
- -webkit-animation: loader-40 2s infinite linear;
- animation: loader-40 2s infinite linear;
- }
- .loader-40:before {
- border-top: 0.2em currentcolor solid;
- top: -0.15em;
- left: calc(-50% - 0.15em);
- -webkit-transform-origin: right center;
- transform-origin: right center;
- }
- .loader-40:after {
- border-bottom: 0.2em currentcolor solid;
- top: 0.15em;
- right: calc(-50% - 0.15em);
- -webkit-transform-origin: left center;
- transform-origin: left center;
- }
-
- @-webkit-keyframes loader-40 {
- from {
- -webkit-transform: rotate(0deg);
- transform: rotate(0deg);
- }
- to {
- -webkit-transform: rotate(359deg);
- transform: rotate(359deg);
- }
- }
-
- @keyframes loader-40 {
- from {
- -webkit-transform: rotate(0deg);
- transform: rotate(0deg);
- }
- to {
- -webkit-transform: rotate(359deg);
- transform: rotate(359deg);
- }
- }
- .loader-41 {
- border: 0.05em currentcolor solid;
- border-radius: 0.2em;
- position: relative;
- background: linear-gradient(45deg, transparent 48%, currentcolor 50%, currentcolor 50%, transparent 52%, transparent), linear-gradient(-45deg, transparent 48%, currentcolor 50%, currentcolor 50%, transparent 52%, transparent);
- background-size: 0.5em 0.5em;
- background-position: 0% 0%;
- -webkit-animation: loader-41 1s infinite linear;
- animation: loader-41 1s infinite linear;
- }
-
- @-webkit-keyframes loader-41 {
- from {
- background-position: 0 0;
- }
- to {
- background-position: -1em 0;
- }
- }
-
- @keyframes loader-41 {
- from {
- background-position: 0 0;
- }
- to {
- background-position: -1em 0;
- }
+fieldset {
+ border: 0 !important;
+ margin: 0 !important;
+ padding: 0 !important;
+}
+
+[class*="loader-"] {
+ display: inline-block;
+ width: 1em;
+ height: 1em;
+ color: inherit;
+ vertical-align: middle;
+ pointer-events: none;
+}
+
+.loader-37 {
+ border-right: 0.1em solid currentcolor;
+ border-radius: 100%;
+ -webkit-animation: loader-37 800ms linear infinite;
+ animation: loader-37 800ms linear infinite;
+}
+.loader-37:before,
+.loader-37:after {
+ content: "";
+ width: 0.8em;
+ height: 0.8em;
+ display: block;
+ position: absolute;
+ top: calc(50% - 0.4em);
+ left: calc(50% - 0.4em);
+ border-left: 0.08em solid currentcolor;
+ border-radius: 100%;
+ animation: loader-37 400ms linear infinite reverse;
+}
+.loader-37:after {
+ width: 0.6em;
+ height: 0.6em;
+ top: calc(50% - 0.3em);
+ left: calc(50% - 0.3em);
+ border: 0;
+ border-right: 0.05em solid currentcolor;
+ -webkit-animation: none;
+ animation: none;
+}
+
+@-webkit-keyframes loader-37 {
+ from {
+ -webkit-transform: rotate(360deg);
+ transform: rotate(360deg);
}
- .loader-42 {
- width: 2em;
- height: 0.66em;
- border: 0.05em currentcolor solid;
- border-radius: 0.1em;
- background: linear-gradient(-60deg, transparent 0%, transparent 50%, currentcolor 50%, currentcolor 75%, transparent 75%, transparent);
- background-size: 1em 2em;
- background-position: 0 0;
- -webkit-animation: loader-42 0.8s infinite linear;
- animation: loader-42 0.8s infinite linear;
+ to {
+ -webkit-transform: rotate(0deg);
+ transform: rotate(0deg);
}
-
- @-webkit-keyframes loader-42 {
- from {
- background-position: 0 0;
- }
- to {
- background-position: -2em 0;
- }
+}
+
+@keyframes loader-37 {
+ from {
+ -webkit-transform: rotate(360deg);
+ transform: rotate(360deg);
}
-
- @keyframes loader-42 {
- from {
- background-position: 0 0;
- }
- to {
- background-position: -2em 0;
- }
+ to {
+ -webkit-transform: rotate(0deg);
+ transform: rotate(0deg);
}
-
-
+}
diff --git a/apps/OpenSign/src/styles/toast.css b/apps/OpenSign/src/styles/toast.css
index 4e3ff0bc9..409833af9 100644
--- a/apps/OpenSign/src/styles/toast.css
+++ b/apps/OpenSign/src/styles/toast.css
@@ -1,209 +1,64 @@
#snackbar {
- visibility: hidden;
- min-width: 250px;
- margin-left: -125px;
- background-color: #333;
- color: #fff;
- text-align: center;
- border-radius: 2px;
- padding: 16px;
- position: fixed;
- z-index: 99999;
- left: 50%;
+ visibility: hidden;
+ min-width: 250px;
+ margin-left: -125px;
+ background-color: #333;
+ color: #fff;
+ text-align: center;
+ border-radius: 2px;
+ padding: 16px;
+ position: fixed;
+ z-index: 99999;
+ left: 50%;
+ top: 30px;
+ font-size: 14px;
+}
+
+#snackbar.show {
+ visibility: visible;
+ -webkit-animation: fadein 0.5s;
+}
+
+@-webkit-keyframes fadein {
+ from {
+ top: 0;
+ opacity: 0;
+ }
+ to {
top: 30px;
- font-size: 14px;
+ opacity: 1;
}
-
- #_editsnackbar {
- visibility: hidden;
- min-width: 250px;
- margin-left: -125px;
- background-color: #333;
- color: #fff;
- text-align: center;
- border-radius: 2px;
- padding: 16px;
- position: fixed;
- z-index: 99999;
- left: 50%;
- top: 30px;
- font-size: 14px;
- }
-
- #_editsnackbar.show {
- visibility: visible;
- -webkit-animation: fadein 0.5s;
- }
-
- #UpdateColumnValue.show {
- visibility: visible;
- -webkit-animation: fadein 0.5s;
+}
+
+@keyframes fadein {
+ from {
+ top: 0;
+ opacity: 0;
}
- #DeleteUser.show {
- visibility: visible;
- -webkit-animation: fadein 0.5s;
- }
- #DeleteUser {
- visibility: hidden;
- min-width: 250px;
- margin-left: -125px;
- background-color: #333;
- color: #fff;
- text-align: center;
- border-radius: 2px;
- padding: 16px;
- position: fixed;
- z-index: 99999;
- left: 50%;
+ to {
top: 30px;
- font-size: 14px;
- }
-
- #deleteObj.show {
- visibility: visible;
- -webkit-animation: fadein 0.5s;
+ opacity: 1;
}
- #deleteObj {
- visibility: hidden;
- min-width: 250px;
- margin-left: -125px;
- background-color: #333;
- color: #fff;
- text-align: center;
- border-radius: 2px;
- padding: 16px;
- position: fixed;
- z-index: 99999;
- left: 50%;
+}
+
+@-webkit-keyframes fadeout {
+ from {
top: 30px;
- font-size: 14px;
+ opacity: 1;
}
-
- #UpdateColumnValue {
- visibility: hidden;
- min-width: 250px;
- margin-left: -125px;
- background-color: #333;
- color: #fff;
- text-align: center;
- border-radius: 2px;
- padding: 16px;
- position: fixed;
- z-index: 99999;
- left: 50%;
- top: 30px;
- font-size: 14px;
- }
-
- #snackbar.show {
- visibility: visible;
- -webkit-animation: fadein 0.5s;
+ to {
+ top: 0;
+ opacity: 0;
}
-
- #snackbar1 {
- visibility: hidden;
- min-width: 250px;
- margin-left: -125px;
- background-color: #333;
- color: #fff;
- text-align: center;
- border-radius: 2px;
- padding: 16px;
- position: fixed;
- z-index: 99999;
- left: 50%;
+}
+
+@keyframes fadeout {
+ from {
top: 30px;
- font-size: 14px;
- }
-
- #snackbar1.show {
- visibility: visible;
- -webkit-animation: fadein 0.5s;
- }
-
- #snackbar10 {
- visibility: hidden;
- min-width: 250px;
- margin-left: -125px;
- background-color: #333;
- color: #fff;
- text-align: center;
- border-radius: 2px;
- padding: 16px;
- position: fixed;
- z-index: 99999;
- left: 50%;
- top: 30px;
- font-size: 14px;
- }
-
- #snackbar10.show {
- visibility: visible;
- -webkit-animation: fadein 0.5s;
- }
-
- #snackbarCol {
- visibility: hidden;
- min-width: 250px;
- margin-left: -125px;
- background-color: #333;
- color: #fff;
- text-align: center;
- border-radius: 2px;
- padding: 16px;
- position: fixed;
- z-index: 99999;
- left: 50%;
- top: 30px;
- font-size: 14px;
- }
-
- #snackbarCol.show {
- visibility: visible;
- -webkit-animation: fadein 0.5s;
- }
-
- @-webkit-keyframes fadein {
- from {
- top: 0;
- opacity: 0;
- }
- to {
- top: 30px;
- opacity: 1;
- }
- }
-
- @keyframes fadein {
- from {
- top: 0;
- opacity: 0;
- }
- to {
- top: 30px;
- opacity: 1;
- }
- }
-
- @-webkit-keyframes fadeout {
- from {
- top: 30px;
- opacity: 1;
- }
- to {
- top: 0;
- opacity: 0;
- }
+ opacity: 1;
}
-
- @keyframes fadeout {
- from {
- top: 30px;
- opacity: 1;
- }
- to {
- top: 0;
- opacity: 0;
- }
+ to {
+ top: 0;
+ opacity: 0;
}
-
\ No newline at end of file
+}
diff --git a/apps/OpenSignServer/Utils.js b/apps/OpenSignServer/Utils.js
new file mode 100644
index 000000000..8fc705ceb
--- /dev/null
+++ b/apps/OpenSignServer/Utils.js
@@ -0,0 +1,40 @@
+export function customAPIurl() {
+ const url = new URL(process.env.SERVER_URL);
+ return url.pathname === '/api/app' ? url.origin + '/api' : url.origin;
+}
+
+export const color = [
+ '#93a3db',
+ '#e6c3db',
+ '#c0e3bc',
+ '#bce3db',
+ '#b8ccdb',
+ '#ceb8db',
+ '#ffccff',
+ '#99ffcc',
+ '#cc99ff',
+ '#ffcc99',
+ '#66ccff',
+ '#ffffcc',
+];
+
+export function replaceMailVaribles(subject, body, variables) {
+ let replacedSubject = subject;
+ let replacedBody = body;
+
+ for (const variable in variables) {
+ const regex = new RegExp(`{{${variable}}}`, 'g');
+ if (subject) {
+ replacedSubject = replacedSubject.replace(regex, variables[variable]);
+ }
+ if (body) {
+ replacedBody = replacedBody.replace(regex, variables[variable]);
+ }
+ }
+
+ const result = {
+ subject: replacedSubject,
+ body: replacedBody,
+ };
+ return result;
+}
diff --git a/apps/OpenSignServer/cloud/customRoute/v1/apiV1.js b/apps/OpenSignServer/cloud/customRoute/v1/apiV1.js
new file mode 100644
index 000000000..343db0d3c
--- /dev/null
+++ b/apps/OpenSignServer/cloud/customRoute/v1/apiV1.js
@@ -0,0 +1,104 @@
+//--npm modules
+import express from 'express';
+import cors from 'cors';
+export const app = express();
+import dotenv from 'dotenv';
+import getUser from './routes/getUser.js';
+import getDocumentList from './routes/getDocumentList.js';
+import getDocument from './routes/getDocument.js';
+import getContact from './routes/getContact.js';
+import deleteContact from './routes/deleteContact.js';
+import getContactList from './routes/getContactList.js';
+import draftDocument from './routes/draftDocument.js';
+import createTemplate from './routes/createTemplate.js';
+import getTemplate from './routes/getTemplate.js';
+import deletedTemplate from './routes/deleteTemplate.js';
+import getTemplatetList from './routes/getTemplateList.js';
+import updateTemplate from './routes/updateTemplate.js';
+import createContact from './routes/createContact.js';
+import multer from 'multer';
+// import fs from 'node:fs';
+import updateDocument from './routes/updateDocument.js';
+import deleteDocument from './routes/deleteDocument.js';
+import createDocumentWithTemplate from './routes/CreateDocumentWithTemplate.js';
+import saveWebhook from './routes/saveWebhook.js';
+import deleteWebhook from './routes/deleteWebhook.js';
+import getWebhook from './routes/getWebhook.js';
+import createDocumentwithCoordinate from './routes/createDocumentwithCoordinate.js';
+import createTemplatewithCoordinate from './routes/createTemplatewithCoordinate.js';
+dotenv.config();
+const storage = multer.memoryStorage();
+const upload = multer({ storage: storage });
+
+app.use(cors());
+app.use(express.json({ limit: '50mb' }));
+app.use(express.urlencoded({ limit: '50mb', extended: true }));
+
+// get user details whose api token used
+app.get('/getuser', getUser);
+
+// get contact on the basis of id
+app.post('/createcontact', createContact);
+
+// get contact on the basis of id
+app.get('/contact/:contact_id', getContact);
+
+// soft delete contact
+app.delete('/contact/:contact_id', deleteContact);
+
+// get list of contacts
+app.get('/contactlist', getContactList);
+
+// create Document
+app.post('/createdocumentwithbinary', upload.array('file', 1), createDocumentwithCoordinate);
+
+// create Document with co-ordinate
+app.post('/createdocument', createDocumentwithCoordinate);
+
+// create Document with base64 without placeholder
+app.post('/draftdocument', draftDocument);
+
+// create Document with templateId
+app.post('/createdocument/:template_id', createDocumentWithTemplate);
+
+// get Document on the basis of id
+app.get('/document/:document_id', getDocument);
+
+// get document on the basis of id
+app.put('/document/:document_id', updateDocument);
+
+// get document on the basis of id
+app.delete('/document/:document_id', deleteDocument);
+
+// get all types of documents on the basis of doctype
+app.get('/documentlist/:doctype', getDocumentList);
+
+// create Template with co-ordinate
+app.post('/createtemplate', createTemplatewithCoordinate);
+
+// create Template
+app.post('/drafttemplate', createTemplate);
+
+// create Template with binary
+app.post('/createtemplatewithbinary', upload.array('file', 1), createTemplatewithCoordinate);
+
+// get template on the basis of id
+app.get('/template/:template_id', getTemplate);
+
+// get template on the basis of id
+app.put('/template/:template_id', updateTemplate);
+
+// get template on the basis of id
+app.delete('/template/:template_id', deletedTemplate);
+
+// get all types of documents on the basis of doctype
+app.get('/templatelist', getTemplatetList);
+
+// set and update webhook
+app.get('/webhook', getWebhook);
+
+// set and update webhook
+app.post('/webhook', saveWebhook);
+
+// set and update webhook
+app.delete('/webhook', deleteWebhook);
diff --git a/apps/OpenSignServer/cloud/customRoute/v1/routes/CreateDocumentWithTemplate.js b/apps/OpenSignServer/cloud/customRoute/v1/routes/CreateDocumentWithTemplate.js
new file mode 100644
index 000000000..6ef70f07a
--- /dev/null
+++ b/apps/OpenSignServer/cloud/customRoute/v1/routes/CreateDocumentWithTemplate.js
@@ -0,0 +1,367 @@
+import axios from 'axios';
+import { customAPIurl, replaceMailVaribles } from '../../../../Utils.js';
+
+// `sendDoctoWebhook` is used to send res data of document on webhook
+async function sendDoctoWebhook(doc, WebhookUrl, userId) {
+ if (WebhookUrl) {
+ const params = {
+ event: 'created',
+ ...doc,
+ };
+ await axios
+ .post(WebhookUrl, params, {
+ headers: { 'Content-Type': 'application/json' },
+ })
+ .then(res => {
+ try {
+ // console.log('res ', res);
+ const webhook = new Parse.Object('contracts_Webhook');
+ webhook.set('Log', res?.status);
+ webhook.set('UserId', {
+ __type: 'Pointer',
+ className: '_User',
+ objectId: userId,
+ });
+ webhook.save(null, { useMasterKey: true });
+ } catch (err) {
+ console.log('err save in contracts_Webhook', err);
+ }
+ })
+ .catch(err => {
+ console.log('Err send data to webhook', err);
+ try {
+ const webhook = new Parse.Object('contracts_Webhook');
+ webhook.set('Log', err?.status);
+ webhook.set('UserId', {
+ __type: 'Pointer',
+ className: '_User',
+ objectId: userId,
+ });
+ webhook.save(null, { useMasterKey: true });
+ } catch (err) {
+ console.log('err save in contracts_Webhook', err);
+ }
+ });
+ // console.log('res ', res.data);
+ }
+}
+export default async function createDocumentWithTemplate(request, response) {
+ const signers = request.body.signers;
+ const folderId = request.body.folderId;
+ const templateId = request.params.template_id;
+ const protocol = customAPIurl();
+ const baseUrl = new URL(process.env.SERVER_URL);
+ const send_email = request.body.send_email;
+ const email_subject = request.body.email_subject;
+ const email_body = request.body.email_body;
+ const sendInOrder = request.body.sendInOrder || false;
+
+ 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);
+ tokenQuery.include('userId');
+ const token = await tokenQuery.first({ useMasterKey: true });
+ if (token !== undefined) {
+ // Valid Token then proceed request
+ const parseUser = JSON.parse(JSON.stringify(token));
+ const userPtr = {
+ __type: 'Pointer',
+ className: '_User',
+ objectId: parseUser.userId.objectId,
+ };
+ const templateQuery = new Parse.Query('contracts_Template');
+ templateQuery.include('ExtUserPtr');
+ const templateRes = await templateQuery.get(templateId, { useMasterKey: true });
+ if (templateRes) {
+ const template = JSON.parse(JSON.stringify(templateRes));
+ if (template?.Placeholders?.length > 0) {
+ const emptyplaceholder = template?.Placeholders.filter(x => !x.signerObjId);
+ const isValid =
+ signers.length >= emptyplaceholder.length &&
+ signers.length <= template?.Placeholders?.length;
+ const placeholder =
+ signers.length > emptyplaceholder.length ? template.Placeholders : emptyplaceholder;
+ const updateSigners = placeholder.every(y => signers?.some(x => x.role === y.Role));
+ // console.log('isValid ', isValid);
+ 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);
+ }
+ object.set('IsSendMail', send_email);
+ if (sendInOrder) {
+ object.set('SendinOrder', sendInOrder);
+ } else if (template?.SendinOrder && template?.SendinOrder) {
+ object.set('SendinOrder', template?.SendinOrder);
+ }
+ let templateSigner = template?.Signers ? template?.Signers : [];
+ let contact = [];
+ if (signers && signers.length > 0) {
+ let parseSigners = [...signers];
+ let createContactUrl = protocol + '/v1/createcontact';
+
+ for (const obj of parseSigners) {
+ const body = {
+ name: obj?.name || '',
+ email: obj?.email || '',
+ phone: obj?.phone || '',
+ };
+ try {
+ const res = await axios.post(createContactUrl, body, {
+ headers: { 'Content-Type': 'application/json', 'x-api-token': reqToken },
+ });
+ const contactPtr = {
+ __type: 'Pointer',
+ className: 'contracts_Contactbook',
+ objectId: res.data?.objectId,
+ };
+ const newObj = { ...obj, contactPtr: contactPtr };
+ contact.push(newObj);
+ } catch (err) {
+ // console.log('err ', err);
+ if (err?.response?.data?.objectId) {
+ const contactPtr = {
+ __type: 'Pointer',
+ className: 'contracts_Contactbook',
+ objectId: err.response.data?.objectId,
+ };
+ const newObj = { ...obj, contactPtr: contactPtr };
+ contact.push(newObj);
+ } else {
+ console.log('err ', err);
+ }
+ }
+ }
+ const contactPtrs = contact.map(x => x.contactPtr);
+ object.set('Signers', [...templateSigner, ...contactPtrs]);
+
+ let updatedPlaceholder = template?.Placeholders?.map(x => {
+ let matchingSigner = contact.find(y => x.Role && x.Role === y.role);
+
+ if (matchingSigner) {
+ return {
+ ...x,
+ signerObjId: matchingSigner?.contactPtr?.objectId,
+ signerPtr: matchingSigner?.contactPtr,
+ };
+ } else {
+ return {
+ ...x,
+ };
+ }
+ });
+ object.set('Placeholders', updatedPlaceholder);
+ } else {
+ object.set('Signers', templateSigner);
+ }
+ object.set('URL', template.URL);
+ object.set('CreatedBy', template.CreatedBy);
+ object.set('ExtUserPtr', {
+ __type: 'Pointer',
+ className: 'contracts_Users',
+ objectId: template.ExtUserPtr.objectId,
+ });
+ if (folderId) {
+ object.set('Folder', folderPtr);
+ }
+ const newACL = new Parse.ACL();
+ newACL.setPublicReadAccess(false);
+ newACL.setPublicWriteAccess(false);
+ newACL.setReadAccess(userPtr.objectId, true);
+ newACL.setWriteAccess(userPtr.objectId, true);
+ object.setACL(newACL);
+ const res = await object.save(null, { useMasterKey: true });
+
+ const newDate = new Date();
+ newDate.setDate(newDate.getDate() + 15);
+ const localExpireDate = newDate.toLocaleDateString('en-US', {
+ day: 'numeric',
+ month: 'long',
+ year: 'numeric',
+ });
+ let sender = template.ExtUserPtr.Email;
+ let sendMail;
+ const serverUrl = process.env.SERVER_URL;
+ const newServer = serverUrl.replaceAll('/', '%2F');
+ const serverParams = `${newServer}%2F&${process.env.APP_ID}&contracts`;
+ if (send_email === false) {
+ console.log("don't send mail");
+ } else {
+ let contactMail = contact;
+ if (sendInOrder) {
+ contactMail = contact.slice();
+ contactMail.splice(1);
+ }
+ for (let i = 0; i < contactMail.length; i++) {
+ try {
+ const imgPng = 'https://qikinnovation.ams3.digitaloceanspaces.com/logo.png';
+ let url = `${process.env.SERVER_URL}/functions/sendmailv3/`;
+ const headers = {
+ 'Content-Type': 'application/json',
+ 'X-Parse-Application-Id': process.env.APP_ID,
+ 'X-Parse-Master-Key': process.env.MASTER_KEY,
+ };
+
+ const objectId = contactMail[i].contactPtr.objectId;
+
+ const hostUrl = baseUrl.origin + '/loadmf/signmicroapp';
+ let signPdf = `${hostUrl}/login/${res.id}/${contactMail[i].email}/${objectId}/${serverParams}`;
+ const openSignUrl = 'https://www.opensignlabs.com/contact-us';
+ const orgName = template.ExtUserPtr.Company ? template.ExtUserPtr.Company : '';
+ const themeBGcolor = '#47a3ad';
+ const email_html =
+ "
Digital Signature Request
" +
+ template.ExtUserPtr.Name +
+ ' has requested you to review and sign ' +
+ template.Name +
+ " .
Sender " +
+ sender +
+ " Organization " +
+ orgName +
+ " Expires on " +
+ localExpireDate +
+ "
This is an automated email from OpenSignâ˘. For any queries regarding this email, please contact the sender " +
+ sender +
+ ' directly.If you think this email is inappropriate or spam, you may file a complaint with OpenSign⢠here .
';
+
+ let replaceVar;
+ const variables = {
+ document_title: template.Name,
+ sender_name: template.ExtUserPtr.Name,
+ sender_mail: template.ExtUserPtr.Email,
+ sender_phone: template.ExtUserPtr.Phone,
+ receiver_name: contactMail[i].name,
+ receiver_email: contactMail[i].email,
+ receiver_phone: contactMail[i].phone,
+ expiry_date: localExpireDate,
+ company_name: orgName,
+ signing_url: signPdf,
+ };
+ if (email_subject && email_body) {
+ replaceVar = replaceMailVaribles(email_subject, email_body, variables);
+ } else if (email_subject) {
+ replaceVar = replaceMailVaribles(email_subject, '', variables);
+ replaceVar = { subject: replaceVar.subject, body: email_html };
+ } else if (email_body) {
+ replaceVar = replaceMailVaribles(
+ `${template.ExtUserPtr.Name} has requested you to sign ${template.Name}`,
+ email_body,
+ variables
+ );
+ } else {
+ replaceVar = {
+ subject: `${template.ExtUserPtr.Name} has requested you to sign ${template.Name}`,
+ body: email_html,
+ };
+ }
+
+ const subject = replaceVar.subject;
+ const html = replaceVar.body;
+ let params = {
+ recipient: contactMail[i].email,
+ subject: subject,
+ from: sender,
+ html: html,
+ };
+ sendMail = await axios.post(url, params, { headers: headers });
+ } catch (error) {
+ console.log('error', error);
+ }
+ }
+ }
+ // if (sendMail.data.result.status === 'success') {
+ try {
+ const doc = {
+ objectId: res.id,
+ file: template?.URL,
+ name: template?.Name,
+ note: template?.Note || '',
+ description: template?.Description || '',
+ signers: contact?.map(x => ({ name: x.name, email: x.email, phone: x.phone })),
+ createdAt: res.createdAt,
+ };
+ if (template.ExtUserPtr && template.ExtUserPtr?.Webhook) {
+ sendDoctoWebhook(doc, template.ExtUserPtr?.Webhook, userPtr?.objectId);
+ }
+ } catch (err) {
+ console.log('Err', err);
+ }
+ if (request.posthog) {
+ request.posthog?.capture({
+ distinctId: parseUser.userId.email,
+ event: 'api_create_document_with_templateid',
+ properties: { response_code: 200 },
+ });
+ }
+ return response.json({
+ objectId: res.id,
+ signurl: contact.map(x => ({
+ email: x.email,
+ url: `${baseUrl.origin}/loadmf/signmicroapp/login/${res.id}/${x.email}/${x.contactPtr.objectId}/${serverParams}`,
+ })),
+ message: 'Document sent successfully!',
+ });
+ // }
+ } else {
+ if (request.posthog) {
+ request.posthog?.capture({
+ distinctId: parseUser.userId.email,
+ event: 'api_create_document_with_templateid',
+ properties: { response_code: 400 },
+ });
+ }
+ return response.status(400).json({ error: 'Please provide signers properly!' });
+ }
+ } else {
+ if (request.posthog) {
+ request.posthog?.capture({
+ distinctId: parseUser.userId.email,
+ event: 'api_create_document_with_templateid',
+ properties: { response_code: 400 },
+ });
+ }
+ return response.status(400).json({ error: 'Please setup template properly!' });
+ }
+ } else {
+ if (request.posthog) {
+ request.posthog?.capture({
+ distinctId: parseUser.userId.email,
+ event: 'api_create_document_with_templateid',
+ properties: { response_code: 404 },
+ });
+ }
+ 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, please try again later!' });
+ }
+}
diff --git a/apps/OpenSignServer/cloud/customRoute/v1/routes/createContact.js b/apps/OpenSignServer/cloud/customRoute/v1/routes/createContact.js
new file mode 100644
index 000000000..32d4683f5
--- /dev/null
+++ b/apps/OpenSignServer/cloud/customRoute/v1/routes/createContact.js
@@ -0,0 +1,216 @@
+import axios from 'axios';
+export default async function createContact(request, response) {
+ const serverUrl = process.env.SERVER_URL;
+ const appId = process.env.APP_ID;
+ const name = request.body.name;
+ const phone = request.body.phone;
+ const email = request.body.email;
+ const reqToken = request.headers['x-api-token'];
+ if (!reqToken) {
+ return response.status(400).json({ error: 'Please Provide API Token' });
+ }
+ try {
+ const tokenQuery = new Parse.Query('appToken');
+ tokenQuery.equalTo('token', reqToken);
+ tokenQuery.include('userId');
+ const token = await tokenQuery.first({ useMasterKey: true });
+ if (token !== undefined) {
+ // Valid Token then proceed request
+ const parseUser = JSON.parse(JSON.stringify(token));
+ const userPtr = {
+ __type: 'Pointer',
+ className: '_User',
+ objectId: parseUser.userId.objectId,
+ };
+
+ try {
+ const contactbook = new Parse.Query('contracts_Contactbook');
+ contactbook.equalTo('Email', email);
+ contactbook.equalTo('CreatedBy', userPtr);
+ contactbook.notEqualTo('IsDeleted', true);
+ const userExists = await contactbook.first({ useMasterKey: true });
+
+ if (userExists) {
+ if (request.posthog) {
+ request.posthog?.capture({
+ distinctId: parseUser.userId.email,
+ event: 'api_create_contact',
+ properties: { response_code: 401 },
+ });
+ }
+ return response
+ .status(401)
+ .json({ error: 'Contact already exists!', objectId: userExists.id });
+ } else {
+ try {
+ const Tenant = new Parse.Query('partners_Tenant');
+ Tenant.equalTo('UserId', userPtr);
+ const tenantRes = await Tenant.first({ useMasterKey: true });
+
+ const contactQuery = new Parse.Object('contracts_Contactbook');
+ contactQuery.set('Name', name);
+ contactQuery.set('Phone', phone);
+ contactQuery.set('Email', email);
+ contactQuery.set('UserRole', 'contracts_Guest');
+ if (tenantRes && tenantRes.id) {
+ contactQuery.set('TenantId', {
+ __type: 'Pointer',
+ className: 'partners_Tenant',
+ objectId: tenantRes.id,
+ });
+ }
+ try {
+ const _users = Parse.Object.extend('User');
+ const _user = new _users();
+ _user.set('name', name);
+ _user.set('username', email);
+ _user.set('email', email);
+ _user.set('phone', phone);
+ _user.set('password', phone);
+
+ const user = await _user.save();
+ if (user) {
+ const roleurl = `${serverUrl}/functions/AddUserToRole`;
+ const headers = {
+ 'Content-Type': 'application/json',
+ 'X-Parse-Application-Id': appId,
+ // sessionToken: localStorage.getItem('accesstoken'),
+ };
+ const body = {
+ appName: 'contracts',
+ roleName: 'contracts_Guest',
+ userId: user.id,
+ };
+ await axios.post(roleurl, body, { headers: headers });
+ const currentUser = userPtr;
+ contactQuery.set('CreatedBy', currentUser);
+ contactQuery.set('UserId', user);
+
+ const acl = new Parse.ACL();
+ acl.setReadAccess(userPtr.objectId, true);
+ acl.setWriteAccess(userPtr.objectId, true);
+ acl.setReadAccess(user.id, true);
+ acl.setWriteAccess(user.id, true);
+ contactQuery.setACL(acl);
+
+ const contactRes = await contactQuery.save();
+ const parseRes = JSON.parse(JSON.stringify(contactRes));
+ if (request.posthog) {
+ request.posthog?.capture({
+ distinctId: parseUser.userId.email,
+ event: 'api_create_contact',
+ properties: { response_code: 200 },
+ });
+ }
+ return response.json({
+ objectId: parseRes.objectId,
+ name: parseRes.Name,
+ email: parseRes.Email,
+ phone: parseRes.Phone,
+ createdAt: parseRes.createdAt,
+ updatedAt: parseRes.updatedAt,
+ });
+ }
+ } catch (err) {
+ console.log('err in', err);
+ if (err.code === 202) {
+ const params = { email: email };
+ const userRes = await Parse.Cloud.run('getUserId', params);
+ const roleurl = `${serverUrl}/functions/AddUserToRole`;
+ const headers = {
+ 'Content-Type': 'application/json',
+ 'X-Parse-Application-Id': appId,
+ // sessionToken: localStorage.getItem('accesstoken'),
+ };
+ const body = {
+ appName: 'contracts',
+ roleName: 'contracts_Guest',
+ userId: userRes.objectId,
+ };
+ await axios.post(roleurl, body, { headers: headers });
+ contactQuery.set('CreatedBy', userPtr.objectId);
+ contactQuery.set('UserId', {
+ __type: 'Pointer',
+ className: '_User',
+ objectId: userRes.id,
+ });
+ const acl = new Parse.ACL();
+ acl.setReadAccess(userPtr.objectId, true);
+ acl.setWriteAccess(userPtr.objectId, true);
+ acl.setReadAccess(userRes.id, true);
+ acl.setWriteAccess(userRes.id, true);
+
+ contactQuery.setACL(acl);
+ const contactRes = await contactQuery.save();
+ if (contactRes) {
+ const parseRes = JSON.parse(JSON.stringify(contactRes));
+ if (request.posthog) {
+ request.posthog?.capture({
+ distinctId: parseUser.userId.email,
+ event: 'api_create_contact',
+ properties: { response_code: 200 },
+ });
+ }
+ return response.json({
+ objectId: parseRes.objectId,
+ name: parseRes.Name,
+ email: parseRes.Email,
+ phone: parseRes.Phone,
+ createdAt: parseRes.createdAt,
+ updatedAt: parseRes.updatedAt,
+ });
+ }
+ } else {
+ if (err.code === 137) {
+ return response.status(401).json({ error: 'Contact already exists!' });
+ }
+ return response
+ .status(400)
+ .json({ error: 'Something went wrong, please try again later!' });
+ }
+ }
+ } catch (err) {
+ console.log('err ', err);
+ if (err.code === 137) {
+ if (request.posthog) {
+ request.posthog?.capture({
+ distinctId: parseUser.userId.email,
+ event: 'api_create_contact',
+ properties: { response_code: 401 },
+ });
+ }
+ return response.status(401).json({ error: 'Contact already exists!' });
+ } else {
+ if (request.posthog) {
+ request.posthog?.capture({
+ distinctId: parseUser.userId.email,
+ event: 'api_create_contact',
+ properties: { response_code: 400 },
+ });
+ }
+ return response
+ .status(400)
+ .json({ error: 'Something went wrong, please try again later!' });
+ }
+ }
+ }
+ } catch (err) {
+ if (request.posthog) {
+ request.posthog?.capture({
+ distinctId: parseUser.userId.email,
+ event: 'api_create_contact',
+ properties: { response_code: 400 },
+ });
+ }
+ return response
+ .status(400)
+ .json({ error: 'Something went wrong, please try again later!' });
+ }
+ } else {
+ return response.status(405).json({ error: 'Invalid API Token!' });
+ }
+ } catch (err) {
+ console.log('Err ', err);
+ return response.status(400).json({ error: 'Something went wrong, please try again later!' });
+ }
+}
diff --git a/apps/OpenSignServer/cloud/customRoute/v1/routes/createDocumentwithCoordinate.js b/apps/OpenSignServer/cloud/customRoute/v1/routes/createDocumentwithCoordinate.js
new file mode 100644
index 000000000..0ca92d067
--- /dev/null
+++ b/apps/OpenSignServer/cloud/customRoute/v1/routes/createDocumentwithCoordinate.js
@@ -0,0 +1,379 @@
+import axios from 'axios';
+import { color, customAPIurl, replaceMailVaribles } from '../../../../Utils.js';
+
+// `sendDoctoWebhook` is used to send res data of document on webhook
+async function sendDoctoWebhook(doc, WebhookUrl, userId) {
+ if (WebhookUrl) {
+ const params = {
+ event: 'created',
+ ...doc,
+ };
+ await axios
+ .post(WebhookUrl, params, {
+ headers: { 'Content-Type': 'application/json' },
+ })
+ .then(res => {
+ try {
+ // console.log('res ', res);
+ const webhook = new Parse.Object('contracts_Webhook');
+ webhook.set('Log', res?.status);
+ webhook.set('UserId', {
+ __type: 'Pointer',
+ className: '_User',
+ objectId: userId,
+ });
+ webhook.save(null, { useMasterKey: true });
+ } catch (err) {
+ console.log('err save in contracts_Webhook', err);
+ }
+ })
+ .catch(err => {
+ console.log('Err send data to webhook', err);
+ try {
+ const webhook = new Parse.Object('contracts_Webhook');
+ webhook.set('Log', err?.status);
+ webhook.set('UserId', {
+ __type: 'Pointer',
+ className: '_User',
+ objectId: userId,
+ });
+ webhook.save(null, { useMasterKey: true });
+ } catch (err) {
+ console.log('err save in contracts_Webhook', err);
+ }
+ });
+ // console.log('res ', res.data);
+ }
+}
+const randomId = () => Math.floor(1000 + Math.random() * 9000);
+export default async function createDocumentwithCoordinate(request, response) {
+ const name = request.body.title;
+ const note = request.body.note;
+ const description = request.body.description;
+ const send_email = request.body.send_email;
+ const signers = request.body.signers;
+ const folderId = request.body.folderId;
+ const base64File = request.body.file;
+ const fileData = request.files?.[0] ? request.files[0].buffer : null;
+ const email_subject = request.body.email_subject;
+ const email_body = request.body.email_body;
+ const sendInOrder = request.body.sendInOrder || false;
+ // console.log('fileData ', fileData);
+ const protocol = customAPIurl();
+ const baseUrl = new URL(process.env.SERVER_URL);
+ const reqToken = request.headers['x-api-token'];
+ if (!reqToken) {
+ return response.status(400).json({ error: 'Please Provide API Token' });
+ }
+ try {
+ const tokenQuery = new Parse.Query('appToken');
+ tokenQuery.equalTo('token', reqToken);
+ tokenQuery.include('userId');
+ const token = await tokenQuery.first({ useMasterKey: true });
+ if (token !== undefined) {
+ // Valid Token then proceed request
+ const parseUser = JSON.parse(JSON.stringify(token));
+ const userPtr = {
+ __type: 'Pointer',
+ className: '_User',
+ objectId: parseUser.userId.objectId,
+ };
+ if (signers && signers.length > 0) {
+ let fileUrl;
+ if (request.files?.[0]) {
+ const file = new Parse.File(request.files?.[0]?.originalname, {
+ base64: fileData?.toString('base64'),
+ });
+ await file.save({ useMasterKey: true });
+ fileUrl = file.url();
+ } else {
+ const file = new Parse.File(`${name}.pdf`, {
+ base64: base64File,
+ });
+ await file.save({ useMasterKey: true });
+ fileUrl = file.url();
+ }
+ const contractsUser = new Parse.Query('contracts_Users');
+ contractsUser.equalTo('UserId', userPtr);
+ const extUser = await contractsUser.first({ useMasterKey: true });
+ const parseExtUser = JSON.parse(JSON.stringify(extUser));
+
+ const extUserPtr = {
+ __type: 'Pointer',
+ className: 'contracts_Users',
+ objectId: extUser.id,
+ };
+
+ const object = new Parse.Object('contracts_Document');
+ object.set('Name', name);
+
+ if (note) {
+ object.set('Note', note);
+ }
+ if (description) {
+ object.set('Description', description);
+ }
+ if (sendInOrder) {
+ object.set('SendinOrder', sendInOrder);
+ }
+ object.set('URL', fileUrl);
+ object.set('CreatedBy', userPtr);
+ object.set('ExtUserPtr', extUserPtr);
+ object.set('IsSendMail', send_email);
+ let contact = [];
+ if (signers && signers.length > 0) {
+ let parseSigners;
+ if (base64File) {
+ parseSigners = signers;
+ } else {
+ parseSigners = JSON.parse(signers);
+ }
+ let createContactUrl = protocol + '/v1/createcontact';
+
+ for (const [index, element] of parseSigners.entries()) {
+ const body = {
+ name: element?.name || '',
+ email: element?.email || '',
+ phone: element?.phone || '',
+ };
+ try {
+ const res = await axios.post(createContactUrl, body, {
+ headers: { 'Content-Type': 'application/json', 'x-api-token': reqToken },
+ });
+ // console.log('res ', res.data);
+ const contactPtr = {
+ __type: 'Pointer',
+ className: 'contracts_Contactbook',
+ objectId: res.data?.objectId,
+ };
+ const newObj = { ...element, contactPtr: contactPtr, index: index };
+ contact.push(newObj);
+ } catch (err) {
+ // console.log('err ', err.response);
+ if (err?.response?.data?.objectId) {
+ const contactPtr = {
+ __type: 'Pointer',
+ className: 'contracts_Contactbook',
+ objectId: err.response.data?.objectId,
+ };
+ const newObj = { ...element, contactPtr: contactPtr, index: index };
+ contact.push(newObj);
+ }
+ }
+ }
+ object.set(
+ 'Signers',
+ contact?.map(x => x.contactPtr)
+ );
+ let updatePlaceholders = contact.map((signer, index) => {
+ const placeHolder = [];
+
+ for (const widget of signer.widgets) {
+ const pageNumber = widget.page;
+ const page = placeHolder.find(page => page.pageNumber === pageNumber);
+
+ const widgetData = {
+ xPosition: widget.x,
+ yPosition: widget.y,
+ isStamp: widget.type === 'stamp',
+ key: randomId(),
+ isDrag: false,
+ firstXPos: widget.x,
+ firstYPos: widget.y,
+ yBottom: 0,
+ scale: 1,
+ isMobile: false,
+ zIndex: 1,
+ type: widget.type,
+ widgetValue: '',
+ Width: widget.w,
+ Height: widget.h,
+ };
+
+ if (page) {
+ page.pos.push(widgetData);
+ } else {
+ placeHolder.push({
+ pageNumber,
+ pos: [widgetData],
+ });
+ }
+ }
+
+ return {
+ signerObjId: signer?.contactPtr?.objectId,
+ signerPtr: signer?.contactPtr,
+ Role: signer.role,
+ Id: randomId(),
+ blockColor: color[signer?.index],
+ placeHolder,
+ };
+ });
+ object.set('Placeholders', updatePlaceholders);
+ }
+ if (folderId) {
+ object.set('Folder', {
+ __type: 'Pointer',
+ className: 'contracts_Document',
+ objectId: folderId,
+ });
+ }
+ const newACL = new Parse.ACL();
+ newACL.setPublicReadAccess(false);
+ newACL.setPublicWriteAccess(false);
+ newACL.setReadAccess(userPtr.objectId, true);
+ newACL.setWriteAccess(userPtr.objectId, true);
+ object.setACL(newACL);
+ const res = await object.save(null, { useMasterKey: true });
+ const doc = {
+ objectId: res.id,
+ file: fileUrl,
+ name: name,
+ note: note || '',
+ description: description || '',
+ signers: contact?.map(x => ({ name: x.name, email: x.email, phone: x.phone })),
+ createdAt: res.createdAt,
+ };
+ if (parseExtUser && parseExtUser.Webhook) {
+ sendDoctoWebhook(doc, parseExtUser?.Webhook, userPtr?.objectId);
+ }
+ const newDate = new Date();
+ newDate.setDate(newDate.getDate() + 15);
+ const localExpireDate = newDate.toLocaleDateString('en-US', {
+ day: 'numeric',
+ month: 'long',
+ year: 'numeric',
+ });
+ let sender = parseExtUser.Email;
+ let sendMail;
+ const serverUrl = process.env.SERVER_URL;
+ const newServer = serverUrl.replaceAll('/', '%2F');
+ const serverParams = `${newServer}%2F&${process.env.APP_ID}&contracts`;
+ if (send_email === false) {
+ console.log("don't send mail");
+ } else {
+ let contactMail = contact;
+ if (sendInOrder) {
+ contactMail = contact.slice();
+ contactMail.splice(1);
+ }
+ for (let i = 0; i < contactMail.length; i++) {
+ try {
+ const imgPng = 'https://qikinnovation.ams3.digitaloceanspaces.com/logo.png';
+ let url = `${process.env.SERVER_URL}/functions/sendmailv3/`;
+ const headers = {
+ 'Content-Type': 'application/json',
+ 'X-Parse-Application-Id': process.env.APP_ID,
+ 'X-Parse-Master-Key': process.env.MASTER_KEY,
+ };
+
+ const objectId = contactMail[i].contactPtr.objectId;
+
+ const hostUrl = baseUrl.origin + '/loadmf/signmicroapp';
+ let signPdf = `${hostUrl}/login/${res.id}/${contactMail[i].email}/${objectId}/${serverParams}`;
+ const openSignUrl = 'https://www.opensignlabs.com/contact-us';
+ const orgName = parseExtUser.Company ? parseExtUser.Company : '';
+ const themeBGcolor = '#47a3ad';
+ const email_html =
+ "
Digital Signature Request
" +
+ parseExtUser.Name +
+ ' has requested you to review and sign ' +
+ name +
+ " .
Sender " +
+ sender +
+ " Organization " +
+ orgName +
+ " Expires on " +
+ localExpireDate +
+ "
This is an automated email from OpenSignâ˘. For any queries regarding this email, please contact the sender " +
+ sender +
+ ' directly.If you think this email is inappropriate or spam, you may file a complaint with OpenSign⢠here .
';
+ let replaceVar;
+ const variables = {
+ document_title: name,
+ sender_name: parseExtUser.Name,
+ sender_mail: parseExtUser.Email,
+ sender_phone: parseExtUser.Phone,
+ receiver_name: contactMail[i].name,
+ receiver_email: contactMail[i].email,
+ receiver_phone: contactMail[i].phone,
+ expiry_date: localExpireDate,
+ company_name: orgName,
+ signing_url: signPdf,
+ };
+ if (email_subject && email_body) {
+ replaceVar = replaceMailVaribles(email_subject, email_body, variables);
+ } else if (email_subject) {
+ replaceVar = replaceMailVaribles(email_subject, '', variables);
+ replaceVar = { subject: replaceVar.subject, body: email_html };
+ } else if (email_body) {
+ replaceVar = replaceMailVaribles(
+ `${parseExtUser.Name} has requested you to sign ${name}`,
+ email_body,
+ variables
+ );
+ } else {
+ replaceVar = {
+ subject: `${parseExtUser.Name} has requested you to sign ${parseExtUser.Name}`,
+ body: email_html,
+ };
+ }
+ const subject = replaceVar.subject;
+ const html = replaceVar.body;
+
+ let params = {
+ recipient: contactMail[i].email,
+ subject: subject,
+ from: sender,
+ html: html,
+ };
+
+ sendMail = await axios.post(url, params, { headers: headers });
+ } catch (error) {
+ console.log('error', error);
+ }
+ }
+ }
+ // if (sendMail.data.result.status === 'success') {
+ if (request.posthog) {
+ request.posthog?.capture({
+ distinctId: parseUser.userId.email,
+ event: 'api_create_document',
+ properties: { response_code: 200 },
+ });
+ }
+ return response.json({
+ objectId: res.id,
+ signurl: contact.map(x => ({
+ email: x.email,
+ url: `${baseUrl.origin}/loadmf/signmicroapp/login/${res.id}/${x.email}/${x.contactPtr.objectId}/${serverParams}`,
+ })),
+ message: 'Document sent successfully!',
+ });
+ // }
+ } else {
+ if (request.posthog) {
+ request.posthog?.capture({
+ distinctId: parseUser.userId.email,
+ event: 'api_create_document',
+ properties: { response_code: 400 },
+ });
+ }
+ return response.status(400).json({ error: 'Please provide signers!' });
+ }
+ } else {
+ return response.status(405).json({ error: 'Invalid API Token!' });
+ }
+ } catch (err) {
+ console.log('err ', err);
+ return response.status(400).json({ error: 'Something went wrong, please try again later!' });
+ }
+}
diff --git a/apps/OpenSignServer/cloud/customRoute/v1/routes/createTemplate.js b/apps/OpenSignServer/cloud/customRoute/v1/routes/createTemplate.js
new file mode 100644
index 000000000..df8b6eacd
--- /dev/null
+++ b/apps/OpenSignServer/cloud/customRoute/v1/routes/createTemplate.js
@@ -0,0 +1,135 @@
+import { customAPIurl } from '../../../../Utils.js';
+
+const randomId = () => Math.floor(1000 + Math.random() * 9000);
+export default async function createTemplate(request, response) {
+ const name = request.body?.title;
+ const note = request.body?.note;
+ const description = request.body?.description;
+ const signers = request.body?.signers;
+ const folderId = request.body?.folderId;
+ const base64File = request.body.file;
+ const SendinOrder = request.body.sendInOrder || false;
+ const fileData = request.files?.[0] ? request.files[0].buffer : null;
+ const baseUrl = new 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);
+ tokenQuery.include('userId');
+ const token = await tokenQuery.first({ useMasterKey: true });
+ if (token !== undefined) {
+ // Valid Token then proceed request
+ const parseUser = JSON.parse(JSON.stringify(token));
+ const userPtr = {
+ __type: 'Pointer',
+ className: '_User',
+ objectId: parseUser.userId.objectId,
+ };
+ let fileUrl;
+ if (base64File) {
+ const file = new Parse.File(`${name}.pdf`, {
+ base64: base64File,
+ });
+ await file.save({ useMasterKey: true });
+ fileUrl = file.url();
+ } else {
+ const file = new Parse.File(request.files?.[0]?.originalname, {
+ base64: fileData?.toString('base64'),
+ });
+ await file.save({ useMasterKey: true });
+ fileUrl = file.url();
+ }
+
+ const contractsUser = new Parse.Query('contracts_Users');
+ contractsUser.equalTo('UserId', userPtr);
+ const extUser = await contractsUser.first({ useMasterKey: true });
+ const extUserPtr = { __type: 'Pointer', className: 'contracts_Users', objectId: extUser.id };
+
+ const folderPtr = { __type: 'Pointer', className: 'contracts_Template', objectId: folderId };
+
+ const object = new Parse.Object('contracts_Template');
+ object.set('Name', name);
+ if (note) {
+ object.set('Note', note);
+ }
+ if (description) {
+ object.set('Description', description);
+ }
+ object.set('URL', fileUrl);
+ object.set('CreatedBy', userPtr);
+ object.set('ExtUserPtr', extUserPtr);
+ if (SendinOrder) {
+ object.set('SendinOrder', SendinOrder);
+ }
+ if (signers && signers.length > 0) {
+ let parseSigners;
+ if (base64File) {
+ parseSigners = signers;
+ } else {
+ parseSigners = JSON.parse(signers);
+ }
+ let createContactUrl = protocol + '/v1/createcontact';
+
+ let contact = [];
+ for (const obj of parseSigners) {
+ const body = {
+ name: obj?.name || '',
+ email: obj?.email || '',
+ phone: obj?.phone || '',
+ };
+ try {
+ const res = await axios.post(createContactUrl, body, {
+ headers: { 'Content-Type': 'application/json', 'x-api-token': reqToken },
+ });
+ // console.log('res ', res.data);
+ contact.push({
+ __type: 'Pointer',
+ className: 'contracts_Contactbook',
+ objectId: res.data?.objectId,
+ });
+ } catch (err) {
+ // console.log('err ', err.response);
+ if (err?.response?.data?.objectId) {
+ contact.push({
+ __type: 'Pointer',
+ className: 'contracts_Contactbook',
+ objectId: err.response.data?.objectId,
+ });
+ }
+ }
+ }
+ object.set('Signers', contact);
+ }
+ if (folderId) {
+ object.set('Folder', folderPtr);
+ }
+ const newACL = new Parse.ACL();
+ newACL.setPublicReadAccess(false);
+ newACL.setPublicWriteAccess(false);
+ newACL.setReadAccess(userPtr.objectId, true);
+ newACL.setWriteAccess(userPtr.objectId, true);
+ object.setACL(newACL);
+ const res = await object.save(null, { useMasterKey: true });
+ if (request.posthog) {
+ request.posthog?.capture({
+ distinctId: parseUser.userId.email,
+ event: 'api_draft_template',
+ properties: { response_code: 200 },
+ });
+ }
+ return response.json({
+ objectId: res.id,
+ url: baseUrl.origin + '/load/signmicroapp/template/' + res.id,
+ });
+ } else {
+ return response.status(405).json({ error: 'Invalid API Token!' });
+ }
+ } catch (err) {
+ console.log('err ', err);
+ return response.status(400).json({ error: 'Something went wrong, please try again later!' });
+ }
+}
diff --git a/apps/OpenSignServer/cloud/customRoute/v1/routes/createTemplatewithCoordinate.js b/apps/OpenSignServer/cloud/customRoute/v1/routes/createTemplatewithCoordinate.js
new file mode 100644
index 000000000..62cab68da
--- /dev/null
+++ b/apps/OpenSignServer/cloud/customRoute/v1/routes/createTemplatewithCoordinate.js
@@ -0,0 +1,214 @@
+import axios from 'axios';
+import { color, customAPIurl } from '../../../../Utils.js';
+
+const randomId = () => Math.floor(1000 + Math.random() * 9000);
+export default async function createTemplatewithCoordinate(request, response) {
+ const name = request.body.title;
+ const note = request.body.note;
+ const description = request.body.description;
+ const signers = request.body.signers;
+ const folderId = request.body.folderId;
+ const base64File = request.body.file;
+ const fileData = request.files?.[0] ? request.files[0].buffer : null;
+ const SendinOrder = request.body.sendInOrder || false;
+ // console.log('fileData ', fileData);
+ const protocol = customAPIurl();
+
+ 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);
+ tokenQuery.include('userId');
+ const token = await tokenQuery.first({ useMasterKey: true });
+ if (token !== undefined) {
+ // Valid Token then proceed request
+ const parseUser = JSON.parse(JSON.stringify(token));
+ const userPtr = {
+ __type: 'Pointer',
+ className: '_User',
+ objectId: parseUser.userId.objectId,
+ };
+ if (signers && signers.length > 0) {
+ let fileUrl;
+ if (request.files?.[0]) {
+ const file = new Parse.File(request.files?.[0]?.originalname, {
+ base64: fileData?.toString('base64'),
+ });
+ await file.save({ useMasterKey: true });
+ fileUrl = file.url();
+ } else {
+ const file = new Parse.File(`${name}.pdf`, {
+ base64: base64File,
+ });
+ await file.save({ useMasterKey: true });
+ fileUrl = file.url();
+ }
+ const contractsUser = new Parse.Query('contracts_Users');
+ contractsUser.equalTo('UserId', userPtr);
+ const extUser = await contractsUser.first({ useMasterKey: true });
+ const extUserPtr = {
+ __type: 'Pointer',
+ className: 'contracts_Users',
+ objectId: extUser.id,
+ };
+
+ const object = new Parse.Object('contracts_Template');
+ object.set('Name', name);
+
+ if (note) {
+ object.set('Note', note);
+ }
+ if (description) {
+ object.set('Description', description);
+ }
+ if (SendinOrder) {
+ object.set('SendinOrder', SendinOrder);
+ }
+ object.set('URL', fileUrl);
+ object.set('CreatedBy', userPtr);
+ object.set('ExtUserPtr', extUserPtr);
+ let contact = [];
+ if (signers && signers.length > 0) {
+ let parseSigners;
+ if (base64File) {
+ parseSigners = signers;
+ } else {
+ parseSigners = JSON.parse(signers);
+ }
+ let createContactUrl = protocol + '/v1/createcontact';
+
+ for (const [index, element] of parseSigners.entries()) {
+ if (element?.name && element.phone && element?.email) {
+ const body = {
+ name: element?.name || '',
+ email: element?.email || '',
+ phone: element?.phone || '',
+ };
+ try {
+ const res = await axios.post(createContactUrl, body, {
+ headers: { 'Content-Type': 'application/json', 'x-api-token': reqToken },
+ });
+ // console.log('res ', res.data);
+ const contactPtr = {
+ __type: 'Pointer',
+ className: 'contracts_Contactbook',
+ objectId: res.data?.objectId,
+ };
+ const newObj = { ...element, contactPtr: contactPtr, index: index };
+ contact.push(newObj);
+ } catch (err) {
+ // console.log('err ', err.response);
+ if (err?.response?.data?.objectId) {
+ const contactPtr = {
+ __type: 'Pointer',
+ className: 'contracts_Contactbook',
+ objectId: err.response.data?.objectId,
+ };
+ const newObj = { ...element, contactPtr: contactPtr, index: index };
+ contact.push(newObj);
+ }
+ }
+ } else {
+ const newObj = { ...element, contactPtr: {}, index: index };
+ contact.push(newObj);
+ }
+ }
+ const updatedSigners = contact?.filter(x => x.contactPtr && x.contactPtr.objectId);
+ if (updatedSigners && updatedSigners.length > 0) {
+ object.set(
+ 'Signers',
+ updatedSigners?.map(x => x.contactPtr)
+ );
+ }
+ let updatePlaceholders = contact.map((signer, index) => {
+ const placeHolder = [];
+
+ for (const widget of signer.widgets) {
+ const pageNumber = widget.page;
+ const page = placeHolder.find(page => page.pageNumber === pageNumber);
+
+ const widgetData = {
+ xPosition: widget.x,
+ yPosition: widget.y,
+ isStamp: widget.type === 'stamp',
+ key: randomId(),
+ isDrag: false,
+ firstXPos: widget.x,
+ firstYPos: widget.y,
+ yBottom: 0,
+ scale: 1,
+ isMobile: false,
+ zIndex: 1,
+ type: widget.type,
+ widgetValue: '',
+ Width: widget.w,
+ Height: widget.h,
+ };
+
+ if (page) {
+ page.pos.push(widgetData);
+ } else {
+ placeHolder.push({
+ pageNumber,
+ pos: [widgetData],
+ });
+ }
+ }
+
+ return {
+ signerObjId: signer?.contactPtr?.objectId,
+ signerPtr: signer?.contactPtr,
+ Role: signer.role,
+ Id: randomId(),
+ blockColor: color[signer?.index],
+ placeHolder,
+ };
+ });
+ object.set('Placeholders', updatePlaceholders);
+ }
+ if (folderId) {
+ object.set('Folder', {
+ __type: 'Pointer',
+ className: 'contracts_Template',
+ objectId: folderId,
+ });
+ }
+ const newACL = new Parse.ACL();
+ newACL.setPublicReadAccess(false);
+ newACL.setPublicWriteAccess(false);
+ newACL.setReadAccess(userPtr.objectId, true);
+ newACL.setWriteAccess(userPtr.objectId, true);
+ object.setACL(newACL);
+ const res = await object.save(null, { useMasterKey: true });
+ if (request.posthog) {
+ request.posthog?.capture({
+ distinctId: parseUser.userId.email,
+ event: 'api_create_template',
+ properties: { response_code: 200 },
+ });
+ }
+ return response.json({
+ objectId: res.id,
+ message: 'Template created successfully!',
+ });
+ } else {
+ if (request.posthog) {
+ request.posthog?.capture({
+ distinctId: parseUser.userId.email,
+ event: 'api_create_template',
+ properties: { response_code: 400 },
+ });
+ }
+ return response.status(400).json({ error: 'Please provide signers!' });
+ }
+ } else {
+ return response.status(405).json({ error: 'Invalid API Token!' });
+ }
+ } catch (err) {
+ console.log('err ', err);
+ return response.status(400).json({ error: 'Something went wrong, please try again later!' });
+ }
+}
diff --git a/apps/OpenSignServer/cloud/customRoute/v1/routes/deleteContact.js b/apps/OpenSignServer/cloud/customRoute/v1/routes/deleteContact.js
new file mode 100644
index 000000000..4926eceba
--- /dev/null
+++ b/apps/OpenSignServer/cloud/customRoute/v1/routes/deleteContact.js
@@ -0,0 +1,65 @@
+export default async function deleteContact(request, response) {
+ 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);
+ tokenQuery.include('userId');
+ const token = await tokenQuery.first({ useMasterKey: true });
+ if (token !== undefined) {
+ // Valid Token then proceed request
+ const parseUser = JSON.parse(JSON.stringify(token));
+ const userPtr = {
+ __type: 'Pointer',
+ className: '_User',
+ objectId: parseUser.userId.objectId,
+ };
+
+ const Contactbook = new Parse.Query('contracts_Contactbook');
+ Contactbook.equalTo('objectId', request.params.contact_id);
+ Contactbook.equalTo('CreatedBy', userPtr);
+ const res = await Contactbook.first({ useMasterKey: true });
+ if (res) {
+ const isDeleted = res.get('IsDeleted');
+ if (isDeleted && isDeleted) {
+ return response.status(404).json({ error: 'Contact not found!' });
+ } else {
+ const Contactbook = Parse.Object.extend('contracts_Contactbook');
+ const deleteQuery = new Contactbook();
+ deleteQuery.id = request.params.contact_id;
+ deleteQuery.set('IsDeleted', true);
+ const deleteRes = await deleteQuery.save(null, { useMasterKey: true });
+ if (deleteRes) {
+ if (request.posthog) {
+ request.posthog?.capture({
+ distinctId: parseUser.userId.email,
+ event: 'api_delete_contact',
+ properties: { response_code: 200 },
+ });
+ }
+ return response.json({
+ objectId: request.params.contact_id,
+ deletedAt: deleteRes.get('updatedAt'),
+ });
+ }
+ }
+ } else {
+ if (request.posthog) {
+ request.posthog?.capture({
+ distinctId: parseUser.userId.email,
+ event: 'api_delete_contact',
+ properties: { response_code: 404 },
+ });
+ }
+ return response.status(404).json({ error: 'Contact not found!' });
+ }
+ } else {
+ return response.status(405).json({ error: 'Invalid API Token!' });
+ }
+ } catch (err) {
+ console.log('err ', err);
+ return response.status(400).json({ error: 'Something went wrong, please try again later!' });
+ }
+}
diff --git a/apps/OpenSignServer/cloud/customRoute/v1/routes/deleteDocument.js b/apps/OpenSignServer/cloud/customRoute/v1/routes/deleteDocument.js
new file mode 100644
index 000000000..b166ec2ef
--- /dev/null
+++ b/apps/OpenSignServer/cloud/customRoute/v1/routes/deleteDocument.js
@@ -0,0 +1,65 @@
+export default async function deleteDocument(request, response) {
+ 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);
+ tokenQuery.include('userId');
+ const token = await tokenQuery.first({ useMasterKey: true });
+ if (token !== undefined) {
+ // Valid Token then proceed request
+ const parseUser = JSON.parse(JSON.stringify(token));
+ const userPtr = {
+ __type: 'Pointer',
+ className: '_User',
+ objectId: parseUser.userId.objectId,
+ };
+
+ const Document = new Parse.Query('contracts_Document');
+ Document.equalTo('objectId', request.params.document_id);
+ Document.equalTo('CreatedBy', userPtr);
+ const res = await Document.first({ useMasterKey: true });
+ if (res) {
+ const isArchive = res.get('IsArchive');
+ if (isArchive && isArchive) {
+ return response.status(404).json({ error: 'Document not found!' });
+ } else {
+ const Document = Parse.Object.extend('contracts_Document');
+ const deleteQuery = new Document();
+ deleteQuery.id = request.params.document_id;
+ deleteQuery.set('IsArchive', true);
+ const deleteRes = await deleteQuery.save(null, { useMasterKey: true });
+ if (deleteRes) {
+ if (request.posthog) {
+ request.posthog?.capture({
+ distinctId: parseUser.userId.email,
+ event: 'api_delete_document',
+ properties: { response_code: 200 },
+ });
+ }
+ return response.json({
+ objectId: request.params.document_id,
+ deletedAt: deleteRes.get('updatedAt'),
+ });
+ }
+ }
+ } else {
+ if (request.posthog) {
+ request.posthog?.capture({
+ distinctId: parseUser.userId.email,
+ event: 'api_delete_document',
+ properties: { response_code: 404 },
+ });
+ }
+ return response.status(404).json({ error: 'Document not found!' });
+ }
+ } else {
+ return response.status(405).json({ error: 'Invalid API Token!' });
+ }
+ } catch (err) {
+ console.log('err ', err);
+ return response.status(400).json({ error: 'Something went wrong, please try again later!' });
+ }
+}
diff --git a/apps/OpenSignServer/cloud/customRoute/v1/routes/deleteTemplate.js b/apps/OpenSignServer/cloud/customRoute/v1/routes/deleteTemplate.js
new file mode 100644
index 000000000..4011795e4
--- /dev/null
+++ b/apps/OpenSignServer/cloud/customRoute/v1/routes/deleteTemplate.js
@@ -0,0 +1,71 @@
+export default async function deletedTemplate(request, response) {
+ const reqToken = request.headers['x-api-token'];
+ if (!reqToken) {
+ return response.status(400).json({ error: 'Please Provide API Token' });
+ }
+ try {
+ const tokenQuery = new Parse.Query('appToken');
+ tokenQuery.equalTo('token', reqToken);
+ tokenQuery.include('userId');
+ const token = await tokenQuery.first({ useMasterKey: true });
+ if (token !== undefined) {
+ // Valid Token then proceed request
+ const parseUser = JSON.parse(JSON.stringify(token));
+ const userPtr = {
+ __type: 'Pointer',
+ className: '_User',
+ objectId: parseUser.userId.objectId,
+ };
+ const template = new Parse.Query('contracts_Template');
+ template.equalTo('objectId', request.params.template_id);
+ template.equalTo('CreatedBy', userPtr);
+ const res = await template.first({ useMasterKey: true });
+ if (res) {
+ const isArchive = res.get('IsArchive');
+ if (isArchive && isArchive) {
+ if (request.posthog) {
+ request.posthog?.capture({
+ distinctId: parseUser.userId.email,
+ event: 'api_delete_template',
+ properties: { response_code: 404 },
+ });
+ }
+ return response.status(404).json({ error: 'Template not found!' });
+ } else {
+ const template = Parse.Object.extend('contracts_Template');
+ const deleteQuery = new template();
+ deleteQuery.id = request.params.template_id;
+ deleteQuery.set('IsArchive', true);
+ const deleteRes = await deleteQuery.save(null, { useMasterKey: true });
+ if (deleteRes) {
+ if (request.posthog) {
+ request.posthog?.capture({
+ distinctId: parseUser.userId.email,
+ event: 'api_delete_template',
+ properties: { response_code: 200 },
+ });
+ }
+ return response.json({
+ objectId: request.params.template_id,
+ deletedAt: deleteRes.get('updatedAt'),
+ });
+ }
+ }
+ } else {
+ if (request.posthog) {
+ request.posthog?.capture({
+ distinctId: parseUser.userId.email,
+ event: 'api_delete_template',
+ properties: { response_code: 404 },
+ });
+ }
+ return response.status(404).json({ error: 'Template not found!' });
+ }
+ } else {
+ return response.status(405).json({ error: 'Invalid API Token!' });
+ }
+ } catch (err) {
+ console.log('err ', err);
+ return response.status(400).json({ error: 'Something went wrong, please try again later!' });
+ }
+}
diff --git a/apps/OpenSignServer/cloud/customRoute/v1/routes/deleteWebhook.js b/apps/OpenSignServer/cloud/customRoute/v1/routes/deleteWebhook.js
new file mode 100644
index 000000000..ac82b521f
--- /dev/null
+++ b/apps/OpenSignServer/cloud/customRoute/v1/routes/deleteWebhook.js
@@ -0,0 +1,57 @@
+export default async function deleteWebhook(request, response) {
+ const reqToken = request.headers['x-api-token'];
+ if (!reqToken) {
+ return response.status(400).json({ error: 'Please Provide API Token' });
+ }
+ try {
+ const tokenQuery = new Parse.Query('appToken');
+ tokenQuery.equalTo('token', reqToken);
+ tokenQuery.include('userId');
+ const token = await tokenQuery.first({ useMasterKey: true });
+ if (token !== undefined) {
+ // Valid Token then proceed request
+ const parseUser = JSON.parse(JSON.stringify(token));
+ const userPtr = {
+ __type: 'Pointer',
+ className: '_User',
+ objectId: parseUser.userId.objectId,
+ };
+
+ const query = new Parse.Query('contracts_Users');
+ query.equalTo('UserId', userPtr);
+ const user = await query.first({ useMasterKey: true });
+ if (user) {
+ const updateQuery = new Parse.Object('contracts_Users');
+ updateQuery.id = user.id;
+ updateQuery.unset('Webhook');
+ const res = await updateQuery.save(null, { useMasterKey: true });
+ if (res) {
+ if (request.posthog) {
+ request.posthog?.capture({
+ distinctId: parseUser.userId.email,
+ event: 'api_delete_webhook',
+ properties: { response_code: 200 },
+ });
+ }
+ return response.json({
+ result: 'Webhook deleted successfully!',
+ });
+ }
+ } else {
+ if (request.posthog) {
+ request.posthog?.capture({
+ distinctId: parseUser.userId.email,
+ event: 'api_delete_webhook',
+ properties: { response_code: 404 },
+ });
+ }
+ return response.status(404).json({ error: 'User not found!' });
+ }
+ } else {
+ return response.status(405).json({ error: 'Invalid API Token!' });
+ }
+ } catch (err) {
+ console.log('err ', err);
+ return response.status(400).json({ error: 'Something went wrong, please try again later!' });
+ }
+}
diff --git a/apps/OpenSignServer/cloud/customRoute/v1/routes/draftDocument.js b/apps/OpenSignServer/cloud/customRoute/v1/routes/draftDocument.js
new file mode 100644
index 000000000..a2ba41d3c
--- /dev/null
+++ b/apps/OpenSignServer/cloud/customRoute/v1/routes/draftDocument.js
@@ -0,0 +1,157 @@
+import axios from 'axios';
+import { customAPIurl } from '../../../../Utils.js';
+
+// const randomId = () => Math.floor(1000 + Math.random() * 9000);
+export default async function draftDocument(request, response) {
+ const name = request.body.title;
+ const note = request.body.note;
+ const description = request.body.description;
+ const signers = request.body.signers;
+ const folderId = request.body.folderId;
+ const base64File = request.body.file;
+ const send_email = request.body.send_email || true;
+ const fileData = request.files?.[0] ? request.files[0].buffer : null;
+ const SendinOrder = request.body.sendInOrder || false;
+ // console.log('fileData ', fileData);
+ const protocol = customAPIurl();
+
+ 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);
+ tokenQuery.include('userId');
+ const token = await tokenQuery.first({ useMasterKey: true });
+ if (token !== undefined) {
+ const parseUser = JSON.parse(JSON.stringify(token));
+ const userPtr = {
+ __type: 'Pointer',
+ className: '_User',
+ objectId: parseUser.userId.objectId,
+ };
+ // Valid Token then proceed request
+ if (signers && signers.length > 0) {
+ let fileUrl;
+ if (request.files?.[0]) {
+ const file = new Parse.File(request.files?.[0]?.originalname, {
+ base64: fileData?.toString('base64'),
+ });
+ await file.save({ useMasterKey: true });
+ fileUrl = file.url();
+ } else {
+ const file = new Parse.File(`${name}.pdf`, {
+ base64: base64File,
+ });
+ await file.save({ useMasterKey: true });
+ fileUrl = file.url();
+ }
+ const contractsUser = new Parse.Query('contracts_Users');
+ contractsUser.equalTo('UserId', userPtr);
+ const extUser = await contractsUser.first({ useMasterKey: true });
+ const extUserPtr = {
+ __type: 'Pointer',
+ className: 'contracts_Users',
+ objectId: extUser.id,
+ };
+
+ const folderPtr = {
+ __type: 'Pointer',
+ className: 'contracts_Document',
+ objectId: folderId,
+ };
+
+ const object = new Parse.Object('contracts_Document');
+ object.set('Name', name);
+ if (note) {
+ object.set('Note', note);
+ }
+ if (description) {
+ object.set('Description', description);
+ }
+ if (SendinOrder) {
+ object.set('SendinOrder', SendinOrder);
+ }
+ object.set('URL', fileUrl);
+ object.set('CreatedBy', userPtr);
+ object.set('ExtUserPtr', extUserPtr);
+ object.set('IsSendMail', send_email);
+ if (signers && signers.length > 0) {
+ let parseSigners;
+ if (base64File) {
+ parseSigners = signers;
+ } else {
+ parseSigners = JSON.parse(signers);
+ }
+ let createContactUrl = protocol + '/v1/createcontact';
+
+ let contact = [];
+ for (const obj of parseSigners) {
+ const body = {
+ name: obj?.name || '',
+ email: obj?.email || '',
+ phone: obj?.phone || '',
+ };
+ try {
+ const res = await axios.post(createContactUrl, body, {
+ headers: { 'Content-Type': 'application/json', 'x-api-token': reqToken },
+ });
+ // console.log('res ', res.data);
+ contact.push({
+ __type: 'Pointer',
+ className: 'contracts_Contactbook',
+ objectId: res.data?.objectId,
+ });
+ } catch (err) {
+ // console.log('err ', err.response);
+ if (err?.response?.data?.objectId) {
+ contact.push({
+ __type: 'Pointer',
+ className: 'contracts_Contactbook',
+ objectId: err.response.data?.objectId,
+ });
+ }
+ }
+ }
+ object.set('Signers', contact);
+ }
+ if (folderId) {
+ object.set('Folder', folderPtr);
+ }
+ const newACL = new Parse.ACL();
+ newACL.setPublicReadAccess(false);
+ newACL.setPublicWriteAccess(false);
+ newACL.setReadAccess(userPtr.objectId, true);
+ newACL.setWriteAccess(userPtr.objectId, true);
+ object.setACL(newACL);
+ const res = await object.save(null, { useMasterKey: true });
+ if (request.posthog) {
+ request.posthog?.capture({
+ distinctId: parseUser.userId.email,
+ event: 'api_draft_document',
+ properties: { response_code: 200 },
+ });
+ }
+ return response.json({
+ objectId: res.id,
+ url: protocol + '/load/signmicroapp/placeholdersign/' + res.id,
+ });
+ } else {
+ if (request.posthog) {
+ request.posthog?.capture({
+ distinctId: parseUser.userId.email,
+ event: 'api_draft_document',
+ properties: { response_code: 400 },
+ });
+ }
+ return response.status(400).json({ error: 'Please provide signers!' });
+ }
+ } else {
+ return response.status(405).json({ error: 'Invalid API Token!' });
+ }
+ } catch (err) {
+ console.log('err ', err);
+ return response.status(400).json({ error: 'Something went wrong, please try again later!' });
+ }
+}
diff --git a/apps/OpenSignServer/cloud/customRoute/v1/routes/getContact.js b/apps/OpenSignServer/cloud/customRoute/v1/routes/getContact.js
new file mode 100644
index 000000000..e3d288586
--- /dev/null
+++ b/apps/OpenSignServer/cloud/customRoute/v1/routes/getContact.js
@@ -0,0 +1,61 @@
+export default async function getContact(request, response) {
+ 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);
+ tokenQuery.include('userId');
+ const token = await tokenQuery.first({ useMasterKey: true });
+ if (token !== undefined) {
+ // Valid Token then proceed request
+ const parseUser = JSON.parse(JSON.stringify(token));
+ const userPtr = {
+ __type: 'Pointer',
+ className: '_User',
+ objectId: parseUser.userId.objectId,
+ };
+
+ const Contactbook = new Parse.Query('contracts_Contactbook');
+ Contactbook.equalTo('objectId', request.params.contact_id);
+ Contactbook.equalTo('CreatedBy', userPtr);
+ Contactbook.notEqualTo('IsDeleted', true);
+ Contactbook.select('Name,Email,Phone');
+
+ const res = await Contactbook.first({ useMasterKey: true });
+ if (res) {
+ const parseRes = JSON.parse(JSON.stringify(res));
+ if (request.posthog) {
+ request.posthog?.capture({
+ distinctId: parseUser.userId.email,
+ event: 'api_get_contact',
+ properties: { response_code: 200 },
+ });
+ }
+ return response.json({
+ objectId: parseRes.objectId,
+ name: parseRes.Name,
+ email: parseRes.Email,
+ phone: parseRes.Phone,
+ createdAt: parseRes.createdAt,
+ updatedAt: parseRes.updatedAt,
+ });
+ } else {
+ if (request.posthog) {
+ request.posthog?.capture({
+ distinctId: parseUser.userId.email,
+ event: 'api_get_contact',
+ properties: { response_code: 404 },
+ });
+ }
+ return response.status(404).json({ error: 'Contact not found!' });
+ }
+ } else {
+ return response.status(405).json({ error: 'Invalid API Token!' });
+ }
+ } catch (err) {
+ console.log('err ', err);
+ return response.status(400).json({ error: 'Something went wrong, please try again later!' });
+ }
+}
diff --git a/apps/OpenSignServer/cloud/customRoute/v1/routes/getContactList.js b/apps/OpenSignServer/cloud/customRoute/v1/routes/getContactList.js
new file mode 100644
index 000000000..f20682c63
--- /dev/null
+++ b/apps/OpenSignServer/cloud/customRoute/v1/routes/getContactList.js
@@ -0,0 +1,63 @@
+export default async function getContactList(request, response) {
+ 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);
+ tokenQuery.include('userId');
+ const token = await tokenQuery.first({ useMasterKey: true });
+ if (token !== undefined) {
+ // Valid Token then proceed request
+ const parseUser = JSON.parse(JSON.stringify(token));
+ const userPtr = {
+ __type: 'Pointer',
+ className: '_User',
+ objectId: parseUser.userId.objectId,
+ };
+ const limit = request?.query?.limit ? parseInt(request.query.limit) : 100;
+ const skip = request?.query?.skip ? parseInt(request.query.skip) : 0;
+ const Contactbook = new Parse.Query('contracts_Contactbook');
+ Contactbook.equalTo('CreatedBy', userPtr);
+ Contactbook.notEqualTo('IsDeleted', true);
+ Contactbook.limit(limit);
+ Contactbook.skip(skip);
+ Contactbook.descending('createdAt');
+ const res = await Contactbook.find({ useMasterKey: true });
+ if (res && res.length > 0) {
+ const parseRes = JSON.parse(JSON.stringify(res));
+ const contactlist = parseRes.map(x => ({
+ objectId: x.objectId,
+ name: x.Name,
+ email: x.Email,
+ phone: x.Phone,
+ createdAt: x.createdAt,
+ updatedAt: x.updatedAt,
+ }));
+ if (request.posthog) {
+ request.posthog?.capture({
+ distinctId: parseUser.userId.email,
+ event: 'api_get_contact_list',
+ properties: { response_code: 200 },
+ });
+ }
+ return response.json({ result: contactlist });
+ } else {
+ if (request.posthog) {
+ request.posthog?.capture({
+ distinctId: parseUser.userId.email,
+ event: 'api_get_contact_list',
+ properties: { response_code: 200 },
+ });
+ }
+ return response.json({ result: [] });
+ }
+ } else {
+ return response.status(405).json({ error: 'Invalid API Token!' });
+ }
+ } catch (err) {
+ console.log('err ', err);
+ return response.status(400).json({ error: 'Something went wrong, please try again later!' });
+ }
+}
diff --git a/apps/OpenSignServer/cloud/customRoute/v1/routes/getDocument.js b/apps/OpenSignServer/cloud/customRoute/v1/routes/getDocument.js
new file mode 100644
index 000000000..cc1e1e03c
--- /dev/null
+++ b/apps/OpenSignServer/cloud/customRoute/v1/routes/getDocument.js
@@ -0,0 +1,84 @@
+export default async function getDocument(request, response) {
+ 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);
+ tokenQuery.include('userId');
+ const token = await tokenQuery.first({ useMasterKey: true });
+ if (token !== undefined) {
+ // Valid Token then proceed request
+ const parseUser = JSON.parse(JSON.stringify(token));
+ const userPtr = {
+ __type: 'Pointer',
+ className: '_User',
+ objectId: parseUser.userId.objectId,
+ };
+ const Document = new Parse.Query('contracts_Document');
+ Document.equalTo('objectId', request.params.document_id);
+ Document.equalTo('CreatedBy', userPtr);
+ Document.notEqualTo('IsArchive', true);
+ Document.include('Signers');
+ Document.include('Folder');
+ Document.include('ExtUserPtr');
+ Document.include('Placeholders.signerPtr');
+ const res = await Document.first({ useMasterKey: true });
+ if (res) {
+ const document = JSON.parse(JSON.stringify(res));
+ if (request.posthog) {
+ request.posthog?.capture({
+ distinctId: parseUser.userId.email,
+ event: 'api_get_document',
+ properties: { response_code: 200 },
+ });
+ }
+ return response.json({
+ objectId: document.objectId,
+ title: document.Name,
+ note: document.Note || '',
+ folder: { objectId: document?.Folder?.objectId, name: document?.Folder?.Name } || '',
+ file: document?.SignedUrl || document.URL,
+ owner: document?.ExtUserPtr?.Name,
+ signers:
+ document?.Placeholders?.map(y => ({
+ role: y.Role,
+ name: y?.signerPtr?.Name || '',
+ email: y?.signerPtr?.Email || '',
+ phone: y?.signerPtr?.Phone || '',
+ widgets: y.placeHolder?.flatMap(x =>
+ x?.pos.map(w => ({
+ type: w?.type ? w.type : w.isStamp ? 'stamp' : 'signature',
+ x: w.xPosition,
+ y: w.yPosition,
+ w: w?.Width || 150,
+ h: w?.Height || 60,
+ page: x?.pageNumber,
+ }))
+ ),
+ })) ||
+ document?.Signers?.map(y => ({ name: y?.Name, email: y?.Email, phone: y?.Phone })) ||
+ [],
+ sendInOrder: document?.SendinOrder || false,
+ createdAt: document.createdAt,
+ updatedAt: document.updatedAt,
+ });
+ } else {
+ if (request.posthog) {
+ request.posthog?.capture({
+ distinctId: parseUser.userId.email,
+ event: 'api_get_document',
+ properties: { response_code: 404 },
+ });
+ }
+ return response.status(404).json({ error: 'Document not found!' });
+ }
+ } else {
+ return response.status(405).json({ error: 'Invalid API Token!' });
+ }
+ } catch (err) {
+ console.log('err ', err);
+ return response.status(400).json({ error: 'Something went wrong, please try again later!' });
+ }
+}
diff --git a/apps/OpenSignServer/cloud/customRoute/v1/routes/getDocumentList.js b/apps/OpenSignServer/cloud/customRoute/v1/routes/getDocumentList.js
new file mode 100644
index 000000000..011ef7807
--- /dev/null
+++ b/apps/OpenSignServer/cloud/customRoute/v1/routes/getDocumentList.js
@@ -0,0 +1,138 @@
+import axios from 'axios';
+import reportJson from '../../../parsefunction/reportsJson.js';
+import dotenv from 'dotenv';
+dotenv.config();
+
+export default async function getDocumentList(request, response) {
+ const reqToken = request.headers['x-api-token'];
+ const appId = process.env.APP_ID;
+ const serverUrl = process.env.SERVER_URL;
+ if (!reqToken) {
+ return response.status(400).json({ error: 'Please Provide API Token' });
+ }
+ try {
+ const tokenQuery = new Parse.Query('appToken');
+ tokenQuery.equalTo('token', reqToken);
+ tokenQuery.include('userId');
+ const token = await tokenQuery.first({ useMasterKey: true });
+ if (token !== undefined) {
+ // Valid Token then proceed request
+ const parseUser = JSON.parse(JSON.stringify(token));
+ const userPtr = {
+ __type: 'Pointer',
+ className: '_User',
+ objectId: parseUser.userId.objectId,
+ };
+ const docType = request.params.doctype;
+ const limit = request?.query?.limit ? request.query.limit : 100;
+ const skip = request?.query?.skip ? request.query.skip : 0;
+ let reportId;
+ switch (docType) {
+ case 'draft':
+ reportId = 'ByHuevtCFY';
+ break;
+ case 'signaturerequest':
+ reportId = '4Hhwbp482K';
+ break;
+ case 'inprogress':
+ reportId = '1MwEuxLEkF';
+ break;
+ case 'completed':
+ reportId = 'kQUoW4hUXz';
+ break;
+ case 'expired':
+ reportId = 'zNqBHXHsYH';
+ break;
+ case 'declined':
+ reportId = 'UPr2Fm5WY3';
+ break;
+ default:
+ reportId = '';
+ }
+ const json = reportId && reportJson(reportId, userPtr.objectId);
+ const clsName = 'contracts_Document';
+ if (reportId && json) {
+ const { params, keys } = json;
+ const orderBy = '-updatedAt';
+ const strParams = JSON.stringify(params);
+ const strKeys = keys.join();
+ const headers = {
+ 'Content-Type': 'application/json',
+ 'X-Parse-Application-Id': appId,
+ 'X-Parse-Master-Key': process.env.MASTER_KEY,
+ };
+ const url = `${serverUrl}/classes/${clsName}?where=${strParams}&keys=${strKeys},Placeholders&order=${orderBy}&skip=${skip}&limit=${limit}&include=AuditTrail.UserPtr,Placeholders.signerPtr`;
+ try {
+ const res = await axios.get(url, { headers: headers });
+ if (res.data && res.data.results.length > 0) {
+ if (request.posthog) {
+ request.posthog?.capture({
+ distinctId: parseUser.userId.email,
+ event: 'api_get_document_list_by_status',
+ properties: { response_code: 200, doc_type: docType },
+ });
+ }
+ const updateRes = res.data.results.map(x => ({
+ objectId: x.objectId,
+ title: x.Name,
+ note: x.Note || '',
+ folder: { objectId: x?.Folder?.objectId, name: x?.Folder?.Name } || '',
+ file: x?.SignedUrl || x.URL,
+ owner: x?.ExtUserPtr?.Name,
+ signers:
+ x?.Placeholders?.map(y => ({
+ role: y.Role,
+ name: y?.signerPtr?.Name || '',
+ email: y?.signerPtr?.Email || '',
+ phone: y?.signerPtr?.Phone || '',
+ widgets: y.placeHolder?.flatMap(x =>
+ x?.pos.map(w => ({
+ type: w?.type ? w.type : w.isStamp ? 'stamp' : 'signature',
+ x: w.xPosition,
+ y: w.yPosition,
+ w: w?.Width || 150,
+ h: w?.Height || 60,
+ page: x?.pageNumber,
+ }))
+ ),
+ })) ||
+ x?.Signers?.map(y => ({ name: y?.Name, email: y?.Email, phone: y?.Phone })) ||
+ [],
+ sendInOrder: x?.SendinOrder || false,
+ createdAt: x.createdAt,
+ updatedAt: x.updatedAt,
+ }));
+ return response.json({ result: updateRes });
+ } else {
+ return response.json({ result: [] });
+ }
+ } catch (err) {
+ console.log('err in getdocument list', err);
+ if (request.posthog) {
+ request.posthog?.capture({
+ distinctId: parseUser.userId.email,
+ event: 'api_get_document_list_by_status',
+ properties: { response_code: 400, doc_type: docType },
+ });
+ }
+ return response
+ .status(400)
+ .json({ error: 'Something went wrong, please try again later!' });
+ }
+ } else {
+ if (request.posthog) {
+ request.posthog?.capture({
+ distinctId: parseUser.userId.email,
+ event: 'api_get_document_list_by_status',
+ properties: { response_code: 404, doc_type: docType },
+ });
+ }
+ return response.status(404).json({ error: 'Report not available!' });
+ }
+ }
+ return response.status(405).json({ error: 'Invalid API Token!' });
+ } catch (err) {
+ console.log('Err', err);
+ return response.status(400).json({ error: 'Something went wrong, please try again later!' });
+ }
+}
diff --git a/apps/OpenSignServer/cloud/customRoute/v1/routes/getTemplate.js b/apps/OpenSignServer/cloud/customRoute/v1/routes/getTemplate.js
new file mode 100644
index 000000000..7b3daa28d
--- /dev/null
+++ b/apps/OpenSignServer/cloud/customRoute/v1/routes/getTemplate.js
@@ -0,0 +1,84 @@
+export default async function getTemplate(request, response) {
+ 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);
+ tokenQuery.include('userId');
+ const token = await tokenQuery.first({ useMasterKey: true });
+ if (token !== undefined) {
+ // Valid Token then proceed request
+ const parseUser = JSON.parse(JSON.stringify(token));
+ const userPtr = {
+ __type: 'Pointer',
+ className: '_User',
+ objectId: parseUser.userId.objectId,
+ };
+
+ const Template = new Parse.Query('contracts_Template');
+ Template.equalTo('objectId', request.params.template_id);
+ Template.equalTo('CreatedBy', userPtr);
+ Template.notEqualTo('IsArchive', true);
+ Template.include('Signers');
+ Template.include('Folder');
+ Template.include('ExtUserPtr');
+ Template.include('Placeholders.signerPtr');
+ const res = await Template.first({ useMasterKey: true });
+ if (res) {
+ const template = JSON.parse(JSON.stringify(res));
+
+ if (request.posthog) {
+ request.posthog?.capture({
+ distinctId: parseUser.userId.email,
+ event: 'api_get_template',
+ properties: { response_code: 200 },
+ });
+ }
+ return response.json({
+ objectId: template.objectId,
+ title: template.Name,
+ note: template.Note || '',
+ folder: { objectId: template?.Folder?.objectId, name: template?.Folder?.Name } || '',
+ file: template?.SignedUrl || template?.URL,
+ owner: template?.ExtUserPtr?.Name,
+ signers:
+ template?.Placeholders?.map(y => ({
+ role: y.Role,
+ name: y?.signerPtr?.Name || '',
+ email: y?.signerPtr?.Email || '',
+ phone: y?.signerPtr?.Phone || '',
+ widgets: y.placeHolder?.flatMap(x =>
+ x?.pos.map(w => ({
+ type: w?.type ? w.type : w.isStamp ? 'stamp' : 'signature',
+ x: w.xPosition,
+ y: w.yPosition,
+ w: w?.Width || 150,
+ h: w?.Height || 60,
+ page: x?.pageNumber,
+ }))
+ ),
+ })) || [],
+ sendInOrder: template?.SendinOrder || false,
+ createdAt: template.createdAt,
+ updatedAt: template.updatedAt,
+ });
+ } else {
+ if (request.posthog) {
+ request.posthog?.capture({
+ distinctId: parseUser.userId.email,
+ event: 'api_get_template',
+ properties: { response_code: 404 },
+ });
+ }
+ return response.status(404).json({ error: 'Template not found!' });
+ }
+ } else {
+ return response.status(405).json({ error: 'Invalid API Token!' });
+ }
+ } catch (err) {
+ console.log('err ', err);
+ return response.status(400).json({ error: 'Something went wrong, please try again later!' });
+ }
+}
diff --git a/apps/OpenSignServer/cloud/customRoute/v1/routes/getTemplateList.js b/apps/OpenSignServer/cloud/customRoute/v1/routes/getTemplateList.js
new file mode 100644
index 000000000..fb1e1ae74
--- /dev/null
+++ b/apps/OpenSignServer/cloud/customRoute/v1/routes/getTemplateList.js
@@ -0,0 +1,111 @@
+import axios from 'axios';
+import dotenv from 'dotenv';
+dotenv.config();
+export default async function getTemplatetList(request, response) {
+ const reqToken = request.headers['x-api-token'];
+ const appId = process.env.APP_ID;
+ const serverUrl = process.env.SERVER_URL;
+ if (!reqToken) {
+ return response.status(400).json({ error: 'Please Provide API Token' });
+ }
+ try {
+ const tokenQuery = new Parse.Query('appToken');
+ tokenQuery.equalTo('token', reqToken);
+ tokenQuery.include('userId');
+ const token = await tokenQuery.first({ useMasterKey: true });
+ if (token !== undefined) {
+ // Valid Token then proceed request
+ const parseUser = JSON.parse(JSON.stringify(token));
+ const userPtr = {
+ __type: 'Pointer',
+ className: '_User',
+ objectId: parseUser.userId.objectId,
+ };
+
+ const limit = request?.query?.limit ? request.query.limit : 100;
+ const skip = request?.query?.skip ? request.query.skip : 0;
+
+ const clsName = 'contracts_Template';
+ const params = {
+ Type: { $ne: 'Folder' },
+ CreatedBy: userPtr,
+ IsArchive: { $ne: true },
+ };
+ const keys = [
+ 'Name',
+ 'Note',
+ 'Description',
+ 'Folder.Name',
+ 'URL',
+ 'SignedUrl',
+ 'ExtUserPtr.Name',
+ 'Signers.Name',
+ 'Signers.Email',
+ 'Signers.Phone',
+ 'Placeholders',
+ ];
+ const orderBy = '-updatedAt';
+ const strParams = JSON.stringify(params);
+ const strKeys = keys.join();
+ const headers = {
+ 'Content-Type': 'application/json',
+ 'X-Parse-Application-Id': appId,
+ 'X-Parse-Master-Key': process.env.MASTER_KEY,
+ };
+ const url = `${serverUrl}/classes/${clsName}?where=${strParams}&keys=${strKeys}&order=${orderBy}&skip=${skip}&limit=${limit}&include=AuditTrail.UserPtr,Placeholders.signerPtr`;
+ const res = await axios.get(url, { headers: headers });
+ if (res.data && res.data.results.length > 0) {
+ if (request.posthog) {
+ request.posthog?.capture({
+ distinctId: parseUser.userId.email,
+ event: 'api_get_template_list',
+ properties: { response_code: 200 },
+ });
+ }
+ const updateRes = res.data.results.map(template => ({
+ objectId: template.objectId,
+ title: template.Name,
+ note: template.Note || '',
+ folder: { objectId: template?.Folder?.objectId, name: template?.Folder?.Name } || '',
+ file: template?.SignedUrl || template.URL,
+ owner: template?.ExtUserPtr?.Name,
+ signers:
+ template?.Placeholders?.map(y => ({
+ role: y.Role,
+ name: y?.signerPtr?.Name || '',
+ email: y?.signerPtr?.Email || '',
+ phone: y?.signerPtr?.Phone || '',
+ widgets: y.placeHolder?.flatMap(x =>
+ x?.pos.map(w => ({
+ type: w?.type ? w.type : w.isStamp ? 'stamp' : 'signature',
+ x: w.xPosition,
+ y: w.yPosition,
+ w: w?.Width || 150,
+ h: w?.Height || 60,
+ page: x?.pageNumber,
+ }))
+ ),
+ })) || [],
+ sendInOrder: template?.SendinOrder || false,
+ createdAt: template.createdAt,
+ updatedAt: template.updatedAt,
+ }));
+
+ return response.json({ result: updateRes });
+ } else {
+ if (request.posthog) {
+ request.posthog?.capture({
+ distinctId: parseUser.userId.email,
+ event: 'api_get_template_list',
+ properties: { response_code: 200 },
+ });
+ }
+ return response.json({ result: [] });
+ }
+ }
+ return response.status(405).json({ error: 'Invalid API Token!' });
+ } catch (err) {
+ console.log('err', err);
+ return response.status(400).json({ error: 'Something went wrong, please try again later!' });
+ }
+}
diff --git a/apps/OpenSignServer/cloud/customRoute/v1/routes/getUser.js b/apps/OpenSignServer/cloud/customRoute/v1/routes/getUser.js
new file mode 100644
index 000000000..45776036e
--- /dev/null
+++ b/apps/OpenSignServer/cloud/customRoute/v1/routes/getUser.js
@@ -0,0 +1,62 @@
+import dotenv from 'dotenv';
+dotenv.config();
+
+export default async function getUser(request, response) {
+ const reqToken = request.headers['x-api-token'];
+ if (!reqToken) {
+ return response.status(400).json({ error: 'Please Provide API Token' });
+ }
+ try {
+ const tokenQuery = new Parse.Query('appToken');
+ tokenQuery.equalTo('token', reqToken);
+ tokenQuery.include('userId');
+ const token = await tokenQuery.first({ useMasterKey: true });
+ if (token !== undefined) {
+ // Valid Token then proceed request
+ const parseUser = JSON.parse(JSON.stringify(token));
+ const userPtr = {
+ __type: 'Pointer',
+ className: '_User',
+ objectId: parseUser.userId.objectId,
+ };
+
+ const query = new Parse.Query('contracts_Users');
+ query.equalTo('UserId', userPtr);
+ query.exclude('IsContactEntry,TourStatus,UserRole,TenantId,UserId,CreatedBy,Plan');
+ const user = await query.first({ useMasterKey: true });
+ if (user) {
+ const parseRes = JSON.parse(JSON.stringify(user));
+ if (request.posthog) {
+ request.posthog?.capture({
+ distinctId: parseUser.userId.email,
+ event: 'api_get_your_account_details',
+ properties: { response_code: 200 },
+ });
+ }
+ return response.json({
+ objectId: parseRes.objectId,
+ name: parseRes.Name,
+ email: parseRes.Email,
+ phone: parseRes.Phone,
+ jobTitle: parseRes.JobTitle,
+ company: parseRes.Company,
+ createdAt: parseRes.createdAt,
+ updatedAt: parseRes.updatedAt,
+ });
+ } else {
+ if (request.posthog) {
+ request.posthog?.capture({
+ distinctId: parseUser.userId.email,
+ event: 'api_get_your_account_details',
+ properties: { response_code: 404 },
+ });
+ }
+ return response.status(404).json({ error: 'User not found!' });
+ }
+ }
+ return response.status(405).json({ error: 'Invalid API Token!' });
+ } catch (err) {
+ console.log('Err', err);
+ return response.status(400).json({ error: 'Something went wrong, please try again later!' });
+ }
+}
diff --git a/apps/OpenSignServer/cloud/customRoute/v1/routes/getWebhook.js b/apps/OpenSignServer/cloud/customRoute/v1/routes/getWebhook.js
new file mode 100644
index 000000000..1dc692942
--- /dev/null
+++ b/apps/OpenSignServer/cloud/customRoute/v1/routes/getWebhook.js
@@ -0,0 +1,55 @@
+export default async function getWebhook(request, response) {
+ const reqToken = request.headers['x-api-token'];
+ if (!reqToken) {
+ return response.status(400).json({ error: 'Please Provide API Token' });
+ }
+ try {
+ const tokenQuery = new Parse.Query('appToken');
+ tokenQuery.equalTo('token', reqToken);
+ tokenQuery.include('userId');
+ const token = await tokenQuery.first({ useMasterKey: true });
+ if (token !== undefined) {
+ // Valid Token then proceed request
+ const parseUser = JSON.parse(JSON.stringify(token));
+ const userPtr = {
+ __type: 'Pointer',
+ className: '_User',
+ objectId: parseUser.userId.objectId,
+ };
+ const query = new Parse.Query('contracts_Users');
+ query.equalTo('UserId', userPtr);
+ const user = await query.first({ useMasterKey: true });
+ if (user) {
+ const extUser = JSON.parse(JSON.stringify(user));
+ if (request.posthog) {
+ request.posthog?.capture({
+ distinctId: parseUser.userId.email,
+ event: 'api_get_webhook',
+ properties: { response_code: 200 },
+ });
+ }
+ if (extUser && extUser.Webhook) {
+ return response.json({
+ webhook: extUser.Webhook,
+ });
+ } else {
+ return response.json({});
+ }
+ } else {
+ if (request.posthog) {
+ request.posthog?.capture({
+ distinctId: parseUser.userId.email,
+ event: 'api_get_webhook',
+ properties: { response_code: 404 },
+ });
+ }
+ return response.status(404).json({ error: 'User not found!' });
+ }
+ } else {
+ return response.status(405).json({ error: 'Invalid API Token!' });
+ }
+ } catch (err) {
+ console.log('Err ', err);
+ return response.status(400).json({ error: 'Something went wrong, please try again later!' });
+ }
+}
diff --git a/apps/OpenSignServer/cloud/customRoute/v1/routes/saveWebhook.js b/apps/OpenSignServer/cloud/customRoute/v1/routes/saveWebhook.js
new file mode 100644
index 000000000..9c6b4b9ba
--- /dev/null
+++ b/apps/OpenSignServer/cloud/customRoute/v1/routes/saveWebhook.js
@@ -0,0 +1,85 @@
+export default async function saveWebhook(request, response) {
+ const Url = request.body.url;
+ const reqToken = request.headers['x-api-token'];
+ if (!reqToken) {
+ return response.status(400).json({ error: 'Please Provide API Token' });
+ }
+ try {
+ const tokenQuery = new Parse.Query('appToken');
+ tokenQuery.equalTo('token', reqToken);
+ tokenQuery.include('userId');
+ const token = await tokenQuery.first({ useMasterKey: true });
+ if (token !== undefined) {
+ // Valid Token then proceed request
+ const parseUser = JSON.parse(JSON.stringify(token));
+ const userPtr = {
+ __type: 'Pointer',
+ className: '_User',
+ objectId: parseUser.userId.objectId,
+ };
+ const query = new Parse.Query('contracts_Users');
+ query.equalTo('UserId', userPtr);
+ const user = await query.first({ useMasterKey: true });
+ if (user) {
+ const extUser = JSON.parse(JSON.stringify(user));
+ const isUrlExist = extUser?.Webhook && extUser?.Webhook === Url;
+
+ if (!isUrlExist) {
+ try {
+ const updateQuery = new Parse.Object('contracts_Users');
+ updateQuery.id = user.id;
+ updateQuery.set('Webhook', Url);
+ const res = await updateQuery.save(null, { useMasterKey: true });
+ if (res) {
+ if (request.posthog) {
+ request.posthog?.capture({
+ distinctId: parseUser.userId.email,
+ event: 'api_save_webhook',
+ properties: { response_code: 200 },
+ });
+ }
+ return response.json({
+ result: 'Webhook updated successfully!',
+ });
+ }
+ } catch (err) {
+ if (request.posthog) {
+ request.posthog?.capture({
+ distinctId: parseUser.userId.email,
+ event: 'api_save_webhook',
+ properties: { response_code: 400 },
+ });
+ }
+ console.log('Err ', err);
+ return response
+ .status(400)
+ .json({ error: 'Something went wrong, please try again later!' });
+ }
+ } else {
+ if (request.posthog) {
+ request.posthog?.capture({
+ distinctId: parseUser.userId.email,
+ event: 'api_save_webhook',
+ properties: { response_code: 401 },
+ });
+ }
+ return response.status(401).json({ error: 'Webhook url already exists!' });
+ }
+ } else {
+ if (request.posthog) {
+ request.posthog?.capture({
+ distinctId: parseUser.userId.email,
+ event: 'api_save_webhook',
+ properties: { response_code: 404 },
+ });
+ }
+ return response.status(404).json({ error: 'User not found!' });
+ }
+ } else {
+ return response.status(405).json({ error: 'Invalid API Token!' });
+ }
+ } catch (err) {
+ console.log('Err ', err);
+ return response.status(400).json({ error: 'Something went wrong, please try again later!' });
+ }
+}
diff --git a/apps/OpenSignServer/cloud/customRoute/v1/routes/updateDocument.js b/apps/OpenSignServer/cloud/customRoute/v1/routes/updateDocument.js
new file mode 100644
index 000000000..4e5246f0a
--- /dev/null
+++ b/apps/OpenSignServer/cloud/customRoute/v1/routes/updateDocument.js
@@ -0,0 +1,93 @@
+export default async function updateDocument(request, response) {
+ 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);
+ tokenQuery.include('userId');
+ const token = await tokenQuery.first({ useMasterKey: true });
+ if (token !== undefined) {
+ // Valid Token then proceed request
+ const allowedKeys = ['name', 'note', 'description', 'folderId'];
+ const objectKeys = Object.keys(request.body);
+ const isValid = objectKeys.every(key => allowedKeys.includes(key)) && objectKeys.length > 0;
+ const parseUser = JSON.parse(JSON.stringify(token));
+ const userPtr = {
+ __type: 'Pointer',
+ className: '_User',
+ objectId: parseUser.userId.objectId,
+ };
+ if (isValid) {
+ const document = new Parse.Query('contracts_Document');
+ document.equalTo('objectId', request.params.document_id);
+ document.equalTo('CreatedBy', userPtr);
+ const res = await document.first({ useMasterKey: true });
+ if (res) {
+ const isArchive = res.get('IsArchive');
+ if (isArchive && isArchive) {
+ return response.status(404).json({ message: 'Document not found!' });
+ } else {
+ const document = Parse.Object.extend('contracts_Document');
+ const updateQuery = new document();
+ updateQuery.id = request.params.document_id;
+ if (request?.body?.name) {
+ updateQuery.set('Name', request?.body?.name);
+ }
+ if (request?.body?.note) {
+ updateQuery.set('Note', request?.body?.note);
+ }
+ if (request?.body?.description) {
+ updateQuery.set('Description', request?.body?.description);
+ }
+ if (request?.body?.folderId) {
+ updateQuery.set('Folder', {
+ __type: 'Pointer',
+ className: 'contracts_Document',
+ objectId: request?.body?.folderId,
+ });
+ }
+ const updatedRes = await updateQuery.save(null, { useMasterKey: true });
+ if (updatedRes) {
+ if (request.posthog) {
+ request.posthog?.capture({
+ distinctId: parseUser.userId.email,
+ event: 'api_update_document',
+ properties: { response_code: 200 },
+ });
+ }
+ return response.json({
+ objectId: updatedRes.id,
+ updatedAt: updatedRes.get('updatedAt'),
+ });
+ }
+ }
+ } else {
+ if (request.posthog) {
+ request.posthog?.capture({
+ distinctId: parseUser.userId.email,
+ event: 'api_update_document',
+ properties: { response_code: 404 },
+ });
+ }
+ return response.status(404).json({ error: 'Document not found!' });
+ }
+ } else {
+ if (request.posthog) {
+ request.posthog?.capture({
+ distinctId: parseUser.userId.email,
+ event: 'api_update_document',
+ properties: { response_code: 400 },
+ });
+ }
+ return response.status(400).json({ error: 'Please provide valid field names!' });
+ }
+ } else {
+ return response.status(405).json({ error: 'Invalid API Token!' });
+ }
+ } catch (err) {
+ console.log('err ', err);
+ return response.status(400).json({ error: 'Something went wrong, please try again later!' });
+ }
+}
diff --git a/apps/OpenSignServer/cloud/customRoute/v1/routes/updateTemplate.js b/apps/OpenSignServer/cloud/customRoute/v1/routes/updateTemplate.js
new file mode 100644
index 000000000..466721610
--- /dev/null
+++ b/apps/OpenSignServer/cloud/customRoute/v1/routes/updateTemplate.js
@@ -0,0 +1,93 @@
+export default async function updateTemplate(request, response) {
+ 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);
+ tokenQuery.include('userId');
+ const token = await tokenQuery.first({ useMasterKey: true });
+ if (token !== undefined) {
+ // Valid Token then proceed request
+ const allowedKeys = ['name', 'note', 'description', 'folderId'];
+ const objectKeys = Object.keys(request.body);
+ const isValid = objectKeys.every(key => allowedKeys.includes(key)) && objectKeys.length > 0;
+ const parseUser = JSON.parse(JSON.stringify(token));
+ const userPtr = {
+ __type: 'Pointer',
+ className: '_User',
+ objectId: parseUser.userId.objectId,
+ };
+ if (isValid) {
+ const template = new Parse.Query('contracts_Template');
+ template.equalTo('objectId', request.params.template_id);
+ template.equalTo('CreatedBy', userPtr);
+ const res = await template.first({ useMasterKey: true });
+ if (res) {
+ const isArchive = res.get('IsArchive');
+ if (isArchive && isArchive) {
+ return response.status(404).json({ message: 'Template not found!' });
+ } else {
+ const template = Parse.Object.extend('contracts_Template');
+ const updateQuery = new template();
+ updateQuery.id = request.params.template_id;
+ if (request?.body?.name) {
+ updateQuery.set('Name', request?.body?.name);
+ }
+ if (request?.body?.note) {
+ updateQuery.set('Note', request?.body?.note);
+ }
+ if (request?.body?.description) {
+ updateQuery.set('Description', request?.body?.description);
+ }
+ if (request?.body?.folderId) {
+ updateQuery.set('Folder', {
+ __type: 'Pointer',
+ className: 'contracts_Template',
+ objectId: request?.body?.folderId,
+ });
+ }
+ const updatedRes = await updateQuery.save(null, { useMasterKey: true });
+ if (updatedRes) {
+ if (request.posthog) {
+ request.posthog?.capture({
+ distinctId: parseUser.userId.email,
+ event: 'api_update_template',
+ properties: { response_code: 200 },
+ });
+ }
+ return response.json({
+ objectId: updatedRes.id,
+ updatedAt: updatedRes.get('updatedAt'),
+ });
+ }
+ }
+ } else {
+ if (request.posthog) {
+ request.posthog?.capture({
+ distinctId: parseUser.userId.email,
+ event: 'api_update_template',
+ properties: { response_code: 404 },
+ });
+ }
+ return response.status(404).json({ error: 'Template not found!' });
+ }
+ } else {
+ if (request.posthog) {
+ request.posthog?.capture({
+ distinctId: parseUser.userId.email,
+ event: 'api_update_template',
+ properties: { response_code: 400 },
+ });
+ }
+ return response.status(400).json({ error: 'Please provide valid field names!' });
+ }
+ } else {
+ return response.status(405).json({ error: 'Invalid API Token!' });
+ }
+ } catch (err) {
+ console.log('err ', err);
+ return response.status(400).json({ error: 'Something went wrong, please try again later!' });
+ }
+}
diff --git a/apps/OpenSignServer/cloud/main.js b/apps/OpenSignServer/cloud/main.js
index 7532bc00d..d0838e72f 100644
--- a/apps/OpenSignServer/cloud/main.js
+++ b/apps/OpenSignServer/cloud/main.js
@@ -17,8 +17,12 @@ import getUserDetails from './parsefunction/getUserDetails.js';
import getDocument from './parsefunction/getDocument.js';
import getDrive from './parsefunction/getDrive.js';
import getReport from './parsefunction/getReport.js';
+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';
+import callWebhook from './parsefunction/callWebhook.js';
Parse.Cloud.define('AddUserToRole', addUserToGroups);
Parse.Cloud.define('UserGroups', getUserGroups);
@@ -34,10 +38,14 @@ Parse.Cloud.define('AuthLoginAsMail', AuthLoginAsMail);
Parse.Cloud.define('getUserId', getUserId);
Parse.Cloud.define('getUserDetails', getUserDetails);
Parse.Cloud.define('getDocument', getDocument);
-Parse.Cloud.define('getDrive', getDrive)
-Parse.Cloud.define('getReport', getReport)
-Parse.Cloud.define("getTemplate", GetTemplate)
+Parse.Cloud.define('getDrive', getDrive);
+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.define('callwebhook', callWebhook);
Parse.Cloud.afterSave('contracts_Document', DocumentAftersave);
Parse.Cloud.afterSave('contracts_Contactbook', ContactbookAftersave);
Parse.Cloud.afterSave('contracts_Users', ContractUsersAftersave);
-Parse.Cloud.afterSave("contracts_Template", TemplateAfterSave)
\ No newline at end of file
+Parse.Cloud.afterSave('contracts_Template', TemplateAfterSave);
diff --git a/apps/OpenSignServer/cloud/parsefunction/ContactBookAftersave.js b/apps/OpenSignServer/cloud/parsefunction/ContactBookAftersave.js
index 644a2a763..fa476e60f 100644
--- a/apps/OpenSignServer/cloud/parsefunction/ContactBookAftersave.js
+++ b/apps/OpenSignServer/cloud/parsefunction/ContactBookAftersave.js
@@ -3,13 +3,13 @@ async function ContactbookAftersave(request) {
you can check as follows */
if (!request.original) {
const user = request.user;
- const object = request.object;
-
+
// Retrieve the current ACL
const acl = new Parse.ACL();
-
+
// Ensure the current user has read access
- if (acl) {
+ if (acl && request?.user) {
+ const object = request.object;
acl.setReadAccess(user, true);
acl.setWriteAccess(user, true);
acl.setReadAccess(object.get('UserId'), true);
diff --git a/apps/OpenSignServer/cloud/parsefunction/DocumentAftersave.js b/apps/OpenSignServer/cloud/parsefunction/DocumentAftersave.js
index 3fd3ad125..dc26a3e09 100644
--- a/apps/OpenSignServer/cloud/parsefunction/DocumentAftersave.js
+++ b/apps/OpenSignServer/cloud/parsefunction/DocumentAftersave.js
@@ -4,20 +4,11 @@ async function DocumentAftersave(request) {
console.log('new entry is insert in contracts_Document');
const createdAt = request.object.get('createdAt');
const Folder = request.object.get('Type');
- // console.log("createdAt")
- // console.log(createdAt)
- // console.log("Folder")
- // console.log(Folder)
- // console.log("before If condition")
if (createdAt && Folder === undefined) {
// console.log("IN If condition")
const TimeToCompleteDays = request.object.get('TimeToCompleteDays');
const ExpiryDate = new Date(createdAt);
- // console.log("ExpiryDate")
- // console.log(ExpiryDate)
ExpiryDate.setDate(ExpiryDate.getDate() + TimeToCompleteDays);
- // console.log("ExpiryDate date after update")
- // console.log(ExpiryDate)
const documentQuery = new Parse.Query('contracts_Document');
const updateQuery = await documentQuery.get(request.object.id, { useMasterKey: true });
updateQuery.set('ExpiryDate', ExpiryDate);
@@ -37,21 +28,23 @@ async function DocumentAftersave(request) {
}
const signers = request.object.get('Signers');
- // console.log("Signers")
- // console.log(signers.length)
// update acl of New Document If There are signers present in array
if (signers && signers.length > 0) {
await updateAclDoc(request.object.id);
} else {
- await updateSelfDoc(request.object.id);
+ if (request?.object?.id && request.user) {
+ await updateSelfDoc(request.object.id);
+ }
}
} else {
- if (request.user) {
+ if (request?.user) {
const signers = request.object.get('Signers');
if (signers && signers.length > 0) {
await updateAclDoc(request.object.id);
} else {
- await updateSelfDoc(request.object.id);
+ if (request?.object?.id) {
+ await updateSelfDoc(request.object.id);
+ }
}
}
}
@@ -65,6 +58,7 @@ async function DocumentAftersave(request) {
// console.log(objId)
const Query = new Parse.Query('contracts_Document');
Query.include('Signers');
+ Query.include('CreatedBy');
const updateACL = await Query.get(objId, { useMasterKey: true });
const res = JSON.parse(JSON.stringify(updateACL));
// console.log("res");
@@ -87,9 +81,10 @@ async function DocumentAftersave(request) {
const newACL = new Parse.ACL();
newACL.setPublicReadAccess(false);
newACL.setPublicWriteAccess(false);
- newACL.setReadAccess(request.user, true);
- newACL.setWriteAccess(request.user, true);
-
+ if (res?.CreatedBy) {
+ newACL.setReadAccess(res?.CreatedBy?.objectId, true);
+ newACL.setWriteAccess(res?.CreatedBy?.objectId, true);
+ }
UsersPtr.forEach(x => {
newACL.setReadAccess(x.objectId, true);
newACL.setWriteAccess(x.objectId, true);
@@ -100,9 +95,9 @@ async function DocumentAftersave(request) {
}
async function updateSelfDoc(objId) {
- // console.log("In side updateSelfDoc func")
// console.log(objId)
const Query = new Parse.Query('contracts_Document');
+ Query.include('CreatedBy');
const updateACL = await Query.get(objId, { useMasterKey: true });
const res = JSON.parse(JSON.stringify(updateACL));
// console.log("res");
@@ -110,8 +105,10 @@ async function DocumentAftersave(request) {
const newACL = new Parse.ACL();
newACL.setPublicReadAccess(false);
newACL.setPublicWriteAccess(false);
- newACL.setReadAccess(request.user, true);
- newACL.setWriteAccess(request.user, true);
+ if (res?.CreatedBy) {
+ newACL.setReadAccess(res?.CreatedBy?.objectId, true);
+ newACL.setWriteAccess(res?.CreatedBy?.objectId, true);
+ }
updateACL.setACL(newACL);
updateACL.save(null, { useMasterKey: true });
}
diff --git a/apps/OpenSignServer/cloud/parsefunction/TemplateAfterSave.js b/apps/OpenSignServer/cloud/parsefunction/TemplateAfterSave.js
index 7d22ccb86..a1d8e7417 100644
--- a/apps/OpenSignServer/cloud/parsefunction/TemplateAfterSave.js
+++ b/apps/OpenSignServer/cloud/parsefunction/TemplateAfterSave.js
@@ -8,15 +8,19 @@ export default async function TemplateAfterSave(request) {
if (signers && signers.length > 0) {
await updateAclDoc(request.object.id);
} else {
- await updateSelfDoc(request.object.id);
+ if (request?.object?.id && request?.user) {
+ await updateSelfDoc(request.object.id);
+ }
}
} else {
- if (request.user) {
+ if (request?.user) {
const signers = request.object.get('Signers');
if (signers && signers.length > 0) {
await updateAclDoc(request.object.id);
} else {
- await updateSelfDoc(request.object.id);
+ if (request?.object?.id) {
+ await updateSelfDoc(request.object.id);
+ }
}
}
}
@@ -30,6 +34,7 @@ export default async function TemplateAfterSave(request) {
// console.log(objId)
const Query = new Parse.Query('contracts_Template');
Query.include('Signers');
+ Query.include('CreatedBy');
const updateACL = await Query.get(objId, { useMasterKey: true });
const res = JSON.parse(JSON.stringify(updateACL));
// console.log("res");
@@ -52,8 +57,10 @@ export default async function TemplateAfterSave(request) {
const newACL = new Parse.ACL();
newACL.setPublicReadAccess(false);
newACL.setPublicWriteAccess(false);
- newACL.setReadAccess(request.user, true);
- newACL.setWriteAccess(request.user, true);
+ if (res?.CreatedBy) {
+ newACL.setReadAccess(res?.CreatedBy?.objectId, true);
+ newACL.setWriteAccess(res?.CreatedBy?.objectId, true);
+ }
UsersPtr.forEach(x => {
newACL.setReadAccess(x.objectId, true);
@@ -66,17 +73,20 @@ export default async function TemplateAfterSave(request) {
async function updateSelfDoc(objId) {
// console.log("Inside updateSelfDoc func")
-
+
const Query = new Parse.Query('contracts_Template');
+ Query.include('CreatedBy');
const updateACL = await Query.get(objId, { useMasterKey: true });
- // const res = JSON.parse(JSON.stringify(updateACL));
+ const res = JSON.parse(JSON.stringify(updateACL));
// console.log("res");
// console.log(JSON.stringify(res));
const newACL = new Parse.ACL();
newACL.setPublicReadAccess(false);
newACL.setPublicWriteAccess(false);
- newACL.setReadAccess(request.user, true);
- newACL.setWriteAccess(request.user, true);
+ if (res?.CreatedBy) {
+ newACL.setReadAccess(res?.CreatedBy?.objectId, true);
+ newACL.setWriteAccess(res?.CreatedBy?.objectId, true);
+ }
updateACL.setACL(newACL);
updateACL.save(null, { useMasterKey: true });
}
diff --git a/apps/OpenSignServer/cloud/parsefunction/callWebhook.js b/apps/OpenSignServer/cloud/parsefunction/callWebhook.js
new file mode 100644
index 000000000..7e2fa4056
--- /dev/null
+++ b/apps/OpenSignServer/cloud/parsefunction/callWebhook.js
@@ -0,0 +1,66 @@
+import axios from 'axios';
+export default async function callWebhook(request) {
+ const event = request.params.event;
+ const body = request.params.body;
+ const serverUrl = process.env.SERVER_URL;
+ const appId = process.env.APP_ID;
+ const userRes = await axios.get(serverUrl + '/users/me', {
+ headers: {
+ 'X-Parse-Application-Id': appId,
+ 'X-Parse-Session-Token': request.headers['sessiontoken'],
+ },
+ });
+
+ const userId = userRes.data && userRes.data.objectId;
+ if (userId) {
+ const extendcls = new Parse.Query('contracts_Users');
+ extendcls.equalTo('UserId', { __type: 'Pointer', className: '_User', objectId: userId });
+ const res = await extendcls.first({ useMasterKey: true });
+ if (res) {
+ const extUser = JSON.parse(JSON.stringify(res));
+ if (extUser?.Webhook) {
+ const params = {
+ event: event,
+ ...body,
+ };
+ await axios
+ .post(extUser?.Webhook, params, {
+ headers: { 'Content-Type': 'application/json' },
+ })
+ .then(res => {
+ try {
+ // console.log('res ', res);
+ const webhook = new Parse.Object('contracts_Webhook');
+ webhook.set('Log', res?.status);
+ webhook.set('UserId', {
+ __type: 'Pointer',
+ className: '_User',
+ objectId: userId,
+ });
+ webhook.save(null, { useMasterKey: true });
+ } catch (err) {
+ console.log('err save in contracts_Webhook', err);
+ }
+ })
+ .catch(err => {
+ console.log('Err send data to webhook', err);
+ try {
+ const webhook = new Parse.Object('contracts_Webhook');
+ webhook.set('Log', err?.status);
+ webhook.set('UserId', {
+ __type: 'Pointer',
+ className: '_User',
+ objectId: userId,
+ });
+ webhook.save(null, { useMasterKey: true });
+ } catch (err) {
+ console.log('err save in contracts_Webhook', err);
+ }
+ });
+ }
+ return { message: 'webhook called!' };
+ }
+ } else {
+ return { message: 'User not found!' };
+ }
+}
diff --git a/apps/OpenSignServer/cloud/parsefunction/generateApiToken.js b/apps/OpenSignServer/cloud/parsefunction/generateApiToken.js
new file mode 100644
index 000000000..8f39ccfdb
--- /dev/null
+++ b/apps/OpenSignServer/cloud/parsefunction/generateApiToken.js
@@ -0,0 +1,44 @@
+import { generateApiKey } from 'generate-api-key';
+import axios from 'axios';
+export default async function generateApiToken(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;
+ if (userId) {
+ const tokenQuery = new Parse.Query('appToken');
+ tokenQuery.equalTo('userId', { __type: 'Pointer', className: '_User', objectId: userId });
+ const token = await tokenQuery.first({ useMasterKey: true });
+ if (token !== undefined) {
+ // return exsiting Token
+ console.log('Regenerate API Token');
+ const AppToken = Parse.Object.extend('appToken');
+ const updateToken = new AppToken();
+ updateToken.id = token.id;
+ const newToken = generateApiKey({ method: 'base62', prefix: 'opensign' });
+ updateToken.set('token', newToken);
+ const updatedRes = await updateToken.save(null, { useMasterKey: true });
+ return updatedRes;
+ } else {
+ // Create New Token
+ console.log('New API Token Generation');
+ const appToken = Parse.Object.extend('appToken');
+ const appTokenQuery = new appToken();
+ const token = generateApiKey({ method: 'base62', prefix: 'opensign' });
+ appTokenQuery.set('token', token);
+ appTokenQuery.set('userId', { __type: 'Pointer', className: '_User', objectId: userId });
+ const newRes = await appTokenQuery.save(null, { useMasterKey: true });
+ return newRes;
+ }
+ } else {
+ return 'User not found!';
+ }
+ } catch (err) {
+ console.log('err ', err);
+ }
+}
diff --git a/apps/OpenSignServer/cloud/parsefunction/getUserDetails.js b/apps/OpenSignServer/cloud/parsefunction/getUserDetails.js
index 2e50b25a8..671b91d9d 100644
--- a/apps/OpenSignServer/cloud/parsefunction/getUserDetails.js
+++ b/apps/OpenSignServer/cloud/parsefunction/getUserDetails.js
@@ -1,9 +1,13 @@
async function getUserDetails(request) {
try {
+ const userId = request.params.userId;
const userQuery = new Parse.Query('contracts_Users');
userQuery.equalTo('Email', request.params.email);
userQuery.include('TenantId');
- userQuery.include('UserId')
+ userQuery.include('UserId');
+ if (userId) {
+ userQuery.equalTo('CreatedBy', { __type: 'Pointer', className: '_User', objectId: userId });
+ }
const res = await userQuery.first({ useMasterKey: true });
return res;
} catch (err) {
diff --git a/apps/OpenSignServer/cloud/parsefunction/getapitoken.js b/apps/OpenSignServer/cloud/parsefunction/getapitoken.js
new file mode 100644
index 000000000..570679f57
--- /dev/null
+++ b/apps/OpenSignServer/cloud/parsefunction/getapitoken.js
@@ -0,0 +1,29 @@
+import axios from 'axios';
+export default async function getapitoken(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;
+ if (userId) {
+ const tokenQuery = new Parse.Query('appToken');
+ tokenQuery.equalTo('userId', { __type: 'Pointer', className: '_User', objectId: userId });
+ const res = await tokenQuery.first({ useMasterKey: true });
+ if (res) {
+ return { status: 'success', result: res.get('token') };
+ }
+ }
+ } catch (err) {
+ console.log('Err', err);
+ console.log('err', err);
+ if (err.code == 209) {
+ return { error: 'Invalid session token' };
+ } else {
+ return { error: "You don't have access!" };
+ }
+ }
+}
diff --git a/apps/OpenSignServer/cloud/parsefunction/pdf/PDF.min.js b/apps/OpenSignServer/cloud/parsefunction/pdf/PDF.min.js
index b6f989cb7..85d56af52 100644
--- a/apps/OpenSignServer/cloud/parsefunction/pdf/PDF.min.js
+++ b/apps/OpenSignServer/cloud/parsefunction/pdf/PDF.min.js
@@ -1,22 +1,18 @@
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,
masterKEY = process.env.MASTER_KEY;
-async function uploadFile(a) {
+async function uploadFile(e, a) {
try {
- var e = new FormData(),
- t =
- (e.append('file', fs.createReadStream(a)),
- { 'content-type': 'multipart/form-data', 'X-Parse-Application-Id': process.env.APP_ID }),
- s = process.env.SERVER_URL.slice(0, -4) + '/file_upload';
- return (await axios.post(s, e, { headers: t })).data;
+ var t = fs.readFileSync(a),
+ s = new Parse.File(e, [...t]),
+ r = (await s.save({ useMasterKey: !0 }), s.url());
+ return { imageUrl: r };
} catch (e) {
- console.log('err ', e), fs.unlinkSync(a);
+ console.log('Err ', e), fs.unlinkSync(a);
}
}
async function updateDoc(t, s, r, i, n, o) {
@@ -33,8 +29,8 @@ async function updateDoc(t, s, r, i, n, o) {
);
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, {
+ 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,
@@ -59,9 +55,9 @@ async function sendMail(e) {
html:
"
A copy of the document " +
s +
- ' Standard is attached to this email. Kindly download the document from the attachment.
This is an automated email from Open Sign. For any queries regarding this email, please contact the sender ' +
+ ' Standard is attached to this email. Kindly download the document from the attachment.
This is an automated email from OpenSignâ˘. 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 here .
'
+ ' directly. If you think this email is inappropriate or spam, you may file a complaint with OpenSignâ˘
here .