Merged in feature/IO-2433-esignature (pull request #3133)
Feature/IO-2433 esignature
This commit is contained in:
11
client/package-lock.json
generated
11
client/package-lock.json
generated
@@ -16,6 +16,7 @@
|
|||||||
"@dnd-kit/modifiers": "^9.0.0",
|
"@dnd-kit/modifiers": "^9.0.0",
|
||||||
"@dnd-kit/sortable": "^10.0.0",
|
"@dnd-kit/sortable": "^10.0.0",
|
||||||
"@dnd-kit/utilities": "^3.2.2",
|
"@dnd-kit/utilities": "^3.2.2",
|
||||||
|
"@documenso/embed-react": "^0.5.1",
|
||||||
"@emotion/is-prop-valid": "^1.4.0",
|
"@emotion/is-prop-valid": "^1.4.0",
|
||||||
"@fingerprintjs/fingerprintjs": "^5.0.1",
|
"@fingerprintjs/fingerprintjs": "^5.0.1",
|
||||||
"@firebase/analytics": "^0.10.19",
|
"@firebase/analytics": "^0.10.19",
|
||||||
@@ -2575,6 +2576,16 @@
|
|||||||
"react": ">=16.8.0"
|
"react": ">=16.8.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@documenso/embed-react": {
|
||||||
|
"version": "0.5.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@documenso/embed-react/-/embed-react-0.5.1.tgz",
|
||||||
|
"integrity": "sha512-PlkZ3vrdZVBTc0J3xfG2wtPVGmxCxWgpQ/SsdR2oBMdTwsR+rDbj9k+CeTv+M9Xi5tKbLr5Y78bS9Sb8K+ltTQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": "^18.0.0 || ^19.0.0",
|
||||||
|
"react-dom": "^18.0.0 || ^19.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@dotenvx/dotenvx": {
|
"node_modules/@dotenvx/dotenvx": {
|
||||||
"version": "1.52.0",
|
"version": "1.52.0",
|
||||||
"resolved": "https://registry.npmjs.org/@dotenvx/dotenvx/-/dotenvx-1.52.0.tgz",
|
"resolved": "https://registry.npmjs.org/@dotenvx/dotenvx/-/dotenvx-1.52.0.tgz",
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
"@dnd-kit/modifiers": "^9.0.0",
|
"@dnd-kit/modifiers": "^9.0.0",
|
||||||
"@dnd-kit/sortable": "^10.0.0",
|
"@dnd-kit/sortable": "^10.0.0",
|
||||||
"@dnd-kit/utilities": "^3.2.2",
|
"@dnd-kit/utilities": "^3.2.2",
|
||||||
|
"@documenso/embed-react": "^0.5.1",
|
||||||
"@emotion/is-prop-valid": "^1.4.0",
|
"@emotion/is-prop-valid": "^1.4.0",
|
||||||
"@fingerprintjs/fingerprintjs": "^5.0.1",
|
"@fingerprintjs/fingerprintjs": "^5.0.1",
|
||||||
"@firebase/analytics": "^0.10.19",
|
"@firebase/analytics": "^0.10.19",
|
||||||
|
|||||||
@@ -509,3 +509,10 @@
|
|||||||
pointer-events: none !important;
|
pointer-events: none !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.esignature-embed {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
border-width: 0;
|
||||||
|
}
|
||||||
@@ -0,0 +1,78 @@
|
|||||||
|
import { EmbedUpdateDocumentV1 } from "@documenso/embed-react";
|
||||||
|
import { Modal } from "antd";
|
||||||
|
import axios from "axios";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
import { connect } from "react-redux";
|
||||||
|
import { createStructuredSelector } from "reselect";
|
||||||
|
import { toggleModalVisible } from "../../redux/modals/modals.actions";
|
||||||
|
import { selectEsignature } from "../../redux/modals/modals.selectors";
|
||||||
|
import { selectBodyshop } from "../../redux/user/user.selectors";
|
||||||
|
|
||||||
|
const mapStateToProps = createStructuredSelector({
|
||||||
|
esignatureModal: selectEsignature,
|
||||||
|
bodyshop: selectBodyshop
|
||||||
|
});
|
||||||
|
|
||||||
|
const mapDispatchToProps = (dispatch) => ({
|
||||||
|
toggleModalVisible: () => dispatch(toggleModalVisible("esignature"))
|
||||||
|
});
|
||||||
|
|
||||||
|
export function EsignatureModalContainer({ esignatureModal, toggleModalVisible, bodyshop }) {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const { open, context } = esignatureModal;
|
||||||
|
const { token, envelopeId, documentId, jobid } = context;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Modal
|
||||||
|
open={open}
|
||||||
|
title={t("jobs.labels.esignature")}
|
||||||
|
onOk={async () => {
|
||||||
|
try {
|
||||||
|
const distResult = await axios.post("/esign/distribute", {
|
||||||
|
documentId,
|
||||||
|
envelopeId,
|
||||||
|
jobid,
|
||||||
|
bodyshopid: bodyshop.id
|
||||||
|
});
|
||||||
|
console.log("Distribution result:", distResult);
|
||||||
|
toggleModalVisible();
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error distributing document:", error);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
onCancel={async () => {
|
||||||
|
try {
|
||||||
|
const cancelResult = await axios.post("/esign/delete", {
|
||||||
|
documentId,
|
||||||
|
envelopeId
|
||||||
|
});
|
||||||
|
console.log("Cancel result:", cancelResult);
|
||||||
|
toggleModalVisible();
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error cancelling document:", error);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
okButtonProps={{ title: "Distribute by Email" }}
|
||||||
|
width="90%"
|
||||||
|
destroyOnHidden
|
||||||
|
>
|
||||||
|
<div style={{ height: "600px", width: "100%" }}>
|
||||||
|
{token ? (
|
||||||
|
<EmbedUpdateDocumentV1
|
||||||
|
presignToken={token}
|
||||||
|
host="https://stg-app.documenso.com"
|
||||||
|
documentId={documentId}
|
||||||
|
className="esignature-embed"
|
||||||
|
onDocumentUpdated={(data) => {
|
||||||
|
console.log("Document updated:", data.documentId);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<div>No token...</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default connect(mapStateToProps, mapDispatchToProps)(EsignatureModalContainer);
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import { MailOutlined, PrinterOutlined } from "@ant-design/icons";
|
import { MailOutlined, PrinterOutlined, SignatureFilled } from "@ant-design/icons";
|
||||||
import { Space, Spin } from "antd";
|
import { Space, Spin } from "antd";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
@@ -10,6 +10,8 @@ import { GenerateDocument } from "../../utils/RenderTemplate";
|
|||||||
import LockWrapperComponent from "../lock-wrapper/lock-wrapper.component";
|
import LockWrapperComponent from "../lock-wrapper/lock-wrapper.component";
|
||||||
import { HasFeatureAccess } from "./../feature-wrapper/feature-wrapper.component";
|
import { HasFeatureAccess } from "./../feature-wrapper/feature-wrapper.component";
|
||||||
import { useNotification } from "../../contexts/Notifications/notificationContext.jsx";
|
import { useNotification } from "../../contexts/Notifications/notificationContext.jsx";
|
||||||
|
import axios from "axios";
|
||||||
|
import { setModalContext } from "../../redux/modals/modals.actions.js";
|
||||||
|
|
||||||
const mapStateToProps = createStructuredSelector({
|
const mapStateToProps = createStructuredSelector({
|
||||||
printCenterModal: selectPrintCenter,
|
printCenterModal: selectPrintCenter,
|
||||||
@@ -17,9 +19,25 @@ const mapStateToProps = createStructuredSelector({
|
|||||||
technician: selectTechnician
|
technician: selectTechnician
|
||||||
});
|
});
|
||||||
|
|
||||||
const mapDispatchToProps = () => ({});
|
const mapDispatchToProps = (dispatch) => ({
|
||||||
|
setEsignatureContext: (context) =>
|
||||||
|
dispatch(
|
||||||
|
setModalContext({
|
||||||
|
context: context,
|
||||||
|
modal: "esignature"
|
||||||
|
})
|
||||||
|
)
|
||||||
|
});
|
||||||
|
|
||||||
export function PrintCenterItemComponent({ printCenterModal, item, id, bodyshop, disabled, technician }) {
|
export function PrintCenterItemComponent({
|
||||||
|
printCenterModal,
|
||||||
|
setEsignatureContext,
|
||||||
|
item,
|
||||||
|
id,
|
||||||
|
bodyshop,
|
||||||
|
disabled,
|
||||||
|
technician
|
||||||
|
}) {
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
const { context } = printCenterModal;
|
const { context } = printCenterModal;
|
||||||
const notification = useNotification();
|
const notification = useNotification();
|
||||||
@@ -39,6 +57,30 @@ export function PrintCenterItemComponent({ printCenterModal, item, id, bodyshop,
|
|||||||
setLoading(false);
|
setLoading(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const esignatureGenerate = async () => {
|
||||||
|
setLoading(true);
|
||||||
|
try {
|
||||||
|
const {
|
||||||
|
data: { token, documentId, evnelopeId }
|
||||||
|
} = await axios.post("/esign/new", {
|
||||||
|
name: item.key,
|
||||||
|
jobid: id,
|
||||||
|
context,
|
||||||
|
bodyshop,
|
||||||
|
templateObject: {
|
||||||
|
name: item.key,
|
||||||
|
variables: { id: id }
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
setEsignatureContext({ context: { token, documentId, evnelopeId, jobid: id } });
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
} finally {
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
if (
|
if (
|
||||||
disabled ||
|
disabled ||
|
||||||
(item.featureNameRestricted && !HasFeatureAccess({ featureName: item.featureNameRestricted, bodyshop }))
|
(item.featureNameRestricted && !HasFeatureAccess({ featureName: item.featureNameRestricted, bodyshop }))
|
||||||
@@ -54,6 +96,7 @@ export function PrintCenterItemComponent({ printCenterModal, item, id, bodyshop,
|
|||||||
<li>
|
<li>
|
||||||
<Space wrap>
|
<Space wrap>
|
||||||
{item.title}
|
{item.title}
|
||||||
|
<SignatureFilled onClick={esignatureGenerate} />
|
||||||
<PrinterOutlined onClick={renderToNewWindow} />
|
<PrinterOutlined onClick={renderToNewWindow} />
|
||||||
{!technician ? (
|
{!technician ? (
|
||||||
<MailOutlined
|
<MailOutlined
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ import InstanceRenderManager from "../../utils/instanceRenderMgr.js";
|
|||||||
import useAlertsNotifications from "../../hooks/useAlertsNotifications.jsx";
|
import useAlertsNotifications from "../../hooks/useAlertsNotifications.jsx";
|
||||||
import { selectDarkMode } from "../../redux/application/application.selectors.js";
|
import { selectDarkMode } from "../../redux/application/application.selectors.js";
|
||||||
import { lazyDev } from "../../utils/lazyWithPreload.jsx";
|
import { lazyDev } from "../../utils/lazyWithPreload.jsx";
|
||||||
|
import EsignatureModalContainer from "../../components/esignature-modal/esignature-modal.container.jsx";
|
||||||
|
|
||||||
const PrintCenterModalContainer = lazyDev(
|
const PrintCenterModalContainer = lazyDev(
|
||||||
() => import("../../components/print-center-modal/print-center-modal.container")
|
() => import("../../components/print-center-modal/print-center-modal.container")
|
||||||
@@ -68,7 +69,9 @@ const FeatureRequestPage = lazyDev(() => import("../feature-request/feature-requ
|
|||||||
const JobCostingModal = lazyDev(() => import("../../components/job-costing-modal/job-costing-modal.container"));
|
const JobCostingModal = lazyDev(() => import("../../components/job-costing-modal/job-costing-modal.container"));
|
||||||
const ReportCenterModal = lazyDev(() => import("../../components/report-center-modal/report-center-modal.container"));
|
const ReportCenterModal = lazyDev(() => import("../../components/report-center-modal/report-center-modal.container"));
|
||||||
const BillEnterModalContainer = lazyDev(() => import("../../components/bill-enter-modal/bill-enter-modal.container"));
|
const BillEnterModalContainer = lazyDev(() => import("../../components/bill-enter-modal/bill-enter-modal.container"));
|
||||||
const TimeTicketModalContainer = lazyDev(() => import("../../components/time-ticket-modal/time-ticket-modal.container"));
|
const TimeTicketModalContainer = lazyDev(
|
||||||
|
() => import("../../components/time-ticket-modal/time-ticket-modal.container")
|
||||||
|
);
|
||||||
const TimeTicketModalTask = lazyDev(
|
const TimeTicketModalTask = lazyDev(
|
||||||
() => import("../../components/time-ticket-task-modal/time-ticket-task-modal.container")
|
() => import("../../components/time-ticket-task-modal/time-ticket-task-modal.container")
|
||||||
);
|
);
|
||||||
@@ -110,7 +113,9 @@ const TtApprovals = lazyDev(() => import("../tt-approvals/tt-approvals.page.cont
|
|||||||
const MyTasksPage = lazyDev(() => import("../tasks/myTasksPageContainer.jsx"));
|
const MyTasksPage = lazyDev(() => import("../tasks/myTasksPageContainer.jsx"));
|
||||||
const AllTasksPage = lazyDev(() => import("../tasks/allTasksPageContainer.jsx"));
|
const AllTasksPage = lazyDev(() => import("../tasks/allTasksPageContainer.jsx"));
|
||||||
|
|
||||||
const TaskUpsertModalContainer = lazyDev(() => import("../../components/task-upsert-modal/task-upsert-modal.container"));
|
const TaskUpsertModalContainer = lazyDev(
|
||||||
|
() => import("../../components/task-upsert-modal/task-upsert-modal.container")
|
||||||
|
);
|
||||||
const { Content } = Layout;
|
const { Content } = Layout;
|
||||||
|
|
||||||
const mapStateToProps = createStructuredSelector({
|
const mapStateToProps = createStructuredSelector({
|
||||||
@@ -178,6 +183,7 @@ export function Manage({ conflict, bodyshop, partsManagementOnly, isDarkMode, cu
|
|||||||
<TaskUpsertModalContainer />
|
<TaskUpsertModalContainer />
|
||||||
<BreadCrumbs />
|
<BreadCrumbs />
|
||||||
<BillEnterModalContainer />
|
<BillEnterModalContainer />
|
||||||
|
<EsignatureModalContainer />
|
||||||
<JobCostingModal />
|
<JobCostingModal />
|
||||||
<ReportCenterModal />
|
<ReportCenterModal />
|
||||||
<EmailOverlayContainer />
|
<EmailOverlayContainer />
|
||||||
|
|||||||
@@ -27,7 +27,8 @@ const INITIAL_STATE = {
|
|||||||
contractFinder: { ...baseModal },
|
contractFinder: { ...baseModal },
|
||||||
inventoryUpsert: { ...baseModal },
|
inventoryUpsert: { ...baseModal },
|
||||||
ca_bc_eftTableConvert: { ...baseModal },
|
ca_bc_eftTableConvert: { ...baseModal },
|
||||||
cardPayment: { ...baseModal }
|
cardPayment: { ...baseModal },
|
||||||
|
esignature: { ...baseModal }
|
||||||
};
|
};
|
||||||
|
|
||||||
const modalsReducer = (state = INITIAL_STATE, action) => {
|
const modalsReducer = (state = INITIAL_STATE, action) => {
|
||||||
|
|||||||
@@ -36,3 +36,4 @@ export const selectInventoryUpsert = createSelector([selectModals], (modals) =>
|
|||||||
export const selectCaBcEtfTableConvert = createSelector([selectModals], (modals) => modals.ca_bc_eftTableConvert);
|
export const selectCaBcEtfTableConvert = createSelector([selectModals], (modals) => modals.ca_bc_eftTableConvert);
|
||||||
|
|
||||||
export const selectCardPayment = createSelector([selectModals], (modals) => modals.cardPayment);
|
export const selectCardPayment = createSelector([selectModals], (modals) => modals.cardPayment);
|
||||||
|
export const selectEsignature = createSelector([selectModals], (modals) => modals.esignature);
|
||||||
|
|||||||
@@ -2203,6 +2203,7 @@
|
|||||||
"duplicateconfirm": "Are you sure you want to duplicate this Job? Some elements of this Job will not be duplicated.",
|
"duplicateconfirm": "Are you sure you want to duplicate this Job? Some elements of this Job will not be duplicated.",
|
||||||
"emailaudit": "Email Audit Trail",
|
"emailaudit": "Email Audit Trail",
|
||||||
"employeeassignments": "Employee Assignments",
|
"employeeassignments": "Employee Assignments",
|
||||||
|
"esignature": "E-Signature",
|
||||||
"estimatelines": "Estimate Lines",
|
"estimatelines": "Estimate Lines",
|
||||||
"estimator": "Estimator",
|
"estimator": "Estimator",
|
||||||
"existing_jobs": "Existing Jobs",
|
"existing_jobs": "Existing Jobs",
|
||||||
|
|||||||
@@ -2203,6 +2203,7 @@
|
|||||||
"duplicateconfirm": "",
|
"duplicateconfirm": "",
|
||||||
"emailaudit": "",
|
"emailaudit": "",
|
||||||
"employeeassignments": "",
|
"employeeassignments": "",
|
||||||
|
"esignature": "",
|
||||||
"estimatelines": "",
|
"estimatelines": "",
|
||||||
"estimator": "",
|
"estimator": "",
|
||||||
"existing_jobs": "Empleos existentes",
|
"existing_jobs": "Empleos existentes",
|
||||||
|
|||||||
@@ -2203,6 +2203,7 @@
|
|||||||
"duplicateconfirm": "",
|
"duplicateconfirm": "",
|
||||||
"emailaudit": "",
|
"emailaudit": "",
|
||||||
"employeeassignments": "",
|
"employeeassignments": "",
|
||||||
|
"esignature": "",
|
||||||
"estimatelines": "",
|
"estimatelines": "",
|
||||||
"estimator": "",
|
"estimator": "",
|
||||||
"existing_jobs": "Emplois existants",
|
"existing_jobs": "Emplois existants",
|
||||||
|
|||||||
730
package-lock.json
generated
730
package-lock.json
generated
@@ -19,6 +19,8 @@
|
|||||||
"@aws-sdk/credential-provider-node": "^3.972.12",
|
"@aws-sdk/credential-provider-node": "^3.972.12",
|
||||||
"@aws-sdk/lib-storage": "^3.997.0",
|
"@aws-sdk/lib-storage": "^3.997.0",
|
||||||
"@aws-sdk/s3-request-presigner": "^3.997.0",
|
"@aws-sdk/s3-request-presigner": "^3.997.0",
|
||||||
|
"@documenso/sdk-typescript": "^0.8.0",
|
||||||
|
"@jsreport/nodejs-client": "^4.1.0",
|
||||||
"@opensearch-project/opensearch": "^2.13.0",
|
"@opensearch-project/opensearch": "^2.13.0",
|
||||||
"@socket.io/admin-ui": "^0.5.1",
|
"@socket.io/admin-ui": "^0.5.1",
|
||||||
"@socket.io/redis-adapter": "^8.3.0",
|
"@socket.io/redis-adapter": "^8.3.0",
|
||||||
@@ -1355,6 +1357,18 @@
|
|||||||
"kuler": "^2.0.0"
|
"kuler": "^2.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@documenso/sdk-typescript": {
|
||||||
|
"version": "0.8.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@documenso/sdk-typescript/-/sdk-typescript-0.8.0.tgz",
|
||||||
|
"integrity": "sha512-Emzd5j+v8tA8gxtL+M/svVuzSOKMZw3/U4bS8zRoagvQEqkt+XNU2JraPEAJzxTjf3ww6EnlURXydbglBmR7AQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"@modelcontextprotocol/sdk": "^1.26.0",
|
||||||
|
"zod": "^3.25.0 || ^4.0.0"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"mcp": "bin/mcp-server.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@esbuild/aix-ppc64": {
|
"node_modules/@esbuild/aix-ppc64": {
|
||||||
"version": "0.27.2",
|
"version": "0.27.2",
|
||||||
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.2.tgz",
|
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.2.tgz",
|
||||||
@@ -2223,6 +2237,18 @@
|
|||||||
"node": ">=6"
|
"node": ">=6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@hono/node-server": {
|
||||||
|
"version": "1.19.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-1.19.9.tgz",
|
||||||
|
"integrity": "sha512-vHL6w3ecZsky+8P5MD+eFfaGTyCeOHUIFYMGpQGbrBTSmNNoxv0if69rEZ5giu36weC5saFuznL411gRX7bJDw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18.14.1"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"hono": "^4"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@humanfs/core": {
|
"node_modules/@humanfs/core": {
|
||||||
"version": "0.19.1",
|
"version": "0.19.1",
|
||||||
"resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz",
|
"resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz",
|
||||||
@@ -2330,12 +2356,364 @@
|
|||||||
"url": "https://opencollective.com/js-sdsl"
|
"url": "https://opencollective.com/js-sdsl"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@jsreport/nodejs-client": {
|
||||||
|
"version": "4.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@jsreport/nodejs-client/-/nodejs-client-4.1.0.tgz",
|
||||||
|
"integrity": "sha512-QWupUQzMzxWFvY+AlSdUZGlinJv4cKhYmVE9rIe+he7rn4B24tezFmNdnrDcTSFv3hj4x7sTNqpeHT0fItfs5Q==",
|
||||||
|
"dependencies": {
|
||||||
|
"axios": "1.13.2",
|
||||||
|
"concat-stream": "2.0.0",
|
||||||
|
"mimic-response": "2.1.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=22.18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@jsreport/nodejs-client/node_modules/axios": {
|
||||||
|
"version": "1.13.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/axios/-/axios-1.13.2.tgz",
|
||||||
|
"integrity": "sha512-VPk9ebNqPcy5lRGuSlKx752IlDatOjT9paPlm8A7yOuW2Fbvp4X3JznJtT4f0GzGLLiWE9W8onz51SqLYwzGaA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"follow-redirects": "^1.15.6",
|
||||||
|
"form-data": "^4.0.4",
|
||||||
|
"proxy-from-env": "^1.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@kurkle/color": {
|
"node_modules/@kurkle/color": {
|
||||||
"version": "0.3.4",
|
"version": "0.3.4",
|
||||||
"resolved": "https://registry.npmjs.org/@kurkle/color/-/color-0.3.4.tgz",
|
"resolved": "https://registry.npmjs.org/@kurkle/color/-/color-0.3.4.tgz",
|
||||||
"integrity": "sha512-M5UknZPHRu3DEDWoipU6sE8PdkZ6Z/S+v4dD+Ke8IaNlpdSQah50lz1KtcFBa2vsdOnwbbnxJwVM4wty6udA5w==",
|
"integrity": "sha512-M5UknZPHRu3DEDWoipU6sE8PdkZ6Z/S+v4dD+Ke8IaNlpdSQah50lz1KtcFBa2vsdOnwbbnxJwVM4wty6udA5w==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/@modelcontextprotocol/sdk": {
|
||||||
|
"version": "1.27.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.27.1.tgz",
|
||||||
|
"integrity": "sha512-sr6GbP+4edBwFndLbM60gf07z0FQ79gaExpnsjMGePXqFcSSb7t6iscpjk9DhFhwd+mTEQrzNafGP8/iGGFYaA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@hono/node-server": "^1.19.9",
|
||||||
|
"ajv": "^8.17.1",
|
||||||
|
"ajv-formats": "^3.0.1",
|
||||||
|
"content-type": "^1.0.5",
|
||||||
|
"cors": "^2.8.5",
|
||||||
|
"cross-spawn": "^7.0.5",
|
||||||
|
"eventsource": "^3.0.2",
|
||||||
|
"eventsource-parser": "^3.0.0",
|
||||||
|
"express": "^5.2.1",
|
||||||
|
"express-rate-limit": "^8.2.1",
|
||||||
|
"hono": "^4.11.4",
|
||||||
|
"jose": "^6.1.3",
|
||||||
|
"json-schema-typed": "^8.0.2",
|
||||||
|
"pkce-challenge": "^5.0.0",
|
||||||
|
"raw-body": "^3.0.0",
|
||||||
|
"zod": "^3.25 || ^4.0",
|
||||||
|
"zod-to-json-schema": "^3.25.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@cfworker/json-schema": "^4.1.1",
|
||||||
|
"zod": "^3.25 || ^4.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@cfworker/json-schema": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"zod": {
|
||||||
|
"optional": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@modelcontextprotocol/sdk/node_modules/accepts": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"mime-types": "^3.0.0",
|
||||||
|
"negotiator": "^1.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@modelcontextprotocol/sdk/node_modules/ajv": {
|
||||||
|
"version": "8.18.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz",
|
||||||
|
"integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"fast-deep-equal": "^3.1.3",
|
||||||
|
"fast-uri": "^3.0.1",
|
||||||
|
"json-schema-traverse": "^1.0.0",
|
||||||
|
"require-from-string": "^2.0.2"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/epoberezkin"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@modelcontextprotocol/sdk/node_modules/content-disposition": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-oIXISMynqSqm241k6kcQ5UwttDILMK4BiurCfGEREw6+X9jkkpEe5T9FZaApyLGGOnFuyMWZpdolTXMtvEJ08Q==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/express"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@modelcontextprotocol/sdk/node_modules/cookie-signature": {
|
||||||
|
"version": "1.2.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz",
|
||||||
|
"integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.6.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@modelcontextprotocol/sdk/node_modules/express": {
|
||||||
|
"version": "5.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/express/-/express-5.2.1.tgz",
|
||||||
|
"integrity": "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"accepts": "^2.0.0",
|
||||||
|
"body-parser": "^2.2.1",
|
||||||
|
"content-disposition": "^1.0.0",
|
||||||
|
"content-type": "^1.0.5",
|
||||||
|
"cookie": "^0.7.1",
|
||||||
|
"cookie-signature": "^1.2.1",
|
||||||
|
"debug": "^4.4.0",
|
||||||
|
"depd": "^2.0.0",
|
||||||
|
"encodeurl": "^2.0.0",
|
||||||
|
"escape-html": "^1.0.3",
|
||||||
|
"etag": "^1.8.1",
|
||||||
|
"finalhandler": "^2.1.0",
|
||||||
|
"fresh": "^2.0.0",
|
||||||
|
"http-errors": "^2.0.0",
|
||||||
|
"merge-descriptors": "^2.0.0",
|
||||||
|
"mime-types": "^3.0.0",
|
||||||
|
"on-finished": "^2.4.1",
|
||||||
|
"once": "^1.4.0",
|
||||||
|
"parseurl": "^1.3.3",
|
||||||
|
"proxy-addr": "^2.0.7",
|
||||||
|
"qs": "^6.14.0",
|
||||||
|
"range-parser": "^1.2.1",
|
||||||
|
"router": "^2.2.0",
|
||||||
|
"send": "^1.1.0",
|
||||||
|
"serve-static": "^2.2.0",
|
||||||
|
"statuses": "^2.0.1",
|
||||||
|
"type-is": "^2.0.1",
|
||||||
|
"vary": "^1.1.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 18"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/express"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@modelcontextprotocol/sdk/node_modules/finalhandler": {
|
||||||
|
"version": "2.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.1.tgz",
|
||||||
|
"integrity": "sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"debug": "^4.4.0",
|
||||||
|
"encodeurl": "^2.0.0",
|
||||||
|
"escape-html": "^1.0.3",
|
||||||
|
"on-finished": "^2.4.1",
|
||||||
|
"parseurl": "^1.3.3",
|
||||||
|
"statuses": "^2.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 18.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/express"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@modelcontextprotocol/sdk/node_modules/fresh": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@modelcontextprotocol/sdk/node_modules/http-errors": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"depd": "~2.0.0",
|
||||||
|
"inherits": "~2.0.4",
|
||||||
|
"setprototypeof": "~1.2.0",
|
||||||
|
"statuses": "~2.0.2",
|
||||||
|
"toidentifier": "~1.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/express"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@modelcontextprotocol/sdk/node_modules/jose": {
|
||||||
|
"version": "6.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/jose/-/jose-6.1.3.tgz",
|
||||||
|
"integrity": "sha512-0TpaTfihd4QMNwrz/ob2Bp7X04yuxJkjRGi4aKmOqwhov54i6u79oCv7T+C7lo70MKH6BesI3vscD1yb/yzKXQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/panva"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@modelcontextprotocol/sdk/node_modules/json-schema-traverse": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/@modelcontextprotocol/sdk/node_modules/media-typer": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@modelcontextprotocol/sdk/node_modules/merge-descriptors": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@modelcontextprotocol/sdk/node_modules/mime-types": {
|
||||||
|
"version": "3.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz",
|
||||||
|
"integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"mime-db": "^1.54.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/express"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@modelcontextprotocol/sdk/node_modules/negotiator": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@modelcontextprotocol/sdk/node_modules/qs": {
|
||||||
|
"version": "6.15.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/qs/-/qs-6.15.0.tgz",
|
||||||
|
"integrity": "sha512-mAZTtNCeetKMH+pSjrb76NAM8V9a05I9aBZOHztWy/UqcJdQYNsf59vrRKWnojAT9Y+GbIvoTBC++CPHqpDBhQ==",
|
||||||
|
"license": "BSD-3-Clause",
|
||||||
|
"dependencies": {
|
||||||
|
"side-channel": "^1.1.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.6"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@modelcontextprotocol/sdk/node_modules/send": {
|
||||||
|
"version": "1.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/send/-/send-1.2.1.tgz",
|
||||||
|
"integrity": "sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"debug": "^4.4.3",
|
||||||
|
"encodeurl": "^2.0.0",
|
||||||
|
"escape-html": "^1.0.3",
|
||||||
|
"etag": "^1.8.1",
|
||||||
|
"fresh": "^2.0.0",
|
||||||
|
"http-errors": "^2.0.1",
|
||||||
|
"mime-types": "^3.0.2",
|
||||||
|
"ms": "^2.1.3",
|
||||||
|
"on-finished": "^2.4.1",
|
||||||
|
"range-parser": "^1.2.1",
|
||||||
|
"statuses": "^2.0.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 18"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/express"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@modelcontextprotocol/sdk/node_modules/serve-static": {
|
||||||
|
"version": "2.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.1.tgz",
|
||||||
|
"integrity": "sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"encodeurl": "^2.0.0",
|
||||||
|
"escape-html": "^1.0.3",
|
||||||
|
"parseurl": "^1.3.3",
|
||||||
|
"send": "^1.2.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 18"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/express"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@modelcontextprotocol/sdk/node_modules/statuses": {
|
||||||
|
"version": "2.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz",
|
||||||
|
"integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@modelcontextprotocol/sdk/node_modules/type-is": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"content-type": "^1.0.5",
|
||||||
|
"media-typer": "^1.1.0",
|
||||||
|
"mime-types": "^3.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@msgpackr-extract/msgpackr-extract-darwin-arm64": {
|
"node_modules/@msgpackr-extract/msgpackr-extract-darwin-arm64": {
|
||||||
"version": "3.0.3",
|
"version": "3.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-arm64/-/msgpackr-extract-darwin-arm64-3.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-arm64/-/msgpackr-extract-darwin-arm64-3.0.3.tgz",
|
||||||
@@ -4222,6 +4600,45 @@
|
|||||||
"url": "https://github.com/sponsors/epoberezkin"
|
"url": "https://github.com/sponsors/epoberezkin"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/ajv-formats": {
|
||||||
|
"version": "3.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz",
|
||||||
|
"integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"ajv": "^8.0.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"ajv": "^8.0.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"ajv": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/ajv-formats/node_modules/ajv": {
|
||||||
|
"version": "8.18.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz",
|
||||||
|
"integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"fast-deep-equal": "^3.1.3",
|
||||||
|
"fast-uri": "^3.0.1",
|
||||||
|
"json-schema-traverse": "^1.0.0",
|
||||||
|
"require-from-string": "^2.0.2"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/epoberezkin"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/ajv-formats/node_modules/json-schema-traverse": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/ansi-colors": {
|
"node_modules/ansi-colors": {
|
||||||
"version": "4.1.3",
|
"version": "4.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz",
|
||||||
@@ -4680,6 +5097,100 @@
|
|||||||
"node": "*"
|
"node": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/body-parser": {
|
||||||
|
"version": "2.2.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.2.tgz",
|
||||||
|
"integrity": "sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"bytes": "^3.1.2",
|
||||||
|
"content-type": "^1.0.5",
|
||||||
|
"debug": "^4.4.3",
|
||||||
|
"http-errors": "^2.0.0",
|
||||||
|
"iconv-lite": "^0.7.0",
|
||||||
|
"on-finished": "^2.4.1",
|
||||||
|
"qs": "^6.14.1",
|
||||||
|
"raw-body": "^3.0.1",
|
||||||
|
"type-is": "^2.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/express"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/body-parser/node_modules/iconv-lite": {
|
||||||
|
"version": "0.7.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz",
|
||||||
|
"integrity": "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"safer-buffer": ">= 2.1.2 < 3.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/express"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/body-parser/node_modules/media-typer": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/body-parser/node_modules/mime-types": {
|
||||||
|
"version": "3.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz",
|
||||||
|
"integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"mime-db": "^1.54.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/express"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/body-parser/node_modules/qs": {
|
||||||
|
"version": "6.15.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/qs/-/qs-6.15.0.tgz",
|
||||||
|
"integrity": "sha512-mAZTtNCeetKMH+pSjrb76NAM8V9a05I9aBZOHztWy/UqcJdQYNsf59vrRKWnojAT9Y+GbIvoTBC++CPHqpDBhQ==",
|
||||||
|
"license": "BSD-3-Clause",
|
||||||
|
"dependencies": {
|
||||||
|
"side-channel": "^1.1.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.6"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/body-parser/node_modules/type-is": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"content-type": "^1.0.5",
|
||||||
|
"media-typer": "^1.1.0",
|
||||||
|
"mime-types": "^3.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/boolbase": {
|
"node_modules/boolbase": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
|
||||||
@@ -6393,6 +6904,27 @@
|
|||||||
"node": ">=0.8.x"
|
"node": ">=0.8.x"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/eventsource": {
|
||||||
|
"version": "3.0.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/eventsource/-/eventsource-3.0.7.tgz",
|
||||||
|
"integrity": "sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"eventsource-parser": "^3.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/eventsource-parser": {
|
||||||
|
"version": "3.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.0.6.tgz",
|
||||||
|
"integrity": "sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/expect-type": {
|
"node_modules/expect-type": {
|
||||||
"version": "1.3.0",
|
"version": "1.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.3.0.tgz",
|
||||||
@@ -6449,6 +6981,24 @@
|
|||||||
"url": "https://opencollective.com/express"
|
"url": "https://opencollective.com/express"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/express-rate-limit": {
|
||||||
|
"version": "8.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-8.2.1.tgz",
|
||||||
|
"integrity": "sha512-PCZEIEIxqwhzw4KF0n7QF4QqruVTcF73O5kFKUnGOyjbCCgizBBiFaYpd/fnBLUMPw/BWw9OsiN7GgrNYr7j6g==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"ip-address": "10.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 16"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/express-rate-limit"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"express": ">= 4.11"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/express/node_modules/body-parser": {
|
"node_modules/express/node_modules/body-parser": {
|
||||||
"version": "1.20.3",
|
"version": "1.20.3",
|
||||||
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz",
|
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz",
|
||||||
@@ -6571,6 +7121,22 @@
|
|||||||
"integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==",
|
"integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/fast-uri": {
|
||||||
|
"version": "3.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz",
|
||||||
|
"integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==",
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/fastify"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/fastify"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"license": "BSD-3-Clause"
|
||||||
|
},
|
||||||
"node_modules/fast-xml-builder": {
|
"node_modules/fast-xml-builder": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/fast-xml-builder/-/fast-xml-builder-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/fast-xml-builder/-/fast-xml-builder-1.0.0.tgz",
|
||||||
@@ -7336,6 +7902,15 @@
|
|||||||
"node": ">= 0.4"
|
"node": ">= 0.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/hono": {
|
||||||
|
"version": "4.12.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/hono/-/hono-4.12.3.tgz",
|
||||||
|
"integrity": "sha512-SFsVSjp8sj5UumXOOFlkZOG6XS9SJDKw0TbwFeV+AJ8xlST8kxK5Z/5EYa111UY8732lK2S/xB653ceuaoGwpg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=16.9.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/hpagent": {
|
"node_modules/hpagent": {
|
||||||
"version": "1.2.0",
|
"version": "1.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/hpagent/-/hpagent-1.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/hpagent/-/hpagent-1.2.0.tgz",
|
||||||
@@ -7594,6 +8169,15 @@
|
|||||||
"url": "https://opencollective.com/ioredis"
|
"url": "https://opencollective.com/ioredis"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/ip-address": {
|
||||||
|
"version": "10.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.0.1.tgz",
|
||||||
|
"integrity": "sha512-NWv9YLW4PoW2B7xtzaS3NCot75m6nK7Icdv0o3lfMceJVRfSoQwqD4wEH5rLwoKJwUiZ/rfpiVBhnaF0FK4HoA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 12"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/ipaddr.js": {
|
"node_modules/ipaddr.js": {
|
||||||
"version": "1.9.1",
|
"version": "1.9.1",
|
||||||
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
|
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
|
||||||
@@ -7835,6 +8419,12 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/is-promise": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/is-regex": {
|
"node_modules/is-regex": {
|
||||||
"version": "1.2.1",
|
"version": "1.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz",
|
||||||
@@ -8108,6 +8698,12 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/json-schema-typed": {
|
||||||
|
"version": "8.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/json-schema-typed/-/json-schema-typed-8.0.2.tgz",
|
||||||
|
"integrity": "sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==",
|
||||||
|
"license": "BSD-2-Clause"
|
||||||
|
},
|
||||||
"node_modules/json-stable-stringify-without-jsonify": {
|
"node_modules/json-stable-stringify-without-jsonify": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
|
||||||
@@ -8607,6 +9203,18 @@
|
|||||||
"node": ">= 0.6"
|
"node": ">= 0.6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/mimic-response": {
|
||||||
|
"version": "2.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz",
|
||||||
|
"integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/minimalistic-assert": {
|
"node_modules/minimalistic-assert": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz",
|
||||||
@@ -9344,6 +9952,15 @@
|
|||||||
"url": "https://github.com/sponsors/jonschlinkert"
|
"url": "https://github.com/sponsors/jonschlinkert"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/pkce-challenge": {
|
||||||
|
"version": "5.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/pkce-challenge/-/pkce-challenge-5.0.1.tgz",
|
||||||
|
"integrity": "sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=16.20.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/possible-typed-array-names": {
|
"node_modules/possible-typed-array-names": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz",
|
||||||
@@ -9576,6 +10193,66 @@
|
|||||||
"node": ">= 0.6"
|
"node": ">= 0.6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/raw-body": {
|
||||||
|
"version": "3.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.2.tgz",
|
||||||
|
"integrity": "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"bytes": "~3.1.2",
|
||||||
|
"http-errors": "~2.0.1",
|
||||||
|
"iconv-lite": "~0.7.0",
|
||||||
|
"unpipe": "~1.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/raw-body/node_modules/http-errors": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"depd": "~2.0.0",
|
||||||
|
"inherits": "~2.0.4",
|
||||||
|
"setprototypeof": "~1.2.0",
|
||||||
|
"statuses": "~2.0.2",
|
||||||
|
"toidentifier": "~1.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/express"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/raw-body/node_modules/iconv-lite": {
|
||||||
|
"version": "0.7.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz",
|
||||||
|
"integrity": "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"safer-buffer": ">= 2.1.2 < 3.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/express"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/raw-body/node_modules/statuses": {
|
||||||
|
"version": "2.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz",
|
||||||
|
"integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/react-is": {
|
"node_modules/react-is": {
|
||||||
"version": "16.13.1",
|
"version": "16.13.1",
|
||||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
|
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
|
||||||
@@ -9741,6 +10418,15 @@
|
|||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/require-from-string": {
|
||||||
|
"version": "2.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
|
||||||
|
"integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/resolve": {
|
"node_modules/resolve": {
|
||||||
"version": "2.0.0-next.5",
|
"version": "2.0.0-next.5",
|
||||||
"resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz",
|
"resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz",
|
||||||
@@ -9933,6 +10619,32 @@
|
|||||||
"fsevents": "~2.3.2"
|
"fsevents": "~2.3.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/router": {
|
||||||
|
"version": "2.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz",
|
||||||
|
"integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"debug": "^4.4.0",
|
||||||
|
"depd": "^2.0.0",
|
||||||
|
"is-promise": "^4.0.0",
|
||||||
|
"parseurl": "^1.3.3",
|
||||||
|
"path-to-regexp": "^8.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/router/node_modules/path-to-regexp": {
|
||||||
|
"version": "8.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.3.0.tgz",
|
||||||
|
"integrity": "sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/express"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/rsa-pem-from-mod-exp": {
|
"node_modules/rsa-pem-from-mod-exp": {
|
||||||
"version": "0.8.6",
|
"version": "0.8.6",
|
||||||
"resolved": "https://registry.npmjs.org/rsa-pem-from-mod-exp/-/rsa-pem-from-mod-exp-0.8.6.tgz",
|
"resolved": "https://registry.npmjs.org/rsa-pem-from-mod-exp/-/rsa-pem-from-mod-exp-0.8.6.tgz",
|
||||||
@@ -12192,6 +12904,24 @@
|
|||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 14"
|
"node": ">= 14"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"node_modules/zod": {
|
||||||
|
"version": "4.3.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/zod/-/zod-4.3.6.tgz",
|
||||||
|
"integrity": "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/colinhacks"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/zod-to-json-schema": {
|
||||||
|
"version": "3.25.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.25.1.tgz",
|
||||||
|
"integrity": "sha512-pM/SU9d3YAggzi6MtR4h7ruuQlqKtad8e9S0fmxcMi+ueAK5Korys/aWcV9LIIHTVbj01NdzxcnXSN+O74ZIVA==",
|
||||||
|
"license": "ISC",
|
||||||
|
"peerDependencies": {
|
||||||
|
"zod": "^3.25 || ^4"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,6 +28,8 @@
|
|||||||
"@aws-sdk/credential-provider-node": "^3.972.12",
|
"@aws-sdk/credential-provider-node": "^3.972.12",
|
||||||
"@aws-sdk/lib-storage": "^3.997.0",
|
"@aws-sdk/lib-storage": "^3.997.0",
|
||||||
"@aws-sdk/s3-request-presigner": "^3.997.0",
|
"@aws-sdk/s3-request-presigner": "^3.997.0",
|
||||||
|
"@documenso/sdk-typescript": "^0.8.0",
|
||||||
|
"@jsreport/nodejs-client": "^4.1.0",
|
||||||
"@opensearch-project/opensearch": "^2.13.0",
|
"@opensearch-project/opensearch": "^2.13.0",
|
||||||
"@socket.io/admin-ui": "^0.5.1",
|
"@socket.io/admin-ui": "^0.5.1",
|
||||||
"@socket.io/redis-adapter": "^8.3.0",
|
"@socket.io/redis-adapter": "^8.3.0",
|
||||||
|
|||||||
@@ -130,6 +130,7 @@ const applyRoutes = ({ app }) => {
|
|||||||
app.use("/ai", require("./server/routes/aiRoutes"));
|
app.use("/ai", require("./server/routes/aiRoutes"));
|
||||||
|
|
||||||
app.use("/chatter", require("./server/routes/chatterRoutes"));
|
app.use("/chatter", require("./server/routes/chatterRoutes"));
|
||||||
|
app.use("/esign", require("./server/routes/esignRoutes"));
|
||||||
|
|
||||||
// Default route for forbidden access
|
// Default route for forbidden access
|
||||||
app.get("/", (req, res) => {
|
app.get("/", (req, res) => {
|
||||||
|
|||||||
304
server/esign/esign-new.js
Normal file
304
server/esign/esign-new.js
Normal file
@@ -0,0 +1,304 @@
|
|||||||
|
|
||||||
|
const { Documenso } = require("@documenso/sdk-typescript");
|
||||||
|
const axios = require("axios");
|
||||||
|
const { jsrAuthString } = require("../utils/utils");
|
||||||
|
const logger = require("../utils/logger");
|
||||||
|
const DOCUMENSO_API_KEY = "api_asojim0czruv13ud";//Done on a by team basis,
|
||||||
|
const documenso = new Documenso({
|
||||||
|
apiKey: DOCUMENSO_API_KEY,//Done on a by team basis,
|
||||||
|
serverURL: "https://stg-app.documenso.com/api/v2",
|
||||||
|
});
|
||||||
|
const JSR_SERVER = "https://reports.test.imex.online";
|
||||||
|
const jsreport = require("@jsreport/nodejs-client");
|
||||||
|
const { QUERY_JOB_FOR_SIGNATURE, INSERT_ESIG_AUDIT_TRAIL } = require("../graphql-client/queries");
|
||||||
|
|
||||||
|
|
||||||
|
async function distributeDocument(req, res) {
|
||||||
|
try {
|
||||||
|
const client = req.userGraphQLClient;
|
||||||
|
|
||||||
|
const { documentId } = req.body;
|
||||||
|
const distributeResult = await documenso.documents.distribute({
|
||||||
|
documentId,
|
||||||
|
});
|
||||||
|
|
||||||
|
const auditEntry = await client.request(INSERT_ESIG_AUDIT_TRAIL, {
|
||||||
|
obj: {
|
||||||
|
jobid: req.body.jobid,
|
||||||
|
bodyshopid: req.body.bodyshopid,
|
||||||
|
operation: `Esignature document with title ${distributeResult.title} (ID: ${documentId}) distributed to recipients.`,
|
||||||
|
useremail: req.user?.email,
|
||||||
|
type: 'esig-distribute'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
res.json({ success: true, distributeResult });
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error distributing document:", error?.data);
|
||||||
|
logger.log(`esig-distribute-error`, "ERROR", "esig", "api", {
|
||||||
|
message: error.message, stack: error.stack,
|
||||||
|
body: req.body
|
||||||
|
});
|
||||||
|
res.status(500).json({ error: "An error occurred while distributing the document." });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function deleteDocument(req, res) {
|
||||||
|
try {
|
||||||
|
const { documentId } = req.body;
|
||||||
|
//TODO: This needs to be hardened to prevent deleting other people's documents, completed ones, etc.
|
||||||
|
const deleteResult = await documenso.documents.delete({
|
||||||
|
documentId
|
||||||
|
});
|
||||||
|
res.json({ success: true, deleteResult });
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error deleting document:", error?.data);
|
||||||
|
logger.log(`esig-delete-error`, "ERROR", "esig", "api", {
|
||||||
|
message: error.message, stack: error.stack,
|
||||||
|
body: req.body
|
||||||
|
});
|
||||||
|
res.status(500).json({ error: "An error occurred while deleting the document." });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function newEsignDocument(req, res) {
|
||||||
|
try {
|
||||||
|
const client = req.userGraphQLClient;
|
||||||
|
const { bodyshop } = req.body
|
||||||
|
const { pdf: fileBuffer, esigData } = await RenderTemplate({ client, req })
|
||||||
|
const fileBlob = new Blob([fileBuffer], { type: "application/pdf" });
|
||||||
|
|
||||||
|
|
||||||
|
//Get the Job data.
|
||||||
|
const { jobs_by_pk: jobData } = await client.request(QUERY_JOB_FOR_SIGNATURE, { jobid: req.body.jobid });
|
||||||
|
|
||||||
|
const createDocumentResponse = await documenso.documents.create({
|
||||||
|
payload: {
|
||||||
|
title: esigData?.title,
|
||||||
|
externalId: `${req.body.jobid}|${req.user?.email}`, //Have to pass the uploaded by later on. Limited to 255 chars.
|
||||||
|
recipients: [
|
||||||
|
{
|
||||||
|
email: "patrick@imexsystems.ca",//jobData.ownr_ea,
|
||||||
|
name: `${jobData.ownr_fn} ${jobData.ownr_ln}`,
|
||||||
|
role: "SIGNER",
|
||||||
|
}
|
||||||
|
],
|
||||||
|
meta: {
|
||||||
|
timezone: bodyshop.timezone,
|
||||||
|
dateFormat: "MM/dd/yyyy hh:mm a",
|
||||||
|
language: "en",
|
||||||
|
subject: esigData?.subject,
|
||||||
|
message: esigData?.message,
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
file: fileBlob
|
||||||
|
});
|
||||||
|
|
||||||
|
const documentResult = await documenso.documents.get({
|
||||||
|
documentId: createDocumentResponse.id,
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
if (esigData?.fields && esigData.fields.length > 0) {
|
||||||
|
try {
|
||||||
|
await documenso.envelopes.fields.createMany({
|
||||||
|
envelopeId: createDocumentResponse.envelopeId,
|
||||||
|
data: esigData.fields.map(sigField => ({ ...sigField, recipientId: documentResult.recipients[0].id, }))
|
||||||
|
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
logger.log(`esig-new-fields-error`, "ERROR", "esig", "api", {
|
||||||
|
message: error.message, stack: error.stack,
|
||||||
|
body: req.body
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const presignToken = await documenso.embedding.embeddingPresignCreateEmbeddingPresignToken({})
|
||||||
|
|
||||||
|
//add to job audit trail.
|
||||||
|
|
||||||
|
const auditEntry = await client.request(INSERT_ESIG_AUDIT_TRAIL, {
|
||||||
|
obj: {
|
||||||
|
jobid: req.body.jobid,
|
||||||
|
bodyshopid: bodyshop.id,
|
||||||
|
operation: `Esignature document created. Subject: ${esigData?.subject || "No subject"}, Message: ${esigData?.message || "No message"}. Document ID: ${createDocumentResponse.id} Envlope ID: ${createDocumentResponse.envelopeId}`,
|
||||||
|
useremail: req.user?.email,
|
||||||
|
type: 'esig-create'
|
||||||
|
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
res.json({ token: presignToken.token, documentId: createDocumentResponse.id, envelopeId: createDocumentResponse.envelopeId });
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
logger.log(`esig-new-error`, "ERROR", "esig", "api", {
|
||||||
|
message: error.message, stack: error.stack,
|
||||||
|
body: req.body
|
||||||
|
});
|
||||||
|
res.status(500).json({ error: "An error occurred while creating the e-sign document." });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async function RenderTemplate({ req }) {
|
||||||
|
//TODO Refactor to pull
|
||||||
|
const jsrAuth = jsrAuthString()
|
||||||
|
|
||||||
|
const jsreportClient = new jsreport("https://reports.test.imex.online", process.env.JSR_USER, process.env.JSR_PASSWORD);
|
||||||
|
const { templateObject, bodyshop } = req.body;
|
||||||
|
let { contextData, useShopSpecificTemplate, shopSpecificFolder, esigData } = await fetchContextData({ templateObject, jsrAuth, req });
|
||||||
|
|
||||||
|
const { ignoreCustomMargins } = { ignoreCustomMargins: false }// Templates[templateObject.name];
|
||||||
|
let reportRequest = {
|
||||||
|
template: {
|
||||||
|
name: useShopSpecificTemplate ? `/${bodyshop.imexshopid}/${templateObject.name}` : `/${templateObject.name}`,
|
||||||
|
|
||||||
|
recipe: "chrome-pdf",
|
||||||
|
...(!ignoreCustomMargins && {
|
||||||
|
chrome: {
|
||||||
|
marginTop:
|
||||||
|
bodyshop.logo_img_path &&
|
||||||
|
bodyshop.logo_img_path.headerMargin &&
|
||||||
|
bodyshop.logo_img_path.headerMargin > 36
|
||||||
|
? bodyshop.logo_img_path.headerMargin
|
||||||
|
: "36px",
|
||||||
|
marginBottom:
|
||||||
|
bodyshop.logo_img_path &&
|
||||||
|
bodyshop.logo_img_path.footerMargin &&
|
||||||
|
bodyshop.logo_img_path.footerMargin > 50
|
||||||
|
? bodyshop.logo_img_path.footerMargin
|
||||||
|
: "50px"
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
...contextData,
|
||||||
|
...templateObject.variables,
|
||||||
|
...templateObject.context,
|
||||||
|
headerpath: shopSpecificFolder ? `/${bodyshop.imexshopid}/header.html` : `/GENERIC/header.html`,
|
||||||
|
footerpath: shopSpecificFolder ? `/${bodyshop.imexshopid}/footer.html` : `/GENERIC/footer.html`,
|
||||||
|
bodyshop: bodyshop,
|
||||||
|
filters: templateObject?.filters,
|
||||||
|
sorters: templateObject?.sorters,
|
||||||
|
offset: bodyshop.timezone, //dayjs().utcOffset(),
|
||||||
|
defaultSorters: templateObject?.defaultSorters
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const render = await jsreportClient.render(reportRequest);
|
||||||
|
|
||||||
|
//Check render object and download. It should be the PDF?
|
||||||
|
const pdfBuffer = await render.body()
|
||||||
|
return { pdf: pdfBuffer, esigData }
|
||||||
|
}
|
||||||
|
|
||||||
|
const fetchContextData = async ({ templateObject, jsrAuth, req, }) => {
|
||||||
|
const { bodyshop } = req.body
|
||||||
|
|
||||||
|
|
||||||
|
const folders = await axios.get(`${JSR_SERVER}/odata/folders`, {
|
||||||
|
headers: { Authorization: jsrAuth }
|
||||||
|
});
|
||||||
|
const shopSpecificFolder = folders.data.value.find((f) => f.name === bodyshop.imexshopid);
|
||||||
|
|
||||||
|
const jsReportQueries = await axios.get(
|
||||||
|
`${JSR_SERVER}/odata/assets?$filter=name eq '${templateObject.name}.query'`,
|
||||||
|
{ headers: { Authorization: jsrAuth } }
|
||||||
|
);
|
||||||
|
const jsReportEsig = await axios.get(
|
||||||
|
`${JSR_SERVER}/odata/assets?$filter=name eq '${templateObject.name}.esig'`,
|
||||||
|
{ headers: { Authorization: jsrAuth } }
|
||||||
|
);
|
||||||
|
|
||||||
|
let templateQueryToExecute;
|
||||||
|
let esigData;
|
||||||
|
let useShopSpecificTemplate = false;
|
||||||
|
// let shopSpecificTemplate;
|
||||||
|
|
||||||
|
if (shopSpecificFolder) {
|
||||||
|
let shopSpecificTemplate = jsReportQueries.data.value.find(
|
||||||
|
(f) => f?.folder?.shortid === shopSpecificFolder.shortid
|
||||||
|
);
|
||||||
|
if (shopSpecificTemplate) {
|
||||||
|
useShopSpecificTemplate = true;
|
||||||
|
templateQueryToExecute = atob(shopSpecificTemplate.content);
|
||||||
|
}
|
||||||
|
let shopSpecificEsig = jsReportEsig.data.value.find(
|
||||||
|
(f) => f?.folder?.shortid === shopSpecificFolder.shortid
|
||||||
|
);
|
||||||
|
if (shopSpecificEsig) {
|
||||||
|
esigData = (atob(shopSpecificEsig.content));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!templateQueryToExecute) {
|
||||||
|
const generalTemplate = jsReportQueries.data.value.find((f) => !f.folder);
|
||||||
|
useShopSpecificTemplate = false;
|
||||||
|
templateQueryToExecute = atob(generalTemplate.content);
|
||||||
|
}
|
||||||
|
if (!esigData) {
|
||||||
|
const generalTemplate = jsReportEsig.data.value.find((f) => !f.folder);
|
||||||
|
useShopSpecificTemplate = false;
|
||||||
|
if (generalTemplate && generalTemplate.content) {
|
||||||
|
esigData = atob(generalTemplate?.content);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const client = req.userGraphQLClient;
|
||||||
|
|
||||||
|
|
||||||
|
// In the print center, we will never have sorters or filters.
|
||||||
|
// We have no template filters or sorters, so we can just execute the query and return the data
|
||||||
|
// if (!hasFilters && !hasSorters && !hasDefaultSorters) {
|
||||||
|
let contextData = {};
|
||||||
|
if (templateQueryToExecute) {
|
||||||
|
const data = await client.request(
|
||||||
|
templateQueryToExecute,
|
||||||
|
templateObject.variables,
|
||||||
|
);
|
||||||
|
contextData = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
let parsedEsigData
|
||||||
|
try {
|
||||||
|
parsedEsigData = esigData ? JSON.parse(esigData) : null;
|
||||||
|
} catch (error) {
|
||||||
|
console.log("Error parsing esig data", error);
|
||||||
|
parsedEsigData = {}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
contextData,
|
||||||
|
useShopSpecificTemplate,
|
||||||
|
shopSpecificFolder,
|
||||||
|
esigData: parsedEsigData
|
||||||
|
};
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return await generateTemplate(templateQueryToExecute, templateObject, useShopSpecificTemplate, shopSpecificFolder);
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
newEsignDocument,
|
||||||
|
distributeDocument,
|
||||||
|
deleteDocument
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// const sample_esig_for_jsr = {
|
||||||
|
// "fields": [
|
||||||
|
// {
|
||||||
|
// "placeholder": "[[signature]]",
|
||||||
|
// "type": "SIGNATURE"
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// "placeholder": "[[date]]",
|
||||||
|
// "type": "DATE"
|
||||||
|
// }
|
||||||
|
// ],
|
||||||
|
// "subject": "CASL Auth Set in JSR",
|
||||||
|
// "message": "CASL Message set in JSR",
|
||||||
|
// "title": "CASL Title set in JSR"
|
||||||
|
// }
|
||||||
393
server/esign/webhook.js
Normal file
393
server/esign/webhook.js
Normal file
@@ -0,0 +1,393 @@
|
|||||||
|
|
||||||
|
const { Documenso } = require("@documenso/sdk-typescript");
|
||||||
|
const fs = require("fs");
|
||||||
|
const path = require("path");
|
||||||
|
const logger = require("../utils/logger");
|
||||||
|
const { QUERY_META_FOR_ESIG_COMPLETION, INSERT_ESIGNATURE_DOCUMENT, INSERT_ESIG_AUDIT_TRAIL } = require("../graphql-client/queries");
|
||||||
|
const { uploadFileBuffer } = require("../media/imgproxy-media");
|
||||||
|
const client = require('../graphql-client/graphql-client').client;
|
||||||
|
const documenso = new Documenso({
|
||||||
|
apiKey: "api_asojim0czruv13ud",//Done on a by team basis,
|
||||||
|
serverURL: "https://stg-app.documenso.com/api/v2",
|
||||||
|
});
|
||||||
|
|
||||||
|
const webhookTypeEnums = {
|
||||||
|
DOCUMENT_CREATED: "DOCUMENT_CREATED",
|
||||||
|
DOCUMENT_SENT: "DOCUMENT_SENT",
|
||||||
|
DOCUMENT_COMPLETED: "DOCUMENT_COMPLETED",
|
||||||
|
DOCUMENT_REJECTED: "DOCUMENT_REJECTED",
|
||||||
|
DOCUMENT_CANCELLED: "DOCUMENT_CANCELLED",
|
||||||
|
DOCUMENT_OPENED: "DOCUMENT_OPENED",
|
||||||
|
DOCUMENT_SIGNED: "DOCUMENT_SIGNED",
|
||||||
|
}
|
||||||
|
|
||||||
|
async function esignWebhook(req, res) {
|
||||||
|
console.log("Esign Webhook Received:", req.body);
|
||||||
|
try {
|
||||||
|
const message = req.body
|
||||||
|
logger.log(`esig-webhook-received`, "DEBUG", "redis", "api", {
|
||||||
|
event: message.event,
|
||||||
|
body: message
|
||||||
|
});
|
||||||
|
|
||||||
|
switch (message.event) {
|
||||||
|
case webhookTypeEnums.DOCUMENT_CREATED:
|
||||||
|
//This is largely a throwaway event we know it was created.
|
||||||
|
console.log("Document created event received. Document ID:", message.payload.documentId);
|
||||||
|
// Here you can add any additional processing you want to do when a document is created
|
||||||
|
break;
|
||||||
|
case webhookTypeEnums.DOCUMENT_COMPLETED:
|
||||||
|
console.log("Document completed event received. Document ID:", message.payload.documentId);
|
||||||
|
await handleDocumentCompleted(message.payload);
|
||||||
|
// Here you can add any additional processing you want to do when a document is completed
|
||||||
|
break;
|
||||||
|
case webhookTypeEnums.DOCUMENT_SIGNED:
|
||||||
|
console.log("Document signed event received. Document ID:", message.payload.documentId);
|
||||||
|
// Here you can add any additional processing you want to do when a document is signed
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
console.log(`Unhandled event type: ${message.event}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// const result = await documenso.documents.download({
|
||||||
|
// documentId: req.body.payload.id,
|
||||||
|
// });
|
||||||
|
// result.resultingBuffer = Buffer.from(result.resultingArrayBuffer);
|
||||||
|
// // Save the document to a file for testing purposes
|
||||||
|
// const downloadsDir = path.join(__dirname, '../downloads');
|
||||||
|
// if (!fs.existsSync(downloadsDir)) {
|
||||||
|
// fs.mkdirSync(downloadsDir, { recursive: true });
|
||||||
|
// }
|
||||||
|
// const filePath = path.join(downloadsDir, `document_${req.body.payload.id}.pdf`);
|
||||||
|
// fs.writeFileSync(filePath, result.resultingBuffer);
|
||||||
|
|
||||||
|
// console.log(result)
|
||||||
|
|
||||||
|
res.sendStatus(200)
|
||||||
|
} catch (error) {
|
||||||
|
logger.log(`esig-webhook-error`, "ERROR", "redis", "api", {
|
||||||
|
message: error.message, stack: error.stack,
|
||||||
|
body: req.body
|
||||||
|
});
|
||||||
|
// const downloadsDir = path.join(__dirname, '../downloads');
|
||||||
|
// if (!fs.existsSync(downloadsDir)) {
|
||||||
|
// fs.mkdirSync(downloadsDir, { recursive: true });
|
||||||
|
// }
|
||||||
|
// const filePath = path.join(downloadsDir, `document_${req.body.payload.id}.pdf`);
|
||||||
|
// fs.writeFileSync(filePath, Buffer.from(err.body));
|
||||||
|
// console.error("Error handling esign webhook:", err);
|
||||||
|
res.sendStatus(500)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function handleDocumentCompleted(payload = sampleComplete) {
|
||||||
|
|
||||||
|
|
||||||
|
//Check if the bodyshop is on image proxy or not
|
||||||
|
try {
|
||||||
|
//Split the external id to get the uploaded user.
|
||||||
|
const [jobid, uploaded_by] = payload.externalId.split("|");
|
||||||
|
|
||||||
|
if (!jobid || !uploaded_by) {
|
||||||
|
throw new Error(`Invalid externalId format. Expected "jobid|uploaded_by", got "${payload.externalId}"`);
|
||||||
|
}
|
||||||
|
const { jobs_by_pk } = await client.request(QUERY_META_FOR_ESIG_COMPLETION, {
|
||||||
|
jobid
|
||||||
|
});
|
||||||
|
const document = await documenso.document.documentDownload({
|
||||||
|
documentId: payload.id,
|
||||||
|
});
|
||||||
|
|
||||||
|
const response = await fetch(document.downloadUrl);
|
||||||
|
const arrayBuffer = await response.arrayBuffer();
|
||||||
|
const buffer = Buffer.from(arrayBuffer);
|
||||||
|
|
||||||
|
|
||||||
|
let key = `${jobs_by_pk.bodyshop.id}/${jobs_by_pk.id}/${replaceAccents(document.filename).replace(/[^A-Z0-9]+/gi, "_")}-${new Date().getTime()}.pdf`;
|
||||||
|
|
||||||
|
if (jobs_by_pk?.bodyshop?.uselocalmediaserver) {
|
||||||
|
//LMS not yet implemented.
|
||||||
|
|
||||||
|
} else {
|
||||||
|
//S3 Upload
|
||||||
|
const uploadResult = await uploadFileBuffer({ key, buffer, contentType: "application/pdf" });
|
||||||
|
if (!uploadResult.success) {
|
||||||
|
logger.log(`esig-webhook-s3-upload-error`, "ERROR", "redis", "api", {
|
||||||
|
message: uploadResult.message,
|
||||||
|
stack: uploadResult.stack,
|
||||||
|
jobid: jobid,
|
||||||
|
documentId: payload.id
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
logger.log(`esig-webhook-s3-upload-success`, "INFO", "redis", "api", {
|
||||||
|
jobid: jobid,
|
||||||
|
documentId: payload.id,
|
||||||
|
s3Key: key,
|
||||||
|
bucket: uploadResult.bucket
|
||||||
|
});
|
||||||
|
const auditEntry = await client.request(INSERT_ESIG_AUDIT_TRAIL, {
|
||||||
|
obj: {
|
||||||
|
jobid: jobs_by_pk.id,
|
||||||
|
bodyshopid: jobs_by_pk.bodyshop.id,
|
||||||
|
operation: `Esignature document with title ${payload.title} (ID: ${payload.documentMeta.id}) has been completed.`,
|
||||||
|
useremail: uploaded_by,
|
||||||
|
type: 'esig-complete'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
//insert the document record with the s3 key and bucket info.
|
||||||
|
await client.request(INSERT_ESIGNATURE_DOCUMENT, {
|
||||||
|
docInput: {
|
||||||
|
jobid: jobs_by_pk.id,
|
||||||
|
uploaded_by: uploaded_by,
|
||||||
|
key,
|
||||||
|
type: "application/pdf",
|
||||||
|
extension: "pdf",
|
||||||
|
bodyshopid: jobs_by_pk.bodyshop.id,
|
||||||
|
size: buffer.length,
|
||||||
|
takenat: new Date().toISOString(),
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
logger.log(`esig-webhook-event-completed-error`, "ERROR", "redis", "api", {
|
||||||
|
message: error.message, stack: error.stack,
|
||||||
|
payload
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
esignWebhook
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const sampleComplete = {
|
||||||
|
"id": 10929,
|
||||||
|
"title": "CASL Title set in JSR",
|
||||||
|
"source": "DOCUMENT",
|
||||||
|
"status": "COMPLETED",
|
||||||
|
"teamId": 742,
|
||||||
|
"userId": 654,
|
||||||
|
"Recipient": [
|
||||||
|
{
|
||||||
|
"id": 24997,
|
||||||
|
"name": "James Tschetter",
|
||||||
|
"role": "SIGNER",
|
||||||
|
"email": "patrick@imexsystems.ca",
|
||||||
|
"token": "uMom0GwL29NBqMfohGpUE",
|
||||||
|
"signedAt": "2026-02-27T22:11:52.835Z",
|
||||||
|
"expiresAt": "2026-05-28T22:10:48.991Z",
|
||||||
|
"documentId": 10929,
|
||||||
|
"readStatus": "OPENED",
|
||||||
|
"sendStatus": "SENT",
|
||||||
|
"templateId": null,
|
||||||
|
"authOptions": {
|
||||||
|
"accessAuth": [],
|
||||||
|
"actionAuth": []
|
||||||
|
},
|
||||||
|
"signingOrder": null,
|
||||||
|
"signingStatus": "SIGNED",
|
||||||
|
"rejectionReason": null,
|
||||||
|
"documentDeletedAt": null,
|
||||||
|
"expirationNotifiedAt": null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"createdAt": "2026-02-27T22:10:10.580Z",
|
||||||
|
"deletedAt": null,
|
||||||
|
"updatedAt": "2026-02-27T22:11:57.753Z",
|
||||||
|
"externalId": null,
|
||||||
|
"formValues": null,
|
||||||
|
"recipients": [
|
||||||
|
{
|
||||||
|
"id": 24997,
|
||||||
|
"name": "James Tschetter",
|
||||||
|
"role": "SIGNER",
|
||||||
|
"email": "patrick@imexsystems.ca",
|
||||||
|
"token": "uMom0GwL29NBqMfohGpUE",
|
||||||
|
"signedAt": "2026-02-27T22:11:52.835Z",
|
||||||
|
"expiresAt": "2026-05-28T22:10:48.991Z",
|
||||||
|
"documentId": 10929,
|
||||||
|
"readStatus": "OPENED",
|
||||||
|
"sendStatus": "SENT",
|
||||||
|
"templateId": null,
|
||||||
|
"authOptions": {
|
||||||
|
"accessAuth": [],
|
||||||
|
"actionAuth": []
|
||||||
|
},
|
||||||
|
"signingOrder": null,
|
||||||
|
"signingStatus": "SIGNED",
|
||||||
|
"rejectionReason": null,
|
||||||
|
"documentDeletedAt": null,
|
||||||
|
"expirationNotifiedAt": null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"templateId": null,
|
||||||
|
"visibility": "EVERYONE",
|
||||||
|
"authOptions": {
|
||||||
|
"globalAccessAuth": [],
|
||||||
|
"globalActionAuth": []
|
||||||
|
},
|
||||||
|
"completedAt": "2026-02-27T22:11:57.752Z",
|
||||||
|
"documentMeta": {
|
||||||
|
"id": "cmm5g3y7u00ecad1sv3ague1w",
|
||||||
|
"message": "CASL Message set in JSR",
|
||||||
|
"subject": "CASL Auth Set in JSR",
|
||||||
|
"language": "en",
|
||||||
|
"timezone": "Etc/UTC",
|
||||||
|
"dateFormat": "yyyy-MM-dd hh:mm a",
|
||||||
|
"redirectUrl": null,
|
||||||
|
"signingOrder": "PARALLEL",
|
||||||
|
"emailSettings": {
|
||||||
|
"documentDeleted": true,
|
||||||
|
"documentPending": true,
|
||||||
|
"recipientSigned": true,
|
||||||
|
"recipientRemoved": true,
|
||||||
|
"documentCompleted": true,
|
||||||
|
"ownerDocumentCompleted": true,
|
||||||
|
"recipientSigningRequest": true
|
||||||
|
},
|
||||||
|
"distributionMethod": "EMAIL",
|
||||||
|
"drawSignatureEnabled": true,
|
||||||
|
"typedSignatureEnabled": true,
|
||||||
|
"allowDictateNextSigner": false,
|
||||||
|
"uploadSignatureEnabled": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// const sampleBody = {
|
||||||
|
// event: "DOCUMENT_COMPLETED",
|
||||||
|
// payload: {
|
||||||
|
// Recipient: [
|
||||||
|
// {
|
||||||
|
// authOptions: {
|
||||||
|
// accessAuth: [
|
||||||
|
// ],
|
||||||
|
// actionAuth: [
|
||||||
|
// ],
|
||||||
|
// },
|
||||||
|
// documentDeletedAt: null,
|
||||||
|
// documentId: 9827,
|
||||||
|
// email: "patrick@imexsystems.ca",
|
||||||
|
// expired: null,
|
||||||
|
// id: 13311,
|
||||||
|
// name: "Customer Fullname",
|
||||||
|
// readStatus: "OPENED",
|
||||||
|
// rejectionReason: null,
|
||||||
|
// role: "SIGNER",
|
||||||
|
// sendStatus: "SENT",
|
||||||
|
// signedAt: "2026-01-30T18:29:12.648Z",
|
||||||
|
// signingOrder: null,
|
||||||
|
// signingStatus: "SIGNED",
|
||||||
|
// templateId: null,
|
||||||
|
// token: "uiEWIsXUPTbWHd7QedVgt",
|
||||||
|
// },
|
||||||
|
// ],
|
||||||
|
// authOptions: {
|
||||||
|
// globalAccessAuth: [
|
||||||
|
// ],
|
||||||
|
// globalActionAuth: [
|
||||||
|
// ],
|
||||||
|
// },
|
||||||
|
// completedAt: "2026-01-30T18:29:16.279Z",
|
||||||
|
// createdAt: "2026-01-30T18:28:48.861Z",
|
||||||
|
// deletedAt: null,
|
||||||
|
// documentMeta: {
|
||||||
|
// allowDictateNextSigner: false,
|
||||||
|
// dateFormat: "yyyy-MM-dd hh:mm a",
|
||||||
|
// distributionMethod: "EMAIL",
|
||||||
|
// drawSignatureEnabled: true,
|
||||||
|
// emailSettings: {
|
||||||
|
// documentCompleted: true,
|
||||||
|
// documentDeleted: true,
|
||||||
|
// documentPending: true,
|
||||||
|
// ownerDocumentCompleted: true,
|
||||||
|
// recipientRemoved: false,
|
||||||
|
// recipientSigned: true,
|
||||||
|
// recipientSigningRequest: true,
|
||||||
|
// },
|
||||||
|
// id: "cml17vfb200qjad1t2spxnc1n",
|
||||||
|
// language: "en",
|
||||||
|
// message: "To perform repairs on your vehicle, we must receive digital authorization. Please review and sign the document to proceed with repairs. ",
|
||||||
|
// redirectUrl: null,
|
||||||
|
// signingOrder: "PARALLEL",
|
||||||
|
// subject: "Repair Authorization for ABC Collision",
|
||||||
|
// timezone: "Etc/UTC",
|
||||||
|
// typedSignatureEnabled: true,
|
||||||
|
// uploadSignatureEnabled: true,
|
||||||
|
// },
|
||||||
|
// externalId: null,
|
||||||
|
// formValues: null,
|
||||||
|
// id: 9827,
|
||||||
|
// recipients: [
|
||||||
|
// {
|
||||||
|
// authOptions: {
|
||||||
|
// accessAuth: [
|
||||||
|
// ],
|
||||||
|
// actionAuth: [
|
||||||
|
// ],
|
||||||
|
// },
|
||||||
|
// documentDeletedAt: null,
|
||||||
|
// documentId: 9827,
|
||||||
|
// email: "patrick@imexsystems.ca",
|
||||||
|
// expired: null,
|
||||||
|
// id: 13311,
|
||||||
|
// name: "Customer Fullname",
|
||||||
|
// readStatus: "OPENED",
|
||||||
|
// rejectionReason: null,
|
||||||
|
// role: "SIGNER",
|
||||||
|
// sendStatus: "SENT",
|
||||||
|
// signedAt: "2026-01-30T18:29:12.648Z",
|
||||||
|
// signingOrder: null,
|
||||||
|
// signingStatus: "SIGNED",
|
||||||
|
// templateId: null,
|
||||||
|
// token: "uiEWIsXUPTbWHd7QedVgt",
|
||||||
|
// },
|
||||||
|
// ],
|
||||||
|
// source: "DOCUMENT",
|
||||||
|
// status: "COMPLETED",
|
||||||
|
// teamId: 742,
|
||||||
|
// templateId: null,
|
||||||
|
// title: "Repair Authorization - 1/30/2026, 6:28:48 PM",
|
||||||
|
// updatedAt: "2026-01-30T18:29:16.280Z",
|
||||||
|
// userId: 654,
|
||||||
|
// visibility: "EVERYONE",
|
||||||
|
// },
|
||||||
|
// createdAt: "2026-01-30T18:29:18.504Z",
|
||||||
|
// webhookEndpoint: "https://dev.patrickfic.com/esign/webhook",
|
||||||
|
// }
|
||||||
|
|
||||||
|
function replaceAccents(str) {
|
||||||
|
// Verifies if the String has accents and replace them
|
||||||
|
if (str.search(/[\xC0-\xFF]/g) > -1) {
|
||||||
|
str = str
|
||||||
|
.replace(/[\xC0-\xC5]/g, "A")
|
||||||
|
.replace(/[\xC6]/g, "AE")
|
||||||
|
.replace(/[\xC7]/g, "C")
|
||||||
|
.replace(/[\xC8-\xCB]/g, "E")
|
||||||
|
.replace(/[\xCC-\xCF]/g, "I")
|
||||||
|
.replace(/[\xD0]/g, "D")
|
||||||
|
.replace(/[\xD1]/g, "N")
|
||||||
|
.replace(/[\xD2-\xD6\xD8]/g, "O")
|
||||||
|
.replace(/[\xD9-\xDC]/g, "U")
|
||||||
|
.replace(/[\xDD]/g, "Y")
|
||||||
|
.replace(/[\xDE]/g, "P")
|
||||||
|
.replace(/[\xE0-\xE5]/g, "a")
|
||||||
|
.replace(/[\xE6]/g, "ae")
|
||||||
|
.replace(/[\xE7]/g, "c")
|
||||||
|
.replace(/[\xE8-\xEB]/g, "e")
|
||||||
|
.replace(/[\xEC-\xEF]/g, "i")
|
||||||
|
.replace(/[\xF1]/g, "n")
|
||||||
|
.replace(/[\xF2-\xF6\xF8]/g, "o")
|
||||||
|
.replace(/[\xF9-\xFC]/g, "u")
|
||||||
|
.replace(/[\xFE]/g, "p")
|
||||||
|
.replace(/[\xFD\xFF]/g, "y");
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
`Unexpected Status or Content-Type: Status 200 Content-Type application/pdf\nBody: %PDF-1.7\n%<25><><EFBFBD><EFBFBD>\n1 0 obj\n<<\n/Type /Catalog\n/Pages 2 0 R\n/Names 74 0 R\n/Dests 75 0 R\n/Info 77 0 R\n/Lang (en-US)\n/Version /1.7\n>>\nendobj\n77 0 obj\n<<\n/Type /Info\n/CreationDate (D:20260227230617Z00'00')\n/Producer <FEFF007000640066002D006C006900620020002800680074007400700073003A002F002F006700690074006800750062002E0063006F006D002F0048006F007000640069006E0067002F007000640066002D006C006900620029>\n/ModDate (D:20260227231057Z)…<>5[<5B>><3E>Wu7<><37>V<EFBFBD><56><EFBFBD><EFBFBD><EFBFBD>Pw<50>WX<57>ܮJ'6NWg<57>vYϳ<><CFB3><EFBFBD><EFBFBD><EFBFBD>Щr<D0A9>\n\t+<2B>1<EFBFBD><10>m{휑<0C>hwb<><62><EFBFBD>8<EFBFBD><38>qy<>1e<31>)۱<>5m<35><6D><08><>MVM!<21>m<EFBFBD>[A<><41><10>{l<><6C>\t<EFBFBD>hia4<61><34>Tm<54><6D>8<><38>a<>e<EFBFBD>}<7D>߫<><DFAB><15>]MVpяG<D18F><47>֏<EFBFBD>jJ<"<22>A<EFBFBD>mO*<2A>P<EFBFBD><0B><><><7F><EFBFBD><EFBFBD>ѧЛ\nendstream\nendobj\n26 0 obj\n<<\n/Length 478/Filter /FlateDecode\n>>\nstream\nx<EFBFBD>MSK<EFBFBD>9<08><>)<29><>*<04>O<EFBFBD>i<EFBFBD><69>,<2C><>o <20><>kS%<25>$<EFBFBD><EFBFBD>hR\rS'<27>I<EFBFBD><49>~<7E><03><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>T[/<2F>{<05>k<EFBFBD>FC#<23><>֛<><D69B><EFBFBD>;Ӏ<>[<5B>⫀m<E2AB80>|Q<1F><>\x1b<EFBFBD><16>><3E>R<><52><EFBFBD><EFBFBD><EFBFBD>a<EFBFBD>E#<23>pI<70><49>._H<5F>ᆫt<E186AB>k<EFBFBD>D3p<33>I<EFBFBD><49><EFBFBD><EFBFBD><01>W2<57><32><EFBFBD>oJ0<4A>j<EFBFBD><6A><EFBFBD>j#<23><>!<21>$<EFBFBD><EFBFBD>-<2D><08><><EFBFBD><EFBFBD><EFBFBD>.Ϋ<><CEAB><EFBFBD>TI|8D<38>H<1C><>Y<EFBFBD><59>x<EFBFBD><78><EFBFBD><EFBFBD>1<EFBFBD>73%<25>u<EFBFBD>T<EFBFBD><54>Ӑ.rcb<63>x<EFBFBD><78>Dd6=<3D><>Oڏ1^<5E>-<2D>...and 252354 more chars`
|
||||||
95
server/esign/webhook.types.ts
Normal file
95
server/esign/webhook.types.ts
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
export type WebhookEventType =
|
||||||
|
| "DOCUMENT_CREATED"
|
||||||
|
| "DOCUMENT_SENT"
|
||||||
|
| "DOCUMENT_COMPLETED"
|
||||||
|
| "DOCUMENT_REJECTED"
|
||||||
|
| "DOCUMENT_CANCELLED"
|
||||||
|
| "DOCUMENT_OPENED"
|
||||||
|
| "DOCUMENT_SIGNED";
|
||||||
|
|
||||||
|
export interface AuthOptions {
|
||||||
|
accessAuth: unknown[];
|
||||||
|
actionAuth: unknown[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Recipient {
|
||||||
|
id: number;
|
||||||
|
name: string;
|
||||||
|
role: string;
|
||||||
|
email: string;
|
||||||
|
token?: string | null;
|
||||||
|
signedAt?: string | null;
|
||||||
|
expiresAt?: string | null;
|
||||||
|
documentId?: number;
|
||||||
|
readStatus?: string | null;
|
||||||
|
sendStatus?: string | null;
|
||||||
|
templateId?: number | null;
|
||||||
|
authOptions?: AuthOptions;
|
||||||
|
signingOrder?: number | null;
|
||||||
|
signingStatus?: string | null;
|
||||||
|
rejectionReason?: string | null;
|
||||||
|
documentDeletedAt?: string | null;
|
||||||
|
expirationNotifiedAt?: string | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface EmailSettings {
|
||||||
|
documentDeleted: boolean;
|
||||||
|
documentPending: boolean;
|
||||||
|
recipientSigned: boolean;
|
||||||
|
recipientRemoved: boolean;
|
||||||
|
documentCompleted: boolean;
|
||||||
|
ownerDocumentCompleted: boolean;
|
||||||
|
recipientSigningRequest: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DocumentMeta {
|
||||||
|
id: string;
|
||||||
|
message?: string | null;
|
||||||
|
subject?: string | null;
|
||||||
|
language?: string | null;
|
||||||
|
timezone?: string | null;
|
||||||
|
dateFormat?: string | null;
|
||||||
|
redirectUrl?: string | null;
|
||||||
|
signingOrder?: string | null;
|
||||||
|
emailSettings?: EmailSettings;
|
||||||
|
distributionMethod?: string | null;
|
||||||
|
drawSignatureEnabled?: boolean;
|
||||||
|
typedSignatureEnabled?: boolean;
|
||||||
|
allowDictateNextSigner?: boolean;
|
||||||
|
uploadSignatureEnabled?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DocumentAuthOptions {
|
||||||
|
globalAccessAuth: unknown[];
|
||||||
|
globalActionAuth: unknown[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DocumentPayload {
|
||||||
|
id: number;
|
||||||
|
title?: string | null;
|
||||||
|
source?: string | null;
|
||||||
|
status?: string | null;
|
||||||
|
teamId?: number | null;
|
||||||
|
userId?: number | null;
|
||||||
|
Recipient?: Recipient[];
|
||||||
|
recipients?: Recipient[];
|
||||||
|
createdAt?: string | null;
|
||||||
|
deletedAt?: string | null;
|
||||||
|
updatedAt?: string | null;
|
||||||
|
externalId?: string | null;
|
||||||
|
formValues?: unknown | null;
|
||||||
|
templateId?: number | null;
|
||||||
|
visibility?: string | null;
|
||||||
|
authOptions?: DocumentAuthOptions;
|
||||||
|
completedAt?: string | null;
|
||||||
|
documentMeta?: DocumentMeta | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface WebhookEventPayload {
|
||||||
|
event: WebhookEventType;
|
||||||
|
payload: DocumentPayload;
|
||||||
|
createdAt?: string | null;
|
||||||
|
webhookEndpoint?: string | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default WebhookEventPayload;
|
||||||
@@ -2253,18 +2253,16 @@ exports.UPDATE_OLD_TRANSITION = `mutation UPDATE_OLD_TRANSITION($jobid: uuid!, $
|
|||||||
|
|
||||||
exports.INSERT_NEW_TRANSITION = (
|
exports.INSERT_NEW_TRANSITION = (
|
||||||
includeOldTransition
|
includeOldTransition
|
||||||
) => `mutation INSERT_NEW_TRANSITION($newTransition: transitions_insert_input!, ${
|
) => `mutation INSERT_NEW_TRANSITION($newTransition: transitions_insert_input!, ${includeOldTransition ? `$oldTransitionId: uuid!, $duration: numeric` : ""
|
||||||
includeOldTransition ? `$oldTransitionId: uuid!, $duration: numeric` : ""
|
|
||||||
}) {
|
}) {
|
||||||
insert_transitions_one(object: $newTransition) {
|
insert_transitions_one(object: $newTransition) {
|
||||||
id
|
id
|
||||||
}
|
}
|
||||||
${
|
${includeOldTransition
|
||||||
includeOldTransition
|
? `update_transitions(where: {id: {_eq: $oldTransitionId}}, _set: {duration: $duration}) {
|
||||||
? `update_transitions(where: {id: {_eq: $oldTransitionId}}, _set: {duration: $duration}) {
|
|
||||||
affected_rows
|
affected_rows
|
||||||
}`
|
}`
|
||||||
: ""
|
: ""
|
||||||
}
|
}
|
||||||
}`;
|
}`;
|
||||||
|
|
||||||
@@ -3256,3 +3254,46 @@ exports.SET_JOB_DMS_ID = `mutation SetJobDmsId($id: uuid!, $dms_id: String!, $dm
|
|||||||
kmin
|
kmin
|
||||||
}
|
}
|
||||||
}`;
|
}`;
|
||||||
|
|
||||||
|
|
||||||
|
exports.QUERY_JOB_FOR_SIGNATURE = `query QUERY_JOB_FOR_SIGNATURE($jobid: uuid!) {
|
||||||
|
jobs_by_pk(id: $jobid) {
|
||||||
|
id
|
||||||
|
ownr_fn
|
||||||
|
ownr_ln
|
||||||
|
ownr_co_nm
|
||||||
|
ownr_ea
|
||||||
|
ownr_ph1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
exports.INSERT_ESIG_AUDIT_TRAIL = `mutation INSERT_ESIG_AUDIT_TRAIL($obj: audit_trail_insert_input!) {
|
||||||
|
insert_audit_trail_one(object: $obj) {
|
||||||
|
id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
exports.QUERY_META_FOR_ESIG_COMPLETION = `query QUERY_META_FOR_ESIG_COMPLETION($jobid: uuid!) {
|
||||||
|
jobs_by_pk(id: $jobid) {
|
||||||
|
id
|
||||||
|
ro_number
|
||||||
|
bodyshop {
|
||||||
|
id
|
||||||
|
uselocalmediaserver
|
||||||
|
localmediatoken
|
||||||
|
localmediaserverhttp
|
||||||
|
localmediaservernetwork
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}`
|
||||||
|
|
||||||
|
exports.INSERT_ESIGNATURE_DOCUMENT = `mutation INSERT_ESIGNATURE_DOCUMENT($docInput: documents_insert_input!) {
|
||||||
|
insert_documents_one(object: $docInput) {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
key
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
@@ -94,6 +94,47 @@ const generateSignedUploadUrls = async (req, res) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Upload a file buffer directly to S3.
|
||||||
|
* Accepts either `req.file.buffer` (e.g. from multer) or `req.body.buffer` (base64 string).
|
||||||
|
*/
|
||||||
|
const uploadFileBuffer = async ({ key, contentType, buffer }) => {
|
||||||
|
try {
|
||||||
|
|
||||||
|
|
||||||
|
if (!key) {
|
||||||
|
throw new Error("key is required");
|
||||||
|
}
|
||||||
|
if (!buffer) {
|
||||||
|
throw new Error("buffer is required");
|
||||||
|
}
|
||||||
|
|
||||||
|
const isPdf = key.toLowerCase().endsWith(".pdf");
|
||||||
|
const client = new S3Client({ region: InstanceRegion() });
|
||||||
|
|
||||||
|
const putParams = {
|
||||||
|
Bucket: imgproxyDestinationBucket,
|
||||||
|
Key: key,
|
||||||
|
Body: buffer,
|
||||||
|
StorageClass: "INTELLIGENT_TIERING"
|
||||||
|
};
|
||||||
|
|
||||||
|
if (contentType) {
|
||||||
|
putParams.ContentType = contentType;
|
||||||
|
} else if (isPdf) {
|
||||||
|
putParams.ContentType = "application/pdf";
|
||||||
|
}
|
||||||
|
|
||||||
|
await client.send(new PutObjectCommand(putParams));
|
||||||
|
|
||||||
|
|
||||||
|
return ({ success: true, key, bucket: imgproxyDestinationBucket });
|
||||||
|
} catch (error) {
|
||||||
|
|
||||||
|
return { success: false, message: error.message, stack: error.stack };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get Thumbnail URLS
|
* Get Thumbnail URLS
|
||||||
* @param req
|
* @param req
|
||||||
@@ -500,6 +541,7 @@ const keyStandardize = (doc) => {
|
|||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
generateSignedUploadUrls,
|
generateSignedUploadUrls,
|
||||||
|
uploadFileBuffer,
|
||||||
getThumbnailUrls,
|
getThumbnailUrls,
|
||||||
getOriginalImageByDocumentId,
|
getOriginalImageByDocumentId,
|
||||||
downloadFiles,
|
downloadFiles,
|
||||||
|
|||||||
17
server/routes/esignRoutes.js
Normal file
17
server/routes/esignRoutes.js
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
const express = require("express");
|
||||||
|
const router = express.Router();
|
||||||
|
|
||||||
|
const validateFirebaseIdTokenMiddleware = require("../middleware/validateFirebaseIdTokenMiddleware");
|
||||||
|
const withUserGraphQLClientMiddleware = require("../middleware/withUserGraphQLClientMiddleware");
|
||||||
|
const { newEsignDocument, distributeDocument, deleteDocument } = require("../esign/esign-new");
|
||||||
|
const { esignWebhook } = require("../esign/webhook");
|
||||||
|
|
||||||
|
//router.use(validateFirebaseIdTokenMiddleware);
|
||||||
|
|
||||||
|
router.post("/new", validateFirebaseIdTokenMiddleware, withUserGraphQLClientMiddleware, newEsignDocument);
|
||||||
|
router.post("/distribute", validateFirebaseIdTokenMiddleware, withUserGraphQLClientMiddleware, distributeDocument);
|
||||||
|
router.post("/delete", validateFirebaseIdTokenMiddleware, withUserGraphQLClientMiddleware, deleteDocument);
|
||||||
|
router.post("/webhook", esignWebhook);
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = router;
|
||||||
@@ -2,6 +2,9 @@ exports.servertime = (req, res) => {
|
|||||||
res.status(200).send(new Date());
|
res.status(200).send(new Date());
|
||||||
};
|
};
|
||||||
|
|
||||||
|
exports.jsrAuthString =() => {
|
||||||
|
return "Basic " + Buffer.from(`${process.env.JSR_USER}:${process.env.JSR_PASSWORD}`).toString("base64")
|
||||||
|
}
|
||||||
exports.jsrAuth = async (req, res) => {
|
exports.jsrAuth = async (req, res) => {
|
||||||
res.send("Basic " + Buffer.from(`${process.env.JSR_USER}:${process.env.JSR_PASSWORD}`).toString("base64"));
|
res.send(exports.jsrAuthString());
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user