Use electronic signature for compliage page NDA
Signed-off-by: Bryan Frimin <bryan@getprobo.com>
This commit is contained in:
@@ -27,12 +27,9 @@ export function MainLayout(props: Props) {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ndaSig = trustCenter.ndaSignature;
|
const nda = trustCenter.nonDisclosureAgreement;
|
||||||
const hasPendingNDA
|
const hasPendingNDA = nda?.viewerSignature
|
||||||
= trustCenter.isViewerMember
|
&& (nda.viewerSignature.status === "PENDING" || nda.viewerSignature.status === "FAILED");
|
||||||
&& trustCenter.ndaFileUrl
|
|
||||||
&& ndaSig
|
|
||||||
&& ndaSig.status !== "COMPLETED";
|
|
||||||
|
|
||||||
if (hasPendingNDA) {
|
if (hasPendingNDA) {
|
||||||
return <Navigate to="/nda" replace />;
|
return <Navigate to="/nda" replace />;
|
||||||
|
|||||||
@@ -31,10 +31,12 @@ export const ndaPageQuery = graphql`
|
|||||||
organization {
|
organization {
|
||||||
name
|
name
|
||||||
}
|
}
|
||||||
ndaFileUrl
|
nonDisclosureAgreement {
|
||||||
ndaFileName
|
fileName
|
||||||
ndaSignature {
|
fileUrl
|
||||||
status
|
viewerSignature {
|
||||||
|
status
|
||||||
|
}
|
||||||
}
|
}
|
||||||
...NDAPageFragment
|
...NDAPageFragment
|
||||||
}
|
}
|
||||||
@@ -44,11 +46,13 @@ export const ndaPageQuery = graphql`
|
|||||||
const ndaPageFragment = graphql`
|
const ndaPageFragment = graphql`
|
||||||
fragment NDAPageFragment on TrustCenter
|
fragment NDAPageFragment on TrustCenter
|
||||||
@refetchable(queryName: "NDAPageRefetchQuery") {
|
@refetchable(queryName: "NDAPageRefetchQuery") {
|
||||||
ndaSignature @required(action: THROW) {
|
nonDisclosureAgreement @required(action: THROW) {
|
||||||
id
|
viewerSignature @required(action: THROW) {
|
||||||
status
|
id
|
||||||
consentText
|
status
|
||||||
lastError
|
consentText
|
||||||
|
lastError
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
@@ -95,7 +99,7 @@ export function NDAPage(props: {
|
|||||||
ndaPageFragment,
|
ndaPageFragment,
|
||||||
trustCenter,
|
trustCenter,
|
||||||
);
|
);
|
||||||
const ndaSignature = data.ndaSignature;
|
const ndaSignature = data.nonDisclosureAgreement.viewerSignature;
|
||||||
|
|
||||||
const { width } = useWindowSize();
|
const { width } = useWindowSize();
|
||||||
const isMobile = width < 1100;
|
const isMobile = width < 1100;
|
||||||
@@ -208,10 +212,11 @@ export function NDAPage(props: {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const nda = trustCenter.nonDisclosureAgreement;
|
||||||
if (
|
if (
|
||||||
!trustCenter.ndaFileUrl
|
!nda
|
||||||
|| !trustCenter.ndaSignature
|
|| !nda.viewerSignature
|
||||||
|| trustCenter.ndaSignature.status === "COMPLETED"
|
|| nda.viewerSignature.status === "COMPLETED"
|
||||||
) {
|
) {
|
||||||
return <Navigate to="/overview" replace />;
|
return <Navigate to="/overview" replace />;
|
||||||
}
|
}
|
||||||
@@ -241,11 +246,11 @@ export function NDAPage(props: {
|
|||||||
trustCenter.organization.name,
|
trustCenter.organization.name,
|
||||||
)}
|
)}
|
||||||
</p>
|
</p>
|
||||||
{isMobile && trustCenter.ndaFileUrl && (
|
{isMobile && nda?.fileUrl && (
|
||||||
<Card className="flex justify-between py-3 px-4 text-sm items-center mt-6">
|
<Card className="flex justify-between py-3 px-4 text-sm items-center mt-6">
|
||||||
{trustCenter.ndaFileName}
|
{nda?.fileName}
|
||||||
<Button variant="secondary" asChild>
|
<Button variant="secondary" asChild>
|
||||||
<a target="_blank" rel="noopener noreferrer" href={trustCenter.ndaFileUrl}>
|
<a target="_blank" rel="noopener noreferrer" href={nda.fileUrl}>
|
||||||
{__("View document")}
|
{__("View document")}
|
||||||
</a>
|
</a>
|
||||||
</Button>
|
</Button>
|
||||||
@@ -323,7 +328,7 @@ export function NDAPage(props: {
|
|||||||
</div>
|
</div>
|
||||||
{isDesktop && (
|
{isDesktop && (
|
||||||
<div className="bg-subtle h-full border-l border-border-solid min-h-0">
|
<div className="bg-subtle h-full border-l border-border-solid min-h-0">
|
||||||
{trustCenter.ndaFileUrl && <PDFPreview src={trustCenter.ndaFileUrl} name={trustCenter.ndaFileName ?? ""} />}
|
{nda?.fileUrl && <PDFPreview src={nda.fileUrl} name={nda.fileName ?? ""} />}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* @generated SignedSource<<93f8676826dfa28c1681da68a6ac1cf2>>
|
* @generated SignedSource<<99908411212decf464eafa45b1fc0e04>>
|
||||||
* @lightSyntaxTransform
|
* @lightSyntaxTransform
|
||||||
* @nogrep
|
* @nogrep
|
||||||
*/
|
*/
|
||||||
@@ -13,11 +13,13 @@ export type ElectronicSignatureStatus = "ACCEPTED" | "COMPLETED" | "FAILED" | "P
|
|||||||
import { FragmentRefs } from "relay-runtime";
|
import { FragmentRefs } from "relay-runtime";
|
||||||
export type NDAPageFragment$data = {
|
export type NDAPageFragment$data = {
|
||||||
readonly id: string;
|
readonly id: string;
|
||||||
readonly ndaSignature: {
|
readonly nonDisclosureAgreement: {
|
||||||
readonly consentText: string;
|
readonly viewerSignature: {
|
||||||
readonly id: string;
|
readonly consentText: string;
|
||||||
readonly lastError: string | null | undefined;
|
readonly id: string;
|
||||||
readonly status: ElectronicSignatureStatus;
|
readonly lastError: string | null | undefined;
|
||||||
|
readonly status: ElectronicSignatureStatus;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
readonly " $fragmentType": "NDAPageFragment";
|
readonly " $fragmentType": "NDAPageFragment";
|
||||||
};
|
};
|
||||||
@@ -59,32 +61,47 @@ return {
|
|||||||
"field": {
|
"field": {
|
||||||
"alias": null,
|
"alias": null,
|
||||||
"args": null,
|
"args": null,
|
||||||
"concreteType": "ElectronicSignature",
|
"concreteType": "NonDisclosureAgreement",
|
||||||
"kind": "LinkedField",
|
"kind": "LinkedField",
|
||||||
"name": "ndaSignature",
|
"name": "nonDisclosureAgreement",
|
||||||
"plural": false,
|
"plural": false,
|
||||||
"selections": [
|
"selections": [
|
||||||
(v0/*: any*/),
|
|
||||||
{
|
{
|
||||||
"alias": null,
|
"kind": "RequiredField",
|
||||||
"args": null,
|
"field": {
|
||||||
"kind": "ScalarField",
|
"alias": null,
|
||||||
"name": "status",
|
"args": null,
|
||||||
"storageKey": null
|
"concreteType": "ElectronicSignature",
|
||||||
},
|
"kind": "LinkedField",
|
||||||
{
|
"name": "viewerSignature",
|
||||||
"alias": null,
|
"plural": false,
|
||||||
"args": null,
|
"selections": [
|
||||||
"kind": "ScalarField",
|
(v0/*: any*/),
|
||||||
"name": "consentText",
|
{
|
||||||
"storageKey": null
|
"alias": null,
|
||||||
},
|
"args": null,
|
||||||
{
|
"kind": "ScalarField",
|
||||||
"alias": null,
|
"name": "status",
|
||||||
"args": null,
|
"storageKey": null
|
||||||
"kind": "ScalarField",
|
},
|
||||||
"name": "lastError",
|
{
|
||||||
"storageKey": null
|
"alias": null,
|
||||||
|
"args": null,
|
||||||
|
"kind": "ScalarField",
|
||||||
|
"name": "consentText",
|
||||||
|
"storageKey": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"alias": null,
|
||||||
|
"args": null,
|
||||||
|
"kind": "ScalarField",
|
||||||
|
"name": "lastError",
|
||||||
|
"storageKey": null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"storageKey": null
|
||||||
|
},
|
||||||
|
"action": "THROW"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"storageKey": null
|
"storageKey": null
|
||||||
@@ -98,6 +115,6 @@ return {
|
|||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
|
||||||
(node as any).hash = "b53a5f455508ed45124b7d09cfb573da";
|
(node as any).hash = "503859b8c00b27214f9f3253bffcb670";
|
||||||
|
|
||||||
export default node;
|
export default node;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* @generated SignedSource<<f1cae8462501cdf634eb02eb143c3806>>
|
* @generated SignedSource<<10a0ee1dfa19239c5c5820f3d58a1e19>>
|
||||||
* @lightSyntaxTransform
|
* @lightSyntaxTransform
|
||||||
* @nogrep
|
* @nogrep
|
||||||
*/
|
*/
|
||||||
@@ -14,10 +14,12 @@ export type ElectronicSignatureStatus = "ACCEPTED" | "COMPLETED" | "FAILED" | "P
|
|||||||
export type NDAPageQuery$variables = Record<PropertyKey, never>;
|
export type NDAPageQuery$variables = Record<PropertyKey, never>;
|
||||||
export type NDAPageQuery$data = {
|
export type NDAPageQuery$data = {
|
||||||
readonly currentTrustCenter: {
|
readonly currentTrustCenter: {
|
||||||
readonly ndaFileName: string | null | undefined;
|
readonly nonDisclosureAgreement: {
|
||||||
readonly ndaFileUrl: string | null | undefined;
|
readonly fileName: string;
|
||||||
readonly ndaSignature: {
|
readonly fileUrl: string;
|
||||||
readonly status: ElectronicSignatureStatus;
|
readonly viewerSignature: {
|
||||||
|
readonly status: ElectronicSignatureStatus;
|
||||||
|
} | null | undefined;
|
||||||
} | null | undefined;
|
} | null | undefined;
|
||||||
readonly organization: {
|
readonly organization: {
|
||||||
readonly name: string;
|
readonly name: string;
|
||||||
@@ -52,14 +54,14 @@ v2 = {
|
|||||||
"alias": null,
|
"alias": null,
|
||||||
"args": null,
|
"args": null,
|
||||||
"kind": "ScalarField",
|
"kind": "ScalarField",
|
||||||
"name": "ndaFileUrl",
|
"name": "fileName",
|
||||||
"storageKey": null
|
"storageKey": null
|
||||||
},
|
},
|
||||||
v3 = {
|
v3 = {
|
||||||
"alias": null,
|
"alias": null,
|
||||||
"args": null,
|
"args": null,
|
||||||
"kind": "ScalarField",
|
"kind": "ScalarField",
|
||||||
"name": "ndaFileName",
|
"name": "fileUrl",
|
||||||
"storageKey": null
|
"storageKey": null
|
||||||
},
|
},
|
||||||
v4 = {
|
v4 = {
|
||||||
@@ -117,17 +119,28 @@ return {
|
|||||||
],
|
],
|
||||||
"storageKey": null
|
"storageKey": null
|
||||||
},
|
},
|
||||||
(v2/*: any*/),
|
|
||||||
(v3/*: any*/),
|
|
||||||
{
|
{
|
||||||
"alias": null,
|
"alias": null,
|
||||||
"args": null,
|
"args": null,
|
||||||
"concreteType": "ElectronicSignature",
|
"concreteType": "NonDisclosureAgreement",
|
||||||
"kind": "LinkedField",
|
"kind": "LinkedField",
|
||||||
"name": "ndaSignature",
|
"name": "nonDisclosureAgreement",
|
||||||
"plural": false,
|
"plural": false,
|
||||||
"selections": [
|
"selections": [
|
||||||
(v4/*: any*/)
|
(v2/*: any*/),
|
||||||
|
(v3/*: any*/),
|
||||||
|
{
|
||||||
|
"alias": null,
|
||||||
|
"args": null,
|
||||||
|
"concreteType": "ElectronicSignature",
|
||||||
|
"kind": "LinkedField",
|
||||||
|
"name": "viewerSignature",
|
||||||
|
"plural": false,
|
||||||
|
"selections": [
|
||||||
|
(v4/*: any*/)
|
||||||
|
],
|
||||||
|
"storageKey": null
|
||||||
|
}
|
||||||
],
|
],
|
||||||
"storageKey": null
|
"storageKey": null
|
||||||
},
|
},
|
||||||
@@ -185,30 +198,41 @@ return {
|
|||||||
],
|
],
|
||||||
"storageKey": null
|
"storageKey": null
|
||||||
},
|
},
|
||||||
(v2/*: any*/),
|
|
||||||
(v3/*: any*/),
|
|
||||||
{
|
{
|
||||||
"alias": null,
|
"alias": null,
|
||||||
"args": null,
|
"args": null,
|
||||||
"concreteType": "ElectronicSignature",
|
"concreteType": "NonDisclosureAgreement",
|
||||||
"kind": "LinkedField",
|
"kind": "LinkedField",
|
||||||
"name": "ndaSignature",
|
"name": "nonDisclosureAgreement",
|
||||||
"plural": false,
|
"plural": false,
|
||||||
"selections": [
|
"selections": [
|
||||||
(v4/*: any*/),
|
(v2/*: any*/),
|
||||||
(v5/*: any*/),
|
(v3/*: any*/),
|
||||||
{
|
{
|
||||||
"alias": null,
|
"alias": null,
|
||||||
"args": null,
|
"args": null,
|
||||||
"kind": "ScalarField",
|
"concreteType": "ElectronicSignature",
|
||||||
"name": "consentText",
|
"kind": "LinkedField",
|
||||||
"storageKey": null
|
"name": "viewerSignature",
|
||||||
},
|
"plural": false,
|
||||||
{
|
"selections": [
|
||||||
"alias": null,
|
(v4/*: any*/),
|
||||||
"args": null,
|
(v5/*: any*/),
|
||||||
"kind": "ScalarField",
|
{
|
||||||
"name": "lastError",
|
"alias": null,
|
||||||
|
"args": null,
|
||||||
|
"kind": "ScalarField",
|
||||||
|
"name": "consentText",
|
||||||
|
"storageKey": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"alias": null,
|
||||||
|
"args": null,
|
||||||
|
"kind": "ScalarField",
|
||||||
|
"name": "lastError",
|
||||||
|
"storageKey": null
|
||||||
|
}
|
||||||
|
],
|
||||||
"storageKey": null
|
"storageKey": null
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -221,16 +245,16 @@ return {
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"params": {
|
"params": {
|
||||||
"cacheID": "c0b175c435c5730e390fcfde596d8bc3",
|
"cacheID": "e1ab3a5206a4ea200ebdb991023a0e99",
|
||||||
"id": null,
|
"id": null,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"name": "NDAPageQuery",
|
"name": "NDAPageQuery",
|
||||||
"operationKind": "query",
|
"operationKind": "query",
|
||||||
"text": "query NDAPageQuery {\n viewer {\n fullName\n id\n }\n currentTrustCenter {\n organization {\n name\n id\n }\n ndaFileUrl\n ndaFileName\n ndaSignature {\n status\n id\n }\n ...NDAPageFragment\n id\n }\n}\n\nfragment NDAPageFragment on TrustCenter {\n ndaSignature {\n id\n status\n consentText\n lastError\n }\n id\n}\n"
|
"text": "query NDAPageQuery {\n viewer {\n fullName\n id\n }\n currentTrustCenter {\n organization {\n name\n id\n }\n nonDisclosureAgreement {\n fileName\n fileUrl\n viewerSignature {\n status\n id\n }\n }\n ...NDAPageFragment\n id\n }\n}\n\nfragment NDAPageFragment on TrustCenter {\n nonDisclosureAgreement {\n viewerSignature {\n id\n status\n consentText\n lastError\n }\n }\n id\n}\n"
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
|
||||||
(node as any).hash = "a78bf8b65feba4627ecb265ca882f645";
|
(node as any).hash = "4f0f0dd672862fb6c3fb5ef2eff80cd9";
|
||||||
|
|
||||||
export default node;
|
export default node;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* @generated SignedSource<<d2d531924e3667658020b431850c193e>>
|
* @generated SignedSource<<58dbdcc5fc52f0dab9eb156856522fd1>>
|
||||||
* @lightSyntaxTransform
|
* @lightSyntaxTransform
|
||||||
* @nogrep
|
* @nogrep
|
||||||
*/
|
*/
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
// @ts-nocheck
|
// @ts-nocheck
|
||||||
|
|
||||||
import { ConcreteRequest } from 'relay-runtime';
|
import { ConcreteRequest } from 'relay-runtime';
|
||||||
export type ElectronicSignatureEventType = "CERTIFICATE_GENERATED" | "CONSENT_GIVEN" | "DOCUMENT_VIEWED" | "FULL_NAME_TYPED" | "SEAL_COMPUTED" | "SIGNATURE_ACCEPTED" | "SIGNATURE_COMPLETED" | "TIMESTAMP_REQUESTED";
|
export type ElectronicSignatureEventType = "CERTIFICATE_GENERATED" | "CONSENT_GIVEN" | "DOCUMENT_VIEWED" | "FULL_NAME_TYPED" | "PROCESSING_ERROR" | "SEAL_COMPUTED" | "SIGNATURE_ACCEPTED" | "SIGNATURE_COMPLETED" | "TIMESTAMP_REQUESTED";
|
||||||
export type RecordSigningEventInput = {
|
export type RecordSigningEventInput = {
|
||||||
eventType: ElectronicSignatureEventType;
|
eventType: ElectronicSignatureEventType;
|
||||||
signatureId: string;
|
signatureId: string;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* @generated SignedSource<<47d15b007fc81de3850393c9b158726c>>
|
* @generated SignedSource<<5c6134b4d6615f24a63ea534c80e76c1>>
|
||||||
* @lightSyntaxTransform
|
* @lightSyntaxTransform
|
||||||
* @nogrep
|
* @nogrep
|
||||||
*/
|
*/
|
||||||
@@ -100,31 +100,42 @@ return {
|
|||||||
{
|
{
|
||||||
"alias": null,
|
"alias": null,
|
||||||
"args": null,
|
"args": null,
|
||||||
"concreteType": "ElectronicSignature",
|
"concreteType": "NonDisclosureAgreement",
|
||||||
"kind": "LinkedField",
|
"kind": "LinkedField",
|
||||||
"name": "ndaSignature",
|
"name": "nonDisclosureAgreement",
|
||||||
"plural": false,
|
"plural": false,
|
||||||
"selections": [
|
"selections": [
|
||||||
(v2/*: any*/),
|
|
||||||
{
|
{
|
||||||
"alias": null,
|
"alias": null,
|
||||||
"args": null,
|
"args": null,
|
||||||
"kind": "ScalarField",
|
"concreteType": "ElectronicSignature",
|
||||||
"name": "status",
|
"kind": "LinkedField",
|
||||||
"storageKey": null
|
"name": "viewerSignature",
|
||||||
},
|
"plural": false,
|
||||||
{
|
"selections": [
|
||||||
"alias": null,
|
(v2/*: any*/),
|
||||||
"args": null,
|
{
|
||||||
"kind": "ScalarField",
|
"alias": null,
|
||||||
"name": "consentText",
|
"args": null,
|
||||||
"storageKey": null
|
"kind": "ScalarField",
|
||||||
},
|
"name": "status",
|
||||||
{
|
"storageKey": null
|
||||||
"alias": null,
|
},
|
||||||
"args": null,
|
{
|
||||||
"kind": "ScalarField",
|
"alias": null,
|
||||||
"name": "lastError",
|
"args": null,
|
||||||
|
"kind": "ScalarField",
|
||||||
|
"name": "consentText",
|
||||||
|
"storageKey": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"alias": null,
|
||||||
|
"args": null,
|
||||||
|
"kind": "ScalarField",
|
||||||
|
"name": "lastError",
|
||||||
|
"storageKey": null
|
||||||
|
}
|
||||||
|
],
|
||||||
"storageKey": null
|
"storageKey": null
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -140,16 +151,16 @@ return {
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"params": {
|
"params": {
|
||||||
"cacheID": "1c61baa555ad2b24794ce0bf5ecc14ac",
|
"cacheID": "fcf227efd02b14a0cb1599e4a5f944bd",
|
||||||
"id": null,
|
"id": null,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"name": "NDAPageRefetchQuery",
|
"name": "NDAPageRefetchQuery",
|
||||||
"operationKind": "query",
|
"operationKind": "query",
|
||||||
"text": "query NDAPageRefetchQuery(\n $id: ID!\n) {\n node(id: $id) {\n __typename\n ...NDAPageFragment\n id\n }\n}\n\nfragment NDAPageFragment on TrustCenter {\n ndaSignature {\n id\n status\n consentText\n lastError\n }\n id\n}\n"
|
"text": "query NDAPageRefetchQuery(\n $id: ID!\n) {\n node(id: $id) {\n __typename\n ...NDAPageFragment\n id\n }\n}\n\nfragment NDAPageFragment on TrustCenter {\n nonDisclosureAgreement {\n viewerSignature {\n id\n status\n consentText\n lastError\n }\n }\n id\n}\n"
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
|
||||||
(node as any).hash = "b53a5f455508ed45124b7d09cfb573da";
|
(node as any).hash = "503859b8c00b27214f9f3253bffcb670";
|
||||||
|
|
||||||
export default node;
|
export default node;
|
||||||
|
|||||||
@@ -13,10 +13,12 @@ export const currentTrustGraphQuery = graphql`
|
|||||||
isViewerMember
|
isViewerMember
|
||||||
logoFileUrl
|
logoFileUrl
|
||||||
darkLogoFileUrl
|
darkLogoFileUrl
|
||||||
ndaFileName
|
nonDisclosureAgreement {
|
||||||
ndaFileUrl
|
fileName
|
||||||
ndaSignature {
|
fileUrl
|
||||||
status
|
viewerSignature {
|
||||||
|
status
|
||||||
|
}
|
||||||
}
|
}
|
||||||
organization {
|
organization {
|
||||||
name
|
name
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* @generated SignedSource<<4bf04c5599ef88c6104919907fb182dd>>
|
* @generated SignedSource<<c89278f85dedf2e3c5d8dbd77cd19222>>
|
||||||
* @lightSyntaxTransform
|
* @lightSyntaxTransform
|
||||||
* @nogrep
|
* @nogrep
|
||||||
*/
|
*/
|
||||||
@@ -26,10 +26,12 @@ export type TrustGraphCurrentQuery$data = {
|
|||||||
readonly id: string;
|
readonly id: string;
|
||||||
readonly isViewerMember: boolean;
|
readonly isViewerMember: boolean;
|
||||||
readonly logoFileUrl: string | null | undefined;
|
readonly logoFileUrl: string | null | undefined;
|
||||||
readonly ndaFileName: string | null | undefined;
|
readonly nonDisclosureAgreement: {
|
||||||
readonly ndaFileUrl: string | null | undefined;
|
readonly fileName: string;
|
||||||
readonly ndaSignature: {
|
readonly fileUrl: string;
|
||||||
readonly status: ElectronicSignatureStatus;
|
readonly viewerSignature: {
|
||||||
|
readonly status: ElectronicSignatureStatus;
|
||||||
|
} | null | undefined;
|
||||||
} | null | undefined;
|
} | null | undefined;
|
||||||
readonly organization: {
|
readonly organization: {
|
||||||
readonly description: string | null | undefined;
|
readonly description: string | null | undefined;
|
||||||
@@ -108,14 +110,14 @@ v7 = {
|
|||||||
"alias": null,
|
"alias": null,
|
||||||
"args": null,
|
"args": null,
|
||||||
"kind": "ScalarField",
|
"kind": "ScalarField",
|
||||||
"name": "ndaFileName",
|
"name": "fileName",
|
||||||
"storageKey": null
|
"storageKey": null
|
||||||
},
|
},
|
||||||
v8 = {
|
v8 = {
|
||||||
"alias": null,
|
"alias": null,
|
||||||
"args": null,
|
"args": null,
|
||||||
"kind": "ScalarField",
|
"kind": "ScalarField",
|
||||||
"name": "ndaFileUrl",
|
"name": "fileUrl",
|
||||||
"storageKey": null
|
"storageKey": null
|
||||||
},
|
},
|
||||||
v9 = {
|
v9 = {
|
||||||
@@ -238,17 +240,28 @@ return {
|
|||||||
(v4/*: any*/),
|
(v4/*: any*/),
|
||||||
(v5/*: any*/),
|
(v5/*: any*/),
|
||||||
(v6/*: any*/),
|
(v6/*: any*/),
|
||||||
(v7/*: any*/),
|
|
||||||
(v8/*: any*/),
|
|
||||||
{
|
{
|
||||||
"alias": null,
|
"alias": null,
|
||||||
"args": null,
|
"args": null,
|
||||||
"concreteType": "ElectronicSignature",
|
"concreteType": "NonDisclosureAgreement",
|
||||||
"kind": "LinkedField",
|
"kind": "LinkedField",
|
||||||
"name": "ndaSignature",
|
"name": "nonDisclosureAgreement",
|
||||||
"plural": false,
|
"plural": false,
|
||||||
"selections": [
|
"selections": [
|
||||||
(v9/*: any*/)
|
(v7/*: any*/),
|
||||||
|
(v8/*: any*/),
|
||||||
|
{
|
||||||
|
"alias": null,
|
||||||
|
"args": null,
|
||||||
|
"concreteType": "ElectronicSignature",
|
||||||
|
"kind": "LinkedField",
|
||||||
|
"name": "viewerSignature",
|
||||||
|
"plural": false,
|
||||||
|
"selections": [
|
||||||
|
(v9/*: any*/)
|
||||||
|
],
|
||||||
|
"storageKey": null
|
||||||
|
}
|
||||||
],
|
],
|
||||||
"storageKey": null
|
"storageKey": null
|
||||||
},
|
},
|
||||||
@@ -353,18 +366,29 @@ return {
|
|||||||
(v4/*: any*/),
|
(v4/*: any*/),
|
||||||
(v5/*: any*/),
|
(v5/*: any*/),
|
||||||
(v6/*: any*/),
|
(v6/*: any*/),
|
||||||
(v7/*: any*/),
|
|
||||||
(v8/*: any*/),
|
|
||||||
{
|
{
|
||||||
"alias": null,
|
"alias": null,
|
||||||
"args": null,
|
"args": null,
|
||||||
"concreteType": "ElectronicSignature",
|
"concreteType": "NonDisclosureAgreement",
|
||||||
"kind": "LinkedField",
|
"kind": "LinkedField",
|
||||||
"name": "ndaSignature",
|
"name": "nonDisclosureAgreement",
|
||||||
"plural": false,
|
"plural": false,
|
||||||
"selections": [
|
"selections": [
|
||||||
(v9/*: any*/),
|
(v7/*: any*/),
|
||||||
(v2/*: any*/)
|
(v8/*: any*/),
|
||||||
|
{
|
||||||
|
"alias": null,
|
||||||
|
"args": null,
|
||||||
|
"concreteType": "ElectronicSignature",
|
||||||
|
"kind": "LinkedField",
|
||||||
|
"name": "viewerSignature",
|
||||||
|
"plural": false,
|
||||||
|
"selections": [
|
||||||
|
(v9/*: any*/),
|
||||||
|
(v2/*: any*/)
|
||||||
|
],
|
||||||
|
"storageKey": null
|
||||||
|
}
|
||||||
],
|
],
|
||||||
"storageKey": null
|
"storageKey": null
|
||||||
},
|
},
|
||||||
@@ -667,16 +691,16 @@ return {
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"params": {
|
"params": {
|
||||||
"cacheID": "5756e245b9ad1dc00d25c505e4764a62",
|
"cacheID": "011070e93164ecde082cc2e74651ef2e",
|
||||||
"id": null,
|
"id": null,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"name": "TrustGraphCurrentQuery",
|
"name": "TrustGraphCurrentQuery",
|
||||||
"operationKind": "query",
|
"operationKind": "query",
|
||||||
"text": "query TrustGraphCurrentQuery {\n viewer {\n email\n fullName\n id\n }\n currentTrustCenter {\n id\n slug\n isViewerMember\n logoFileUrl\n darkLogoFileUrl\n ndaFileName\n ndaFileUrl\n ndaSignature {\n status\n id\n }\n organization {\n name\n description\n websiteUrl\n email\n headquarterAddress\n id\n }\n ...OverviewPageFragment\n vendorInfo: vendors(first: 0) {\n totalCount\n }\n audits(first: 50) {\n edges {\n node {\n id\n ...AuditRowFragment\n }\n }\n }\n }\n}\n\nfragment AuditRowFragment on Audit {\n report {\n id\n filename\n isUserAuthorized\n hasUserRequestedAccess\n }\n framework {\n id\n name\n lightLogoURL\n darkLogoURL\n }\n}\n\nfragment DocumentRowFragment on Document {\n id\n title\n isUserAuthorized\n hasUserRequestedAccess\n}\n\nfragment OverviewPageFragment on TrustCenter {\n references(first: 14) {\n edges {\n node {\n id\n name\n logoUrl\n websiteUrl\n }\n }\n }\n vendors(first: 3) {\n edges {\n node {\n id\n countries\n ...VendorRowFragment\n }\n }\n }\n documents(first: 5) {\n edges {\n node {\n id\n ...DocumentRowFragment\n documentType\n }\n }\n }\n trustCenterFiles(first: 5) {\n edges {\n node {\n id\n category\n ...TrustCenterFileRowFragment\n }\n }\n }\n}\n\nfragment TrustCenterFileRowFragment on TrustCenterFile {\n id\n name\n isUserAuthorized\n hasUserRequestedAccess\n}\n\nfragment VendorRowFragment on Vendor {\n name\n description\n websiteUrl\n countries\n}\n"
|
"text": "query TrustGraphCurrentQuery {\n viewer {\n email\n fullName\n id\n }\n currentTrustCenter {\n id\n slug\n isViewerMember\n logoFileUrl\n darkLogoFileUrl\n nonDisclosureAgreement {\n fileName\n fileUrl\n viewerSignature {\n status\n id\n }\n }\n organization {\n name\n description\n websiteUrl\n email\n headquarterAddress\n id\n }\n ...OverviewPageFragment\n vendorInfo: vendors(first: 0) {\n totalCount\n }\n audits(first: 50) {\n edges {\n node {\n id\n ...AuditRowFragment\n }\n }\n }\n }\n}\n\nfragment AuditRowFragment on Audit {\n report {\n id\n filename\n isUserAuthorized\n hasUserRequestedAccess\n }\n framework {\n id\n name\n lightLogoURL\n darkLogoURL\n }\n}\n\nfragment DocumentRowFragment on Document {\n id\n title\n isUserAuthorized\n hasUserRequestedAccess\n}\n\nfragment OverviewPageFragment on TrustCenter {\n references(first: 14) {\n edges {\n node {\n id\n name\n logoUrl\n websiteUrl\n }\n }\n }\n vendors(first: 3) {\n edges {\n node {\n id\n countries\n ...VendorRowFragment\n }\n }\n }\n documents(first: 5) {\n edges {\n node {\n id\n ...DocumentRowFragment\n documentType\n }\n }\n }\n trustCenterFiles(first: 5) {\n edges {\n node {\n id\n category\n ...TrustCenterFileRowFragment\n }\n }\n }\n}\n\nfragment TrustCenterFileRowFragment on TrustCenterFile {\n id\n name\n isUserAuthorized\n hasUserRequestedAccess\n}\n\nfragment VendorRowFragment on Vendor {\n name\n description\n websiteUrl\n countries\n}\n"
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
|
||||||
(node as any).hash = "3b8d99e97c59c613f0ef2f01951a5221";
|
(node as any).hash = "6cbe676214b698d12e2cae08060a7285";
|
||||||
|
|
||||||
export default node;
|
export default node;
|
||||||
|
|||||||
2
go.mod
2
go.mod
@@ -17,7 +17,6 @@ require (
|
|||||||
github.com/elimity-com/scim v0.0.0-20240320110924-172bf2aee9c8
|
github.com/elimity-com/scim v0.0.0-20240320110924-172bf2aee9c8
|
||||||
github.com/go-chi/chi/v5 v5.2.4
|
github.com/go-chi/chi/v5 v5.2.4
|
||||||
github.com/go-chi/cors v1.2.2
|
github.com/go-chi/cors v1.2.2
|
||||||
github.com/google/uuid v1.6.0
|
|
||||||
github.com/jackc/pgx/v5 v5.8.0
|
github.com/jackc/pgx/v5 v5.8.0
|
||||||
github.com/jhillyerd/enmime v1.3.0
|
github.com/jhillyerd/enmime v1.3.0
|
||||||
github.com/modelcontextprotocol/go-sdk v1.2.0
|
github.com/modelcontextprotocol/go-sdk v1.2.0
|
||||||
@@ -85,6 +84,7 @@ require (
|
|||||||
github.com/google/jsonschema-go v0.4.2 // indirect
|
github.com/google/jsonschema-go v0.4.2 // indirect
|
||||||
github.com/google/s2a-go v0.1.9 // indirect
|
github.com/google/s2a-go v0.1.9 // indirect
|
||||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
|
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
|
||||||
|
github.com/google/uuid v1.6.0 // indirect
|
||||||
github.com/googleapis/enterprise-certificate-proxy v0.3.9 // indirect
|
github.com/googleapis/enterprise-certificate-proxy v0.3.9 // indirect
|
||||||
github.com/googleapis/gax-go/v2 v2.16.0 // indirect
|
github.com/googleapis/gax-go/v2 v2.16.0 // indirect
|
||||||
github.com/gorilla/websocket v1.5.3 // indirect
|
github.com/gorilla/websocket v1.5.3 // indirect
|
||||||
|
|||||||
@@ -216,58 +216,6 @@ LIMIT 1
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (es *ElectronicSignature) LoadByOrgEmailAndDocType(
|
|
||||||
ctx context.Context,
|
|
||||||
conn pg.Conn,
|
|
||||||
scope Scoper,
|
|
||||||
orgID gid.GID,
|
|
||||||
email string,
|
|
||||||
docType ElectronicSignatureDocumentType,
|
|
||||||
fileID gid.GID,
|
|
||||||
) error {
|
|
||||||
q := `
|
|
||||||
SELECT
|
|
||||||
id, tenant_id, organization_id, status, document_type, file_id,
|
|
||||||
signer_email, consent_text, signer_full_name, signer_ip_address,
|
|
||||||
signer_user_agent, file_hash, seal, seal_version, tsa_token, signed_at,
|
|
||||||
certificate_file_id, certificate_processing_started_at,
|
|
||||||
attempt_count, max_attempts, last_attempted_at, last_error,
|
|
||||||
processing_started_at, created_at, updated_at
|
|
||||||
FROM electronic_signatures
|
|
||||||
WHERE %s
|
|
||||||
AND organization_id = @organization_id
|
|
||||||
AND signer_email = @signer_email
|
|
||||||
AND document_type = @document_type
|
|
||||||
AND file_id = @file_id
|
|
||||||
LIMIT 1
|
|
||||||
`
|
|
||||||
q = fmt.Sprintf(q, scope.SQLFragment())
|
|
||||||
|
|
||||||
args := pgx.StrictNamedArgs{
|
|
||||||
"organization_id": orgID,
|
|
||||||
"signer_email": email,
|
|
||||||
"document_type": docType,
|
|
||||||
"file_id": fileID,
|
|
||||||
}
|
|
||||||
maps.Copy(args, scope.SQLArguments())
|
|
||||||
|
|
||||||
rows, err := conn.Query(ctx, q, args)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("cannot query electronic signature: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
sig, err := pgx.CollectExactlyOneRow(rows, pgx.RowToStructByName[ElectronicSignature])
|
|
||||||
if err != nil {
|
|
||||||
if errors.Is(err, pgx.ErrNoRows) {
|
|
||||||
return ErrResourceNotFound
|
|
||||||
}
|
|
||||||
return fmt.Errorf("cannot collect electronic signature: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
*es = sig
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (es *ElectronicSignature) LoadNextAcceptedForUpdateSkipLocked(
|
func (es *ElectronicSignature) LoadNextAcceptedForUpdateSkipLocked(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
conn pg.Conn,
|
conn pg.Conn,
|
||||||
|
|||||||
2
pkg/coredata/migrations/20260220T092400Z.sql
Normal file
2
pkg/coredata/migrations/20260220T092400Z.sql
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
ALTER TABLE trust_center_accesses
|
||||||
|
ADD COLUMN electronic_signature_id TEXT REFERENCES electronic_signatures(id);
|
||||||
@@ -42,6 +42,7 @@ type (
|
|||||||
HasAcceptedNonDisclosureAgreement bool `db:"has_accepted_non_disclosure_agreement"`
|
HasAcceptedNonDisclosureAgreement bool `db:"has_accepted_non_disclosure_agreement"`
|
||||||
HasAcceptedNonDisclosureAgreementMetadata json.RawMessage `db:"has_accepted_non_disclosure_agreement_metadata"`
|
HasAcceptedNonDisclosureAgreementMetadata json.RawMessage `db:"has_accepted_non_disclosure_agreement_metadata"`
|
||||||
NDAFileID *gid.GID `db:"nda_file_id"`
|
NDAFileID *gid.GID `db:"nda_file_id"`
|
||||||
|
ElectronicSignatureID *gid.GID `db:"electronic_signature_id"`
|
||||||
CreatedAt time.Time `db:"created_at"`
|
CreatedAt time.Time `db:"created_at"`
|
||||||
UpdatedAt time.Time `db:"updated_at"`
|
UpdatedAt time.Time `db:"updated_at"`
|
||||||
}
|
}
|
||||||
@@ -90,6 +91,7 @@ SELECT
|
|||||||
has_accepted_non_disclosure_agreement,
|
has_accepted_non_disclosure_agreement,
|
||||||
has_accepted_non_disclosure_agreement_metadata,
|
has_accepted_non_disclosure_agreement_metadata,
|
||||||
nda_file_id,
|
nda_file_id,
|
||||||
|
electronic_signature_id,
|
||||||
created_at,
|
created_at,
|
||||||
updated_at
|
updated_at
|
||||||
FROM
|
FROM
|
||||||
@@ -143,6 +145,7 @@ SELECT
|
|||||||
has_accepted_non_disclosure_agreement,
|
has_accepted_non_disclosure_agreement,
|
||||||
has_accepted_non_disclosure_agreement_metadata,
|
has_accepted_non_disclosure_agreement_metadata,
|
||||||
nda_file_id,
|
nda_file_id,
|
||||||
|
electronic_signature_id,
|
||||||
created_at,
|
created_at,
|
||||||
updated_at
|
updated_at
|
||||||
FROM
|
FROM
|
||||||
@@ -196,6 +199,7 @@ INSERT INTO trust_center_accesses (
|
|||||||
name,
|
name,
|
||||||
state,
|
state,
|
||||||
has_accepted_non_disclosure_agreement,
|
has_accepted_non_disclosure_agreement,
|
||||||
|
electronic_signature_id,
|
||||||
created_at,
|
created_at,
|
||||||
updated_at
|
updated_at
|
||||||
) VALUES (
|
) VALUES (
|
||||||
@@ -207,6 +211,7 @@ INSERT INTO trust_center_accesses (
|
|||||||
@name,
|
@name,
|
||||||
@state,
|
@state,
|
||||||
@has_accepted_non_disclosure_agreement,
|
@has_accepted_non_disclosure_agreement,
|
||||||
|
@electronic_signature_id,
|
||||||
@created_at,
|
@created_at,
|
||||||
@updated_at
|
@updated_at
|
||||||
)
|
)
|
||||||
@@ -221,6 +226,7 @@ INSERT INTO trust_center_accesses (
|
|||||||
"name": tca.Name,
|
"name": tca.Name,
|
||||||
"state": tca.State,
|
"state": tca.State,
|
||||||
"has_accepted_non_disclosure_agreement": tca.HasAcceptedNonDisclosureAgreement,
|
"has_accepted_non_disclosure_agreement": tca.HasAcceptedNonDisclosureAgreement,
|
||||||
|
"electronic_signature_id": tca.ElectronicSignatureID,
|
||||||
"created_at": tca.CreatedAt,
|
"created_at": tca.CreatedAt,
|
||||||
"updated_at": tca.UpdatedAt,
|
"updated_at": tca.UpdatedAt,
|
||||||
}
|
}
|
||||||
@@ -251,7 +257,8 @@ UPDATE trust_center_accesses SET
|
|||||||
updated_at = @updated_at,
|
updated_at = @updated_at,
|
||||||
has_accepted_non_disclosure_agreement = @has_accepted_non_disclosure_agreement,
|
has_accepted_non_disclosure_agreement = @has_accepted_non_disclosure_agreement,
|
||||||
has_accepted_non_disclosure_agreement_metadata = @has_accepted_non_disclosure_agreement_metadata,
|
has_accepted_non_disclosure_agreement_metadata = @has_accepted_non_disclosure_agreement_metadata,
|
||||||
nda_file_id = @nda_file_id
|
nda_file_id = @nda_file_id,
|
||||||
|
electronic_signature_id = @electronic_signature_id
|
||||||
WHERE
|
WHERE
|
||||||
%s
|
%s
|
||||||
AND id = @id
|
AND id = @id
|
||||||
@@ -266,7 +273,8 @@ WHERE
|
|||||||
"updated_at": tca.UpdatedAt,
|
"updated_at": tca.UpdatedAt,
|
||||||
"has_accepted_non_disclosure_agreement": tca.HasAcceptedNonDisclosureAgreement,
|
"has_accepted_non_disclosure_agreement": tca.HasAcceptedNonDisclosureAgreement,
|
||||||
"has_accepted_non_disclosure_agreement_metadata": tca.HasAcceptedNonDisclosureAgreementMetadata,
|
"has_accepted_non_disclosure_agreement_metadata": tca.HasAcceptedNonDisclosureAgreementMetadata,
|
||||||
"nda_file_id": tca.NDAFileID,
|
"nda_file_id": tca.NDAFileID,
|
||||||
|
"electronic_signature_id": tca.ElectronicSignatureID,
|
||||||
}
|
}
|
||||||
maps.Copy(args, scope.SQLArguments())
|
maps.Copy(args, scope.SQLArguments())
|
||||||
|
|
||||||
@@ -324,6 +332,7 @@ SELECT
|
|||||||
has_accepted_non_disclosure_agreement,
|
has_accepted_non_disclosure_agreement,
|
||||||
has_accepted_non_disclosure_agreement_metadata,
|
has_accepted_non_disclosure_agreement_metadata,
|
||||||
nda_file_id,
|
nda_file_id,
|
||||||
|
electronic_signature_id,
|
||||||
created_at,
|
created_at,
|
||||||
updated_at
|
updated_at
|
||||||
FROM
|
FROM
|
||||||
|
|||||||
@@ -174,16 +174,16 @@ func (s *Service) CreateSignature(
|
|||||||
return sig, nil
|
return sig, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) AcceptSignature(ctx context.Context, req *AcceptSignatureRequest) error {
|
func (s *Service) AcceptSignature(ctx context.Context, req *AcceptSignatureRequest) (*coredata.ElectronicSignature, error) {
|
||||||
var (
|
var (
|
||||||
scope = coredata.NewScopeFromObjectID(req.SignatureID)
|
scope = coredata.NewScopeFromObjectID(req.SignatureID)
|
||||||
now = time.Now()
|
now = time.Now()
|
||||||
|
signature = coredata.ElectronicSignature{}
|
||||||
)
|
)
|
||||||
|
|
||||||
return s.pg.WithTx(
|
err := s.pg.WithTx(
|
||||||
ctx,
|
ctx,
|
||||||
func(tx pg.Conn) error {
|
func(tx pg.Conn) error {
|
||||||
var signature coredata.ElectronicSignature
|
|
||||||
if err := signature.LoadByID(ctx, tx, scope, req.SignatureID); err != nil {
|
if err := signature.LoadByID(ctx, tx, scope, req.SignatureID); err != nil {
|
||||||
return fmt.Errorf("cannot load electronic signature: %w", err)
|
return fmt.Errorf("cannot load electronic signature: %w", err)
|
||||||
}
|
}
|
||||||
@@ -193,7 +193,6 @@ func (s *Service) AcceptSignature(ctx context.Context, req *AcceptSignatureReque
|
|||||||
return fmt.Errorf("cannot accept electronic signature in status %s", signature.Status)
|
return fmt.Errorf("cannot accept electronic signature in status %s", signature.Status)
|
||||||
}
|
}
|
||||||
|
|
||||||
// If retrying from FAILED, reset attempt tracking.
|
|
||||||
if signature.Status == coredata.ElectronicSignatureStatusFailed {
|
if signature.Status == coredata.ElectronicSignatureStatusFailed {
|
||||||
signature.AttemptCount = 0
|
signature.AttemptCount = 0
|
||||||
signature.LastError = nil
|
signature.LastError = nil
|
||||||
@@ -210,7 +209,7 @@ func (s *Service) AcceptSignature(ctx context.Context, req *AcceptSignatureReque
|
|||||||
return fmt.Errorf("cannot update signature: %w", err)
|
return fmt.Errorf("cannot update signature: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
s.recordEvent(
|
if err := s.recordEvent(
|
||||||
ctx,
|
ctx,
|
||||||
tx,
|
tx,
|
||||||
&RecordEventRequest{
|
&RecordEventRequest{
|
||||||
@@ -221,11 +220,18 @@ func (s *Service) AcceptSignature(ctx context.Context, req *AcceptSignatureReque
|
|||||||
ActorIPAddr: req.SignerIPAddr,
|
ActorIPAddr: req.SignerIPAddr,
|
||||||
ActorUA: req.SignerUA,
|
ActorUA: req.SignerUA,
|
||||||
},
|
},
|
||||||
)
|
); err != nil {
|
||||||
|
return fmt.Errorf("cannot record event: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &signature, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) RecordEvent(ctx context.Context, req *RecordEventRequest) error {
|
func (s *Service) RecordEvent(ctx context.Context, req *RecordEventRequest) error {
|
||||||
@@ -262,7 +268,7 @@ func (s *Service) recordEvent(ctx context.Context, tx pg.Conn, req *RecordEventR
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) LoadSignatureByID(ctx context.Context, id gid.GID) (*coredata.ElectronicSignature, error) {
|
func (s *Service) GetSignatureByID(ctx context.Context, id gid.GID) (*coredata.ElectronicSignature, error) {
|
||||||
var (
|
var (
|
||||||
scope = coredata.NewScopeFromObjectID(id)
|
scope = coredata.NewScopeFromObjectID(id)
|
||||||
signature = coredata.ElectronicSignature{}
|
signature = coredata.ElectronicSignature{}
|
||||||
@@ -285,36 +291,28 @@ func (s *Service) LoadSignatureByID(ctx context.Context, id gid.GID) (*coredata.
|
|||||||
return &signature, nil
|
return &signature, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) LoadSignatureByOrgEmailAndDocType(
|
|
||||||
ctx context.Context,
|
|
||||||
orgID gid.GID,
|
|
||||||
email string,
|
|
||||||
docType coredata.ElectronicSignatureDocumentType,
|
|
||||||
fileID gid.GID,
|
|
||||||
) (*coredata.ElectronicSignature, error) {
|
|
||||||
scope := coredata.NewScopeFromObjectID(orgID)
|
|
||||||
var sig coredata.ElectronicSignature
|
|
||||||
err := s.pg.WithConn(ctx, func(conn pg.Conn) error {
|
|
||||||
return sig.LoadByOrgEmailAndDocType(ctx, conn, scope, orgID, email, docType, fileID)
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &sig, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Service) GenerateCertificateFileURL(
|
func (s *Service) GenerateCertificateFileURL(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
certificateFileID gid.GID,
|
certificateFileID gid.GID,
|
||||||
expiresIn time.Duration,
|
expiresIn time.Duration,
|
||||||
) (string, error) {
|
) (string, error) {
|
||||||
scope := coredata.NewScopeFromObjectID(certificateFileID)
|
var (
|
||||||
var file coredata.File
|
scope = coredata.NewScopeFromObjectID(certificateFileID)
|
||||||
err := s.pg.WithConn(ctx, func(conn pg.Conn) error {
|
file = coredata.File{}
|
||||||
return file.LoadByID(ctx, conn, scope, certificateFileID)
|
)
|
||||||
})
|
|
||||||
|
err := s.pg.WithConn(
|
||||||
|
ctx,
|
||||||
|
func(conn pg.Conn) error {
|
||||||
|
if err := file.LoadByID(ctx, conn, scope, certificateFileID); err != nil {
|
||||||
|
return fmt.Errorf("cannot load certificate file: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("cannot load certificate file: %w", err)
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
url, err := s.fileManager.GenerateFileUrl(ctx, &file, expiresIn)
|
url, err := s.fileManager.GenerateFileUrl(ctx, &file, expiresIn)
|
||||||
@@ -325,7 +323,7 @@ func (s *Service) GenerateCertificateFileURL(
|
|||||||
return url, nil
|
return url, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) LoadEventsBySignatureID(
|
func (s *Service) GetEventsBySignatureID(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
signatureID gid.GID,
|
signatureID gid.GID,
|
||||||
) (coredata.ElectronicSignatureEvents, error) {
|
) (coredata.ElectronicSignatureEvents, error) {
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ func (c *TSAClient) Timestamp(ctx context.Context, data []byte) ([]byte, error)
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("esign: TSA request failed: %w", err)
|
return nil, fmt.Errorf("esign: TSA request failed: %w", err)
|
||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
defer func() { _ = resp.Body.Close() }()
|
||||||
|
|
||||||
if resp.StatusCode != http.StatusOK {
|
if resp.StatusCode != http.StatusOK {
|
||||||
return nil, fmt.Errorf("esign: TSA returned HTTP %d", resp.StatusCode)
|
return nil, fmt.Errorf("esign: TSA returned HTTP %d", resp.StatusCode)
|
||||||
|
|||||||
@@ -250,12 +250,8 @@ func (s TrustCenterAccessService) Create(
|
|||||||
UpdatedAt: now,
|
UpdatedAt: now,
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := access.Insert(ctx, tx, s.svc.scope); err != nil {
|
|
||||||
return fmt.Errorf("cannot insert trust center access: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if trustCenter.NonDisclosureAgreementFileID != nil && s.svc.esign != nil {
|
if trustCenter.NonDisclosureAgreementFileID != nil && s.svc.esign != nil {
|
||||||
_, err := s.svc.esign.CreateSignature(
|
sig, err := s.svc.esign.CreateSignature(
|
||||||
ctx,
|
ctx,
|
||||||
tx,
|
tx,
|
||||||
&esign.CreateSignatureRequest{
|
&esign.CreateSignatureRequest{
|
||||||
@@ -265,10 +261,14 @@ func (s TrustCenterAccessService) Create(
|
|||||||
SignerEmail: access.Email,
|
SignerEmail: access.Email,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("cannot create pending signature: %w", err)
|
return fmt.Errorf("cannot create pending signature: %w", err)
|
||||||
}
|
}
|
||||||
|
access.ElectronicSignatureID = &sig.ID
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := access.Insert(ctx, tx, s.svc.scope); err != nil {
|
||||||
|
return fmt.Errorf("cannot insert trust center access: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@@ -107,9 +107,8 @@ func (req *UpdateTrustCenterBrandRequest) Validate() error {
|
|||||||
func (s TrustCenterService) Get(
|
func (s TrustCenterService) Get(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
trustCenterID gid.GID,
|
trustCenterID gid.GID,
|
||||||
) (*coredata.TrustCenter, *coredata.File, error) {
|
) (*coredata.TrustCenter, error) {
|
||||||
var trustCenter *coredata.TrustCenter
|
var trustCenter *coredata.TrustCenter
|
||||||
var file *coredata.File
|
|
||||||
|
|
||||||
err := s.svc.pg.WithConn(
|
err := s.svc.pg.WithConn(
|
||||||
ctx,
|
ctx,
|
||||||
@@ -119,30 +118,22 @@ func (s TrustCenterService) Get(
|
|||||||
return fmt.Errorf("cannot load trust center: %w", err)
|
return fmt.Errorf("cannot load trust center: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if trustCenter.NonDisclosureAgreementFileID != nil {
|
|
||||||
file = &coredata.File{}
|
|
||||||
if err := file.LoadByID(ctx, conn, s.svc.scope, *trustCenter.NonDisclosureAgreementFileID); err != nil {
|
|
||||||
return fmt.Errorf("cannot load file: %w", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, fmt.Errorf("cannot load trust center: %w", err)
|
return nil, fmt.Errorf("cannot load trust center: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return trustCenter, file, nil
|
return trustCenter, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s TrustCenterService) GetByOrganizationID(
|
func (s TrustCenterService) GetByOrganizationID(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
organizationID gid.GID,
|
organizationID gid.GID,
|
||||||
) (*coredata.TrustCenter, *coredata.File, error) {
|
) (*coredata.TrustCenter, error) {
|
||||||
var trustCenter *coredata.TrustCenter
|
var trustCenter *coredata.TrustCenter
|
||||||
var file *coredata.File
|
|
||||||
|
|
||||||
err := s.svc.pg.WithConn(
|
err := s.svc.pg.WithConn(
|
||||||
ctx,
|
ctx,
|
||||||
@@ -152,22 +143,15 @@ func (s TrustCenterService) GetByOrganizationID(
|
|||||||
return fmt.Errorf("cannot load trust center: %w", err)
|
return fmt.Errorf("cannot load trust center: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if trustCenter.NonDisclosureAgreementFileID != nil {
|
|
||||||
file = &coredata.File{}
|
|
||||||
if err := file.LoadByID(ctx, conn, s.svc.scope, *trustCenter.NonDisclosureAgreementFileID); err != nil {
|
|
||||||
return fmt.Errorf("cannot load file: %w", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return trustCenter, file, nil
|
return trustCenter, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s TrustCenterService) Update(
|
func (s TrustCenterService) Update(
|
||||||
|
|||||||
@@ -1243,7 +1243,7 @@ func (r *documentVersionSignatureConnectionResolver) TotalCount(ctx context.Cont
|
|||||||
|
|
||||||
// CertificateFileURL is the resolver for the certificateFileUrl field.
|
// CertificateFileURL is the resolver for the certificateFileUrl field.
|
||||||
func (r *electronicSignatureResolver) CertificateFileURL(ctx context.Context, obj *types.ElectronicSignature) (*string, error) {
|
func (r *electronicSignatureResolver) CertificateFileURL(ctx context.Context, obj *types.ElectronicSignature) (*string, error) {
|
||||||
sig, err := r.esign.LoadSignatureByID(ctx, obj.ID)
|
sig, err := r.esign.GetSignatureByID(ctx, obj.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("cannot load signature: %w", err)
|
return nil, fmt.Errorf("cannot load signature: %w", err)
|
||||||
}
|
}
|
||||||
@@ -1262,7 +1262,7 @@ func (r *electronicSignatureResolver) CertificateFileURL(ctx context.Context, ob
|
|||||||
|
|
||||||
// Events is the resolver for the events field.
|
// Events is the resolver for the events field.
|
||||||
func (r *electronicSignatureResolver) Events(ctx context.Context, obj *types.ElectronicSignature) ([]*types.ElectronicSignatureEvent, error) {
|
func (r *electronicSignatureResolver) Events(ctx context.Context, obj *types.ElectronicSignature) ([]*types.ElectronicSignatureEvent, error) {
|
||||||
events, err := r.esign.LoadEventsBySignatureID(ctx, obj.ID)
|
events, err := r.esign.GetEventsBySignatureID(ctx, obj.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("cannot load signature events: %w", err)
|
return nil, fmt.Errorf("cannot load signature events: %w", err)
|
||||||
}
|
}
|
||||||
@@ -6394,13 +6394,13 @@ func (r *organizationResolver) TrustCenter(ctx context.Context, obj *types.Organ
|
|||||||
|
|
||||||
prb := r.ProboService(ctx, obj.ID.TenantID())
|
prb := r.ProboService(ctx, obj.ID.TenantID())
|
||||||
|
|
||||||
trustCenter, file, err := prb.TrustCenters.GetByOrganizationID(ctx, obj.ID)
|
trustCenter, err := prb.TrustCenters.GetByOrganizationID(ctx, obj.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// TODO no panic use gqlutils.InternalError
|
// TODO no panic use gqlutils.InternalError
|
||||||
panic(fmt.Errorf("cannot get trust center: %w", err))
|
panic(fmt.Errorf("cannot get trust center: %w", err))
|
||||||
}
|
}
|
||||||
|
|
||||||
return types.NewTrustCenter(trustCenter, file), nil
|
return types.NewTrustCenter(trustCenter, nil), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// CustomDomain is the resolver for the customDomain field.
|
// CustomDomain is the resolver for the customDomain field.
|
||||||
@@ -6874,11 +6874,11 @@ func (r *queryResolver) Node(ctx context.Context, id gid.GID) (types.Node, error
|
|||||||
case coredata.TrustCenterEntityType:
|
case coredata.TrustCenterEntityType:
|
||||||
action = probo.ActionTrustCenterGet
|
action = probo.ActionTrustCenterGet
|
||||||
loadNode = func(ctx context.Context, id gid.GID) (types.Node, error) {
|
loadNode = func(ctx context.Context, id gid.GID) (types.Node, error) {
|
||||||
trustCenter, file, err := prb.TrustCenters.Get(ctx, id)
|
trustCenter, err := prb.TrustCenters.Get(ctx, id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return types.NewTrustCenter(trustCenter, file), nil
|
return types.NewTrustCenter(trustCenter, nil), nil
|
||||||
}
|
}
|
||||||
case coredata.TrustCenterAccessEntityType:
|
case coredata.TrustCenterAccessEntityType:
|
||||||
action = probo.ActionTrustCenterAccessGet
|
action = probo.ActionTrustCenterAccessGet
|
||||||
@@ -7739,7 +7739,7 @@ func (r *trustCenterResolver) Organization(ctx context.Context, obj *types.Trust
|
|||||||
|
|
||||||
prb := r.ProboService(ctx, obj.ID.TenantID())
|
prb := r.ProboService(ctx, obj.ID.TenantID())
|
||||||
|
|
||||||
trustCenter, _, err := prb.TrustCenters.Get(ctx, obj.ID)
|
trustCenter, err := prb.TrustCenters.Get(ctx, obj.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(fmt.Errorf("cannot get trust center: %w", err))
|
panic(fmt.Errorf("cannot get trust center: %w", err))
|
||||||
}
|
}
|
||||||
@@ -7832,24 +7832,13 @@ func (r *trustCenterAccessResolver) NdaSignature(ctx context.Context, obj *types
|
|||||||
return nil, fmt.Errorf("cannot load trust center access: %w", err)
|
return nil, fmt.Errorf("cannot load trust center access: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
trustCenter, _, err := prb.TrustCenters.Get(ctx, access.TrustCenterID)
|
if access.ElectronicSignatureID == nil {
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("cannot load trust center: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if trustCenter.NonDisclosureAgreementFileID == nil {
|
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
sig, err := r.esign.LoadSignatureByOrgEmailAndDocType(
|
sig, err := r.esign.GetSignatureByID(ctx, *access.ElectronicSignatureID)
|
||||||
ctx,
|
|
||||||
access.OrganizationID,
|
|
||||||
string(access.Email),
|
|
||||||
coredata.ElectronicSignatureDocumentTypeNDA,
|
|
||||||
*trustCenter.NonDisclosureAgreementFileID,
|
|
||||||
)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil // No signature row — pre-existing access
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return types.NewElectronicSignature(sig), nil
|
return types.NewElectronicSignature(sig), nil
|
||||||
|
|||||||
@@ -488,18 +488,23 @@ type TrustCenterFileEdge {
|
|||||||
node: TrustCenterFile!
|
node: TrustCenterFile!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type NonDisclosureAgreement {
|
||||||
|
fileName: String!
|
||||||
|
fileUrl: String! @goField(forceResolver: true)
|
||||||
|
viewerSignature: ElectronicSignature @goField(forceResolver: true)
|
||||||
|
}
|
||||||
|
|
||||||
type TrustCenter implements Node {
|
type TrustCenter implements Node {
|
||||||
id: ID!
|
id: ID!
|
||||||
active: Boolean!
|
active: Boolean!
|
||||||
slug: String!
|
slug: String!
|
||||||
logoFileUrl: String @goField(forceResolver: true)
|
logoFileUrl: String @goField(forceResolver: true)
|
||||||
darkLogoFileUrl: String @goField(forceResolver: true)
|
darkLogoFileUrl: String @goField(forceResolver: true)
|
||||||
ndaFileName: String
|
|
||||||
ndaFileUrl: String @goField(forceResolver: true)
|
nonDisclosureAgreement: NonDisclosureAgreement @goField(forceResolver: true)
|
||||||
ndaSignature: ElectronicSignature @goField(forceResolver: true)
|
|
||||||
organization: Organization! @goField(forceResolver: true)
|
|
||||||
isViewerMember: Boolean! @goField(forceResolver: true)
|
isViewerMember: Boolean! @goField(forceResolver: true)
|
||||||
hasAcceptedNonDisclosureAgreement: Boolean! @goField(forceResolver: true)
|
organization: Organization! @goField(forceResolver: true)
|
||||||
|
|
||||||
documents(
|
documents(
|
||||||
first: Int
|
first: Int
|
||||||
@@ -601,14 +606,6 @@ type ExportTrustCenterFilePayload {
|
|||||||
data: String!
|
data: String!
|
||||||
}
|
}
|
||||||
|
|
||||||
input AcceptNonDisclosureAgreementInput {
|
|
||||||
fullName: String!
|
|
||||||
}
|
|
||||||
|
|
||||||
type AcceptNonDisclosureAgreementPayload {
|
|
||||||
success: Boolean!
|
|
||||||
}
|
|
||||||
|
|
||||||
# Electronic Signature
|
# Electronic Signature
|
||||||
|
|
||||||
enum ElectronicSignatureStatus
|
enum ElectronicSignatureStatus
|
||||||
@@ -770,11 +767,7 @@ type Mutation {
|
|||||||
input: ExportTrustCenterFileInput!
|
input: ExportTrustCenterFileInput!
|
||||||
): ExportTrustCenterFilePayload! @session(required: OPTIONAL)
|
): ExportTrustCenterFilePayload! @session(required: OPTIONAL)
|
||||||
|
|
||||||
acceptNonDisclosureAgreement(
|
requestDocumentAccess(
|
||||||
input: AcceptNonDisclosureAgreementInput!
|
|
||||||
): AcceptNonDisclosureAgreementPayload @session(required: PRESENT)
|
|
||||||
|
|
||||||
requestDocumentAccess(
|
|
||||||
input: RequestDocumentAccessInput!
|
input: RequestDocumentAccessInput!
|
||||||
): RequestAccessesPayload! @session(required: PRESENT)
|
): RequestAccessesPayload! @session(required: PRESENT)
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -18,16 +18,16 @@ import (
|
|||||||
"go.probo.inc/probo/pkg/coredata"
|
"go.probo.inc/probo/pkg/coredata"
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewTrustCenter(tc *coredata.TrustCenter, file *coredata.File) *TrustCenter {
|
func NewTrustCenter(tc *coredata.TrustCenter) *TrustCenter {
|
||||||
var ndaFileName *string
|
|
||||||
if file != nil {
|
|
||||||
ndaFileName = &file.FileName
|
|
||||||
}
|
|
||||||
|
|
||||||
return &TrustCenter{
|
return &TrustCenter{
|
||||||
ID: tc.ID,
|
ID: tc.ID,
|
||||||
Active: tc.Active,
|
Active: tc.Active,
|
||||||
Slug: tc.Slug,
|
Slug: tc.Slug,
|
||||||
NdaFileName: ndaFileName,
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewNonDisclosureAgreement(file *coredata.File) *NonDisclosureAgreement {
|
||||||
|
return &NonDisclosureAgreement{
|
||||||
|
FileName: file.FileName,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,14 +25,6 @@ type AcceptElectronicSignaturePayload struct {
|
|||||||
Signature *ElectronicSignature `json:"signature"`
|
Signature *ElectronicSignature `json:"signature"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type AcceptNonDisclosureAgreementInput struct {
|
|
||||||
FullName string `json:"fullName"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type AcceptNonDisclosureAgreementPayload struct {
|
|
||||||
Success bool `json:"success"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type Audit struct {
|
type Audit struct {
|
||||||
ID gid.GID `json:"id"`
|
ID gid.GID `json:"id"`
|
||||||
Framework *Framework `json:"framework"`
|
Framework *Framework `json:"framework"`
|
||||||
@@ -136,6 +128,12 @@ func (this Identity) GetID() gid.GID { return this.ID }
|
|||||||
type Mutation struct {
|
type Mutation struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type NonDisclosureAgreement struct {
|
||||||
|
FileName string `json:"fileName"`
|
||||||
|
FileURL string `json:"fileUrl"`
|
||||||
|
ViewerSignature *ElectronicSignature `json:"viewerSignature,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
type Organization struct {
|
type Organization struct {
|
||||||
ID gid.GID `json:"id"`
|
ID gid.GID `json:"id"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
@@ -203,22 +201,19 @@ type SendMagicLinkPayload struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type TrustCenter struct {
|
type TrustCenter struct {
|
||||||
ID gid.GID `json:"id"`
|
ID gid.GID `json:"id"`
|
||||||
Active bool `json:"active"`
|
Active bool `json:"active"`
|
||||||
Slug string `json:"slug"`
|
Slug string `json:"slug"`
|
||||||
LogoFileURL *string `json:"logoFileUrl,omitempty"`
|
LogoFileURL *string `json:"logoFileUrl,omitempty"`
|
||||||
DarkLogoFileURL *string `json:"darkLogoFileUrl,omitempty"`
|
DarkLogoFileURL *string `json:"darkLogoFileUrl,omitempty"`
|
||||||
NdaFileName *string `json:"ndaFileName,omitempty"`
|
NonDisclosureAgreement *NonDisclosureAgreement `json:"nonDisclosureAgreement,omitempty"`
|
||||||
NdaFileURL *string `json:"ndaFileUrl,omitempty"`
|
IsViewerMember bool `json:"isViewerMember"`
|
||||||
NdaSignature *ElectronicSignature `json:"ndaSignature,omitempty"`
|
Organization *Organization `json:"organization"`
|
||||||
Organization *Organization `json:"organization"`
|
Documents *DocumentConnection `json:"documents"`
|
||||||
IsViewerMember bool `json:"isViewerMember"`
|
Audits *AuditConnection `json:"audits"`
|
||||||
HasAcceptedNonDisclosureAgreement bool `json:"hasAcceptedNonDisclosureAgreement"`
|
Vendors *VendorConnection `json:"vendors"`
|
||||||
Documents *DocumentConnection `json:"documents"`
|
References *TrustCenterReferenceConnection `json:"references"`
|
||||||
Audits *AuditConnection `json:"audits"`
|
TrustCenterFiles *TrustCenterFileConnection `json:"trustCenterFiles"`
|
||||||
Vendors *VendorConnection `json:"vendors"`
|
|
||||||
References *TrustCenterReferenceConnection `json:"references"`
|
|
||||||
TrustCenterFiles *TrustCenterFileConnection `json:"trustCenterFiles"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (TrustCenter) IsNode() {}
|
func (TrustCenter) IsNode() {}
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ func (r *documentResolver) IsUserAuthorized(ctx context.Context, obj *types.Docu
|
|||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
documentAccess, err := trustService.TrustCenterAccesses.LoadDocumentAccess(
|
documentAccess, err := trustService.TrustCenterAccesses.GetDocumentAccess(
|
||||||
ctx,
|
ctx,
|
||||||
trustCenter.ID,
|
trustCenter.ID,
|
||||||
identity.EmailAddress,
|
identity.EmailAddress,
|
||||||
@@ -123,7 +123,7 @@ func (r *documentResolver) HasUserRequestedAccess(ctx context.Context, obj *type
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Try to load document access - if it exists (regardless of active status), user has requested it
|
// Try to load document access - if it exists (regardless of active status), user has requested it
|
||||||
_, err := trustService.TrustCenterAccesses.LoadDocumentAccess(
|
_, err := trustService.TrustCenterAccesses.GetDocumentAccess(
|
||||||
ctx,
|
ctx,
|
||||||
trustCenter.ID,
|
trustCenter.ID,
|
||||||
identity.EmailAddress,
|
identity.EmailAddress,
|
||||||
@@ -228,6 +228,41 @@ func (r *mutationResolver) RequestAllAccesses(ctx context.Context) (*types.Reque
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *mutationResolver) checkNDASignature(
|
||||||
|
ctx context.Context,
|
||||||
|
trustCenter *coredata.TrustCenter,
|
||||||
|
identity *coredata.Identity,
|
||||||
|
) error {
|
||||||
|
if trustCenter.NonDisclosureAgreementFileID == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
trustService := r.TrustService(ctx, trustCenter.ID.TenantID())
|
||||||
|
|
||||||
|
access, err := trustService.TrustCenterAccesses.GetAccess(ctx, trustCenter.ID, identity.EmailAddress)
|
||||||
|
if err != nil {
|
||||||
|
return gqlutils.Forbiddenf(ctx, "user has not signed the NDA")
|
||||||
|
}
|
||||||
|
|
||||||
|
if access.ElectronicSignatureID == nil {
|
||||||
|
return gqlutils.Forbiddenf(ctx, "user has not signed the NDA")
|
||||||
|
}
|
||||||
|
|
||||||
|
sig, err := r.esign.GetSignatureByID(ctx, *access.ElectronicSignatureID)
|
||||||
|
if err != nil {
|
||||||
|
return gqlutils.Forbiddenf(ctx, "user has not signed the NDA")
|
||||||
|
}
|
||||||
|
|
||||||
|
switch sig.Status {
|
||||||
|
case coredata.ElectronicSignatureStatusAccepted,
|
||||||
|
coredata.ElectronicSignatureStatusProcessing,
|
||||||
|
coredata.ElectronicSignatureStatusCompleted:
|
||||||
|
return nil
|
||||||
|
default:
|
||||||
|
return gqlutils.Forbiddenf(ctx, "user has not signed the NDA")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ExportDocumentPDF is the resolver for the exportDocumentPDF field.
|
// ExportDocumentPDF is the resolver for the exportDocumentPDF field.
|
||||||
func (r *mutationResolver) ExportDocumentPDF(ctx context.Context, input types.ExportDocumentPDFInput) (*types.ExportDocumentPDFPayload, error) {
|
func (r *mutationResolver) ExportDocumentPDF(ctx context.Context, input types.ExportDocumentPDFInput) (*types.ExportDocumentPDFPayload, error) {
|
||||||
trustService := r.TrustService(ctx, input.DocumentID.TenantID())
|
trustService := r.TrustService(ctx, input.DocumentID.TenantID())
|
||||||
@@ -256,35 +291,13 @@ func (r *mutationResolver) ExportDocumentPDF(ctx context.Context, input types.Ex
|
|||||||
return nil, gqlutils.Unauthenticated(ctx, errors.New("unauthenticated"))
|
return nil, gqlutils.Unauthenticated(ctx, errors.New("unauthenticated"))
|
||||||
}
|
}
|
||||||
|
|
||||||
ndaExists := true
|
documentAccess, err := trustService.TrustCenterAccesses.GetDocumentAccess(
|
||||||
hasAcceptedNDA := false
|
|
||||||
|
|
||||||
if trustCenter.NonDisclosureAgreementFileID == nil {
|
|
||||||
ndaExists = false
|
|
||||||
}
|
|
||||||
|
|
||||||
if ndaExists {
|
|
||||||
hasAcceptedNDA, err = trustService.TrustCenterAccesses.HasAcceptedNonDisclosureAgreement(
|
|
||||||
ctx,
|
|
||||||
trustCenter.ID,
|
|
||||||
identity.EmailAddress,
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
r.logger.ErrorCtx(ctx, "cannot check if user has accepted NDA", log.Error(err))
|
|
||||||
return nil, gqlutils.Internal(ctx)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
documentAccess, err := trustService.TrustCenterAccesses.LoadDocumentAccess(
|
|
||||||
ctx,
|
ctx,
|
||||||
trustCenter.ID,
|
trustCenter.ID,
|
||||||
identity.EmailAddress,
|
identity.EmailAddress,
|
||||||
input.DocumentID,
|
input.DocumentID,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// FIXME check for not found and return without error in this case
|
|
||||||
// r.logger.ErrorCtx(ctx, "cannot check document access", log.Error(err))
|
|
||||||
// return false, gqlutils.Internal(ctx)
|
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -292,8 +305,8 @@ func (r *mutationResolver) ExportDocumentPDF(ctx context.Context, input types.Ex
|
|||||||
return nil, gqlutils.Forbiddenf(ctx, "access denied: no permission to access this document")
|
return nil, gqlutils.Forbiddenf(ctx, "access denied: no permission to access this document")
|
||||||
}
|
}
|
||||||
|
|
||||||
if ndaExists && !hasAcceptedNDA {
|
if err := r.checkNDASignature(ctx, trustCenter, identity); err != nil {
|
||||||
return nil, gqlutils.Forbiddenf(ctx, "user has not accepted NDA")
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
pdf, err := trustService.Documents.ExportPDF(ctx, input.DocumentID, identity.EmailAddress)
|
pdf, err := trustService.Documents.ExportPDF(ctx, input.DocumentID, identity.EmailAddress)
|
||||||
@@ -336,35 +349,13 @@ func (r *mutationResolver) ExportReportPDF(ctx context.Context, input types.Expo
|
|||||||
return nil, gqlutils.Unauthenticatedf(ctx, "unauthenticated")
|
return nil, gqlutils.Unauthenticatedf(ctx, "unauthenticated")
|
||||||
}
|
}
|
||||||
|
|
||||||
ndaExists := true
|
reportAccess, err := trustService.TrustCenterAccesses.GetReportAccess(
|
||||||
hasAcceptedNDA := false
|
|
||||||
|
|
||||||
if trustCenter.NonDisclosureAgreementFileID == nil {
|
|
||||||
ndaExists = false
|
|
||||||
}
|
|
||||||
|
|
||||||
if ndaExists {
|
|
||||||
hasAcceptedNDA, err = trustService.TrustCenterAccesses.HasAcceptedNonDisclosureAgreement(
|
|
||||||
ctx,
|
|
||||||
trustCenter.ID,
|
|
||||||
identity.EmailAddress,
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
r.logger.ErrorCtx(ctx, "cannot check if user has accepted NDA", log.Error(err))
|
|
||||||
return nil, gqlutils.Internal(ctx)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
reportAccess, err := trustService.TrustCenterAccesses.LoadReportAccess(
|
|
||||||
ctx,
|
ctx,
|
||||||
trustCenter.ID,
|
trustCenter.ID,
|
||||||
identity.EmailAddress,
|
identity.EmailAddress,
|
||||||
input.ReportID,
|
input.ReportID,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// FIXME check for not found and return without error in this case
|
|
||||||
// r.logger.ErrorCtx(ctx, "cannot check report access", log.Error(err))
|
|
||||||
// return false, gqlutils.Internal(ctx)
|
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -372,8 +363,8 @@ func (r *mutationResolver) ExportReportPDF(ctx context.Context, input types.Expo
|
|||||||
return nil, gqlutils.Forbiddenf(ctx, "access denied: no permission to access this report")
|
return nil, gqlutils.Forbiddenf(ctx, "access denied: no permission to access this report")
|
||||||
}
|
}
|
||||||
|
|
||||||
if ndaExists && !hasAcceptedNDA {
|
if err := r.checkNDASignature(ctx, trustCenter, identity); err != nil {
|
||||||
return nil, gqlutils.Forbiddenf(ctx, "user has not accepted NDA")
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
pdf, err := trustService.Reports.ExportPDF(ctx, input.ReportID, identity.EmailAddress)
|
pdf, err := trustService.Reports.ExportPDF(ctx, input.ReportID, identity.EmailAddress)
|
||||||
@@ -415,33 +406,12 @@ func (r *mutationResolver) ExportTrustCenterFile(ctx context.Context, input type
|
|||||||
return nil, gqlutils.Unauthenticatedf(ctx, "unauthenticated")
|
return nil, gqlutils.Unauthenticatedf(ctx, "unauthenticated")
|
||||||
}
|
}
|
||||||
|
|
||||||
ndaExists := true
|
fileAccess, err := trustService.TrustCenterAccesses.GetTrustCenterFileAccess(ctx,
|
||||||
hasAcceptedNDA := false
|
|
||||||
|
|
||||||
if trustCenter.NonDisclosureAgreementFileID == nil {
|
|
||||||
ndaExists = false
|
|
||||||
}
|
|
||||||
|
|
||||||
if ndaExists {
|
|
||||||
hasAcceptedNDA, err = trustService.TrustCenterAccesses.HasAcceptedNonDisclosureAgreement(ctx,
|
|
||||||
trustCenter.ID,
|
|
||||||
identity.EmailAddress,
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
r.logger.ErrorCtx(ctx, "cannot check if user has accepted NDA", log.Error(err))
|
|
||||||
return nil, gqlutils.Internal(ctx)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fileAccess, err := trustService.TrustCenterAccesses.LoadTrustCenterFileAccess(ctx,
|
|
||||||
trustCenter.ID,
|
trustCenter.ID,
|
||||||
identity.EmailAddress,
|
identity.EmailAddress,
|
||||||
input.TrustCenterFileID,
|
input.TrustCenterFileID,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// FIXME check for not found and return without error in this case
|
|
||||||
// r.logger.ErrorCtx(ctx, "cannot check trust center file access", log.Error(err))
|
|
||||||
// return false, gqlutils.Internal(ctx)
|
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -449,8 +419,8 @@ func (r *mutationResolver) ExportTrustCenterFile(ctx context.Context, input type
|
|||||||
return nil, gqlutils.Forbiddenf(ctx, "access denied: no permission to access this file")
|
return nil, gqlutils.Forbiddenf(ctx, "access denied: no permission to access this file")
|
||||||
}
|
}
|
||||||
|
|
||||||
if ndaExists && !hasAcceptedNDA {
|
if err := r.checkNDASignature(ctx, trustCenter, identity); err != nil {
|
||||||
return nil, gqlutils.Forbiddenf(ctx, "user has not accepted NDA")
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
fileData, err := trustService.TrustCenterFiles.ExportFile(ctx, input.TrustCenterFileID, identity.EmailAddress)
|
fileData, err := trustService.TrustCenterFiles.ExportFile(ctx, input.TrustCenterFileID, identity.EmailAddress)
|
||||||
@@ -464,42 +434,6 @@ func (r *mutationResolver) ExportTrustCenterFile(ctx context.Context, input type
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// AcceptNonDisclosureAgreement is the resolver for the acceptNonDisclosureAgreement field.
|
|
||||||
func (r *mutationResolver) AcceptNonDisclosureAgreement(ctx context.Context, input types.AcceptNonDisclosureAgreementInput) (*types.AcceptNonDisclosureAgreementPayload, error) {
|
|
||||||
identity := authn.IdentityFromContext(ctx)
|
|
||||||
if identity == nil {
|
|
||||||
return nil, gqlutils.Unauthenticatedf(ctx, "unauthenticated")
|
|
||||||
}
|
|
||||||
trustCenter := compliancepage.CompliancePageFromContext(ctx)
|
|
||||||
trustService := r.TrustService(ctx, trustCenter.ID.TenantID())
|
|
||||||
|
|
||||||
httpReq := gqlutils.HTTPRequestFromContext(ctx)
|
|
||||||
|
|
||||||
if _, err := r.iam.AuthService.UpdateIdentity(ctx, identity.ID, input.FullName); err != nil {
|
|
||||||
var errNotFound *iam.ErrIdentityNotFound
|
|
||||||
if errors.As(err, &errNotFound) {
|
|
||||||
return nil, gqlutils.NotFound(ctx, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
r.logger.ErrorCtx(ctx, "cannot update identity", log.Error(err))
|
|
||||||
return nil, gqlutils.Internal(ctx)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := trustService.TrustCenterAccesses.AcceptNonDisclosureAgreement(
|
|
||||||
ctx,
|
|
||||||
&trust.AcceptNDARequest{
|
|
||||||
TrustCenterID: trustCenter.ID,
|
|
||||||
Email: identity.EmailAddress,
|
|
||||||
IPAddr: httpReq.RemoteAddr,
|
|
||||||
},
|
|
||||||
); err != nil {
|
|
||||||
r.logger.ErrorCtx(ctx, "cannot accept NDA", log.Error(err))
|
|
||||||
return nil, gqlutils.Internal(ctx)
|
|
||||||
}
|
|
||||||
|
|
||||||
return &types.AcceptNonDisclosureAgreementPayload{Success: true}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// RequestDocumentAccess is the resolver for the requestDocumentAccess field.
|
// RequestDocumentAccess is the resolver for the requestDocumentAccess field.
|
||||||
func (r *mutationResolver) RequestDocumentAccess(ctx context.Context, input types.RequestDocumentAccessInput) (*types.RequestAccessesPayload, error) {
|
func (r *mutationResolver) RequestDocumentAccess(ctx context.Context, input types.RequestDocumentAccessInput) (*types.RequestAccessesPayload, error) {
|
||||||
trustCenter := compliancepage.CompliancePageFromContext(ctx)
|
trustCenter := compliancepage.CompliancePageFromContext(ctx)
|
||||||
@@ -651,12 +585,10 @@ func (r *mutationResolver) RequestTrustCenterFileAccess(ctx context.Context, inp
|
|||||||
|
|
||||||
// AcceptElectronicSignature is the resolver for the acceptElectronicSignature field.
|
// AcceptElectronicSignature is the resolver for the acceptElectronicSignature field.
|
||||||
func (r *mutationResolver) AcceptElectronicSignature(ctx context.Context, input types.AcceptElectronicSignatureInput) (*types.AcceptElectronicSignaturePayload, error) {
|
func (r *mutationResolver) AcceptElectronicSignature(ctx context.Context, input types.AcceptElectronicSignatureInput) (*types.AcceptElectronicSignaturePayload, error) {
|
||||||
identity := authn.IdentityFromContext(ctx)
|
var (
|
||||||
if identity == nil {
|
identity = authn.IdentityFromContext(ctx)
|
||||||
return nil, gqlutils.Unauthenticatedf(ctx, "unauthenticated")
|
httpReq = gqlutils.HTTPRequestFromContext(ctx)
|
||||||
}
|
)
|
||||||
|
|
||||||
httpReq := gqlutils.HTTPRequestFromContext(ctx)
|
|
||||||
|
|
||||||
if _, err := r.iam.AuthService.UpdateIdentity(ctx, identity.ID, input.FullName); err != nil {
|
if _, err := r.iam.AuthService.UpdateIdentity(ctx, identity.ID, input.FullName); err != nil {
|
||||||
var errNotFound *iam.ErrIdentityNotFound
|
var errNotFound *iam.ErrIdentityNotFound
|
||||||
@@ -668,45 +600,44 @@ func (r *mutationResolver) AcceptElectronicSignature(ctx context.Context, input
|
|||||||
return nil, gqlutils.Internal(ctx)
|
return nil, gqlutils.Internal(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := r.esign.AcceptSignature(ctx, &esign.AcceptSignatureRequest{
|
signature, err := r.esign.AcceptSignature(
|
||||||
SignatureID: input.SignatureID,
|
ctx,
|
||||||
SignerFullName: input.FullName,
|
&esign.AcceptSignatureRequest{
|
||||||
SignerEmail: identity.EmailAddress,
|
SignatureID: input.SignatureID,
|
||||||
SignerIPAddr: httpReq.RemoteAddr,
|
SignerFullName: input.FullName,
|
||||||
SignerUA: httpReq.UserAgent(),
|
SignerEmail: identity.EmailAddress,
|
||||||
}); err != nil {
|
SignerIPAddr: httpReq.RemoteAddr,
|
||||||
|
SignerUA: httpReq.UserAgent(),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
r.logger.ErrorCtx(ctx, "cannot accept electronic signature", log.Error(err))
|
r.logger.ErrorCtx(ctx, "cannot accept electronic signature", log.Error(err))
|
||||||
return nil, gqlutils.Internal(ctx)
|
return nil, gqlutils.Internal(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
sig, err := r.esign.LoadSignatureByID(ctx, input.SignatureID)
|
|
||||||
if err != nil {
|
|
||||||
r.logger.ErrorCtx(ctx, "cannot load electronic signature", log.Error(err))
|
|
||||||
return nil, gqlutils.Internal(ctx)
|
|
||||||
}
|
|
||||||
|
|
||||||
return &types.AcceptElectronicSignaturePayload{
|
return &types.AcceptElectronicSignaturePayload{
|
||||||
Signature: types.NewElectronicSignature(sig),
|
Signature: types.NewElectronicSignature(signature),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// RecordSigningEvent is the resolver for the recordSigningEvent field.
|
// RecordSigningEvent is the resolver for the recordSigningEvent field.
|
||||||
func (r *mutationResolver) RecordSigningEvent(ctx context.Context, input types.RecordSigningEventInput) (*types.RecordSigningEventPayload, error) {
|
func (r *mutationResolver) RecordSigningEvent(ctx context.Context, input types.RecordSigningEventInput) (*types.RecordSigningEventPayload, error) {
|
||||||
identity := authn.IdentityFromContext(ctx)
|
var (
|
||||||
if identity == nil {
|
identity = authn.IdentityFromContext(ctx)
|
||||||
return nil, gqlutils.Unauthenticatedf(ctx, "unauthenticated")
|
httpReq = gqlutils.HTTPRequestFromContext(ctx)
|
||||||
}
|
)
|
||||||
|
|
||||||
httpReq := gqlutils.HTTPRequestFromContext(ctx)
|
if err := r.esign.RecordEvent(
|
||||||
|
ctx,
|
||||||
if err := r.esign.RecordEvent(ctx, &esign.RecordEventRequest{
|
&esign.RecordEventRequest{
|
||||||
SignatureID: input.SignatureID,
|
SignatureID: input.SignatureID,
|
||||||
EventType: input.EventType,
|
EventType: input.EventType,
|
||||||
EventSource: coredata.ElectronicSignatureEventSourceClient,
|
EventSource: coredata.ElectronicSignatureEventSourceClient,
|
||||||
ActorEmail: identity.EmailAddress,
|
ActorEmail: identity.EmailAddress,
|
||||||
ActorIPAddr: httpReq.RemoteAddr,
|
ActorIPAddr: httpReq.RemoteAddr,
|
||||||
ActorUA: httpReq.UserAgent(),
|
ActorUA: httpReq.UserAgent(),
|
||||||
}); err != nil {
|
},
|
||||||
|
); err != nil {
|
||||||
r.logger.ErrorCtx(ctx, "cannot record signing event", log.Error(err))
|
r.logger.ErrorCtx(ctx, "cannot record signing event", log.Error(err))
|
||||||
return nil, gqlutils.Internal(ctx)
|
return nil, gqlutils.Internal(ctx)
|
||||||
}
|
}
|
||||||
@@ -714,6 +645,46 @@ func (r *mutationResolver) RecordSigningEvent(ctx context.Context, input types.R
|
|||||||
return &types.RecordSigningEventPayload{Success: true}, nil
|
return &types.RecordSigningEventPayload{Success: true}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FileURL is the resolver for the fileUrl field.
|
||||||
|
func (r *nonDisclosureAgreementResolver) FileURL(ctx context.Context, obj *types.NonDisclosureAgreement) (string, error) {
|
||||||
|
trustCenter := compliancepage.CompliancePageFromContext(ctx)
|
||||||
|
trustService := r.TrustService(ctx, trustCenter.ID.TenantID())
|
||||||
|
|
||||||
|
fileURL, err := trustService.TrustCenters.GenerateNDAFileURL(ctx, trustCenter.ID, 15*time.Minute)
|
||||||
|
if err != nil {
|
||||||
|
return "", gqlutils.Internal(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
return fileURL, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ViewerSignature is the resolver for the viewerSignature field.
|
||||||
|
func (r *nonDisclosureAgreementResolver) ViewerSignature(ctx context.Context, obj *types.NonDisclosureAgreement) (*types.ElectronicSignature, error) {
|
||||||
|
identity := authn.IdentityFromContext(ctx)
|
||||||
|
if identity == nil {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
trustCenter := compliancepage.CompliancePageFromContext(ctx)
|
||||||
|
trustService := r.TrustService(ctx, trustCenter.ID.TenantID())
|
||||||
|
|
||||||
|
access, err := trustService.TrustCenterAccesses.GetAccess(ctx, trustCenter.ID, identity.EmailAddress)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if access.ElectronicSignatureID == nil {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
sig, err := r.esign.GetSignatureByID(ctx, *access.ElectronicSignatureID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return types.NewElectronicSignature(sig), nil
|
||||||
|
}
|
||||||
|
|
||||||
// LogoURL is the resolver for the logoUrl field.
|
// LogoURL is the resolver for the logoUrl field.
|
||||||
func (r *organizationResolver) LogoURL(ctx context.Context, obj *types.Organization) (*string, error) {
|
func (r *organizationResolver) LogoURL(ctx context.Context, obj *types.Organization) (*string, error) {
|
||||||
trustService := r.TrustService(ctx, obj.ID.TenantID())
|
trustService := r.TrustService(ctx, obj.ID.TenantID())
|
||||||
@@ -793,12 +764,12 @@ func (r *queryResolver) Node(ctx context.Context, id gid.GID) (types.Node, error
|
|||||||
return types.NewVendor(vendor), nil
|
return types.NewVendor(vendor), nil
|
||||||
|
|
||||||
case coredata.TrustCenterEntityType:
|
case coredata.TrustCenterEntityType:
|
||||||
trustCenter, file, err := trustService.TrustCenters.Get(ctx, id)
|
trustCenter, err := trustService.TrustCenters.Get(ctx, id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
r.logger.ErrorCtx(ctx, "cannot get trust center", log.Error(err))
|
r.logger.ErrorCtx(ctx, "cannot get trust center", log.Error(err))
|
||||||
return nil, gqlutils.Internal(ctx)
|
return nil, gqlutils.Internal(ctx)
|
||||||
}
|
}
|
||||||
return types.NewTrustCenter(trustCenter, file), nil
|
return types.NewTrustCenter(trustCenter), nil
|
||||||
|
|
||||||
case coredata.TrustCenterReferenceEntityType:
|
case coredata.TrustCenterReferenceEntityType:
|
||||||
reference, err := trustService.TrustCenterReferences.Get(ctx, id)
|
reference, err := trustService.TrustCenterReferences.Get(ctx, id)
|
||||||
@@ -824,12 +795,12 @@ func (r *queryResolver) CurrentTrustCenter(ctx context.Context) (*types.TrustCen
|
|||||||
panic(fmt.Errorf("cannot get organization: %w", err))
|
panic(fmt.Errorf("cannot get organization: %w", err))
|
||||||
}
|
}
|
||||||
|
|
||||||
trustCenter, file, err := trustService.TrustCenters.Get(ctx, trustCenter.ID)
|
trustCenter, err = trustService.TrustCenters.Get(ctx, trustCenter.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(fmt.Errorf("cannot get trust center: %w", err))
|
panic(fmt.Errorf("cannot get trust center: %w", err))
|
||||||
}
|
}
|
||||||
|
|
||||||
response := types.NewTrustCenter(trustCenter, file)
|
response := types.NewTrustCenter(trustCenter)
|
||||||
response.Organization = types.NewOrganization(org)
|
response.Organization = types.NewOrganization(org)
|
||||||
|
|
||||||
return response, nil
|
return response, nil
|
||||||
@@ -856,7 +827,7 @@ func (r *reportResolver) IsUserAuthorized(ctx context.Context, obj *types.Report
|
|||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
reportAccess, err := trustService.TrustCenterAccesses.LoadReportAccess(ctx,
|
reportAccess, err := trustService.TrustCenterAccesses.GetReportAccess(ctx,
|
||||||
trustCenter.ID,
|
trustCenter.ID,
|
||||||
identity.EmailAddress,
|
identity.EmailAddress,
|
||||||
obj.ID,
|
obj.ID,
|
||||||
@@ -890,7 +861,7 @@ func (r *reportResolver) HasUserRequestedAccess(ctx context.Context, obj *types.
|
|||||||
return false, nil // User is not authenticated, so no access requested
|
return false, nil // User is not authenticated, so no access requested
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := trustService.TrustCenterAccesses.LoadReportAccess(ctx,
|
_, err := trustService.TrustCenterAccesses.GetReportAccess(ctx,
|
||||||
trustCenter.ID,
|
trustCenter.ID,
|
||||||
identity.EmailAddress,
|
identity.EmailAddress,
|
||||||
obj.ID,
|
obj.ID,
|
||||||
@@ -919,50 +890,25 @@ func (r *trustCenterResolver) DarkLogoFileURL(ctx context.Context, obj *types.Tr
|
|||||||
return trustService.TrustCenters.GenerateDarkLogoURL(ctx, obj.ID, 1*time.Hour)
|
return trustService.TrustCenters.GenerateDarkLogoURL(ctx, obj.ID, 1*time.Hour)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NdaFileURL is the resolver for the ndaFileUrl field.
|
// NonDisclosureAgreement is the resolver for the nonDisclosureAgreement field.
|
||||||
func (r *trustCenterResolver) NdaFileURL(ctx context.Context, obj *types.TrustCenter) (*string, error) {
|
func (r *trustCenterResolver) NonDisclosureAgreement(ctx context.Context, obj *types.TrustCenter) (*types.NonDisclosureAgreement, error) {
|
||||||
|
trustCenter := compliancepage.CompliancePageFromContext(ctx)
|
||||||
|
if trustCenter.NonDisclosureAgreementFileID == nil {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
trustService := r.TrustService(ctx, obj.ID.TenantID())
|
trustService := r.TrustService(ctx, obj.ID.TenantID())
|
||||||
|
|
||||||
fileURL, err := trustService.TrustCenters.GenerateNDAFileURL(ctx, obj.ID, 15*time.Minute)
|
file, err := trustService.TrustCenters.GetNDAFile(ctx, obj.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// FIXME: add error not found check etc
|
r.logger.ErrorCtx(ctx, "cannot load NDA file", log.Error(err))
|
||||||
// r.logger.ErrorCtx(ctx, "cannot generate NDA file URL", log.Error(err))
|
return nil, gqlutils.Internal(ctx)
|
||||||
// return nil, gqlutils.Internal(ctx)
|
}
|
||||||
|
if file == nil {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return &fileURL, nil
|
return types.NewNonDisclosureAgreement(file), nil
|
||||||
}
|
|
||||||
|
|
||||||
// NdaSignature is the resolver for the ndaSignature field.
|
|
||||||
func (r *trustCenterResolver) NdaSignature(ctx context.Context, obj *types.TrustCenter) (*types.ElectronicSignature, error) {
|
|
||||||
identity := authn.IdentityFromContext(ctx)
|
|
||||||
if identity == nil {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
trustCenter := compliancepage.CompliancePageFromContext(ctx)
|
|
||||||
if trustCenter == nil || trustCenter.NonDisclosureAgreementFileID == nil {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
sig, err := r.esign.LoadSignatureByOrgEmailAndDocType(
|
|
||||||
ctx,
|
|
||||||
trustCenter.OrganizationID,
|
|
||||||
identity.EmailAddress.String(),
|
|
||||||
coredata.ElectronicSignatureDocumentTypeNDA,
|
|
||||||
*trustCenter.NonDisclosureAgreementFileID,
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return types.NewElectronicSignature(sig), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Organization is the resolver for the organization field.
|
|
||||||
func (r *trustCenterResolver) Organization(ctx context.Context, obj *types.TrustCenter) (*types.Organization, error) {
|
|
||||||
return obj.Organization, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsViewerMember is the resolver for the isViewerMember field.
|
// IsViewerMember is the resolver for the isViewerMember field.
|
||||||
@@ -972,22 +918,9 @@ func (r *trustCenterResolver) IsViewerMember(ctx context.Context, obj *types.Tru
|
|||||||
return membership != nil, nil
|
return membership != nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// HasAcceptedNonDisclosureAgreement is the resolver for the hasAcceptedNonDisclosureAgreement field.
|
// Organization is the resolver for the organization field.
|
||||||
func (r *trustCenterResolver) HasAcceptedNonDisclosureAgreement(ctx context.Context, obj *types.TrustCenter) (bool, error) {
|
func (r *trustCenterResolver) Organization(ctx context.Context, obj *types.TrustCenter) (*types.Organization, error) {
|
||||||
trustService := r.TrustService(ctx, obj.ID.TenantID())
|
return obj.Organization, nil
|
||||||
|
|
||||||
identity := authn.IdentityFromContext(ctx)
|
|
||||||
if identity == nil {
|
|
||||||
return false, nil // User is not authenticated, so no NDA accepted
|
|
||||||
}
|
|
||||||
|
|
||||||
hasAcceptedNDA, err := trustService.TrustCenterAccesses.HasAcceptedNonDisclosureAgreement(ctx, obj.ID, identity.EmailAddress)
|
|
||||||
if err != nil {
|
|
||||||
r.logger.ErrorCtx(ctx, "cannot check if user has accepted NDA", log.Error(err))
|
|
||||||
return false, gqlutils.Internal(ctx)
|
|
||||||
}
|
|
||||||
|
|
||||||
return hasAcceptedNDA, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Documents is the resolver for the documents field.
|
// Documents is the resolver for the documents field.
|
||||||
@@ -1112,7 +1045,7 @@ func (r *trustCenterFileResolver) IsUserAuthorized(ctx context.Context, obj *typ
|
|||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
fileAccess, err := trustService.TrustCenterAccesses.LoadTrustCenterFileAccess(ctx,
|
fileAccess, err := trustService.TrustCenterAccesses.GetTrustCenterFileAccess(ctx,
|
||||||
trustCenter.ID,
|
trustCenter.ID,
|
||||||
identity.EmailAddress,
|
identity.EmailAddress,
|
||||||
obj.ID,
|
obj.ID,
|
||||||
@@ -1146,7 +1079,7 @@ func (r *trustCenterFileResolver) HasUserRequestedAccess(ctx context.Context, ob
|
|||||||
return false, nil // User is not authenticated, so no access requested
|
return false, nil // User is not authenticated, so no access requested
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := trustService.TrustCenterAccesses.LoadTrustCenterFileAccess(ctx,
|
_, err := trustService.TrustCenterAccesses.GetTrustCenterFileAccess(ctx,
|
||||||
trustCenter.ID,
|
trustCenter.ID,
|
||||||
identity.EmailAddress,
|
identity.EmailAddress,
|
||||||
obj.ID,
|
obj.ID,
|
||||||
@@ -1201,6 +1134,11 @@ func (r *Resolver) Framework() schema.FrameworkResolver { return &frameworkResol
|
|||||||
// Mutation returns schema.MutationResolver implementation.
|
// Mutation returns schema.MutationResolver implementation.
|
||||||
func (r *Resolver) Mutation() schema.MutationResolver { return &mutationResolver{r} }
|
func (r *Resolver) Mutation() schema.MutationResolver { return &mutationResolver{r} }
|
||||||
|
|
||||||
|
// NonDisclosureAgreement returns schema.NonDisclosureAgreementResolver implementation.
|
||||||
|
func (r *Resolver) NonDisclosureAgreement() schema.NonDisclosureAgreementResolver {
|
||||||
|
return &nonDisclosureAgreementResolver{r}
|
||||||
|
}
|
||||||
|
|
||||||
// Organization returns schema.OrganizationResolver implementation.
|
// Organization returns schema.OrganizationResolver implementation.
|
||||||
func (r *Resolver) Organization() schema.OrganizationResolver { return &organizationResolver{r} }
|
func (r *Resolver) Organization() schema.OrganizationResolver { return &organizationResolver{r} }
|
||||||
|
|
||||||
@@ -1232,6 +1170,7 @@ type auditResolver struct{ *Resolver }
|
|||||||
type documentResolver struct{ *Resolver }
|
type documentResolver struct{ *Resolver }
|
||||||
type frameworkResolver struct{ *Resolver }
|
type frameworkResolver struct{ *Resolver }
|
||||||
type mutationResolver struct{ *Resolver }
|
type mutationResolver struct{ *Resolver }
|
||||||
|
type nonDisclosureAgreementResolver struct{ *Resolver }
|
||||||
type organizationResolver struct{ *Resolver }
|
type organizationResolver struct{ *Resolver }
|
||||||
type queryResolver struct{ *Resolver }
|
type queryResolver struct{ *Resolver }
|
||||||
type reportResolver struct{ *Resolver }
|
type reportResolver struct{ *Resolver }
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ package trust
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
@@ -155,13 +154,8 @@ func (s TrustCenterAccessService) Request(
|
|||||||
UpdatedAt: now,
|
UpdatedAt: now,
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := access.Insert(ctx, tx, s.svc.scope); err != nil {
|
|
||||||
return fmt.Errorf("cannot insert trust center access: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create PENDING electronic signature when NDA is configured.
|
|
||||||
if trustCenter.NonDisclosureAgreementFileID != nil && s.svc.esign != nil {
|
if trustCenter.NonDisclosureAgreementFileID != nil && s.svc.esign != nil {
|
||||||
_, err := s.svc.esign.CreateSignature(
|
sig, err := s.svc.esign.CreateSignature(
|
||||||
ctx,
|
ctx,
|
||||||
tx,
|
tx,
|
||||||
&esign.CreateSignatureRequest{
|
&esign.CreateSignatureRequest{
|
||||||
@@ -174,6 +168,11 @@ func (s TrustCenterAccessService) Request(
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("cannot create pending signature: %w", err)
|
return fmt.Errorf("cannot create pending signature: %w", err)
|
||||||
}
|
}
|
||||||
|
access.ElectronicSignatureID = &sig.ID
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := access.Insert(ctx, tx, s.svc.scope); err != nil {
|
||||||
|
return fmt.Errorf("cannot insert trust center access: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -243,93 +242,21 @@ func (s TrustCenterAccessService) Request(
|
|||||||
return access, nil
|
return access, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s TrustCenterAccessService) HasAcceptedNonDisclosureAgreement(ctx context.Context, trustCenterID gid.GID, email mail.Addr) (bool, error) {
|
func (s TrustCenterAccessService) GetAccess(
|
||||||
|
ctx context.Context,
|
||||||
|
trustCenterID gid.GID,
|
||||||
|
email mail.Addr,
|
||||||
|
) (coredata.TrustCenterAccess, error) {
|
||||||
var access coredata.TrustCenterAccess
|
var access coredata.TrustCenterAccess
|
||||||
|
|
||||||
err := s.svc.pg.WithConn(ctx, func(conn pg.Conn) error {
|
err := s.svc.pg.WithConn(ctx, func(conn pg.Conn) error {
|
||||||
return access.LoadByTrustCenterIDAndEmail(ctx, conn, s.svc.scope, trustCenterID, email)
|
return access.LoadByTrustCenterIDAndEmail(ctx, conn, s.svc.scope, trustCenterID, email)
|
||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
return access, err
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Legacy path: check the old boolean field.
|
|
||||||
if access.HasAcceptedNonDisclosureAgreement {
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// New path: check for an electronic signature in ACCEPTED or later status.
|
|
||||||
if s.svc.esign != nil {
|
|
||||||
trustCenter := &coredata.TrustCenter{}
|
|
||||||
err := s.svc.pg.WithConn(ctx, func(conn pg.Conn) error {
|
|
||||||
return trustCenter.LoadByID(ctx, conn, s.svc.scope, trustCenterID)
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if trustCenter.NonDisclosureAgreementFileID != nil {
|
|
||||||
sig, err := s.svc.esign.LoadSignatureByOrgEmailAndDocType(
|
|
||||||
ctx,
|
|
||||||
trustCenter.OrganizationID,
|
|
||||||
email.String(),
|
|
||||||
coredata.ElectronicSignatureDocumentTypeNDA,
|
|
||||||
*trustCenter.NonDisclosureAgreementFileID,
|
|
||||||
)
|
|
||||||
if err == nil {
|
|
||||||
switch sig.Status {
|
|
||||||
case coredata.ElectronicSignatureStatusAccepted,
|
|
||||||
coredata.ElectronicSignatureStatusProcessing,
|
|
||||||
coredata.ElectronicSignatureStatusCompleted:
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type AcceptNDARequest struct {
|
func (s TrustCenterAccessService) GetDocumentAccess(
|
||||||
TrustCenterID gid.GID
|
|
||||||
Email mail.Addr
|
|
||||||
IPAddr string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s TrustCenterAccessService) AcceptNonDisclosureAgreement(ctx context.Context, req *AcceptNDARequest) error {
|
|
||||||
return s.svc.pg.WithTx(ctx, func(tx pg.Conn) error {
|
|
||||||
access := &coredata.TrustCenterAccess{}
|
|
||||||
if err := access.LoadByTrustCenterIDAndEmail(ctx, tx, s.svc.scope, req.TrustCenterID, req.Email); err != nil {
|
|
||||||
return fmt.Errorf("cannot load trust center access: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
trustCenter := &coredata.TrustCenter{}
|
|
||||||
if err := trustCenter.LoadByID(ctx, tx, s.svc.scope, req.TrustCenterID); err != nil {
|
|
||||||
return fmt.Errorf("cannot load trust center: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
acceptationLogs, err := json.Marshal(map[string]string{
|
|
||||||
"email": req.Email.String(),
|
|
||||||
"timestamp": time.Now().Format(time.RFC3339),
|
|
||||||
"ip": req.IPAddr,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("cannot marshal non disclosure agreement acceptation logs: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
access.HasAcceptedNonDisclosureAgreement = true
|
|
||||||
access.UpdatedAt = time.Now()
|
|
||||||
access.HasAcceptedNonDisclosureAgreementMetadata = acceptationLogs
|
|
||||||
access.NDAFileID = trustCenter.NonDisclosureAgreementFileID
|
|
||||||
if err := access.Update(ctx, tx, s.svc.scope); err != nil {
|
|
||||||
return fmt.Errorf("cannot update trust center access: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s TrustCenterAccessService) LoadDocumentAccess(
|
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
trustCenterID gid.GID,
|
trustCenterID gid.GID,
|
||||||
email mail.Addr,
|
email mail.Addr,
|
||||||
@@ -372,7 +299,7 @@ func (s TrustCenterAccessService) LoadDocumentAccess(
|
|||||||
return documentAccess, nil
|
return documentAccess, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s TrustCenterAccessService) LoadReportAccess(
|
func (s TrustCenterAccessService) GetReportAccess(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
trustCenterID gid.GID,
|
trustCenterID gid.GID,
|
||||||
email mail.Addr,
|
email mail.Addr,
|
||||||
@@ -415,7 +342,7 @@ func (s TrustCenterAccessService) LoadReportAccess(
|
|||||||
return reportAccess, nil
|
return reportAccess, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s TrustCenterAccessService) LoadTrustCenterFileAccess(
|
func (s TrustCenterAccessService) GetTrustCenterFileAccess(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
trustCenterID gid.GID,
|
trustCenterID gid.GID,
|
||||||
email mail.Addr,
|
email mail.Addr,
|
||||||
|
|||||||
@@ -34,9 +34,8 @@ type TrustCenterService struct {
|
|||||||
func (s TrustCenterService) Get(
|
func (s TrustCenterService) Get(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
trustCenterID gid.GID,
|
trustCenterID gid.GID,
|
||||||
) (*coredata.TrustCenter, *coredata.File, error) {
|
) (*coredata.TrustCenter, error) {
|
||||||
var trustCenter *coredata.TrustCenter
|
var trustCenter *coredata.TrustCenter
|
||||||
var file *coredata.File
|
|
||||||
|
|
||||||
err := s.svc.pg.WithConn(
|
err := s.svc.pg.WithConn(
|
||||||
ctx,
|
ctx,
|
||||||
@@ -46,22 +45,15 @@ func (s TrustCenterService) Get(
|
|||||||
return fmt.Errorf("cannot load trust center: %w", err)
|
return fmt.Errorf("cannot load trust center: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if trustCenter.NonDisclosureAgreementFileID != nil {
|
|
||||||
file = &coredata.File{}
|
|
||||||
if err := file.LoadByID(ctx, conn, s.svc.scope, *trustCenter.NonDisclosureAgreementFileID); err != nil {
|
|
||||||
return fmt.Errorf("cannot load file: %w", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, fmt.Errorf("cannot load trust center: %w", err)
|
return nil, fmt.Errorf("cannot load trust center: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return trustCenter, file, nil
|
return trustCenter, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s TrustCenterService) GetByOrganizationID(
|
func (s TrustCenterService) GetByOrganizationID(
|
||||||
@@ -89,6 +81,39 @@ func (s TrustCenterService) GetByOrganizationID(
|
|||||||
return trustCenter, nil
|
return trustCenter, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s TrustCenterService) GetNDAFile(
|
||||||
|
ctx context.Context,
|
||||||
|
trustCenterID gid.GID,
|
||||||
|
) (*coredata.File, error) {
|
||||||
|
var file *coredata.File
|
||||||
|
|
||||||
|
err := s.svc.pg.WithConn(
|
||||||
|
ctx,
|
||||||
|
func(conn pg.Conn) error {
|
||||||
|
trustCenter := &coredata.TrustCenter{}
|
||||||
|
if err := trustCenter.LoadByID(ctx, conn, s.svc.scope, trustCenterID); err != nil {
|
||||||
|
return fmt.Errorf("cannot load trust center: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if trustCenter.NonDisclosureAgreementFileID == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
file = &coredata.File{}
|
||||||
|
if err := file.LoadByID(ctx, conn, s.svc.scope, *trustCenter.NonDisclosureAgreementFileID); err != nil {
|
||||||
|
return fmt.Errorf("cannot load file: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return file, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (s TrustCenterService) GenerateNDAFileURL(
|
func (s TrustCenterService) GenerateNDAFileURL(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
trustCenterID gid.GID,
|
trustCenterID gid.GID,
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ func (s VendorService) CountForTrustCenterId(
|
|||||||
err := s.svc.pg.WithConn(
|
err := s.svc.pg.WithConn(
|
||||||
ctx,
|
ctx,
|
||||||
func(conn pg.Conn) (err error) {
|
func(conn pg.Conn) (err error) {
|
||||||
trustCenter, _, err := s.svc.TrustCenters.Get(ctx, trustCenterID)
|
trustCenter, err := s.svc.TrustCenters.Get(ctx, trustCenterID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("cannot load trust center: %w", err)
|
return fmt.Errorf("cannot load trust center: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user