Add nda to trust center
Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
This commit is contained in:
@@ -26,6 +26,7 @@ export const trustCenterAccessesQuery = graphql`
|
|||||||
email
|
email
|
||||||
name
|
name
|
||||||
active
|
active
|
||||||
|
hasAcceptedNonDisclosureAgreement
|
||||||
createdAt
|
createdAt
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -48,6 +49,7 @@ export const createTrustCenterAccessMutation = graphql`
|
|||||||
email
|
email
|
||||||
name
|
name
|
||||||
active
|
active
|
||||||
|
hasAcceptedNonDisclosureAgreement
|
||||||
createdAt
|
createdAt
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -65,6 +67,7 @@ export const updateTrustCenterAccessMutation = graphql`
|
|||||||
email
|
email
|
||||||
name
|
name
|
||||||
active
|
active
|
||||||
|
hasAcceptedNonDisclosureAgreement
|
||||||
createdAt
|
createdAt
|
||||||
updatedAt
|
updatedAt
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ export const trustCenterQuery = graphql`
|
|||||||
id
|
id
|
||||||
active
|
active
|
||||||
slug
|
slug
|
||||||
|
ndaFileName
|
||||||
|
ndaFileUrl
|
||||||
createdAt
|
createdAt
|
||||||
updatedAt
|
updatedAt
|
||||||
}
|
}
|
||||||
@@ -66,3 +68,48 @@ export function useUpdateTrustCenterMutation() {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const uploadTrustCenterNDAMutation = graphql`
|
||||||
|
mutation TrustCenterGraphUploadNDAMutation($input: UploadTrustCenterNDAInput!) {
|
||||||
|
uploadTrustCenterNDA(input: $input) {
|
||||||
|
trustCenter {
|
||||||
|
id
|
||||||
|
ndaFileName
|
||||||
|
updatedAt
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
export function useUploadTrustCenterNDAMutation() {
|
||||||
|
return useMutationWithToasts(
|
||||||
|
uploadTrustCenterNDAMutation,
|
||||||
|
{
|
||||||
|
successMessage: "NDA uploaded successfully",
|
||||||
|
errorMessage: "Failed to upload NDA",
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export const deleteTrustCenterNDAMutation = graphql`
|
||||||
|
mutation TrustCenterGraphDeleteNDAMutation($input: DeleteTrustCenterNDAInput!) {
|
||||||
|
deleteTrustCenterNDA(input: $input) {
|
||||||
|
trustCenter {
|
||||||
|
id
|
||||||
|
ndaFileName
|
||||||
|
updatedAt
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
export function useDeleteTrustCenterNDAMutation() {
|
||||||
|
return useMutationWithToasts(
|
||||||
|
deleteTrustCenterNDAMutation,
|
||||||
|
{
|
||||||
|
successMessage: "NDA deleted successfully",
|
||||||
|
errorMessage: "Failed to delete NDA",
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* @generated SignedSource<<ae95aed7bc22c95f8cc2ab591039c810>>
|
* @generated SignedSource<<5ccaab70e4cb8c4b5bee7fbe6ba2c0b6>>
|
||||||
* @lightSyntaxTransform
|
* @lightSyntaxTransform
|
||||||
* @nogrep
|
* @nogrep
|
||||||
*/
|
*/
|
||||||
@@ -27,6 +27,7 @@ export type TrustCenterAccessGraphCreateMutation$data = {
|
|||||||
readonly active: boolean;
|
readonly active: boolean;
|
||||||
readonly createdAt: any;
|
readonly createdAt: any;
|
||||||
readonly email: string;
|
readonly email: string;
|
||||||
|
readonly hasAcceptedNonDisclosureAgreement: boolean;
|
||||||
readonly id: string;
|
readonly id: string;
|
||||||
readonly name: string;
|
readonly name: string;
|
||||||
};
|
};
|
||||||
@@ -107,6 +108,13 @@ v3 = {
|
|||||||
"name": "active",
|
"name": "active",
|
||||||
"storageKey": null
|
"storageKey": null
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"alias": null,
|
||||||
|
"args": null,
|
||||||
|
"kind": "ScalarField",
|
||||||
|
"name": "hasAcceptedNonDisclosureAgreement",
|
||||||
|
"storageKey": null
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"alias": null,
|
"alias": null,
|
||||||
"args": null,
|
"args": null,
|
||||||
@@ -186,16 +194,16 @@ return {
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"params": {
|
"params": {
|
||||||
"cacheID": "eafddcd0263963235d3249c22eb50593",
|
"cacheID": "fa88b100be7598cf46159cf79199c398",
|
||||||
"id": null,
|
"id": null,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"name": "TrustCenterAccessGraphCreateMutation",
|
"name": "TrustCenterAccessGraphCreateMutation",
|
||||||
"operationKind": "mutation",
|
"operationKind": "mutation",
|
||||||
"text": "mutation TrustCenterAccessGraphCreateMutation(\n $input: CreateTrustCenterAccessInput!\n) {\n createTrustCenterAccess(input: $input) {\n trustCenterAccessEdge {\n cursor\n node {\n id\n email\n name\n active\n createdAt\n }\n }\n }\n}\n"
|
"text": "mutation TrustCenterAccessGraphCreateMutation(\n $input: CreateTrustCenterAccessInput!\n) {\n createTrustCenterAccess(input: $input) {\n trustCenterAccessEdge {\n cursor\n node {\n id\n email\n name\n active\n hasAcceptedNonDisclosureAgreement\n createdAt\n }\n }\n }\n}\n"
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
|
||||||
(node as any).hash = "99676fee0b2de06a92cdad66c577eee7";
|
(node as any).hash = "6c6c1344730e7d908a5c6392f578ca81";
|
||||||
|
|
||||||
export default node;
|
export default node;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* @generated SignedSource<<2333a6a7d5415f1a08a5612dcaceee8f>>
|
* @generated SignedSource<<e9cdda9f586cee5ffe66f238216060f6>>
|
||||||
* @lightSyntaxTransform
|
* @lightSyntaxTransform
|
||||||
* @nogrep
|
* @nogrep
|
||||||
*/
|
*/
|
||||||
@@ -22,6 +22,7 @@ export type TrustCenterAccessGraphQuery$data = {
|
|||||||
readonly active: boolean;
|
readonly active: boolean;
|
||||||
readonly createdAt: any;
|
readonly createdAt: any;
|
||||||
readonly email: string;
|
readonly email: string;
|
||||||
|
readonly hasAcceptedNonDisclosureAgreement: boolean;
|
||||||
readonly id: string;
|
readonly id: string;
|
||||||
readonly name: string;
|
readonly name: string;
|
||||||
};
|
};
|
||||||
@@ -163,6 +164,13 @@ v5 = [
|
|||||||
"name": "active",
|
"name": "active",
|
||||||
"storageKey": null
|
"storageKey": null
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"alias": null,
|
||||||
|
"args": null,
|
||||||
|
"kind": "ScalarField",
|
||||||
|
"name": "hasAcceptedNonDisclosureAgreement",
|
||||||
|
"storageKey": null
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"alias": null,
|
"alias": null,
|
||||||
"args": null,
|
"args": null,
|
||||||
@@ -290,7 +298,7 @@ return {
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"params": {
|
"params": {
|
||||||
"cacheID": "5b83cd4ae2434ce2e00de7230d264432",
|
"cacheID": "0286ec03fb4ae012ada7bae8a2234152",
|
||||||
"id": null,
|
"id": null,
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"connection": [
|
"connection": [
|
||||||
@@ -307,11 +315,11 @@ return {
|
|||||||
},
|
},
|
||||||
"name": "TrustCenterAccessGraphQuery",
|
"name": "TrustCenterAccessGraphQuery",
|
||||||
"operationKind": "query",
|
"operationKind": "query",
|
||||||
"text": "query TrustCenterAccessGraphQuery(\n $trustCenterId: ID!\n) {\n node(id: $trustCenterId) {\n __typename\n ... on TrustCenter {\n id\n accesses(first: 100, orderBy: {field: CREATED_AT, direction: DESC}) {\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n edges {\n cursor\n node {\n id\n email\n name\n active\n createdAt\n __typename\n }\n }\n }\n }\n id\n }\n}\n"
|
"text": "query TrustCenterAccessGraphQuery(\n $trustCenterId: ID!\n) {\n node(id: $trustCenterId) {\n __typename\n ... on TrustCenter {\n id\n accesses(first: 100, orderBy: {field: CREATED_AT, direction: DESC}) {\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n edges {\n cursor\n node {\n id\n email\n name\n active\n hasAcceptedNonDisclosureAgreement\n createdAt\n __typename\n }\n }\n }\n }\n id\n }\n}\n"
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
|
||||||
(node as any).hash = "af598fd2af198e63ed84fd618857a985";
|
(node as any).hash = "f837b96937f1397ac1a3065f58386e4d";
|
||||||
|
|
||||||
export default node;
|
export default node;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* @generated SignedSource<<6de2ecb63a58c88c3008368061943b49>>
|
* @generated SignedSource<<d2f40d8fc2bd9c7627d308660dedb1e5>>
|
||||||
* @lightSyntaxTransform
|
* @lightSyntaxTransform
|
||||||
* @nogrep
|
* @nogrep
|
||||||
*/
|
*/
|
||||||
@@ -23,6 +23,7 @@ export type TrustCenterAccessGraphUpdateMutation$data = {
|
|||||||
readonly active: boolean;
|
readonly active: boolean;
|
||||||
readonly createdAt: any;
|
readonly createdAt: any;
|
||||||
readonly email: string;
|
readonly email: string;
|
||||||
|
readonly hasAcceptedNonDisclosureAgreement: boolean;
|
||||||
readonly id: string;
|
readonly id: string;
|
||||||
readonly name: string;
|
readonly name: string;
|
||||||
readonly updatedAt: any;
|
readonly updatedAt: any;
|
||||||
@@ -93,6 +94,13 @@ v1 = [
|
|||||||
"name": "active",
|
"name": "active",
|
||||||
"storageKey": null
|
"storageKey": null
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"alias": null,
|
||||||
|
"args": null,
|
||||||
|
"kind": "ScalarField",
|
||||||
|
"name": "hasAcceptedNonDisclosureAgreement",
|
||||||
|
"storageKey": null
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"alias": null,
|
"alias": null,
|
||||||
"args": null,
|
"args": null,
|
||||||
@@ -132,16 +140,16 @@ return {
|
|||||||
"selections": (v1/*: any*/)
|
"selections": (v1/*: any*/)
|
||||||
},
|
},
|
||||||
"params": {
|
"params": {
|
||||||
"cacheID": "683ee01fb5173b49b0a7f3c2d99cf002",
|
"cacheID": "223169ee8a4f65008047097ecff68fc5",
|
||||||
"id": null,
|
"id": null,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"name": "TrustCenterAccessGraphUpdateMutation",
|
"name": "TrustCenterAccessGraphUpdateMutation",
|
||||||
"operationKind": "mutation",
|
"operationKind": "mutation",
|
||||||
"text": "mutation TrustCenterAccessGraphUpdateMutation(\n $input: UpdateTrustCenterAccessInput!\n) {\n updateTrustCenterAccess(input: $input) {\n trustCenterAccess {\n id\n email\n name\n active\n createdAt\n updatedAt\n }\n }\n}\n"
|
"text": "mutation TrustCenterAccessGraphUpdateMutation(\n $input: UpdateTrustCenterAccessInput!\n) {\n updateTrustCenterAccess(input: $input) {\n trustCenterAccess {\n id\n email\n name\n active\n hasAcceptedNonDisclosureAgreement\n createdAt\n updatedAt\n }\n }\n}\n"
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
|
||||||
(node as any).hash = "cccd083b0047f6bc7b504b7494205e9d";
|
(node as any).hash = "0da1f737e6ea1db7a1b9930c4b6cc545";
|
||||||
|
|
||||||
export default node;
|
export default node;
|
||||||
|
|||||||
121
apps/console/src/hooks/graph/__generated__/TrustCenterGraphDeleteNDAMutation.graphql.ts
generated
Normal file
121
apps/console/src/hooks/graph/__generated__/TrustCenterGraphDeleteNDAMutation.graphql.ts
generated
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
/**
|
||||||
|
* @generated SignedSource<<43a8665719f251c1bae028ff7821b14a>>
|
||||||
|
* @lightSyntaxTransform
|
||||||
|
* @nogrep
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
// @ts-nocheck
|
||||||
|
|
||||||
|
import { ConcreteRequest } from 'relay-runtime';
|
||||||
|
export type DeleteTrustCenterNDAInput = {
|
||||||
|
trustCenterId: string;
|
||||||
|
};
|
||||||
|
export type TrustCenterGraphDeleteNDAMutation$variables = {
|
||||||
|
input: DeleteTrustCenterNDAInput;
|
||||||
|
};
|
||||||
|
export type TrustCenterGraphDeleteNDAMutation$data = {
|
||||||
|
readonly deleteTrustCenterNDA: {
|
||||||
|
readonly trustCenter: {
|
||||||
|
readonly id: string;
|
||||||
|
readonly ndaFileName: string | null | undefined;
|
||||||
|
readonly updatedAt: any;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
export type TrustCenterGraphDeleteNDAMutation = {
|
||||||
|
response: TrustCenterGraphDeleteNDAMutation$data;
|
||||||
|
variables: TrustCenterGraphDeleteNDAMutation$variables;
|
||||||
|
};
|
||||||
|
|
||||||
|
const node: ConcreteRequest = (function(){
|
||||||
|
var v0 = [
|
||||||
|
{
|
||||||
|
"defaultValue": null,
|
||||||
|
"kind": "LocalArgument",
|
||||||
|
"name": "input"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
v1 = [
|
||||||
|
{
|
||||||
|
"alias": null,
|
||||||
|
"args": [
|
||||||
|
{
|
||||||
|
"kind": "Variable",
|
||||||
|
"name": "input",
|
||||||
|
"variableName": "input"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"concreteType": "DeleteTrustCenterNDAPayload",
|
||||||
|
"kind": "LinkedField",
|
||||||
|
"name": "deleteTrustCenterNDA",
|
||||||
|
"plural": false,
|
||||||
|
"selections": [
|
||||||
|
{
|
||||||
|
"alias": null,
|
||||||
|
"args": null,
|
||||||
|
"concreteType": "TrustCenter",
|
||||||
|
"kind": "LinkedField",
|
||||||
|
"name": "trustCenter",
|
||||||
|
"plural": false,
|
||||||
|
"selections": [
|
||||||
|
{
|
||||||
|
"alias": null,
|
||||||
|
"args": null,
|
||||||
|
"kind": "ScalarField",
|
||||||
|
"name": "id",
|
||||||
|
"storageKey": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"alias": null,
|
||||||
|
"args": null,
|
||||||
|
"kind": "ScalarField",
|
||||||
|
"name": "ndaFileName",
|
||||||
|
"storageKey": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"alias": null,
|
||||||
|
"args": null,
|
||||||
|
"kind": "ScalarField",
|
||||||
|
"name": "updatedAt",
|
||||||
|
"storageKey": null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"storageKey": null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"storageKey": null
|
||||||
|
}
|
||||||
|
];
|
||||||
|
return {
|
||||||
|
"fragment": {
|
||||||
|
"argumentDefinitions": (v0/*: any*/),
|
||||||
|
"kind": "Fragment",
|
||||||
|
"metadata": null,
|
||||||
|
"name": "TrustCenterGraphDeleteNDAMutation",
|
||||||
|
"selections": (v1/*: any*/),
|
||||||
|
"type": "Mutation",
|
||||||
|
"abstractKey": null
|
||||||
|
},
|
||||||
|
"kind": "Request",
|
||||||
|
"operation": {
|
||||||
|
"argumentDefinitions": (v0/*: any*/),
|
||||||
|
"kind": "Operation",
|
||||||
|
"name": "TrustCenterGraphDeleteNDAMutation",
|
||||||
|
"selections": (v1/*: any*/)
|
||||||
|
},
|
||||||
|
"params": {
|
||||||
|
"cacheID": "fa3ebf3593c396bf05819d357d9f909f",
|
||||||
|
"id": null,
|
||||||
|
"metadata": {},
|
||||||
|
"name": "TrustCenterGraphDeleteNDAMutation",
|
||||||
|
"operationKind": "mutation",
|
||||||
|
"text": "mutation TrustCenterGraphDeleteNDAMutation(\n $input: DeleteTrustCenterNDAInput!\n) {\n deleteTrustCenterNDA(input: $input) {\n trustCenter {\n id\n ndaFileName\n updatedAt\n }\n }\n}\n"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
})();
|
||||||
|
|
||||||
|
(node as any).hash = "9c055069b9e2e7432fed7509f6578a07";
|
||||||
|
|
||||||
|
export default node;
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* @generated SignedSource<<25550a93c5459c3b405c782be19ac888>>
|
* @generated SignedSource<<9dbea87f398ce8189cb2431d7c03912c>>
|
||||||
* @lightSyntaxTransform
|
* @lightSyntaxTransform
|
||||||
* @nogrep
|
* @nogrep
|
||||||
*/
|
*/
|
||||||
@@ -37,6 +37,8 @@ export type TrustCenterGraphQuery$data = {
|
|||||||
readonly active: boolean;
|
readonly active: boolean;
|
||||||
readonly createdAt: any;
|
readonly createdAt: any;
|
||||||
readonly id: string;
|
readonly id: string;
|
||||||
|
readonly ndaFileName: string | null | undefined;
|
||||||
|
readonly ndaFileUrl: string | null | undefined;
|
||||||
readonly slug: string;
|
readonly slug: string;
|
||||||
readonly updatedAt: any;
|
readonly updatedAt: any;
|
||||||
} | null | undefined;
|
} | null | undefined;
|
||||||
@@ -114,6 +116,20 @@ v5 = {
|
|||||||
"name": "slug",
|
"name": "slug",
|
||||||
"storageKey": null
|
"storageKey": null
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"alias": null,
|
||||||
|
"args": null,
|
||||||
|
"kind": "ScalarField",
|
||||||
|
"name": "ndaFileName",
|
||||||
|
"storageKey": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"alias": null,
|
||||||
|
"args": null,
|
||||||
|
"kind": "ScalarField",
|
||||||
|
"name": "ndaFileUrl",
|
||||||
|
"storageKey": null
|
||||||
|
},
|
||||||
(v4/*: any*/),
|
(v4/*: any*/),
|
||||||
{
|
{
|
||||||
"alias": null,
|
"alias": null,
|
||||||
@@ -544,16 +560,16 @@ return {
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"params": {
|
"params": {
|
||||||
"cacheID": "28c1a32327e2fee9320fd091100ec800",
|
"cacheID": "8dff30a639470418ba7151cb5743d3cc",
|
||||||
"id": null,
|
"id": null,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"name": "TrustCenterGraphQuery",
|
"name": "TrustCenterGraphQuery",
|
||||||
"operationKind": "query",
|
"operationKind": "query",
|
||||||
"text": "query TrustCenterGraphQuery(\n $organizationId: ID!\n) {\n organization: node(id: $organizationId) {\n __typename\n ... on Organization {\n id\n name\n trustCenter {\n id\n active\n slug\n createdAt\n updatedAt\n }\n documents(first: 100) {\n edges {\n node {\n id\n ...TrustCenterDocumentsCardFragment\n }\n }\n }\n audits(first: 100) {\n edges {\n node {\n id\n ...TrustCenterAuditsCardFragment\n }\n }\n }\n vendors(first: 100) {\n edges {\n node {\n id\n ...TrustCenterVendorsCardFragment\n }\n }\n }\n }\n id\n }\n}\n\nfragment TrustCenterAuditsCardFragment on Audit {\n id\n name\n framework {\n name\n id\n }\n validFrom\n validUntil\n state\n showOnTrustCenter\n createdAt\n}\n\nfragment TrustCenterDocumentsCardFragment on Document {\n id\n title\n createdAt\n documentType\n showOnTrustCenter\n versions(first: 1) {\n edges {\n node {\n id\n status\n }\n }\n }\n}\n\nfragment TrustCenterVendorsCardFragment on Vendor {\n id\n name\n category\n description\n showOnTrustCenter\n createdAt\n}\n"
|
"text": "query TrustCenterGraphQuery(\n $organizationId: ID!\n) {\n organization: node(id: $organizationId) {\n __typename\n ... on Organization {\n id\n name\n trustCenter {\n id\n active\n slug\n ndaFileName\n ndaFileUrl\n createdAt\n updatedAt\n }\n documents(first: 100) {\n edges {\n node {\n id\n ...TrustCenterDocumentsCardFragment\n }\n }\n }\n audits(first: 100) {\n edges {\n node {\n id\n ...TrustCenterAuditsCardFragment\n }\n }\n }\n vendors(first: 100) {\n edges {\n node {\n id\n ...TrustCenterVendorsCardFragment\n }\n }\n }\n }\n id\n }\n}\n\nfragment TrustCenterAuditsCardFragment on Audit {\n id\n name\n framework {\n name\n id\n }\n validFrom\n validUntil\n state\n showOnTrustCenter\n createdAt\n}\n\nfragment TrustCenterDocumentsCardFragment on Document {\n id\n title\n createdAt\n documentType\n showOnTrustCenter\n versions(first: 1) {\n edges {\n node {\n id\n status\n }\n }\n }\n}\n\nfragment TrustCenterVendorsCardFragment on Vendor {\n id\n name\n category\n description\n showOnTrustCenter\n createdAt\n}\n"
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
|
||||||
(node as any).hash = "260529b3ca03240b07989f278bb7a539";
|
(node as any).hash = "21b2915ae5002dd54c990013e94adf5d";
|
||||||
|
|
||||||
export default node;
|
export default node;
|
||||||
|
|||||||
123
apps/console/src/hooks/graph/__generated__/TrustCenterGraphUploadNDAMutation.graphql.ts
generated
Normal file
123
apps/console/src/hooks/graph/__generated__/TrustCenterGraphUploadNDAMutation.graphql.ts
generated
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
/**
|
||||||
|
* @generated SignedSource<<966d4aa638042469c717ddc96e5c5d78>>
|
||||||
|
* @lightSyntaxTransform
|
||||||
|
* @nogrep
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
// @ts-nocheck
|
||||||
|
|
||||||
|
import { ConcreteRequest } from 'relay-runtime';
|
||||||
|
export type UploadTrustCenterNDAInput = {
|
||||||
|
file: any;
|
||||||
|
fileName: string;
|
||||||
|
trustCenterId: string;
|
||||||
|
};
|
||||||
|
export type TrustCenterGraphUploadNDAMutation$variables = {
|
||||||
|
input: UploadTrustCenterNDAInput;
|
||||||
|
};
|
||||||
|
export type TrustCenterGraphUploadNDAMutation$data = {
|
||||||
|
readonly uploadTrustCenterNDA: {
|
||||||
|
readonly trustCenter: {
|
||||||
|
readonly id: string;
|
||||||
|
readonly ndaFileName: string | null | undefined;
|
||||||
|
readonly updatedAt: any;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
export type TrustCenterGraphUploadNDAMutation = {
|
||||||
|
response: TrustCenterGraphUploadNDAMutation$data;
|
||||||
|
variables: TrustCenterGraphUploadNDAMutation$variables;
|
||||||
|
};
|
||||||
|
|
||||||
|
const node: ConcreteRequest = (function(){
|
||||||
|
var v0 = [
|
||||||
|
{
|
||||||
|
"defaultValue": null,
|
||||||
|
"kind": "LocalArgument",
|
||||||
|
"name": "input"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
v1 = [
|
||||||
|
{
|
||||||
|
"alias": null,
|
||||||
|
"args": [
|
||||||
|
{
|
||||||
|
"kind": "Variable",
|
||||||
|
"name": "input",
|
||||||
|
"variableName": "input"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"concreteType": "UploadTrustCenterNDAPayload",
|
||||||
|
"kind": "LinkedField",
|
||||||
|
"name": "uploadTrustCenterNDA",
|
||||||
|
"plural": false,
|
||||||
|
"selections": [
|
||||||
|
{
|
||||||
|
"alias": null,
|
||||||
|
"args": null,
|
||||||
|
"concreteType": "TrustCenter",
|
||||||
|
"kind": "LinkedField",
|
||||||
|
"name": "trustCenter",
|
||||||
|
"plural": false,
|
||||||
|
"selections": [
|
||||||
|
{
|
||||||
|
"alias": null,
|
||||||
|
"args": null,
|
||||||
|
"kind": "ScalarField",
|
||||||
|
"name": "id",
|
||||||
|
"storageKey": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"alias": null,
|
||||||
|
"args": null,
|
||||||
|
"kind": "ScalarField",
|
||||||
|
"name": "ndaFileName",
|
||||||
|
"storageKey": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"alias": null,
|
||||||
|
"args": null,
|
||||||
|
"kind": "ScalarField",
|
||||||
|
"name": "updatedAt",
|
||||||
|
"storageKey": null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"storageKey": null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"storageKey": null
|
||||||
|
}
|
||||||
|
];
|
||||||
|
return {
|
||||||
|
"fragment": {
|
||||||
|
"argumentDefinitions": (v0/*: any*/),
|
||||||
|
"kind": "Fragment",
|
||||||
|
"metadata": null,
|
||||||
|
"name": "TrustCenterGraphUploadNDAMutation",
|
||||||
|
"selections": (v1/*: any*/),
|
||||||
|
"type": "Mutation",
|
||||||
|
"abstractKey": null
|
||||||
|
},
|
||||||
|
"kind": "Request",
|
||||||
|
"operation": {
|
||||||
|
"argumentDefinitions": (v0/*: any*/),
|
||||||
|
"kind": "Operation",
|
||||||
|
"name": "TrustCenterGraphUploadNDAMutation",
|
||||||
|
"selections": (v1/*: any*/)
|
||||||
|
},
|
||||||
|
"params": {
|
||||||
|
"cacheID": "09a5dbf73f3e279173691b235f9da2e2",
|
||||||
|
"id": null,
|
||||||
|
"metadata": {},
|
||||||
|
"name": "TrustCenterGraphUploadNDAMutation",
|
||||||
|
"operationKind": "mutation",
|
||||||
|
"text": "mutation TrustCenterGraphUploadNDAMutation(\n $input: UploadTrustCenterNDAInput!\n) {\n uploadTrustCenterNDA(input: $input) {\n trustCenter {\n id\n ndaFileName\n updatedAt\n }\n }\n}\n"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
})();
|
||||||
|
|
||||||
|
(node as any).hash = "b9877f8a5b9c2c12addeb939360719f1";
|
||||||
|
|
||||||
|
export default node;
|
||||||
@@ -34,6 +34,9 @@ interface TrustCenterQueryData {
|
|||||||
active: boolean;
|
active: boolean;
|
||||||
slug: string;
|
slug: string;
|
||||||
isUserAuthenticated: boolean;
|
isUserAuthenticated: boolean;
|
||||||
|
hasAcceptedNonDisclosureAgreement: boolean;
|
||||||
|
ndaFileName: string | null;
|
||||||
|
ndaFileUrl: string | null;
|
||||||
organization: {
|
organization: {
|
||||||
id: string;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
@@ -96,7 +99,19 @@ interface CreateTrustCenterAccessVariables {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
type GraphQLVariables = TrustCenterQueryVariables | ExportDocumentPDFVariables | CreateTrustCenterAccessVariables | Record<string, never>;
|
interface AcceptNonDisclosureAgreementData {
|
||||||
|
acceptNonDisclosureAgreement: {
|
||||||
|
success: boolean;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
interface AcceptNonDisclosureAgreementVariables {
|
||||||
|
input: {
|
||||||
|
trustCenterId: string;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
type GraphQLVariables = TrustCenterQueryVariables | ExportDocumentPDFVariables | CreateTrustCenterAccessVariables | AcceptNonDisclosureAgreementVariables | Record<string, never>;
|
||||||
|
|
||||||
async function trustCenterGraphQLRequest<T = unknown>(
|
async function trustCenterGraphQLRequest<T = unknown>(
|
||||||
operationName: string,
|
operationName: string,
|
||||||
@@ -127,12 +142,14 @@ async function trustCenterGraphQLRequest<T = unknown>(
|
|||||||
|
|
||||||
function isCriticalError(error: GraphQLError): boolean {
|
function isCriticalError(error: GraphQLError): boolean {
|
||||||
const message = error.message?.toLowerCase() || '';
|
const message = error.message?.toLowerCase() || '';
|
||||||
const path = error.path || [];
|
|
||||||
|
|
||||||
if (message.includes('access denied') || message.includes('authentication required')) {
|
if (
|
||||||
if (path.length > 2) {
|
message.includes('access denied') ||
|
||||||
return false;
|
message.includes('authentication required') ||
|
||||||
}
|
message.includes('user has not accepted nda') ||
|
||||||
|
message.includes('no nda file found')
|
||||||
|
) {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -145,6 +162,9 @@ const TRUST_CENTER_QUERY = `
|
|||||||
active
|
active
|
||||||
slug
|
slug
|
||||||
isUserAuthenticated
|
isUserAuthenticated
|
||||||
|
hasAcceptedNonDisclosureAgreement
|
||||||
|
ndaFileName
|
||||||
|
ndaFileUrl
|
||||||
organization {
|
organization {
|
||||||
id
|
id
|
||||||
name
|
name
|
||||||
@@ -213,6 +233,16 @@ const CREATE_TRUST_CENTER_ACCESS_MUTATION = `
|
|||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
const ACCEPT_NDA_MUTATION = `
|
||||||
|
mutation AcceptNonDisclosureAgreementMutation(
|
||||||
|
$input: AcceptNonDisclosureAgreementInput!
|
||||||
|
) {
|
||||||
|
acceptNonDisclosureAgreement(input: $input) {
|
||||||
|
success
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
export function useTrustCenterQuery(slug: string) {
|
export function useTrustCenterQuery(slug: string) {
|
||||||
return useQuery<TrustCenterQueryData>({
|
return useQuery<TrustCenterQueryData>({
|
||||||
queryKey: ["trust-center", slug],
|
queryKey: ["trust-center", slug],
|
||||||
@@ -297,3 +327,27 @@ export function useCreateTrustCenterAccess() {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function useAcceptNonDisclosureAgreement() {
|
||||||
|
return useMutation<AcceptNonDisclosureAgreementData, Error, { trustCenterId: string }>({
|
||||||
|
mutationFn: async (input: { trustCenterId: string }) => {
|
||||||
|
const result = await trustCenterGraphQLRequest<AcceptNonDisclosureAgreementData>(
|
||||||
|
"AcceptNonDisclosureAgreementMutation",
|
||||||
|
ACCEPT_NDA_MUTATION,
|
||||||
|
{ input }
|
||||||
|
);
|
||||||
|
|
||||||
|
if (result.errors && result.errors.length > 0) {
|
||||||
|
throw new Error(
|
||||||
|
`GraphQL error: ${result.errors.map((e) => e.message).join(", ")}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!result.data) {
|
||||||
|
throw new Error("No data returned from mutation");
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.data;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|||||||
@@ -127,7 +127,9 @@ export default function TrustCenterAccessPage() {
|
|||||||
if (error) {
|
if (error) {
|
||||||
const isTokenError = error.toLowerCase().includes('token') ||
|
const isTokenError = error.toLowerCase().includes('token') ||
|
||||||
error.toLowerCase().includes('expired') ||
|
error.toLowerCase().includes('expired') ||
|
||||||
error.toLowerCase().includes('invalid');
|
error.toLowerCase().includes('invalid') ||
|
||||||
|
error.toLowerCase().includes('401') ||
|
||||||
|
error.toLowerCase().includes('unauthorized');
|
||||||
|
|
||||||
if (isTokenError) {
|
if (isTokenError) {
|
||||||
return <TokenErrorPage error={error} />;
|
return <TokenErrorPage error={error} />;
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import {
|
|||||||
useDialogRef,
|
useDialogRef,
|
||||||
IconTrashCan,
|
IconTrashCan,
|
||||||
IconPencil,
|
IconPencil,
|
||||||
|
IconCheckmark1,
|
||||||
} from "@probo/ui";
|
} from "@probo/ui";
|
||||||
import { useTranslate } from "@probo/i18n";
|
import { useTranslate } from "@probo/i18n";
|
||||||
import { useOutletContext } from "react-router";
|
import { useOutletContext } from "react-router";
|
||||||
@@ -85,6 +86,7 @@ export default function TrustCenterAccessTab() {
|
|||||||
email: string;
|
email: string;
|
||||||
name: string;
|
name: string;
|
||||||
active: boolean;
|
active: boolean;
|
||||||
|
hasAcceptedNonDisclosureAgreement: boolean;
|
||||||
createdAt: Date;
|
createdAt: Date;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -95,6 +97,7 @@ export default function TrustCenterAccessTab() {
|
|||||||
email: edge.node.email,
|
email: edge.node.email,
|
||||||
name: edge.node.name,
|
name: edge.node.name,
|
||||||
active: edge.node.active,
|
active: edge.node.active,
|
||||||
|
hasAcceptedNonDisclosureAgreement: edge.node.hasAcceptedNonDisclosureAgreement,
|
||||||
createdAt: new Date(edge.node.createdAt)
|
createdAt: new Date(edge.node.createdAt)
|
||||||
})) ?? [];
|
})) ?? [];
|
||||||
|
|
||||||
@@ -203,6 +206,7 @@ export default function TrustCenterAccessTab() {
|
|||||||
<Th>{__("Email")}</Th>
|
<Th>{__("Email")}</Th>
|
||||||
<Th>{__("Date")}</Th>
|
<Th>{__("Date")}</Th>
|
||||||
<Th>{__("Active")}</Th>
|
<Th>{__("Active")}</Th>
|
||||||
|
<Th>{__("NDA")}</Th>
|
||||||
<Th></Th>
|
<Th></Th>
|
||||||
</Tr>
|
</Tr>
|
||||||
</Thead>
|
</Thead>
|
||||||
@@ -220,6 +224,11 @@ export default function TrustCenterAccessTab() {
|
|||||||
onChange={(active) => handleToggleActive(access.id, active)}
|
onChange={(active) => handleToggleActive(access.id, active)}
|
||||||
/>
|
/>
|
||||||
</Td>
|
</Td>
|
||||||
|
<Td>
|
||||||
|
{access.hasAcceptedNonDisclosureAgreement && (
|
||||||
|
<IconCheckmark1 size={16} className="text-txt-success" />
|
||||||
|
)}
|
||||||
|
</Td>
|
||||||
<Td noLink width={160} className="text-end">
|
<Td noLink width={160} className="text-end">
|
||||||
<div className="flex gap-2 justify-end">
|
<div className="flex gap-2 justify-end">
|
||||||
<Button
|
<Button
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import {
|
|||||||
Button,
|
Button,
|
||||||
Card,
|
Card,
|
||||||
Checkbox,
|
Checkbox,
|
||||||
|
Dropzone,
|
||||||
Field,
|
Field,
|
||||||
Input,
|
Input,
|
||||||
PageHeader,
|
PageHeader,
|
||||||
@@ -12,9 +13,10 @@ import {
|
|||||||
Tabs,
|
Tabs,
|
||||||
TabLink,
|
TabLink,
|
||||||
TabItem,
|
TabItem,
|
||||||
|
IconTrashCan,
|
||||||
} from "@probo/ui";
|
} from "@probo/ui";
|
||||||
import { usePreloadedQuery, type PreloadedQuery } from "react-relay";
|
import { usePreloadedQuery, type PreloadedQuery } from "react-relay";
|
||||||
import { trustCenterQuery, useUpdateTrustCenterMutation } from "/hooks/graph/TrustCenterGraph";
|
import { trustCenterQuery, useUpdateTrustCenterMutation, useUploadTrustCenterNDAMutation, useDeleteTrustCenterNDAMutation } from "/hooks/graph/TrustCenterGraph";
|
||||||
import type { TrustCenterGraphQuery } from "/hooks/graph/__generated__/TrustCenterGraphQuery.graphql";
|
import type { TrustCenterGraphQuery } from "/hooks/graph/__generated__/TrustCenterGraphQuery.graphql";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { useOrganizationId } from "/hooks/useOrganizationId";
|
import { useOrganizationId } from "/hooks/useOrganizationId";
|
||||||
@@ -32,6 +34,8 @@ export default function TrustCenterPage({ queryRef }: Props) {
|
|||||||
const { organization } = usePreloadedQuery(trustCenterQuery, queryRef);
|
const { organization } = usePreloadedQuery(trustCenterQuery, queryRef);
|
||||||
|
|
||||||
const [updateTrustCenter, isUpdating] = useUpdateTrustCenterMutation();
|
const [updateTrustCenter, isUpdating] = useUpdateTrustCenterMutation();
|
||||||
|
const [uploadNDA, isUploadingNDA] = useUploadTrustCenterNDAMutation();
|
||||||
|
const [deleteNDA, isDeletingNDA] = useDeleteTrustCenterNDAMutation();
|
||||||
const [isActive, setIsActive] = useState(organization.trustCenter?.active || false);
|
const [isActive, setIsActive] = useState(organization.trustCenter?.active || false);
|
||||||
const [slug, setSlug] = useState(organization.trustCenter?.slug || "");
|
const [slug, setSlug] = useState(organization.trustCenter?.slug || "");
|
||||||
const [isUpdatingSlug, setIsUpdatingSlug] = useState(false);
|
const [isUpdatingSlug, setIsUpdatingSlug] = useState(false);
|
||||||
@@ -101,6 +105,57 @@ export default function TrustCenterPage({ queryRef }: Props) {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleNDAUpload = async (files: File[]) => {
|
||||||
|
if (!organization.trustCenter?.id) {
|
||||||
|
toast({
|
||||||
|
title: __("Error"),
|
||||||
|
description: __("Trust center not found"),
|
||||||
|
variant: "error",
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (files.length === 0) return;
|
||||||
|
|
||||||
|
const file = files[0];
|
||||||
|
|
||||||
|
await uploadNDA({
|
||||||
|
variables: {
|
||||||
|
input: {
|
||||||
|
trustCenterId: organization.trustCenter.id,
|
||||||
|
fileName: file.name,
|
||||||
|
file: null,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
uploadables: {
|
||||||
|
"input.file": file,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleNDADelete = async () => {
|
||||||
|
if (!organization.trustCenter?.id) {
|
||||||
|
toast({
|
||||||
|
title: __("Error"),
|
||||||
|
description: __("Trust center not found"),
|
||||||
|
variant: "error",
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!confirm(__("Are you sure you want to delete the NDA file?"))) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await deleteNDA({
|
||||||
|
variables: {
|
||||||
|
input: {
|
||||||
|
trustCenterId: organization.trustCenter.id,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
const trustCenterUrl = organization.trustCenter?.slug
|
const trustCenterUrl = organization.trustCenter?.slug
|
||||||
? `${window.location.origin}/trust/${organization.trustCenter.slug}`
|
? `${window.location.origin}/trust/${organization.trustCenter.slug}`
|
||||||
: null;
|
: null;
|
||||||
@@ -211,6 +266,68 @@ export default function TrustCenterPage({ queryRef }: Props) {
|
|||||||
</div>
|
</div>
|
||||||
</Card>
|
</Card>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div className="space-y-4">
|
||||||
|
<div className="flex items-center justify-between">
|
||||||
|
<h2 className="text-base font-medium">{__("Non-Disclosure Agreement")}</h2>
|
||||||
|
{(isUploadingNDA || isDeletingNDA) && <Spinner />}
|
||||||
|
</div>
|
||||||
|
<Card padded className="space-y-4">
|
||||||
|
<div className="space-y-2">
|
||||||
|
{!organization.trustCenter?.ndaFileName ? (
|
||||||
|
<p className="text-sm text-txt-tertiary">
|
||||||
|
{__("Upload a Non-Disclosure Agreement that visitors must accept before accessing your trust center")}
|
||||||
|
</p>
|
||||||
|
) : (<></>)}
|
||||||
|
{organization.trustCenter?.ndaFileName ? (
|
||||||
|
<div className="space-y-3">
|
||||||
|
<div className="flex items-center justify-between">
|
||||||
|
<div className="space-y-1">
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
<p className="text-sm font-medium">
|
||||||
|
{organization.trustCenter.ndaFileName || __("Non-Disclosure Agreement")}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<p className="text-xs text-txt-tertiary">
|
||||||
|
{__("Visitors will need to accept this NDA before accessing your trust center")}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
<Button
|
||||||
|
type="button"
|
||||||
|
variant="secondary"
|
||||||
|
onClick={() => {
|
||||||
|
if (organization.trustCenter?.ndaFileUrl) {
|
||||||
|
window.open(organization.trustCenter.ndaFileUrl, '_blank');
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{__("Download PDF")}
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
variant="quaternary"
|
||||||
|
icon={IconTrashCan}
|
||||||
|
onClick={handleNDADelete}
|
||||||
|
disabled={isDeletingNDA}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<Dropzone
|
||||||
|
description={__("Upload PDF files up to 10MB")}
|
||||||
|
isUploading={isUploadingNDA}
|
||||||
|
onDrop={handleNDAUpload}
|
||||||
|
accept={{
|
||||||
|
"application/pdf": [".pdf"],
|
||||||
|
}}
|
||||||
|
maxSize={10}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div className="space-y-4">
|
<div className="space-y-4">
|
||||||
<Tabs>
|
<Tabs>
|
||||||
<TabItem
|
<TabItem
|
||||||
|
|||||||
187
apps/console/src/trust/components/NDAAcceptanceDialog.tsx
Normal file
187
apps/console/src/trust/components/NDAAcceptanceDialog.tsx
Normal file
@@ -0,0 +1,187 @@
|
|||||||
|
import { useState, useEffect } from "react";
|
||||||
|
import {
|
||||||
|
Dialog,
|
||||||
|
DialogContent,
|
||||||
|
DialogFooter,
|
||||||
|
Button,
|
||||||
|
Checkbox,
|
||||||
|
IconLock,
|
||||||
|
IconArrowDown,
|
||||||
|
useToast,
|
||||||
|
useDialogRef
|
||||||
|
} from "@probo/ui";
|
||||||
|
import { useTranslate } from "@probo/i18n";
|
||||||
|
import { useAcceptNonDisclosureAgreement } from "/hooks/useTrustCenterQueries";
|
||||||
|
import { buildEndpoint } from "/providers/RelayProviders";
|
||||||
|
import { sprintf } from "@probo/helpers";
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
trustCenterId: string;
|
||||||
|
organizationName: string;
|
||||||
|
ndaFileName?: string | null;
|
||||||
|
ndaFileUrl?: string | null;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function NDAAcceptanceDialog({ trustCenterId, organizationName, ndaFileName, ndaFileUrl }: Props) {
|
||||||
|
const { __ } = useTranslate();
|
||||||
|
const { toast } = useToast();
|
||||||
|
const [isChecked, setIsChecked] = useState(false);
|
||||||
|
const dialogRef = useDialogRef();
|
||||||
|
const acceptNdaMutation = useAcceptNonDisclosureAgreement();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
dialogRef.current?.open();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const handleLogout = async () => {
|
||||||
|
try {
|
||||||
|
const response = await fetch(buildEndpoint('/api/trust/v1/auth/logout'), {
|
||||||
|
method: 'DELETE',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
credentials: 'include',
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error("Logout failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
window.location.reload();
|
||||||
|
} catch (error) {
|
||||||
|
toast({
|
||||||
|
title: __("Error"),
|
||||||
|
description: __("Logout failed"),
|
||||||
|
variant: "error",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleAccept = () => {
|
||||||
|
if (!isChecked) {
|
||||||
|
toast({
|
||||||
|
title: __("Agreement Required"),
|
||||||
|
description: __("Please check the box to confirm your agreement"),
|
||||||
|
variant: "error",
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
acceptNdaMutation.mutate(
|
||||||
|
{ trustCenterId },
|
||||||
|
{
|
||||||
|
onSuccess: () => {
|
||||||
|
window.location.reload();
|
||||||
|
},
|
||||||
|
onError: () => {
|
||||||
|
toast({
|
||||||
|
title: __("Error"),
|
||||||
|
description: __("Failed to accept the Non-Disclosure Agreement"),
|
||||||
|
variant: "error",
|
||||||
|
});
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleCancel = () => {
|
||||||
|
handleLogout();
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Dialog
|
||||||
|
ref={dialogRef}
|
||||||
|
closable={false}
|
||||||
|
onClose={handleCancel}
|
||||||
|
>
|
||||||
|
<DialogContent>
|
||||||
|
<div className="space-y-3 p-4">
|
||||||
|
<div className="text-center">
|
||||||
|
<div className="mx-auto flex h-12 w-12 items-center justify-center rounded-full bg-amber-50 border border-amber-200 mb-3">
|
||||||
|
<IconLock className="h-6 w-6 text-amber-600" />
|
||||||
|
</div>
|
||||||
|
<h2 className="text-lg font-semibold text-txt-primary mb-2">
|
||||||
|
{__("Non-Disclosure Agreement")}
|
||||||
|
</h2>
|
||||||
|
<p className="text-sm text-txt-secondary">
|
||||||
|
{sprintf(__("To access %s's trust center, you must accept the Non-Disclosure Agreement."), organizationName)}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="bg-level-1 p-3 rounded-lg border border-border-subtle">
|
||||||
|
{ndaFileName && ndaFileUrl ? (
|
||||||
|
<div className="text-center">
|
||||||
|
<p className="text-sm font-medium text-txt-primary mb-3">
|
||||||
|
{__("Please review and download the Non-Disclosure Agreement:")}
|
||||||
|
</p>
|
||||||
|
<div className="flex justify-center">
|
||||||
|
<Button
|
||||||
|
variant="secondary"
|
||||||
|
icon={IconArrowDown}
|
||||||
|
onClick={() => {
|
||||||
|
const link = document.createElement('a');
|
||||||
|
link.href = ndaFileUrl;
|
||||||
|
link.download = ndaFileName || 'NDA.pdf';
|
||||||
|
link.target = '_blank';
|
||||||
|
link.rel = 'noopener noreferrer';
|
||||||
|
document.body.appendChild(link);
|
||||||
|
link.click();
|
||||||
|
document.body.removeChild(link);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{sprintf(__("Download %s"), ndaFileName)}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<p className="text-sm font-medium text-txt-primary mb-2">
|
||||||
|
{__("By accepting this agreement, you commit to:")}
|
||||||
|
</p>
|
||||||
|
<ul className="text-sm text-txt-secondary space-y-0.5">
|
||||||
|
<li className="flex items-start">
|
||||||
|
<span className="inline-block w-2 h-2 rounded-full bg-txt-tertiary mt-1.5 mr-2 flex-shrink-0"></span>
|
||||||
|
{__("Keep confidential information secure")}
|
||||||
|
</li>
|
||||||
|
<li className="flex items-start">
|
||||||
|
<span className="inline-block w-2 h-2 rounded-full bg-txt-tertiary mt-1.5 mr-2 flex-shrink-0"></span>
|
||||||
|
{__("Not share or disclose sensitive data")}
|
||||||
|
</li>
|
||||||
|
<li className="flex items-start">
|
||||||
|
<span className="inline-block w-2 h-2 rounded-full bg-txt-tertiary mt-1.5 mr-2 flex-shrink-0"></span>
|
||||||
|
{__("Use information only for authorized purposes")}
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="flex items-start space-x-2 p-3 bg-level-0 rounded-lg border border-border-subtle">
|
||||||
|
<div className="mt-0.5">
|
||||||
|
<Checkbox
|
||||||
|
checked={isChecked}
|
||||||
|
onChange={setIsChecked}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<label
|
||||||
|
className="text-sm text-txt-primary cursor-pointer flex-1"
|
||||||
|
onClick={() => setIsChecked(!isChecked)}
|
||||||
|
>
|
||||||
|
{__("I agree to the terms of the Non-Disclosure Agreement and will handle all information accordingly.")}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</DialogContent>
|
||||||
|
|
||||||
|
<DialogFooter exitLabel={__("Disconnect")}>
|
||||||
|
<Button
|
||||||
|
variant="primary"
|
||||||
|
onClick={handleAccept}
|
||||||
|
disabled={!isChecked || acceptNdaMutation.isPending}
|
||||||
|
>
|
||||||
|
{acceptNdaMutation.isPending ? __("Accepting...") : __("Accept & Continue")}
|
||||||
|
</Button>
|
||||||
|
</DialogFooter>
|
||||||
|
</Dialog>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -5,6 +5,7 @@ import { PublicTrustCenterLayout } from "/layouts/PublicTrustCenterLayout";
|
|||||||
import { PublicTrustCenterAudits } from "../components/PublicTrustCenterAudits";
|
import { PublicTrustCenterAudits } from "../components/PublicTrustCenterAudits";
|
||||||
import { PublicTrustCenterVendors } from "../components/PublicTrustCenterVendors";
|
import { PublicTrustCenterVendors } from "../components/PublicTrustCenterVendors";
|
||||||
import { PublicTrustCenterDocuments } from "../components/PublicTrustCenterDocuments";
|
import { PublicTrustCenterDocuments } from "../components/PublicTrustCenterDocuments";
|
||||||
|
import { NDAAcceptanceDialog } from "../components/NDAAcceptanceDialog";
|
||||||
import { Spinner } from "@probo/ui";
|
import { Spinner } from "@probo/ui";
|
||||||
import { useTrustCenterQuery, type TrustCenterDocument, type TrustCenterAudit, type TrustCenterVendor } from "/hooks/useTrustCenterQueries";
|
import { useTrustCenterQuery, type TrustCenterDocument, type TrustCenterAudit, type TrustCenterVendor } from "/hooks/useTrustCenterQueries";
|
||||||
|
|
||||||
@@ -66,36 +67,49 @@ export default function PublicTrustCenterPage() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const { trustCenterBySlug } = data;
|
const { trustCenterBySlug } = data;
|
||||||
const { documents, audits, vendors, isUserAuthenticated } = trustCenterBySlug;
|
const { documents, audits, vendors, isUserAuthenticated, hasAcceptedNonDisclosureAgreement } = trustCenterBySlug;
|
||||||
|
|
||||||
const trustCenterDocuments = documents.edges.map((edge) => edge.node) as TrustCenterDocument[];
|
const trustCenterDocuments = documents.edges.map((edge) => edge.node) as TrustCenterDocument[];
|
||||||
const trustCenterAudits = audits.edges.map((edge) => edge.node) as TrustCenterAudit[];
|
const trustCenterAudits = audits.edges.map((edge) => edge.node) as TrustCenterAudit[];
|
||||||
const trustCenterVendors = vendors.edges.map((edge) => edge.node) as TrustCenterVendor[];
|
const trustCenterVendors = vendors.edges.map((edge) => edge.node) as TrustCenterVendor[];
|
||||||
|
|
||||||
|
const showNdaDialog = isUserAuthenticated && !hasAcceptedNonDisclosureAgreement;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PublicTrustCenterLayout
|
<>
|
||||||
organizationName={organizationName}
|
{showNdaDialog && (
|
||||||
organizationLogo={organization?.logoUrl}
|
<NDAAcceptanceDialog
|
||||||
isAuthenticated={isUserAuthenticated}
|
|
||||||
>
|
|
||||||
<div className="space-y-12">
|
|
||||||
<PublicTrustCenterAudits
|
|
||||||
audits={trustCenterAudits}
|
|
||||||
organizationName={organizationName}
|
|
||||||
isAuthenticated={isUserAuthenticated}
|
|
||||||
trustCenterId={trustCenterBySlug.id}
|
trustCenterId={trustCenterBySlug.id}
|
||||||
/>
|
|
||||||
<PublicTrustCenterDocuments
|
|
||||||
documents={trustCenterDocuments}
|
|
||||||
organizationName={organizationName}
|
organizationName={organizationName}
|
||||||
isAuthenticated={isUserAuthenticated}
|
ndaFileName={trustCenterBySlug.ndaFileName}
|
||||||
trustCenterId={trustCenterBySlug.id}
|
ndaFileUrl={trustCenterBySlug.ndaFileUrl}
|
||||||
/>
|
/>
|
||||||
<PublicTrustCenterVendors
|
)}
|
||||||
vendors={trustCenterVendors}
|
|
||||||
organizationName={organizationName}
|
<PublicTrustCenterLayout
|
||||||
/>
|
organizationName={organizationName}
|
||||||
</div>
|
organizationLogo={organization?.logoUrl}
|
||||||
</PublicTrustCenterLayout>
|
isAuthenticated={isUserAuthenticated}
|
||||||
|
>
|
||||||
|
<div className="space-y-12">
|
||||||
|
<PublicTrustCenterAudits
|
||||||
|
audits={trustCenterAudits}
|
||||||
|
organizationName={organizationName}
|
||||||
|
isAuthenticated={isUserAuthenticated}
|
||||||
|
trustCenterId={trustCenterBySlug.id}
|
||||||
|
/>
|
||||||
|
<PublicTrustCenterDocuments
|
||||||
|
documents={trustCenterDocuments}
|
||||||
|
organizationName={organizationName}
|
||||||
|
isAuthenticated={isUserAuthenticated}
|
||||||
|
trustCenterId={trustCenterBySlug.id}
|
||||||
|
/>
|
||||||
|
<PublicTrustCenterVendors
|
||||||
|
vendors={trustCenterVendors}
|
||||||
|
organizationName={organizationName}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</PublicTrustCenterLayout>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ type Props = {
|
|||||||
className?: string;
|
className?: string;
|
||||||
ref?: DialogRef;
|
ref?: DialogRef;
|
||||||
onClose?: () => void;
|
onClose?: () => void;
|
||||||
|
closable?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useDialogRef = (): DialogRef => {
|
export const useDialogRef = (): DialogRef => {
|
||||||
@@ -64,6 +65,7 @@ export function Dialog({
|
|||||||
ref,
|
ref,
|
||||||
defaultOpen,
|
defaultOpen,
|
||||||
onClose,
|
onClose,
|
||||||
|
closable = true,
|
||||||
}: Props) {
|
}: Props) {
|
||||||
const { overlay, content, header, title: titleClassname } = dialog();
|
const { overlay, content, header, title: titleClassname } = dialog();
|
||||||
const [open, setOpen] = useState(!!defaultOpen);
|
const [open, setOpen] = useState(!!defaultOpen);
|
||||||
@@ -80,41 +82,55 @@ export function Dialog({
|
|||||||
}
|
}
|
||||||
|
|
||||||
const onOpenChange = (open: boolean) => {
|
const onOpenChange = (open: boolean) => {
|
||||||
|
if (!open && !closable) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
setOpen(open);
|
setOpen(open);
|
||||||
if (!open) {
|
if (!open) {
|
||||||
onClose?.();
|
onClose?.();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const contentProps = closable ? {} : {
|
||||||
|
onEscapeKeyDown: (e: Event) => e.preventDefault(),
|
||||||
|
onPointerDownOutside: (e: Event) => e.preventDefault(),
|
||||||
|
onInteractOutside: (e: Event) => e.preventDefault(),
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Root open={open} onOpenChange={onOpenChange}>
|
<Root open={open} onOpenChange={closable ? onOpenChange : undefined}>
|
||||||
{trigger && <Trigger asChild>{trigger}</Trigger>}
|
{trigger && <Trigger asChild>{trigger}</Trigger>}
|
||||||
<Portal>
|
<Portal>
|
||||||
<Overlay className={overlay()} />
|
<Overlay className={overlay()} />
|
||||||
<Content
|
<Content
|
||||||
aria-describedby={undefined}
|
aria-describedby={undefined}
|
||||||
className={content({ className })}
|
className={content({ className })}
|
||||||
|
{...contentProps}
|
||||||
>
|
>
|
||||||
{title ? (
|
{title ? (
|
||||||
<div className={header()}>
|
<div className={header()}>
|
||||||
<Title className={titleClassname()}> {title}</Title>
|
<Title className={titleClassname()}> {title}</Title>
|
||||||
|
{closable && (
|
||||||
|
<Close asChild>
|
||||||
|
<Button
|
||||||
|
tabIndex={-1}
|
||||||
|
variant="tertiary"
|
||||||
|
icon={IconCrossLargeX}
|
||||||
|
/>
|
||||||
|
</Close>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
closable && (
|
||||||
<Close asChild>
|
<Close asChild>
|
||||||
<Button
|
<Button
|
||||||
tabIndex={-1}
|
tabIndex={-1}
|
||||||
variant="tertiary"
|
variant="tertiary"
|
||||||
|
className="absolute top-4 right-4"
|
||||||
icon={IconCrossLargeX}
|
icon={IconCrossLargeX}
|
||||||
/>
|
/>
|
||||||
</Close>
|
</Close>
|
||||||
</div>
|
)
|
||||||
) : (
|
|
||||||
<Close asChild>
|
|
||||||
<Button
|
|
||||||
tabIndex={-1}
|
|
||||||
variant="tertiary"
|
|
||||||
className="absolute top-4 right-4"
|
|
||||||
icon={IconCrossLargeX}
|
|
||||||
/>
|
|
||||||
</Close>
|
|
||||||
)}
|
)}
|
||||||
{children}
|
{children}
|
||||||
</Content>
|
</Content>
|
||||||
|
|||||||
@@ -14,6 +14,12 @@
|
|||||||
|
|
||||||
package coredata
|
package coredata
|
||||||
|
|
||||||
|
type ctxKey struct{ name string }
|
||||||
|
|
||||||
|
var (
|
||||||
|
ContextKeyIPAddress = &ctxKey{name: "ip_address"}
|
||||||
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
OrganizationEntityType uint16 = iota
|
OrganizationEntityType uint16 = iota
|
||||||
FrameworkEntityType
|
FrameworkEntityType
|
||||||
|
|||||||
10
pkg/coredata/migrations/20250909T114034Z.sql
Normal file
10
pkg/coredata/migrations/20250909T114034Z.sql
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
ALTER TABLE trust_center_accesses ADD COLUMN has_accepted_non_disclosure_agreement BOOLEAN NOT NULL DEFAULT FALSE;
|
||||||
|
ALTER TABLE trust_center_accesses ALTER COLUMN has_accepted_non_disclosure_agreement DROP DEFAULT;
|
||||||
|
ALTER TABLE trust_center_accesses ADD COLUMN has_accepted_non_disclosure_agreement_metadata JSONB;
|
||||||
|
|
||||||
|
ALTER TABLE trust_centers ADD COLUMN non_disclosure_agreement_file_id TEXT;
|
||||||
|
ALTER TABLE trust_centers ADD CONSTRAINT trust_centers_non_disclosure_agreement_file_id_fkey
|
||||||
|
FOREIGN KEY (non_disclosure_agreement_file_id)
|
||||||
|
REFERENCES files(id)
|
||||||
|
ON UPDATE CASCADE
|
||||||
|
ON DELETE RESTRICT;
|
||||||
@@ -28,13 +28,14 @@ import (
|
|||||||
|
|
||||||
type (
|
type (
|
||||||
TrustCenter struct {
|
TrustCenter struct {
|
||||||
ID gid.GID `db:"id"`
|
ID gid.GID `db:"id"`
|
||||||
OrganizationID gid.GID `db:"organization_id"`
|
OrganizationID gid.GID `db:"organization_id"`
|
||||||
TenantID gid.TenantID `db:"tenant_id"`
|
TenantID gid.TenantID `db:"tenant_id"`
|
||||||
Active bool `db:"active"`
|
Active bool `db:"active"`
|
||||||
Slug string `db:"slug"`
|
Slug string `db:"slug"`
|
||||||
CreatedAt time.Time `db:"created_at"`
|
NonDisclosureAgreementFileID *gid.GID `db:"non_disclosure_agreement_file_id"`
|
||||||
UpdatedAt time.Time `db:"updated_at"`
|
CreatedAt time.Time `db:"created_at"`
|
||||||
|
UpdatedAt time.Time `db:"updated_at"`
|
||||||
}
|
}
|
||||||
|
|
||||||
TrustCenters []*TrustCenter
|
TrustCenters []*TrustCenter
|
||||||
@@ -62,6 +63,7 @@ SELECT
|
|||||||
tenant_id,
|
tenant_id,
|
||||||
active,
|
active,
|
||||||
slug,
|
slug,
|
||||||
|
non_disclosure_agreement_file_id,
|
||||||
created_at,
|
created_at,
|
||||||
updated_at
|
updated_at
|
||||||
FROM
|
FROM
|
||||||
@@ -105,6 +107,7 @@ SELECT
|
|||||||
tenant_id,
|
tenant_id,
|
||||||
active,
|
active,
|
||||||
slug,
|
slug,
|
||||||
|
non_disclosure_agreement_file_id,
|
||||||
created_at,
|
created_at,
|
||||||
updated_at
|
updated_at
|
||||||
FROM
|
FROM
|
||||||
@@ -147,6 +150,7 @@ SELECT
|
|||||||
tenant_id,
|
tenant_id,
|
||||||
active,
|
active,
|
||||||
slug,
|
slug,
|
||||||
|
non_disclosure_agreement_file_id,
|
||||||
created_at,
|
created_at,
|
||||||
updated_at
|
updated_at
|
||||||
FROM
|
FROM
|
||||||
@@ -185,6 +189,7 @@ INSERT INTO trust_centers (
|
|||||||
tenant_id,
|
tenant_id,
|
||||||
active,
|
active,
|
||||||
slug,
|
slug,
|
||||||
|
non_disclosure_agreement_file_id,
|
||||||
created_at,
|
created_at,
|
||||||
updated_at
|
updated_at
|
||||||
) VALUES (
|
) VALUES (
|
||||||
@@ -193,19 +198,21 @@ INSERT INTO trust_centers (
|
|||||||
@tenant_id,
|
@tenant_id,
|
||||||
@active,
|
@active,
|
||||||
@slug,
|
@slug,
|
||||||
|
@non_disclosure_agreement_file_id,
|
||||||
@created_at,
|
@created_at,
|
||||||
@updated_at
|
@updated_at
|
||||||
)
|
)
|
||||||
`
|
`
|
||||||
|
|
||||||
args := pgx.StrictNamedArgs{
|
args := pgx.StrictNamedArgs{
|
||||||
"id": tc.ID,
|
"id": tc.ID,
|
||||||
"organization_id": tc.OrganizationID,
|
"organization_id": tc.OrganizationID,
|
||||||
"tenant_id": tc.TenantID,
|
"tenant_id": tc.TenantID,
|
||||||
"active": tc.Active,
|
"active": tc.Active,
|
||||||
"slug": tc.Slug,
|
"slug": tc.Slug,
|
||||||
"created_at": tc.CreatedAt,
|
"non_disclosure_agreement_file_id": tc.NonDisclosureAgreementFileID,
|
||||||
"updated_at": tc.UpdatedAt,
|
"created_at": tc.CreatedAt,
|
||||||
|
"updated_at": tc.UpdatedAt,
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := conn.Exec(ctx, q, args)
|
_, err := conn.Exec(ctx, q, args)
|
||||||
@@ -226,6 +233,7 @@ UPDATE trust_centers
|
|||||||
SET
|
SET
|
||||||
active = @active,
|
active = @active,
|
||||||
slug = @slug,
|
slug = @slug,
|
||||||
|
non_disclosure_agreement_file_id = @non_disclosure_agreement_file_id,
|
||||||
updated_at = @updated_at
|
updated_at = @updated_at
|
||||||
WHERE
|
WHERE
|
||||||
%s
|
%s
|
||||||
@@ -235,10 +243,11 @@ WHERE
|
|||||||
q = fmt.Sprintf(q, scope.SQLFragment())
|
q = fmt.Sprintf(q, scope.SQLFragment())
|
||||||
|
|
||||||
args := pgx.StrictNamedArgs{
|
args := pgx.StrictNamedArgs{
|
||||||
"id": tc.ID,
|
"id": tc.ID,
|
||||||
"active": tc.Active,
|
"active": tc.Active,
|
||||||
"slug": tc.Slug,
|
"slug": tc.Slug,
|
||||||
"updated_at": tc.UpdatedAt,
|
"non_disclosure_agreement_file_id": tc.NonDisclosureAgreementFileID,
|
||||||
|
"updated_at": tc.UpdatedAt,
|
||||||
}
|
}
|
||||||
maps.Copy(args, scope.SQLArguments())
|
maps.Copy(args, scope.SQLArguments())
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ package coredata
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"maps"
|
"maps"
|
||||||
@@ -29,14 +30,16 @@ import (
|
|||||||
|
|
||||||
type (
|
type (
|
||||||
TrustCenterAccess struct {
|
TrustCenterAccess struct {
|
||||||
ID gid.GID `db:"id"`
|
ID gid.GID `db:"id"`
|
||||||
TenantID gid.TenantID `db:"tenant_id"`
|
TenantID gid.TenantID `db:"tenant_id"`
|
||||||
TrustCenterID gid.GID `db:"trust_center_id"`
|
TrustCenterID gid.GID `db:"trust_center_id"`
|
||||||
Email string `db:"email"`
|
Email string `db:"email"`
|
||||||
Name string `db:"name"`
|
Name string `db:"name"`
|
||||||
Active bool `db:"active"`
|
Active bool `db:"active"`
|
||||||
CreatedAt time.Time `db:"created_at"`
|
HasAcceptedNonDisclosureAgreement bool `db:"has_accepted_non_disclosure_agreement"`
|
||||||
UpdatedAt time.Time `db:"updated_at"`
|
HasAcceptedNonDisclosureAgreementMetadata json.RawMessage `db:"has_accepted_non_disclosure_agreement_metadata"`
|
||||||
|
CreatedAt time.Time `db:"created_at"`
|
||||||
|
UpdatedAt time.Time `db:"updated_at"`
|
||||||
}
|
}
|
||||||
|
|
||||||
TrustCenterAccesses []*TrustCenterAccess
|
TrustCenterAccesses []*TrustCenterAccess
|
||||||
@@ -73,6 +76,8 @@ SELECT
|
|||||||
email,
|
email,
|
||||||
name,
|
name,
|
||||||
active,
|
active,
|
||||||
|
has_accepted_non_disclosure_agreement,
|
||||||
|
has_accepted_non_disclosure_agreement_metadata,
|
||||||
created_at,
|
created_at,
|
||||||
updated_at
|
updated_at
|
||||||
FROM
|
FROM
|
||||||
@@ -122,6 +127,8 @@ SELECT
|
|||||||
email,
|
email,
|
||||||
name,
|
name,
|
||||||
active,
|
active,
|
||||||
|
has_accepted_non_disclosure_agreement,
|
||||||
|
has_accepted_non_disclosure_agreement_metadata,
|
||||||
created_at,
|
created_at,
|
||||||
updated_at
|
updated_at
|
||||||
FROM
|
FROM
|
||||||
@@ -173,6 +180,7 @@ INSERT INTO trust_center_accesses (
|
|||||||
email,
|
email,
|
||||||
name,
|
name,
|
||||||
active,
|
active,
|
||||||
|
has_accepted_non_disclosure_agreement,
|
||||||
created_at,
|
created_at,
|
||||||
updated_at
|
updated_at
|
||||||
) VALUES (
|
) VALUES (
|
||||||
@@ -182,20 +190,22 @@ INSERT INTO trust_center_accesses (
|
|||||||
@email,
|
@email,
|
||||||
@name,
|
@name,
|
||||||
@active,
|
@active,
|
||||||
|
@has_accepted_non_disclosure_agreement,
|
||||||
@created_at,
|
@created_at,
|
||||||
@updated_at
|
@updated_at
|
||||||
)
|
)
|
||||||
`
|
`
|
||||||
|
|
||||||
args := pgx.StrictNamedArgs{
|
args := pgx.StrictNamedArgs{
|
||||||
"id": tca.ID,
|
"id": tca.ID,
|
||||||
"tenant_id": tca.TenantID,
|
"tenant_id": tca.TenantID,
|
||||||
"trust_center_id": tca.TrustCenterID,
|
"trust_center_id": tca.TrustCenterID,
|
||||||
"email": tca.Email,
|
"email": tca.Email,
|
||||||
"name": tca.Name,
|
"name": tca.Name,
|
||||||
"active": tca.Active,
|
"active": tca.Active,
|
||||||
"created_at": tca.CreatedAt,
|
"has_accepted_non_disclosure_agreement": tca.HasAcceptedNonDisclosureAgreement,
|
||||||
"updated_at": tca.UpdatedAt,
|
"created_at": tca.CreatedAt,
|
||||||
|
"updated_at": tca.UpdatedAt,
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := conn.Exec(ctx, q, args)
|
_, err := conn.Exec(ctx, q, args)
|
||||||
@@ -215,7 +225,9 @@ func (tca *TrustCenterAccess) Update(
|
|||||||
UPDATE trust_center_accesses SET
|
UPDATE trust_center_accesses SET
|
||||||
name = @name,
|
name = @name,
|
||||||
active = @active,
|
active = @active,
|
||||||
updated_at = @updated_at
|
updated_at = @updated_at,
|
||||||
|
has_accepted_non_disclosure_agreement = @has_accepted_non_disclosure_agreement,
|
||||||
|
has_accepted_non_disclosure_agreement_metadata = @has_accepted_non_disclosure_agreement_metadata
|
||||||
WHERE
|
WHERE
|
||||||
%s
|
%s
|
||||||
AND id = @id
|
AND id = @id
|
||||||
@@ -224,10 +236,12 @@ WHERE
|
|||||||
q = fmt.Sprintf(q, scope.SQLFragment())
|
q = fmt.Sprintf(q, scope.SQLFragment())
|
||||||
|
|
||||||
args := pgx.StrictNamedArgs{
|
args := pgx.StrictNamedArgs{
|
||||||
"id": tca.ID,
|
"id": tca.ID,
|
||||||
"name": tca.Name,
|
"name": tca.Name,
|
||||||
"active": tca.Active,
|
"active": tca.Active,
|
||||||
"updated_at": tca.UpdatedAt,
|
"updated_at": tca.UpdatedAt,
|
||||||
|
"has_accepted_non_disclosure_agreement": tca.HasAcceptedNonDisclosureAgreement,
|
||||||
|
"has_accepted_non_disclosure_agreement_metadata": tca.HasAcceptedNonDisclosureAgreementMetadata,
|
||||||
}
|
}
|
||||||
maps.Copy(args, scope.SQLArguments())
|
maps.Copy(args, scope.SQLArguments())
|
||||||
|
|
||||||
@@ -281,6 +295,8 @@ SELECT
|
|||||||
email,
|
email,
|
||||||
name,
|
name,
|
||||||
active,
|
active,
|
||||||
|
has_accepted_non_disclosure_agreement,
|
||||||
|
has_accepted_non_disclosure_agreement_metadata,
|
||||||
created_at,
|
created_at,
|
||||||
updated_at
|
updated_at
|
||||||
FROM
|
FROM
|
||||||
|
|||||||
@@ -149,14 +149,15 @@ func (s TrustCenterAccessService) Create(
|
|||||||
}
|
}
|
||||||
|
|
||||||
access = &coredata.TrustCenterAccess{
|
access = &coredata.TrustCenterAccess{
|
||||||
ID: gid.New(s.svc.scope.GetTenantID(), coredata.TrustCenterAccessEntityType),
|
ID: gid.New(s.svc.scope.GetTenantID(), coredata.TrustCenterAccessEntityType),
|
||||||
TenantID: s.svc.scope.GetTenantID(),
|
TenantID: s.svc.scope.GetTenantID(),
|
||||||
TrustCenterID: req.TrustCenterID,
|
TrustCenterID: req.TrustCenterID,
|
||||||
Email: req.Email,
|
Email: req.Email,
|
||||||
Name: req.Name,
|
Name: req.Name,
|
||||||
Active: req.Active,
|
Active: req.Active,
|
||||||
CreatedAt: now,
|
HasAcceptedNonDisclosureAgreement: false,
|
||||||
UpdatedAt: now,
|
CreatedAt: now,
|
||||||
|
UpdatedAt: now,
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := access.Insert(ctx, tx, s.svc.scope); err != nil {
|
if err := access.Insert(ctx, tx, s.svc.scope); err != nil {
|
||||||
|
|||||||
@@ -17,10 +17,17 @@ package probo
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"mime"
|
||||||
|
"net/url"
|
||||||
|
"path/filepath"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go-v2/aws"
|
||||||
|
"github.com/aws/aws-sdk-go-v2/service/s3"
|
||||||
"github.com/getprobo/probo/pkg/coredata"
|
"github.com/getprobo/probo/pkg/coredata"
|
||||||
"github.com/getprobo/probo/pkg/gid"
|
"github.com/getprobo/probo/pkg/gid"
|
||||||
|
"go.gearno.de/crypto/uuid"
|
||||||
"go.gearno.de/kit/pg"
|
"go.gearno.de/kit/pg"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -30,71 +37,100 @@ type (
|
|||||||
}
|
}
|
||||||
|
|
||||||
UpdateTrustCenterRequest struct {
|
UpdateTrustCenterRequest struct {
|
||||||
ID gid.GID
|
ID gid.GID
|
||||||
Active *bool
|
Active *bool
|
||||||
Slug *string
|
Slug *string
|
||||||
|
NonDisclosureAgreementFileID *gid.GID
|
||||||
|
}
|
||||||
|
|
||||||
|
UploadTrustCenterNDARequest struct {
|
||||||
|
TrustCenterID gid.GID
|
||||||
|
File io.Reader
|
||||||
|
FileName string
|
||||||
|
}
|
||||||
|
|
||||||
|
DeleteTrustCenterNDARequest struct {
|
||||||
|
TrustCenterID gid.GID
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s TrustCenterService) Get(
|
func (s TrustCenterService) Get(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
trustCenterID gid.GID,
|
trustCenterID gid.GID,
|
||||||
) (*coredata.TrustCenter, error) {
|
) (*coredata.TrustCenter, *coredata.File, error) {
|
||||||
trustCenter := &coredata.TrustCenter{}
|
var trustCenter *coredata.TrustCenter
|
||||||
|
var file *coredata.File
|
||||||
|
|
||||||
err := s.svc.pg.WithConn(
|
err := s.svc.pg.WithConn(
|
||||||
ctx,
|
ctx,
|
||||||
func(conn pg.Conn) error {
|
func(conn pg.Conn) error {
|
||||||
err := trustCenter.LoadByID(ctx, conn, s.svc.scope, trustCenterID)
|
trustCenter = &coredata.TrustCenter{}
|
||||||
if err != nil {
|
if err := trustCenter.LoadByID(ctx, conn, s.svc.scope, trustCenterID); err != nil {
|
||||||
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, err
|
return nil, nil, fmt.Errorf("cannot load trust center: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return trustCenter, nil
|
return trustCenter, file, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s TrustCenterService) GetByOrganizationID(
|
func (s TrustCenterService) GetByOrganizationID(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
organizationID gid.GID,
|
organizationID gid.GID,
|
||||||
) (*coredata.TrustCenter, error) {
|
) (*coredata.TrustCenter, *coredata.File, error) {
|
||||||
trustCenter := &coredata.TrustCenter{}
|
var trustCenter *coredata.TrustCenter
|
||||||
|
var file *coredata.File
|
||||||
|
|
||||||
err := s.svc.pg.WithConn(
|
err := s.svc.pg.WithConn(
|
||||||
ctx,
|
ctx,
|
||||||
func(conn pg.Conn) error {
|
func(conn pg.Conn) error {
|
||||||
err := trustCenter.LoadByOrganizationID(ctx, conn, s.svc.scope, organizationID)
|
trustCenter = &coredata.TrustCenter{}
|
||||||
if err != nil {
|
if err := trustCenter.LoadByOrganizationID(ctx, conn, s.svc.scope, organizationID); err != nil {
|
||||||
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, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return trustCenter, nil
|
return trustCenter, file, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s TrustCenterService) Update(
|
func (s TrustCenterService) Update(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
req *UpdateTrustCenterRequest,
|
req *UpdateTrustCenterRequest,
|
||||||
) (*coredata.TrustCenter, error) {
|
) (*coredata.TrustCenter, *coredata.File, error) {
|
||||||
trustCenter := &coredata.TrustCenter{}
|
var trustCenter *coredata.TrustCenter
|
||||||
|
var file *coredata.File
|
||||||
|
|
||||||
err := s.svc.pg.WithTx(
|
err := s.svc.pg.WithTx(
|
||||||
ctx,
|
ctx,
|
||||||
func(conn pg.Conn) error {
|
func(conn pg.Conn) error {
|
||||||
|
trustCenter = &coredata.TrustCenter{}
|
||||||
if err := trustCenter.LoadByID(ctx, conn, s.svc.scope, req.ID); err != nil {
|
if err := trustCenter.LoadByID(ctx, conn, s.svc.scope, req.ID); err != nil {
|
||||||
return fmt.Errorf("cannot load trust center: %w", err)
|
return fmt.Errorf("cannot load trust center: %w", err)
|
||||||
}
|
}
|
||||||
@@ -112,13 +148,189 @@ func (s TrustCenterService) Update(
|
|||||||
return fmt.Errorf("cannot update trust center: %w", err)
|
return fmt.Errorf("cannot update 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 {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return trustCenter, file, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s TrustCenterService) UploadNDA(
|
||||||
|
ctx context.Context,
|
||||||
|
req *UploadTrustCenterNDARequest,
|
||||||
|
) (*coredata.TrustCenter, *coredata.File, error) {
|
||||||
|
objectKey, err := uuid.NewV7()
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, fmt.Errorf("cannot generate object key: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
mimeType := mime.TypeByExtension(filepath.Ext(req.FileName))
|
||||||
|
|
||||||
|
_, err = s.svc.s3.PutObject(ctx, &s3.PutObjectInput{
|
||||||
|
Bucket: &s.svc.bucket,
|
||||||
|
Key: aws.String(objectKey.String()),
|
||||||
|
Body: req.File,
|
||||||
|
ContentType: &mimeType,
|
||||||
|
Metadata: map[string]string{
|
||||||
|
"type": "trust-center-nda",
|
||||||
|
"trust-center-id": req.TrustCenterID.String(),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, fmt.Errorf("cannot upload file to S3: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
headOutput, err := s.svc.s3.HeadObject(ctx, &s3.HeadObjectInput{
|
||||||
|
Bucket: aws.String(s.svc.bucket),
|
||||||
|
Key: aws.String(objectKey.String()),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, fmt.Errorf("cannot get object metadata: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
now := time.Now()
|
||||||
|
|
||||||
|
fileID := gid.New(s.svc.scope.GetTenantID(), coredata.FileEntityType)
|
||||||
|
|
||||||
|
var trustCenter *coredata.TrustCenter
|
||||||
|
var file *coredata.File
|
||||||
|
|
||||||
|
err = s.svc.pg.WithTx(
|
||||||
|
ctx,
|
||||||
|
func(conn pg.Conn) error {
|
||||||
|
trustCenter = &coredata.TrustCenter{}
|
||||||
|
if err := trustCenter.LoadByID(ctx, conn, s.svc.scope, req.TrustCenterID); err != nil {
|
||||||
|
return fmt.Errorf("cannot load trust center: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
file = &coredata.File{
|
||||||
|
ID: fileID,
|
||||||
|
BucketName: s.svc.bucket,
|
||||||
|
MimeType: mimeType,
|
||||||
|
FileName: req.FileName,
|
||||||
|
FileKey: objectKey.String(),
|
||||||
|
FileSize: int(*headOutput.ContentLength),
|
||||||
|
CreatedAt: now,
|
||||||
|
UpdatedAt: now,
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := file.Insert(ctx, conn, s.svc.scope); err != nil {
|
||||||
|
return fmt.Errorf("cannot insert file: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
trustCenter.NonDisclosureAgreementFileID = &fileID
|
||||||
|
trustCenter.UpdatedAt = now
|
||||||
|
|
||||||
|
if err := trustCenter.Update(ctx, conn, s.svc.scope); err != nil {
|
||||||
|
return fmt.Errorf("cannot update trust center: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return trustCenter, file, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s TrustCenterService) DeleteNDA(
|
||||||
|
ctx context.Context,
|
||||||
|
req *DeleteTrustCenterNDARequest,
|
||||||
|
) (*coredata.TrustCenter, *coredata.File, error) {
|
||||||
|
var trustCenter *coredata.TrustCenter
|
||||||
|
|
||||||
|
err := s.svc.pg.WithTx(
|
||||||
|
ctx,
|
||||||
|
func(conn pg.Conn) error {
|
||||||
|
trustCenter = &coredata.TrustCenter{}
|
||||||
|
if err := trustCenter.LoadByID(ctx, conn, s.svc.scope, req.TrustCenterID); err != nil {
|
||||||
|
return fmt.Errorf("cannot load trust center: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
trustCenter.NonDisclosureAgreementFileID = nil
|
||||||
|
trustCenter.UpdatedAt = time.Now()
|
||||||
|
|
||||||
|
if err := trustCenter.Update(ctx, conn, s.svc.scope); err != nil {
|
||||||
|
return fmt.Errorf("cannot update trust center: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return trustCenter, nil, nil // File is nil after deletion
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s TrustCenterService) GenerateNDAFileURL(
|
||||||
|
ctx context.Context,
|
||||||
|
trustCenterID gid.GID,
|
||||||
|
expiresIn time.Duration,
|
||||||
|
) (*string, error) {
|
||||||
|
var file *coredata.File
|
||||||
|
trustCenter := &coredata.TrustCenter{}
|
||||||
|
|
||||||
|
err := s.svc.pg.WithConn(
|
||||||
|
ctx,
|
||||||
|
func(conn pg.Conn) error {
|
||||||
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return trustCenter, nil
|
if trustCenter.NonDisclosureAgreementFileID == nil {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
presignClient := s3.NewPresignClient(s.svc.s3)
|
||||||
|
|
||||||
|
encodedFilename := url.QueryEscape(file.FileName)
|
||||||
|
contentDisposition := fmt.Sprintf("attachment; filename=\"%s\"; filename*=UTF-8''%s",
|
||||||
|
encodedFilename, encodedFilename)
|
||||||
|
|
||||||
|
presignedReq, err := presignClient.PresignGetObject(ctx, &s3.GetObjectInput{
|
||||||
|
Bucket: aws.String(s.svc.bucket),
|
||||||
|
Key: aws.String(file.FileKey),
|
||||||
|
ResponseCacheControl: aws.String("max-age=3600, public"),
|
||||||
|
ResponseContentDisposition: aws.String(contentDisposition),
|
||||||
|
}, func(opts *s3.PresignOptions) {
|
||||||
|
opts.Expires = expiresIn
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("cannot presign GetObject request: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &presignedReq.URL, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1144,6 +1144,8 @@ type TrustCenter implements Node {
|
|||||||
id: ID!
|
id: ID!
|
||||||
active: Boolean!
|
active: Boolean!
|
||||||
slug: String!
|
slug: String!
|
||||||
|
ndaFileName: String
|
||||||
|
ndaFileUrl: String @goField(forceResolver: true)
|
||||||
createdAt: Datetime!
|
createdAt: Datetime!
|
||||||
updatedAt: Datetime!
|
updatedAt: Datetime!
|
||||||
organization: Organization! @goField(forceResolver: true)
|
organization: Organization! @goField(forceResolver: true)
|
||||||
@@ -1889,6 +1891,7 @@ type TrustCenterAccess implements Node {
|
|||||||
email: String!
|
email: String!
|
||||||
name: String!
|
name: String!
|
||||||
active: Boolean!
|
active: Boolean!
|
||||||
|
hasAcceptedNonDisclosureAgreement: Boolean!
|
||||||
createdAt: Datetime!
|
createdAt: Datetime!
|
||||||
updatedAt: Datetime!
|
updatedAt: Datetime!
|
||||||
}
|
}
|
||||||
@@ -2218,6 +2221,14 @@ type Mutation {
|
|||||||
input: UpdateTrustCenterInput!
|
input: UpdateTrustCenterInput!
|
||||||
): UpdateTrustCenterPayload!
|
): UpdateTrustCenterPayload!
|
||||||
|
|
||||||
|
uploadTrustCenterNDA(
|
||||||
|
input: UploadTrustCenterNDAInput!
|
||||||
|
): UploadTrustCenterNDAPayload!
|
||||||
|
|
||||||
|
deleteTrustCenterNDA(
|
||||||
|
input: DeleteTrustCenterNDAInput!
|
||||||
|
): DeleteTrustCenterNDAPayload!
|
||||||
|
|
||||||
# Trust Center Access CRUD mutations
|
# Trust Center Access CRUD mutations
|
||||||
createTrustCenterAccess(
|
createTrustCenterAccess(
|
||||||
input: CreateTrustCenterAccessInput!
|
input: CreateTrustCenterAccessInput!
|
||||||
@@ -2503,6 +2514,16 @@ input UpdateTrustCenterInput {
|
|||||||
slug: String
|
slug: String
|
||||||
}
|
}
|
||||||
|
|
||||||
|
input UploadTrustCenterNDAInput {
|
||||||
|
trustCenterId: ID!
|
||||||
|
fileName: String!
|
||||||
|
file: Upload!
|
||||||
|
}
|
||||||
|
|
||||||
|
input DeleteTrustCenterNDAInput {
|
||||||
|
trustCenterId: ID!
|
||||||
|
}
|
||||||
|
|
||||||
input CreateTrustCenterAccessInput {
|
input CreateTrustCenterAccessInput {
|
||||||
trustCenterId: ID!
|
trustCenterId: ID!
|
||||||
email: String!
|
email: String!
|
||||||
@@ -3135,6 +3156,14 @@ type UpdateTrustCenterPayload {
|
|||||||
trustCenter: TrustCenter!
|
trustCenter: TrustCenter!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type UploadTrustCenterNDAPayload {
|
||||||
|
trustCenter: TrustCenter!
|
||||||
|
}
|
||||||
|
|
||||||
|
type DeleteTrustCenterNDAPayload {
|
||||||
|
trustCenter: TrustCenter!
|
||||||
|
}
|
||||||
|
|
||||||
type CreateTrustCenterAccessPayload {
|
type CreateTrustCenterAccessPayload {
|
||||||
trustCenterAccessEdge: TrustCenterAccessEdge!
|
trustCenterAccessEdge: TrustCenterAccessEdge!
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -18,12 +18,18 @@ import (
|
|||||||
"github.com/getprobo/probo/pkg/coredata"
|
"github.com/getprobo/probo/pkg/coredata"
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewTrustCenter(tc *coredata.TrustCenter) *TrustCenter {
|
func NewTrustCenter(tc *coredata.TrustCenter, file *coredata.File) *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,
|
||||||
CreatedAt: tc.CreatedAt,
|
NdaFileName: ndaFileName,
|
||||||
UpdatedAt: tc.UpdatedAt,
|
CreatedAt: tc.CreatedAt,
|
||||||
|
UpdatedAt: tc.UpdatedAt,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,12 +23,13 @@ type TrustCenterAccessOrderBy = OrderBy[coredata.TrustCenterAccessOrderField]
|
|||||||
|
|
||||||
func NewTrustCenterAccess(tca *coredata.TrustCenterAccess) *TrustCenterAccess {
|
func NewTrustCenterAccess(tca *coredata.TrustCenterAccess) *TrustCenterAccess {
|
||||||
return &TrustCenterAccess{
|
return &TrustCenterAccess{
|
||||||
ID: tca.ID,
|
ID: tca.ID,
|
||||||
Email: tca.Email,
|
Email: tca.Email,
|
||||||
Name: tca.Name,
|
Name: tca.Name,
|
||||||
Active: tca.Active,
|
Active: tca.Active,
|
||||||
CreatedAt: tca.CreatedAt,
|
HasAcceptedNonDisclosureAgreement: tca.HasAcceptedNonDisclosureAgreement,
|
||||||
UpdatedAt: tca.UpdatedAt,
|
CreatedAt: tca.CreatedAt,
|
||||||
|
UpdatedAt: tca.UpdatedAt,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -828,6 +828,14 @@ type DeleteTrustCenterAccessPayload struct {
|
|||||||
DeletedTrustCenterAccessID gid.GID `json:"deletedTrustCenterAccessId"`
|
DeletedTrustCenterAccessID gid.GID `json:"deletedTrustCenterAccessId"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type DeleteTrustCenterNDAInput struct {
|
||||||
|
TrustCenterID gid.GID `json:"trustCenterId"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type DeleteTrustCenterNDAPayload struct {
|
||||||
|
TrustCenter *TrustCenter `json:"trustCenter"`
|
||||||
|
}
|
||||||
|
|
||||||
type DeleteVendorBusinessAssociateAgreementInput struct {
|
type DeleteVendorBusinessAssociateAgreementInput struct {
|
||||||
VendorID gid.GID `json:"vendorId"`
|
VendorID gid.GID `json:"vendorId"`
|
||||||
}
|
}
|
||||||
@@ -1436,6 +1444,8 @@ 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"`
|
||||||
|
NdaFileName *string `json:"ndaFileName,omitempty"`
|
||||||
|
NdaFileURL *string `json:"ndaFileUrl,omitempty"`
|
||||||
CreatedAt time.Time `json:"createdAt"`
|
CreatedAt time.Time `json:"createdAt"`
|
||||||
UpdatedAt time.Time `json:"updatedAt"`
|
UpdatedAt time.Time `json:"updatedAt"`
|
||||||
Organization *Organization `json:"organization"`
|
Organization *Organization `json:"organization"`
|
||||||
@@ -1446,12 +1456,13 @@ func (TrustCenter) IsNode() {}
|
|||||||
func (this TrustCenter) GetID() gid.GID { return this.ID }
|
func (this TrustCenter) GetID() gid.GID { return this.ID }
|
||||||
|
|
||||||
type TrustCenterAccess struct {
|
type TrustCenterAccess struct {
|
||||||
ID gid.GID `json:"id"`
|
ID gid.GID `json:"id"`
|
||||||
Email string `json:"email"`
|
Email string `json:"email"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Active bool `json:"active"`
|
Active bool `json:"active"`
|
||||||
CreatedAt time.Time `json:"createdAt"`
|
HasAcceptedNonDisclosureAgreement bool `json:"hasAcceptedNonDisclosureAgreement"`
|
||||||
UpdatedAt time.Time `json:"updatedAt"`
|
CreatedAt time.Time `json:"createdAt"`
|
||||||
|
UpdatedAt time.Time `json:"updatedAt"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (TrustCenterAccess) IsNode() {}
|
func (TrustCenterAccess) IsNode() {}
|
||||||
@@ -1831,6 +1842,16 @@ type UploadTaskEvidencePayload struct {
|
|||||||
EvidenceEdge *EvidenceEdge `json:"evidenceEdge"`
|
EvidenceEdge *EvidenceEdge `json:"evidenceEdge"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type UploadTrustCenterNDAInput struct {
|
||||||
|
TrustCenterID gid.GID `json:"trustCenterId"`
|
||||||
|
FileName string `json:"fileName"`
|
||||||
|
File graphql.Upload `json:"file"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type UploadTrustCenterNDAPayload struct {
|
||||||
|
TrustCenter *TrustCenter `json:"trustCenter"`
|
||||||
|
}
|
||||||
|
|
||||||
type UploadVendorBusinessAssociateAgreementInput struct {
|
type UploadVendorBusinessAssociateAgreementInput struct {
|
||||||
VendorID gid.GID `json:"vendorId"`
|
VendorID gid.GID `json:"vendorId"`
|
||||||
ValidFrom *time.Time `json:"validFrom,omitempty"`
|
ValidFrom *time.Time `json:"validFrom,omitempty"`
|
||||||
|
|||||||
@@ -1145,7 +1145,7 @@ func (r *mutationResolver) DeleteOrganization(ctx context.Context, input types.D
|
|||||||
func (r *mutationResolver) UpdateTrustCenter(ctx context.Context, input types.UpdateTrustCenterInput) (*types.UpdateTrustCenterPayload, error) {
|
func (r *mutationResolver) UpdateTrustCenter(ctx context.Context, input types.UpdateTrustCenterInput) (*types.UpdateTrustCenterPayload, error) {
|
||||||
prb := r.ProboService(ctx, input.TrustCenterID.TenantID())
|
prb := r.ProboService(ctx, input.TrustCenterID.TenantID())
|
||||||
|
|
||||||
trustCenter, err := prb.TrustCenters.Update(ctx, &probo.UpdateTrustCenterRequest{
|
trustCenter, file, err := prb.TrustCenters.Update(ctx, &probo.UpdateTrustCenterRequest{
|
||||||
ID: input.TrustCenterID,
|
ID: input.TrustCenterID,
|
||||||
Active: input.Active,
|
Active: input.Active,
|
||||||
Slug: input.Slug,
|
Slug: input.Slug,
|
||||||
@@ -1155,7 +1155,41 @@ func (r *mutationResolver) UpdateTrustCenter(ctx context.Context, input types.Up
|
|||||||
}
|
}
|
||||||
|
|
||||||
return &types.UpdateTrustCenterPayload{
|
return &types.UpdateTrustCenterPayload{
|
||||||
TrustCenter: types.NewTrustCenter(trustCenter),
|
TrustCenter: types.NewTrustCenter(trustCenter, file),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UploadTrustCenterNda is the resolver for the uploadTrustCenterNDA field.
|
||||||
|
func (r *mutationResolver) UploadTrustCenterNda(ctx context.Context, input types.UploadTrustCenterNDAInput) (*types.UploadTrustCenterNDAPayload, error) {
|
||||||
|
prb := r.ProboService(ctx, input.TrustCenterID.TenantID())
|
||||||
|
|
||||||
|
trustCenter, file, err := prb.TrustCenters.UploadNDA(ctx, &probo.UploadTrustCenterNDARequest{
|
||||||
|
TrustCenterID: input.TrustCenterID,
|
||||||
|
File: input.File.File,
|
||||||
|
FileName: input.FileName,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("cannot upload trust center NDA: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &types.UploadTrustCenterNDAPayload{
|
||||||
|
TrustCenter: types.NewTrustCenter(trustCenter, file),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteTrustCenterNda is the resolver for the deleteTrustCenterNDA field.
|
||||||
|
func (r *mutationResolver) DeleteTrustCenterNda(ctx context.Context, input types.DeleteTrustCenterNDAInput) (*types.DeleteTrustCenterNDAPayload, error) {
|
||||||
|
prb := r.ProboService(ctx, input.TrustCenterID.TenantID())
|
||||||
|
|
||||||
|
trustCenter, file, err := prb.TrustCenters.DeleteNDA(ctx, &probo.DeleteTrustCenterNDARequest{
|
||||||
|
TrustCenterID: input.TrustCenterID,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("cannot delete trust center NDA: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &types.DeleteTrustCenterNDAPayload{
|
||||||
|
TrustCenter: types.NewTrustCenter(trustCenter, file),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3895,12 +3929,12 @@ func (r *organizationResolver) Snapshots(ctx context.Context, obj *types.Organiz
|
|||||||
func (r *organizationResolver) TrustCenter(ctx context.Context, obj *types.Organization) (*types.TrustCenter, error) {
|
func (r *organizationResolver) TrustCenter(ctx context.Context, obj *types.Organization) (*types.TrustCenter, error) {
|
||||||
prb := r.ProboService(ctx, obj.ID.TenantID())
|
prb := r.ProboService(ctx, obj.ID.TenantID())
|
||||||
|
|
||||||
trustCenter, err := prb.TrustCenters.GetByOrganizationID(ctx, obj.ID)
|
trustCenter, file, err := prb.TrustCenters.GetByOrganizationID(ctx, obj.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("cannot get trust center: %w", err)
|
return nil, fmt.Errorf("cannot get trust center: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return types.NewTrustCenter(trustCenter), nil
|
return types.NewTrustCenter(trustCenter, file), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// TotalCount is the resolver for the totalCount field.
|
// TotalCount is the resolver for the totalCount field.
|
||||||
@@ -4115,11 +4149,12 @@ func (r *queryResolver) Node(ctx context.Context, id gid.GID) (types.Node, error
|
|||||||
}
|
}
|
||||||
return types.NewSnapshot(snapshot), nil
|
return types.NewSnapshot(snapshot), nil
|
||||||
case coredata.TrustCenterEntityType:
|
case coredata.TrustCenterEntityType:
|
||||||
trustCenter, err := prb.TrustCenters.Get(ctx, id)
|
trustCenter, file, err := prb.TrustCenters.Get(ctx, id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(fmt.Errorf("cannot get trust center: %w", err))
|
panic(fmt.Errorf("cannot get trust center with file: %w", err))
|
||||||
}
|
}
|
||||||
return types.NewTrustCenter(trustCenter), nil
|
|
||||||
|
return types.NewTrustCenter(trustCenter, file), nil
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4462,6 +4497,18 @@ func (r *taskConnectionResolver) TotalCount(ctx context.Context, obj *types.Task
|
|||||||
panic(fmt.Errorf("unsupported resolver: %T", obj.Resolver))
|
panic(fmt.Errorf("unsupported resolver: %T", obj.Resolver))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NdaFileURL is the resolver for the ndaFileUrl field.
|
||||||
|
func (r *trustCenterResolver) NdaFileURL(ctx context.Context, obj *types.TrustCenter) (*string, error) {
|
||||||
|
prb := r.ProboService(ctx, obj.ID.TenantID())
|
||||||
|
|
||||||
|
fileURL, err := prb.TrustCenters.GenerateNDAFileURL(ctx, obj.ID, 15*time.Minute)
|
||||||
|
if err != nil {
|
||||||
|
panic(fmt.Errorf("failed to generate NDA file URL: %w", err))
|
||||||
|
}
|
||||||
|
|
||||||
|
return fileURL, nil
|
||||||
|
}
|
||||||
|
|
||||||
// Organization is the resolver for the organization field.
|
// Organization is the resolver for the organization field.
|
||||||
func (r *trustCenterResolver) Organization(ctx context.Context, obj *types.TrustCenter) (*types.Organization, error) {
|
func (r *trustCenterResolver) Organization(ctx context.Context, obj *types.TrustCenter) (*types.Organization, error) {
|
||||||
prb := r.ProboService(ctx, obj.ID.TenantID())
|
prb := r.ProboService(ctx, obj.ID.TenantID())
|
||||||
|
|||||||
@@ -31,6 +31,10 @@ type TokenAccessData struct {
|
|||||||
Scope string
|
Scope string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *TokenAccessData) GetEmail() string {
|
||||||
|
return t.Email
|
||||||
|
}
|
||||||
|
|
||||||
type ContextAccessor interface {
|
type ContextAccessor interface {
|
||||||
UserFromContext(ctx context.Context) *coredata.User
|
UserFromContext(ctx context.Context) *coredata.User
|
||||||
TokenAccessFromContext(ctx context.Context) *TokenAccessData
|
TokenAccessFromContext(ctx context.Context) *TokenAccessData
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/99designs/gqlgen/graphql/handler"
|
"github.com/99designs/gqlgen/graphql/handler"
|
||||||
@@ -138,20 +139,29 @@ func graphqlHandler(logger *log.Logger, usrmgrSvc *usrmgr.Service, trustSvc *tru
|
|||||||
return WithSession(usrmgrSvc, trustSvc, authCfg, trustAuthCfg, srv.ServeHTTP)
|
return WithSession(usrmgrSvc, trustSvc, authCfg, trustAuthCfg, srv.ServeHTTP)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TrustService returns a trust service scoped to the given tenant
|
func (r *Resolver) RootTrustService(ctx context.Context) *trust.TenantService {
|
||||||
func (r *Resolver) TrustService(ctx context.Context, tenantID gid.TenantID) *trust.TenantService {
|
return r.trustCenterSvc.WithTenant(gid.NewTenantID())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Resolver) PublicTrustService(ctx context.Context, tenantID gid.TenantID) *trust.TenantService {
|
||||||
return r.trustCenterSvc.WithTenant(tenantID)
|
return r.trustCenterSvc.WithTenant(tenantID)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetTenantService returns a tenant service for the given tenant ID
|
func (r *Resolver) PrivateTrustService(ctx context.Context, tenantID gid.TenantID) (*trust.TenantService, error) {
|
||||||
func (r *Resolver) GetTenantService(ctx context.Context, tenantID gid.TenantID) *trust.TenantService {
|
if err := auth.ValidateTenantAccess(ctx, r, userTenantContextKey, tenantID); err != nil {
|
||||||
return r.trustCenterSvc.WithTenant(tenantID)
|
return nil, fmt.Errorf("cannot access trust center: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return r.trustCenterSvc.WithTenant(tenantID), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func WithSession(usrmgrSvc *usrmgr.Service, trustSvc *trust.Service, authCfg console_v1.AuthConfig, trustAuthCfg TrustAuthConfig, next http.HandlerFunc) http.HandlerFunc {
|
func WithSession(usrmgrSvc *usrmgr.Service, trustSvc *trust.Service, authCfg console_v1.AuthConfig, trustAuthCfg TrustAuthConfig, next http.HandlerFunc) http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
ctx := r.Context()
|
ctx := r.Context()
|
||||||
|
|
||||||
|
ip := extractIPAddress(r)
|
||||||
|
ctx = context.WithValue(ctx, coredata.ContextKeyIPAddress, ip)
|
||||||
|
|
||||||
if authCtx := tryTokenAuth(ctx, w, r, trustSvc, trustAuthCfg); authCtx != nil {
|
if authCtx := tryTokenAuth(ctx, w, r, trustSvc, trustAuthCfg); authCtx != nil {
|
||||||
next(w, r.WithContext(authCtx))
|
next(w, r.WithContext(authCtx))
|
||||||
return
|
return
|
||||||
@@ -219,15 +229,14 @@ func tryTokenAuth(ctx context.Context, w http.ResponseWriter, r *http.Request, t
|
|||||||
tenantID := basicPayload.Data.TrustCenterID.TenantID()
|
tenantID := basicPayload.Data.TrustCenterID.TenantID()
|
||||||
|
|
||||||
tenantSvc := trustSvc.WithTenant(tenantID)
|
tenantSvc := trustSvc.WithTenant(tenantID)
|
||||||
payload, err := tenantSvc.TrustCenterAccesses.ValidateToken(ctx, cookie.Value)
|
if err := tenantSvc.TrustCenterAccesses.ValidateToken(ctx, basicPayload.Data.TrustCenterID, basicPayload.Data.Email); err != nil {
|
||||||
if err != nil {
|
|
||||||
clearTokenCookie(w, trustAuthCfg)
|
clearTokenCookie(w, trustAuthCfg)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
tokenAccess := &auth.TokenAccessData{
|
tokenAccess := &auth.TokenAccessData{
|
||||||
TrustCenterID: payload.TrustCenterID,
|
TrustCenterID: basicPayload.Data.TrustCenterID,
|
||||||
Email: payload.Email,
|
Email: basicPayload.Data.Email,
|
||||||
TenantID: tenantID,
|
TenantID: tenantID,
|
||||||
Scope: trustAuthCfg.Scope,
|
Scope: trustAuthCfg.Scope,
|
||||||
}
|
}
|
||||||
@@ -256,3 +265,21 @@ func updateSessionIfNeeded(ctx context.Context, usrmgrSvc *usrmgr.Service) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func extractIPAddress(r *http.Request) string {
|
||||||
|
if xff := r.Header.Get("X-Forwarded-For"); xff != "" {
|
||||||
|
if ip := strings.Split(xff, ",")[0]; ip != "" {
|
||||||
|
return strings.TrimSpace(ip)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if xri := r.Header.Get("X-Real-IP"); xri != "" {
|
||||||
|
return strings.TrimSpace(xri)
|
||||||
|
}
|
||||||
|
|
||||||
|
if ip := strings.Split(r.RemoteAddr, ":")[0]; ip != "" {
|
||||||
|
return ip
|
||||||
|
}
|
||||||
|
|
||||||
|
return "unknown"
|
||||||
|
}
|
||||||
|
|||||||
@@ -199,8 +199,11 @@ type TrustCenter implements Node {
|
|||||||
id: ID!
|
id: ID!
|
||||||
active: Boolean!
|
active: Boolean!
|
||||||
slug: String!
|
slug: String!
|
||||||
|
ndaFileName: String
|
||||||
|
ndaFileUrl: String @goField(forceResolver: true)
|
||||||
organization: Organization! @goField(forceResolver: true)
|
organization: Organization! @goField(forceResolver: true)
|
||||||
isUserAuthenticated: Boolean! @goField(forceResolver: true)
|
isUserAuthenticated: Boolean! @goField(forceResolver: true)
|
||||||
|
hasAcceptedNonDisclosureAgreement: Boolean! @goField(forceResolver: true)
|
||||||
|
|
||||||
documents(
|
documents(
|
||||||
first: Int
|
first: Int
|
||||||
@@ -246,10 +249,18 @@ input ExportDocumentPDFInput {
|
|||||||
documentId: ID!
|
documentId: ID!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
input AcceptNonDisclosureAgreementInput {
|
||||||
|
trustCenterId: ID!
|
||||||
|
}
|
||||||
|
|
||||||
type ExportDocumentPDFPayload {
|
type ExportDocumentPDFPayload {
|
||||||
data: String!
|
data: String!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type AcceptNonDisclosureAgreementPayload{
|
||||||
|
success: Boolean!
|
||||||
|
}
|
||||||
|
|
||||||
type Query {
|
type Query {
|
||||||
trustCenterBySlug(slug: String!): TrustCenter @mustBeAuthenticated(role: NONE)
|
trustCenterBySlug(slug: String!): TrustCenter @mustBeAuthenticated(role: NONE)
|
||||||
}
|
}
|
||||||
@@ -262,4 +273,8 @@ type Mutation {
|
|||||||
exportDocumentPDF(
|
exportDocumentPDF(
|
||||||
input: ExportDocumentPDFInput!
|
input: ExportDocumentPDFInput!
|
||||||
): ExportDocumentPDFPayload! @mustBeAuthenticated(role: USER)
|
): ExportDocumentPDFPayload! @mustBeAuthenticated(role: USER)
|
||||||
|
|
||||||
|
acceptNonDisclosureAgreement(
|
||||||
|
input: AcceptNonDisclosureAgreementInput!
|
||||||
|
): AcceptNonDisclosureAgreementPayload! @mustBeAuthenticated(role: USER)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,6 +57,10 @@ type DirectiveRoot struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type ComplexityRoot struct {
|
type ComplexityRoot struct {
|
||||||
|
AcceptNonDisclosureAgreementPayload struct {
|
||||||
|
Success func(childComplexity int) int
|
||||||
|
}
|
||||||
|
|
||||||
Audit struct {
|
Audit struct {
|
||||||
Framework func(childComplexity int) int
|
Framework func(childComplexity int) int
|
||||||
ID func(childComplexity int) int
|
ID func(childComplexity int) int
|
||||||
@@ -103,8 +107,9 @@ type ComplexityRoot struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Mutation struct {
|
Mutation struct {
|
||||||
CreateTrustCenterAccess func(childComplexity int, input types.CreateTrustCenterAccessInput) int
|
AcceptNonDisclosureAgreement func(childComplexity int, input types.AcceptNonDisclosureAgreementInput) int
|
||||||
ExportDocumentPDF func(childComplexity int, input types.ExportDocumentPDFInput) int
|
CreateTrustCenterAccess func(childComplexity int, input types.CreateTrustCenterAccessInput) int
|
||||||
|
ExportDocumentPDF func(childComplexity int, input types.ExportDocumentPDFInput) int
|
||||||
}
|
}
|
||||||
|
|
||||||
Organization struct {
|
Organization struct {
|
||||||
@@ -131,14 +136,17 @@ type ComplexityRoot struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TrustCenter struct {
|
TrustCenter struct {
|
||||||
Active func(childComplexity int) int
|
Active func(childComplexity int) int
|
||||||
Audits func(childComplexity int, first *int, after *page.CursorKey, last *int, before *page.CursorKey) int
|
Audits func(childComplexity int, first *int, after *page.CursorKey, last *int, before *page.CursorKey) int
|
||||||
Documents func(childComplexity int, first *int, after *page.CursorKey, last *int, before *page.CursorKey) int
|
Documents func(childComplexity int, first *int, after *page.CursorKey, last *int, before *page.CursorKey) int
|
||||||
ID func(childComplexity int) int
|
HasAcceptedNonDisclosureAgreement func(childComplexity int) int
|
||||||
IsUserAuthenticated func(childComplexity int) int
|
ID func(childComplexity int) int
|
||||||
Organization func(childComplexity int) int
|
IsUserAuthenticated func(childComplexity int) int
|
||||||
Slug func(childComplexity int) int
|
NdaFileName func(childComplexity int) int
|
||||||
Vendors func(childComplexity int, first *int, after *page.CursorKey, last *int, before *page.CursorKey) int
|
NdaFileURL func(childComplexity int) int
|
||||||
|
Organization func(childComplexity int) int
|
||||||
|
Slug func(childComplexity int) int
|
||||||
|
Vendors func(childComplexity int, first *int, after *page.CursorKey, last *int, before *page.CursorKey) int
|
||||||
}
|
}
|
||||||
|
|
||||||
TrustCenterAccess struct {
|
TrustCenterAccess struct {
|
||||||
@@ -175,6 +183,7 @@ type AuditResolver interface {
|
|||||||
type MutationResolver interface {
|
type MutationResolver interface {
|
||||||
CreateTrustCenterAccess(ctx context.Context, input types.CreateTrustCenterAccessInput) (*types.CreateTrustCenterAccessPayload, error)
|
CreateTrustCenterAccess(ctx context.Context, input types.CreateTrustCenterAccessInput) (*types.CreateTrustCenterAccessPayload, error)
|
||||||
ExportDocumentPDF(ctx context.Context, input types.ExportDocumentPDFInput) (*types.ExportDocumentPDFPayload, error)
|
ExportDocumentPDF(ctx context.Context, input types.ExportDocumentPDFInput) (*types.ExportDocumentPDFPayload, error)
|
||||||
|
AcceptNonDisclosureAgreement(ctx context.Context, input types.AcceptNonDisclosureAgreementInput) (*types.AcceptNonDisclosureAgreementPayload, error)
|
||||||
}
|
}
|
||||||
type OrganizationResolver interface {
|
type OrganizationResolver interface {
|
||||||
LogoURL(ctx context.Context, obj *types.Organization) (*string, error)
|
LogoURL(ctx context.Context, obj *types.Organization) (*string, error)
|
||||||
@@ -186,8 +195,10 @@ type ReportResolver interface {
|
|||||||
DownloadURL(ctx context.Context, obj *types.Report) (*string, error)
|
DownloadURL(ctx context.Context, obj *types.Report) (*string, error)
|
||||||
}
|
}
|
||||||
type TrustCenterResolver interface {
|
type TrustCenterResolver interface {
|
||||||
|
NdaFileURL(ctx context.Context, obj *types.TrustCenter) (*string, error)
|
||||||
Organization(ctx context.Context, obj *types.TrustCenter) (*types.Organization, error)
|
Organization(ctx context.Context, obj *types.TrustCenter) (*types.Organization, error)
|
||||||
IsUserAuthenticated(ctx context.Context, obj *types.TrustCenter) (bool, error)
|
IsUserAuthenticated(ctx context.Context, obj *types.TrustCenter) (bool, error)
|
||||||
|
HasAcceptedNonDisclosureAgreement(ctx context.Context, obj *types.TrustCenter) (bool, error)
|
||||||
Documents(ctx context.Context, obj *types.TrustCenter, first *int, after *page.CursorKey, last *int, before *page.CursorKey) (*types.DocumentConnection, error)
|
Documents(ctx context.Context, obj *types.TrustCenter, first *int, after *page.CursorKey, last *int, before *page.CursorKey) (*types.DocumentConnection, error)
|
||||||
Audits(ctx context.Context, obj *types.TrustCenter, first *int, after *page.CursorKey, last *int, before *page.CursorKey) (*types.AuditConnection, error)
|
Audits(ctx context.Context, obj *types.TrustCenter, first *int, after *page.CursorKey, last *int, before *page.CursorKey) (*types.AuditConnection, error)
|
||||||
Vendors(ctx context.Context, obj *types.TrustCenter, first *int, after *page.CursorKey, last *int, before *page.CursorKey) (*types.VendorConnection, error)
|
Vendors(ctx context.Context, obj *types.TrustCenter, first *int, after *page.CursorKey, last *int, before *page.CursorKey) (*types.VendorConnection, error)
|
||||||
@@ -212,6 +223,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin
|
|||||||
_ = ec
|
_ = ec
|
||||||
switch typeName + "." + field {
|
switch typeName + "." + field {
|
||||||
|
|
||||||
|
case "AcceptNonDisclosureAgreementPayload.success":
|
||||||
|
if e.complexity.AcceptNonDisclosureAgreementPayload.Success == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
return e.complexity.AcceptNonDisclosureAgreementPayload.Success(childComplexity), true
|
||||||
|
|
||||||
case "Audit.framework":
|
case "Audit.framework":
|
||||||
if e.complexity.Audit.Framework == nil {
|
if e.complexity.Audit.Framework == nil {
|
||||||
break
|
break
|
||||||
@@ -338,6 +356,18 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin
|
|||||||
|
|
||||||
return e.complexity.Framework.Name(childComplexity), true
|
return e.complexity.Framework.Name(childComplexity), true
|
||||||
|
|
||||||
|
case "Mutation.acceptNonDisclosureAgreement":
|
||||||
|
if e.complexity.Mutation.AcceptNonDisclosureAgreement == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
args, err := ec.field_Mutation_acceptNonDisclosureAgreement_args(ctx, rawArgs)
|
||||||
|
if err != nil {
|
||||||
|
return 0, false
|
||||||
|
}
|
||||||
|
|
||||||
|
return e.complexity.Mutation.AcceptNonDisclosureAgreement(childComplexity, args["input"].(types.AcceptNonDisclosureAgreementInput)), true
|
||||||
|
|
||||||
case "Mutation.createTrustCenterAccess":
|
case "Mutation.createTrustCenterAccess":
|
||||||
if e.complexity.Mutation.CreateTrustCenterAccess == nil {
|
if e.complexity.Mutation.CreateTrustCenterAccess == nil {
|
||||||
break
|
break
|
||||||
@@ -475,6 +505,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin
|
|||||||
|
|
||||||
return e.complexity.TrustCenter.Documents(childComplexity, args["first"].(*int), args["after"].(*page.CursorKey), args["last"].(*int), args["before"].(*page.CursorKey)), true
|
return e.complexity.TrustCenter.Documents(childComplexity, args["first"].(*int), args["after"].(*page.CursorKey), args["last"].(*int), args["before"].(*page.CursorKey)), true
|
||||||
|
|
||||||
|
case "TrustCenter.hasAcceptedNonDisclosureAgreement":
|
||||||
|
if e.complexity.TrustCenter.HasAcceptedNonDisclosureAgreement == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
return e.complexity.TrustCenter.HasAcceptedNonDisclosureAgreement(childComplexity), true
|
||||||
|
|
||||||
case "TrustCenter.id":
|
case "TrustCenter.id":
|
||||||
if e.complexity.TrustCenter.ID == nil {
|
if e.complexity.TrustCenter.ID == nil {
|
||||||
break
|
break
|
||||||
@@ -489,6 +526,20 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin
|
|||||||
|
|
||||||
return e.complexity.TrustCenter.IsUserAuthenticated(childComplexity), true
|
return e.complexity.TrustCenter.IsUserAuthenticated(childComplexity), true
|
||||||
|
|
||||||
|
case "TrustCenter.ndaFileName":
|
||||||
|
if e.complexity.TrustCenter.NdaFileName == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
return e.complexity.TrustCenter.NdaFileName(childComplexity), true
|
||||||
|
|
||||||
|
case "TrustCenter.ndaFileUrl":
|
||||||
|
if e.complexity.TrustCenter.NdaFileURL == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
return e.complexity.TrustCenter.NdaFileURL(childComplexity), true
|
||||||
|
|
||||||
case "TrustCenter.organization":
|
case "TrustCenter.organization":
|
||||||
if e.complexity.TrustCenter.Organization == nil {
|
if e.complexity.TrustCenter.Organization == nil {
|
||||||
break
|
break
|
||||||
@@ -621,6 +672,7 @@ func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler {
|
|||||||
opCtx := graphql.GetOperationContext(ctx)
|
opCtx := graphql.GetOperationContext(ctx)
|
||||||
ec := executionContext{opCtx, e, 0, 0, make(chan graphql.DeferredResult)}
|
ec := executionContext{opCtx, e, 0, 0, make(chan graphql.DeferredResult)}
|
||||||
inputUnmarshalMap := graphql.BuildUnmarshalerMap(
|
inputUnmarshalMap := graphql.BuildUnmarshalerMap(
|
||||||
|
ec.unmarshalInputAcceptNonDisclosureAgreementInput,
|
||||||
ec.unmarshalInputCreateTrustCenterAccessInput,
|
ec.unmarshalInputCreateTrustCenterAccessInput,
|
||||||
ec.unmarshalInputExportDocumentPDFInput,
|
ec.unmarshalInputExportDocumentPDFInput,
|
||||||
)
|
)
|
||||||
@@ -921,8 +973,11 @@ type TrustCenter implements Node {
|
|||||||
id: ID!
|
id: ID!
|
||||||
active: Boolean!
|
active: Boolean!
|
||||||
slug: String!
|
slug: String!
|
||||||
|
ndaFileName: String
|
||||||
|
ndaFileUrl: String @goField(forceResolver: true)
|
||||||
organization: Organization! @goField(forceResolver: true)
|
organization: Organization! @goField(forceResolver: true)
|
||||||
isUserAuthenticated: Boolean! @goField(forceResolver: true)
|
isUserAuthenticated: Boolean! @goField(forceResolver: true)
|
||||||
|
hasAcceptedNonDisclosureAgreement: Boolean! @goField(forceResolver: true)
|
||||||
|
|
||||||
documents(
|
documents(
|
||||||
first: Int
|
first: Int
|
||||||
@@ -968,10 +1023,18 @@ input ExportDocumentPDFInput {
|
|||||||
documentId: ID!
|
documentId: ID!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
input AcceptNonDisclosureAgreementInput {
|
||||||
|
trustCenterId: ID!
|
||||||
|
}
|
||||||
|
|
||||||
type ExportDocumentPDFPayload {
|
type ExportDocumentPDFPayload {
|
||||||
data: String!
|
data: String!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type AcceptNonDisclosureAgreementPayload{
|
||||||
|
success: Boolean!
|
||||||
|
}
|
||||||
|
|
||||||
type Query {
|
type Query {
|
||||||
trustCenterBySlug(slug: String!): TrustCenter @mustBeAuthenticated(role: NONE)
|
trustCenterBySlug(slug: String!): TrustCenter @mustBeAuthenticated(role: NONE)
|
||||||
}
|
}
|
||||||
@@ -984,6 +1047,10 @@ type Mutation {
|
|||||||
exportDocumentPDF(
|
exportDocumentPDF(
|
||||||
input: ExportDocumentPDFInput!
|
input: ExportDocumentPDFInput!
|
||||||
): ExportDocumentPDFPayload! @mustBeAuthenticated(role: USER)
|
): ExportDocumentPDFPayload! @mustBeAuthenticated(role: USER)
|
||||||
|
|
||||||
|
acceptNonDisclosureAgreement(
|
||||||
|
input: AcceptNonDisclosureAgreementInput!
|
||||||
|
): AcceptNonDisclosureAgreementPayload! @mustBeAuthenticated(role: USER)
|
||||||
}
|
}
|
||||||
`, BuiltIn: false},
|
`, BuiltIn: false},
|
||||||
}
|
}
|
||||||
@@ -1021,6 +1088,29 @@ func (ec *executionContext) dir_mustBeAuthenticated_argsRole(
|
|||||||
return zeroVal, nil
|
return zeroVal, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) field_Mutation_acceptNonDisclosureAgreement_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) {
|
||||||
|
var err error
|
||||||
|
args := map[string]any{}
|
||||||
|
arg0, err := ec.field_Mutation_acceptNonDisclosureAgreement_argsInput(ctx, rawArgs)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
args["input"] = arg0
|
||||||
|
return args, nil
|
||||||
|
}
|
||||||
|
func (ec *executionContext) field_Mutation_acceptNonDisclosureAgreement_argsInput(
|
||||||
|
ctx context.Context,
|
||||||
|
rawArgs map[string]any,
|
||||||
|
) (types.AcceptNonDisclosureAgreementInput, error) {
|
||||||
|
ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("input"))
|
||||||
|
if tmp, ok := rawArgs["input"]; ok {
|
||||||
|
return ec.unmarshalNAcceptNonDisclosureAgreementInput2githubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋtrustᚋv1ᚋtypesᚐAcceptNonDisclosureAgreementInput(ctx, tmp)
|
||||||
|
}
|
||||||
|
|
||||||
|
var zeroVal types.AcceptNonDisclosureAgreementInput
|
||||||
|
return zeroVal, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (ec *executionContext) field_Mutation_createTrustCenterAccess_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) {
|
func (ec *executionContext) field_Mutation_createTrustCenterAccess_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) {
|
||||||
var err error
|
var err error
|
||||||
args := map[string]any{}
|
args := map[string]any{}
|
||||||
@@ -1444,6 +1534,50 @@ func (ec *executionContext) field___Type_fields_argsIncludeDeprecated(
|
|||||||
|
|
||||||
// region **************************** field.gotpl *****************************
|
// region **************************** field.gotpl *****************************
|
||||||
|
|
||||||
|
func (ec *executionContext) _AcceptNonDisclosureAgreementPayload_success(ctx context.Context, field graphql.CollectedField, obj *types.AcceptNonDisclosureAgreementPayload) (ret graphql.Marshaler) {
|
||||||
|
fc, err := ec.fieldContext_AcceptNonDisclosureAgreementPayload_success(ctx, field)
|
||||||
|
if err != nil {
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
ctx = graphql.WithFieldContext(ctx, fc)
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
ec.Error(ctx, ec.Recover(ctx, r))
|
||||||
|
ret = graphql.Null
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
|
||||||
|
ctx = rctx // use context from middleware stack in children
|
||||||
|
return obj.Success, nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
ec.Error(ctx, err)
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
if resTmp == nil {
|
||||||
|
if !graphql.HasFieldError(ctx, fc) {
|
||||||
|
ec.Errorf(ctx, "must not be null")
|
||||||
|
}
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
res := resTmp.(bool)
|
||||||
|
fc.Result = res
|
||||||
|
return ec.marshalNBoolean2bool(ctx, field.Selections, res)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) fieldContext_AcceptNonDisclosureAgreementPayload_success(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
|
||||||
|
fc = &graphql.FieldContext{
|
||||||
|
Object: "AcceptNonDisclosureAgreementPayload",
|
||||||
|
Field: field,
|
||||||
|
IsMethod: false,
|
||||||
|
IsResolver: false,
|
||||||
|
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
|
||||||
|
return nil, errors.New("field of type Boolean does not have child fields")
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return fc, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (ec *executionContext) _Audit_id(ctx context.Context, field graphql.CollectedField, obj *types.Audit) (ret graphql.Marshaler) {
|
func (ec *executionContext) _Audit_id(ctx context.Context, field graphql.CollectedField, obj *types.Audit) (ret graphql.Marshaler) {
|
||||||
fc, err := ec.fieldContext_Audit_id(ctx, field)
|
fc, err := ec.fieldContext_Audit_id(ctx, field)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -2479,6 +2613,92 @@ func (ec *executionContext) fieldContext_Mutation_exportDocumentPDF(ctx context.
|
|||||||
return fc, nil
|
return fc, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) _Mutation_acceptNonDisclosureAgreement(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
|
||||||
|
fc, err := ec.fieldContext_Mutation_acceptNonDisclosureAgreement(ctx, field)
|
||||||
|
if err != nil {
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
ctx = graphql.WithFieldContext(ctx, fc)
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
ec.Error(ctx, ec.Recover(ctx, r))
|
||||||
|
ret = graphql.Null
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
|
||||||
|
directive0 := func(rctx context.Context) (any, error) {
|
||||||
|
ctx = rctx // use context from middleware stack in children
|
||||||
|
return ec.resolvers.Mutation().AcceptNonDisclosureAgreement(rctx, fc.Args["input"].(types.AcceptNonDisclosureAgreementInput))
|
||||||
|
}
|
||||||
|
|
||||||
|
directive1 := func(ctx context.Context) (any, error) {
|
||||||
|
role, err := ec.unmarshalORole2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋtrustᚋv1ᚋtypesᚐRole(ctx, "USER")
|
||||||
|
if err != nil {
|
||||||
|
var zeroVal *types.AcceptNonDisclosureAgreementPayload
|
||||||
|
return zeroVal, err
|
||||||
|
}
|
||||||
|
if ec.directives.MustBeAuthenticated == nil {
|
||||||
|
var zeroVal *types.AcceptNonDisclosureAgreementPayload
|
||||||
|
return zeroVal, errors.New("directive mustBeAuthenticated is not implemented")
|
||||||
|
}
|
||||||
|
return ec.directives.MustBeAuthenticated(ctx, nil, directive0, role)
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp, err := directive1(rctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, graphql.ErrorOnPath(ctx, err)
|
||||||
|
}
|
||||||
|
if tmp == nil {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
if data, ok := tmp.(*types.AcceptNonDisclosureAgreementPayload); ok {
|
||||||
|
return data, nil
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf(`unexpected type %T from directive, should be *github.com/getprobo/probo/pkg/server/api/trust/v1/types.AcceptNonDisclosureAgreementPayload`, tmp)
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
ec.Error(ctx, err)
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
if resTmp == nil {
|
||||||
|
if !graphql.HasFieldError(ctx, fc) {
|
||||||
|
ec.Errorf(ctx, "must not be null")
|
||||||
|
}
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
res := resTmp.(*types.AcceptNonDisclosureAgreementPayload)
|
||||||
|
fc.Result = res
|
||||||
|
return ec.marshalNAcceptNonDisclosureAgreementPayload2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋtrustᚋv1ᚋtypesᚐAcceptNonDisclosureAgreementPayload(ctx, field.Selections, res)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) fieldContext_Mutation_acceptNonDisclosureAgreement(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
|
||||||
|
fc = &graphql.FieldContext{
|
||||||
|
Object: "Mutation",
|
||||||
|
Field: field,
|
||||||
|
IsMethod: true,
|
||||||
|
IsResolver: true,
|
||||||
|
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
|
||||||
|
switch field.Name {
|
||||||
|
case "success":
|
||||||
|
return ec.fieldContext_AcceptNonDisclosureAgreementPayload_success(ctx, field)
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("no field named %q was found under type AcceptNonDisclosureAgreementPayload", field.Name)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
err = ec.Recover(ctx, r)
|
||||||
|
ec.Error(ctx, err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
ctx = graphql.WithFieldContext(ctx, fc)
|
||||||
|
if fc.Args, err = ec.field_Mutation_acceptNonDisclosureAgreement_args(ctx, field.ArgumentMap(ec.Variables)); err != nil {
|
||||||
|
ec.Error(ctx, err)
|
||||||
|
return fc, err
|
||||||
|
}
|
||||||
|
return fc, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (ec *executionContext) _Organization_id(ctx context.Context, field graphql.CollectedField, obj *types.Organization) (ret graphql.Marshaler) {
|
func (ec *executionContext) _Organization_id(ctx context.Context, field graphql.CollectedField, obj *types.Organization) (ret graphql.Marshaler) {
|
||||||
fc, err := ec.fieldContext_Organization_id(ctx, field)
|
fc, err := ec.fieldContext_Organization_id(ctx, field)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -2847,10 +3067,16 @@ func (ec *executionContext) fieldContext_Query_trustCenterBySlug(ctx context.Con
|
|||||||
return ec.fieldContext_TrustCenter_active(ctx, field)
|
return ec.fieldContext_TrustCenter_active(ctx, field)
|
||||||
case "slug":
|
case "slug":
|
||||||
return ec.fieldContext_TrustCenter_slug(ctx, field)
|
return ec.fieldContext_TrustCenter_slug(ctx, field)
|
||||||
|
case "ndaFileName":
|
||||||
|
return ec.fieldContext_TrustCenter_ndaFileName(ctx, field)
|
||||||
|
case "ndaFileUrl":
|
||||||
|
return ec.fieldContext_TrustCenter_ndaFileUrl(ctx, field)
|
||||||
case "organization":
|
case "organization":
|
||||||
return ec.fieldContext_TrustCenter_organization(ctx, field)
|
return ec.fieldContext_TrustCenter_organization(ctx, field)
|
||||||
case "isUserAuthenticated":
|
case "isUserAuthenticated":
|
||||||
return ec.fieldContext_TrustCenter_isUserAuthenticated(ctx, field)
|
return ec.fieldContext_TrustCenter_isUserAuthenticated(ctx, field)
|
||||||
|
case "hasAcceptedNonDisclosureAgreement":
|
||||||
|
return ec.fieldContext_TrustCenter_hasAcceptedNonDisclosureAgreement(ctx, field)
|
||||||
case "documents":
|
case "documents":
|
||||||
return ec.fieldContext_TrustCenter_documents(ctx, field)
|
return ec.fieldContext_TrustCenter_documents(ctx, field)
|
||||||
case "audits":
|
case "audits":
|
||||||
@@ -3294,6 +3520,88 @@ func (ec *executionContext) fieldContext_TrustCenter_slug(_ context.Context, fie
|
|||||||
return fc, nil
|
return fc, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) _TrustCenter_ndaFileName(ctx context.Context, field graphql.CollectedField, obj *types.TrustCenter) (ret graphql.Marshaler) {
|
||||||
|
fc, err := ec.fieldContext_TrustCenter_ndaFileName(ctx, field)
|
||||||
|
if err != nil {
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
ctx = graphql.WithFieldContext(ctx, fc)
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
ec.Error(ctx, ec.Recover(ctx, r))
|
||||||
|
ret = graphql.Null
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
|
||||||
|
ctx = rctx // use context from middleware stack in children
|
||||||
|
return obj.NdaFileName, nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
ec.Error(ctx, err)
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
if resTmp == nil {
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
res := resTmp.(*string)
|
||||||
|
fc.Result = res
|
||||||
|
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) fieldContext_TrustCenter_ndaFileName(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
|
||||||
|
fc = &graphql.FieldContext{
|
||||||
|
Object: "TrustCenter",
|
||||||
|
Field: field,
|
||||||
|
IsMethod: false,
|
||||||
|
IsResolver: false,
|
||||||
|
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
|
||||||
|
return nil, errors.New("field of type String does not have child fields")
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return fc, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) _TrustCenter_ndaFileUrl(ctx context.Context, field graphql.CollectedField, obj *types.TrustCenter) (ret graphql.Marshaler) {
|
||||||
|
fc, err := ec.fieldContext_TrustCenter_ndaFileUrl(ctx, field)
|
||||||
|
if err != nil {
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
ctx = graphql.WithFieldContext(ctx, fc)
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
ec.Error(ctx, ec.Recover(ctx, r))
|
||||||
|
ret = graphql.Null
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
|
||||||
|
ctx = rctx // use context from middleware stack in children
|
||||||
|
return ec.resolvers.TrustCenter().NdaFileURL(rctx, obj)
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
ec.Error(ctx, err)
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
if resTmp == nil {
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
res := resTmp.(*string)
|
||||||
|
fc.Result = res
|
||||||
|
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) fieldContext_TrustCenter_ndaFileUrl(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
|
||||||
|
fc = &graphql.FieldContext{
|
||||||
|
Object: "TrustCenter",
|
||||||
|
Field: field,
|
||||||
|
IsMethod: true,
|
||||||
|
IsResolver: true,
|
||||||
|
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
|
||||||
|
return nil, errors.New("field of type String does not have child fields")
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return fc, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (ec *executionContext) _TrustCenter_organization(ctx context.Context, field graphql.CollectedField, obj *types.TrustCenter) (ret graphql.Marshaler) {
|
func (ec *executionContext) _TrustCenter_organization(ctx context.Context, field graphql.CollectedField, obj *types.TrustCenter) (ret graphql.Marshaler) {
|
||||||
fc, err := ec.fieldContext_TrustCenter_organization(ctx, field)
|
fc, err := ec.fieldContext_TrustCenter_organization(ctx, field)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -3390,6 +3698,50 @@ func (ec *executionContext) fieldContext_TrustCenter_isUserAuthenticated(_ conte
|
|||||||
return fc, nil
|
return fc, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) _TrustCenter_hasAcceptedNonDisclosureAgreement(ctx context.Context, field graphql.CollectedField, obj *types.TrustCenter) (ret graphql.Marshaler) {
|
||||||
|
fc, err := ec.fieldContext_TrustCenter_hasAcceptedNonDisclosureAgreement(ctx, field)
|
||||||
|
if err != nil {
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
ctx = graphql.WithFieldContext(ctx, fc)
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
ec.Error(ctx, ec.Recover(ctx, r))
|
||||||
|
ret = graphql.Null
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
|
||||||
|
ctx = rctx // use context from middleware stack in children
|
||||||
|
return ec.resolvers.TrustCenter().HasAcceptedNonDisclosureAgreement(rctx, obj)
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
ec.Error(ctx, err)
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
if resTmp == nil {
|
||||||
|
if !graphql.HasFieldError(ctx, fc) {
|
||||||
|
ec.Errorf(ctx, "must not be null")
|
||||||
|
}
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
res := resTmp.(bool)
|
||||||
|
fc.Result = res
|
||||||
|
return ec.marshalNBoolean2bool(ctx, field.Selections, res)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) fieldContext_TrustCenter_hasAcceptedNonDisclosureAgreement(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
|
||||||
|
fc = &graphql.FieldContext{
|
||||||
|
Object: "TrustCenter",
|
||||||
|
Field: field,
|
||||||
|
IsMethod: true,
|
||||||
|
IsResolver: true,
|
||||||
|
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
|
||||||
|
return nil, errors.New("field of type Boolean does not have child fields")
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return fc, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (ec *executionContext) _TrustCenter_documents(ctx context.Context, field graphql.CollectedField, obj *types.TrustCenter) (ret graphql.Marshaler) {
|
func (ec *executionContext) _TrustCenter_documents(ctx context.Context, field graphql.CollectedField, obj *types.TrustCenter) (ret graphql.Marshaler) {
|
||||||
fc, err := ec.fieldContext_TrustCenter_documents(ctx, field)
|
fc, err := ec.fieldContext_TrustCenter_documents(ctx, field)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -6162,6 +6514,33 @@ func (ec *executionContext) fieldContext___Type_isOneOf(_ context.Context, field
|
|||||||
|
|
||||||
// region **************************** input.gotpl *****************************
|
// region **************************** input.gotpl *****************************
|
||||||
|
|
||||||
|
func (ec *executionContext) unmarshalInputAcceptNonDisclosureAgreementInput(ctx context.Context, obj any) (types.AcceptNonDisclosureAgreementInput, error) {
|
||||||
|
var it types.AcceptNonDisclosureAgreementInput
|
||||||
|
asMap := map[string]any{}
|
||||||
|
for k, v := range obj.(map[string]any) {
|
||||||
|
asMap[k] = v
|
||||||
|
}
|
||||||
|
|
||||||
|
fieldsInOrder := [...]string{"trustCenterId"}
|
||||||
|
for _, k := range fieldsInOrder {
|
||||||
|
v, ok := asMap[k]
|
||||||
|
if !ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
switch k {
|
||||||
|
case "trustCenterId":
|
||||||
|
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("trustCenterId"))
|
||||||
|
data, err := ec.unmarshalNID2githubᚗcomᚋgetproboᚋproboᚋpkgᚋgidᚐGID(ctx, v)
|
||||||
|
if err != nil {
|
||||||
|
return it, err
|
||||||
|
}
|
||||||
|
it.TrustCenterID = data
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return it, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (ec *executionContext) unmarshalInputCreateTrustCenterAccessInput(ctx context.Context, obj any) (types.CreateTrustCenterAccessInput, error) {
|
func (ec *executionContext) unmarshalInputCreateTrustCenterAccessInput(ctx context.Context, obj any) (types.CreateTrustCenterAccessInput, error) {
|
||||||
var it types.CreateTrustCenterAccessInput
|
var it types.CreateTrustCenterAccessInput
|
||||||
asMap := map[string]any{}
|
asMap := map[string]any{}
|
||||||
@@ -6303,6 +6682,45 @@ func (ec *executionContext) _Node(ctx context.Context, sel ast.SelectionSet, obj
|
|||||||
|
|
||||||
// region **************************** object.gotpl ****************************
|
// region **************************** object.gotpl ****************************
|
||||||
|
|
||||||
|
var acceptNonDisclosureAgreementPayloadImplementors = []string{"AcceptNonDisclosureAgreementPayload"}
|
||||||
|
|
||||||
|
func (ec *executionContext) _AcceptNonDisclosureAgreementPayload(ctx context.Context, sel ast.SelectionSet, obj *types.AcceptNonDisclosureAgreementPayload) graphql.Marshaler {
|
||||||
|
fields := graphql.CollectFields(ec.OperationContext, sel, acceptNonDisclosureAgreementPayloadImplementors)
|
||||||
|
|
||||||
|
out := graphql.NewFieldSet(fields)
|
||||||
|
deferred := make(map[string]*graphql.FieldSet)
|
||||||
|
for i, field := range fields {
|
||||||
|
switch field.Name {
|
||||||
|
case "__typename":
|
||||||
|
out.Values[i] = graphql.MarshalString("AcceptNonDisclosureAgreementPayload")
|
||||||
|
case "success":
|
||||||
|
out.Values[i] = ec._AcceptNonDisclosureAgreementPayload_success(ctx, field, obj)
|
||||||
|
if out.Values[i] == graphql.Null {
|
||||||
|
out.Invalids++
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
panic("unknown field " + strconv.Quote(field.Name))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
out.Dispatch(ctx)
|
||||||
|
if out.Invalids > 0 {
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
|
||||||
|
atomic.AddInt32(&ec.deferred, int32(len(deferred)))
|
||||||
|
|
||||||
|
for label, dfs := range deferred {
|
||||||
|
ec.processDeferredGroup(graphql.DeferredGroup{
|
||||||
|
Label: label,
|
||||||
|
Path: graphql.GetPath(ctx),
|
||||||
|
FieldSet: dfs,
|
||||||
|
Context: ctx,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
var auditImplementors = []string{"Audit", "Node"}
|
var auditImplementors = []string{"Audit", "Node"}
|
||||||
|
|
||||||
func (ec *executionContext) _Audit(ctx context.Context, sel ast.SelectionSet, obj *types.Audit) graphql.Marshaler {
|
func (ec *executionContext) _Audit(ctx context.Context, sel ast.SelectionSet, obj *types.Audit) graphql.Marshaler {
|
||||||
@@ -6791,6 +7209,13 @@ func (ec *executionContext) _Mutation(ctx context.Context, sel ast.SelectionSet)
|
|||||||
if out.Values[i] == graphql.Null {
|
if out.Values[i] == graphql.Null {
|
||||||
out.Invalids++
|
out.Invalids++
|
||||||
}
|
}
|
||||||
|
case "acceptNonDisclosureAgreement":
|
||||||
|
out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) {
|
||||||
|
return ec._Mutation_acceptNonDisclosureAgreement(ctx, field)
|
||||||
|
})
|
||||||
|
if out.Values[i] == graphql.Null {
|
||||||
|
out.Invalids++
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
panic("unknown field " + strconv.Quote(field.Name))
|
panic("unknown field " + strconv.Quote(field.Name))
|
||||||
}
|
}
|
||||||
@@ -7111,6 +7536,41 @@ func (ec *executionContext) _TrustCenter(ctx context.Context, sel ast.SelectionS
|
|||||||
if out.Values[i] == graphql.Null {
|
if out.Values[i] == graphql.Null {
|
||||||
atomic.AddUint32(&out.Invalids, 1)
|
atomic.AddUint32(&out.Invalids, 1)
|
||||||
}
|
}
|
||||||
|
case "ndaFileName":
|
||||||
|
out.Values[i] = ec._TrustCenter_ndaFileName(ctx, field, obj)
|
||||||
|
case "ndaFileUrl":
|
||||||
|
field := field
|
||||||
|
|
||||||
|
innerFunc := func(ctx context.Context, _ *graphql.FieldSet) (res graphql.Marshaler) {
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
ec.Error(ctx, ec.Recover(ctx, r))
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
res = ec._TrustCenter_ndaFileUrl(ctx, field, obj)
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
if field.Deferrable != nil {
|
||||||
|
dfs, ok := deferred[field.Deferrable.Label]
|
||||||
|
di := 0
|
||||||
|
if ok {
|
||||||
|
dfs.AddField(field)
|
||||||
|
di = len(dfs.Values) - 1
|
||||||
|
} else {
|
||||||
|
dfs = graphql.NewFieldSet([]graphql.CollectedField{field})
|
||||||
|
deferred[field.Deferrable.Label] = dfs
|
||||||
|
}
|
||||||
|
dfs.Concurrently(di, func(ctx context.Context) graphql.Marshaler {
|
||||||
|
return innerFunc(ctx, dfs)
|
||||||
|
})
|
||||||
|
|
||||||
|
// don't run the out.Concurrently() call below
|
||||||
|
out.Values[i] = graphql.Null
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) })
|
||||||
case "organization":
|
case "organization":
|
||||||
field := field
|
field := field
|
||||||
|
|
||||||
@@ -7182,6 +7642,42 @@ func (ec *executionContext) _TrustCenter(ctx context.Context, sel ast.SelectionS
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) })
|
||||||
|
case "hasAcceptedNonDisclosureAgreement":
|
||||||
|
field := field
|
||||||
|
|
||||||
|
innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) {
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
ec.Error(ctx, ec.Recover(ctx, r))
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
res = ec._TrustCenter_hasAcceptedNonDisclosureAgreement(ctx, field, obj)
|
||||||
|
if res == graphql.Null {
|
||||||
|
atomic.AddUint32(&fs.Invalids, 1)
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
if field.Deferrable != nil {
|
||||||
|
dfs, ok := deferred[field.Deferrable.Label]
|
||||||
|
di := 0
|
||||||
|
if ok {
|
||||||
|
dfs.AddField(field)
|
||||||
|
di = len(dfs.Values) - 1
|
||||||
|
} else {
|
||||||
|
dfs = graphql.NewFieldSet([]graphql.CollectedField{field})
|
||||||
|
deferred[field.Deferrable.Label] = dfs
|
||||||
|
}
|
||||||
|
dfs.Concurrently(di, func(ctx context.Context) graphql.Marshaler {
|
||||||
|
return innerFunc(ctx, dfs)
|
||||||
|
})
|
||||||
|
|
||||||
|
// don't run the out.Concurrently() call below
|
||||||
|
out.Values[i] = graphql.Null
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) })
|
out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) })
|
||||||
case "documents":
|
case "documents":
|
||||||
field := field
|
field := field
|
||||||
@@ -7849,6 +8345,25 @@ func (ec *executionContext) ___Type(ctx context.Context, sel ast.SelectionSet, o
|
|||||||
|
|
||||||
// region ***************************** type.gotpl *****************************
|
// region ***************************** type.gotpl *****************************
|
||||||
|
|
||||||
|
func (ec *executionContext) unmarshalNAcceptNonDisclosureAgreementInput2githubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋtrustᚋv1ᚋtypesᚐAcceptNonDisclosureAgreementInput(ctx context.Context, v any) (types.AcceptNonDisclosureAgreementInput, error) {
|
||||||
|
res, err := ec.unmarshalInputAcceptNonDisclosureAgreementInput(ctx, v)
|
||||||
|
return res, graphql.ErrorOnPath(ctx, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) marshalNAcceptNonDisclosureAgreementPayload2githubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋtrustᚋv1ᚋtypesᚐAcceptNonDisclosureAgreementPayload(ctx context.Context, sel ast.SelectionSet, v types.AcceptNonDisclosureAgreementPayload) graphql.Marshaler {
|
||||||
|
return ec._AcceptNonDisclosureAgreementPayload(ctx, sel, &v)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) marshalNAcceptNonDisclosureAgreementPayload2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋtrustᚋv1ᚋtypesᚐAcceptNonDisclosureAgreementPayload(ctx context.Context, sel ast.SelectionSet, v *types.AcceptNonDisclosureAgreementPayload) graphql.Marshaler {
|
||||||
|
if v == nil {
|
||||||
|
if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) {
|
||||||
|
ec.Errorf(ctx, "the requested element is null which the schema does not allow")
|
||||||
|
}
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
return ec._AcceptNonDisclosureAgreementPayload(ctx, sel, v)
|
||||||
|
}
|
||||||
|
|
||||||
func (ec *executionContext) marshalNAudit2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋtrustᚋv1ᚋtypesᚐAudit(ctx context.Context, sel ast.SelectionSet, v *types.Audit) graphql.Marshaler {
|
func (ec *executionContext) marshalNAudit2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋtrustᚋv1ᚋtypesᚐAudit(ctx context.Context, sel ast.SelectionSet, v *types.Audit) graphql.Marshaler {
|
||||||
if v == nil {
|
if v == nil {
|
||||||
if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) {
|
if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) {
|
||||||
|
|||||||
@@ -109,15 +109,12 @@ func validateTrustCenterAccessToken(ctx context.Context, trustSvc *trust.Service
|
|||||||
return nil, fmt.Errorf("cannot validate trust center access token: %w", err)
|
return nil, fmt.Errorf("cannot validate trust center access token: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
tenantID := token.Data.TrustCenterID.TenantID()
|
tenantSvc := trustSvc.WithTenant(token.Data.TrustCenterID.TenantID())
|
||||||
tenantSvc := trustSvc.WithTenant(tenantID)
|
if err := tenantSvc.TrustCenterAccesses.ValidateToken(ctx, token.Data.TrustCenterID, token.Data.Email); err != nil {
|
||||||
|
|
||||||
accessData, err := tenantSvc.TrustCenterAccesses.ValidateToken(ctx, tokenString)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("cannot validate trust center access token: %w", err)
|
return nil, fmt.Errorf("cannot validate trust center access token: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return accessData, nil
|
return &token.Data, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func trustCenterLogoutHandler(authCfg console_v1.AuthConfig, trustAuthCfg TrustAuthConfig) http.HandlerFunc {
|
func trustCenterLogoutHandler(authCfg console_v1.AuthConfig, trustAuthCfg TrustAuthConfig) http.HandlerFunc {
|
||||||
|
|||||||
@@ -18,10 +18,16 @@ import (
|
|||||||
"github.com/getprobo/probo/pkg/coredata"
|
"github.com/getprobo/probo/pkg/coredata"
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewTrustCenter(tc *coredata.TrustCenter) *TrustCenter {
|
func NewTrustCenter(tc *coredata.TrustCenter, file *coredata.File) *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,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,14 @@ type Node interface {
|
|||||||
GetID() gid.GID
|
GetID() gid.GID
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type AcceptNonDisclosureAgreementInput struct {
|
||||||
|
TrustCenterID gid.GID `json:"trustCenterId"`
|
||||||
|
}
|
||||||
|
|
||||||
|
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"`
|
||||||
@@ -115,14 +123,17 @@ func (Report) IsNode() {}
|
|||||||
func (this Report) GetID() gid.GID { return this.ID }
|
func (this Report) GetID() gid.GID { return this.ID }
|
||||||
|
|
||||||
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"`
|
||||||
Organization *Organization `json:"organization"`
|
NdaFileName *string `json:"ndaFileName,omitempty"`
|
||||||
IsUserAuthenticated bool `json:"isUserAuthenticated"`
|
NdaFileURL *string `json:"ndaFileUrl,omitempty"`
|
||||||
Documents *DocumentConnection `json:"documents"`
|
Organization *Organization `json:"organization"`
|
||||||
Audits *AuditConnection `json:"audits"`
|
IsUserAuthenticated bool `json:"isUserAuthenticated"`
|
||||||
Vendors *VendorConnection `json:"vendors"`
|
HasAcceptedNonDisclosureAgreement bool `json:"hasAcceptedNonDisclosureAgreement"`
|
||||||
|
Documents *DocumentConnection `json:"documents"`
|
||||||
|
Audits *AuditConnection `json:"audits"`
|
||||||
|
Vendors *VendorConnection `json:"vendors"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (TrustCenter) IsNode() {}
|
func (TrustCenter) IsNode() {}
|
||||||
|
|||||||
@@ -11,9 +11,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/getprobo/probo/pkg/coredata"
|
"github.com/getprobo/probo/pkg/coredata"
|
||||||
"github.com/getprobo/probo/pkg/gid"
|
|
||||||
"github.com/getprobo/probo/pkg/page"
|
"github.com/getprobo/probo/pkg/page"
|
||||||
"github.com/getprobo/probo/pkg/server/api/trust/v1/auth"
|
|
||||||
"github.com/getprobo/probo/pkg/server/api/trust/v1/schema"
|
"github.com/getprobo/probo/pkg/server/api/trust/v1/schema"
|
||||||
"github.com/getprobo/probo/pkg/server/api/trust/v1/types"
|
"github.com/getprobo/probo/pkg/server/api/trust/v1/types"
|
||||||
"github.com/getprobo/probo/pkg/trust"
|
"github.com/getprobo/probo/pkg/trust"
|
||||||
@@ -21,14 +19,14 @@ import (
|
|||||||
|
|
||||||
// Framework is the resolver for the framework field.
|
// Framework is the resolver for the framework field.
|
||||||
func (r *auditResolver) Framework(ctx context.Context, obj *types.Audit) (*types.Framework, error) {
|
func (r *auditResolver) Framework(ctx context.Context, obj *types.Audit) (*types.Framework, error) {
|
||||||
trust := r.TrustService(ctx, obj.ID.TenantID())
|
publicTrustService := r.PublicTrustService(ctx, obj.ID.TenantID())
|
||||||
|
|
||||||
audit, err := trust.Audits.Get(ctx, obj.ID)
|
audit, err := publicTrustService.Audits.Get(ctx, obj.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(fmt.Errorf("cannot load audit: %w", err))
|
panic(fmt.Errorf("cannot load audit: %w", err))
|
||||||
}
|
}
|
||||||
|
|
||||||
framework, err := trust.Frameworks.Get(ctx, audit.FrameworkID)
|
framework, err := publicTrustService.Frameworks.Get(ctx, audit.FrameworkID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(fmt.Errorf("cannot load framework: %w", err))
|
panic(fmt.Errorf("cannot load framework: %w", err))
|
||||||
}
|
}
|
||||||
@@ -38,9 +36,9 @@ func (r *auditResolver) Framework(ctx context.Context, obj *types.Audit) (*types
|
|||||||
|
|
||||||
// Report is the resolver for the report field.
|
// Report is the resolver for the report field.
|
||||||
func (r *auditResolver) Report(ctx context.Context, obj *types.Audit) (*types.Report, error) {
|
func (r *auditResolver) Report(ctx context.Context, obj *types.Audit) (*types.Report, error) {
|
||||||
trust := r.TrustService(ctx, obj.ID.TenantID())
|
publicTrustService := r.PublicTrustService(ctx, obj.ID.TenantID())
|
||||||
|
|
||||||
audit, err := trust.Audits.Get(ctx, obj.ID)
|
audit, err := publicTrustService.Audits.Get(ctx, obj.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(fmt.Errorf("cannot load audit: %w", err))
|
panic(fmt.Errorf("cannot load audit: %w", err))
|
||||||
}
|
}
|
||||||
@@ -49,7 +47,7 @@ func (r *auditResolver) Report(ctx context.Context, obj *types.Audit) (*types.Re
|
|||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
report, err := trust.Reports.Get(ctx, *audit.ReportID)
|
report, err := publicTrustService.Reports.Get(ctx, *audit.ReportID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(fmt.Errorf("cannot load report: %w", err))
|
panic(fmt.Errorf("cannot load report: %w", err))
|
||||||
}
|
}
|
||||||
@@ -59,9 +57,9 @@ func (r *auditResolver) Report(ctx context.Context, obj *types.Audit) (*types.Re
|
|||||||
|
|
||||||
// CreateTrustCenterAccess is the resolver for the createTrustCenterAccess field.
|
// CreateTrustCenterAccess is the resolver for the createTrustCenterAccess field.
|
||||||
func (r *mutationResolver) CreateTrustCenterAccess(ctx context.Context, input types.CreateTrustCenterAccessInput) (*types.CreateTrustCenterAccessPayload, error) {
|
func (r *mutationResolver) CreateTrustCenterAccess(ctx context.Context, input types.CreateTrustCenterAccessInput) (*types.CreateTrustCenterAccessPayload, error) {
|
||||||
trustSvc := r.trustCenterSvc.WithTenant(input.TrustCenterID.TenantID())
|
publicTrustService := r.PublicTrustService(ctx, input.TrustCenterID.TenantID())
|
||||||
|
|
||||||
access, err := trustSvc.TrustCenterAccesses.Create(ctx, &trust.CreateTrustCenterAccessRequest{
|
access, err := publicTrustService.TrustCenterAccesses.Create(ctx, &trust.CreateTrustCenterAccessRequest{
|
||||||
TrustCenterID: input.TrustCenterID,
|
TrustCenterID: input.TrustCenterID,
|
||||||
Email: input.Email,
|
Email: input.Email,
|
||||||
Name: input.Name,
|
Name: input.Name,
|
||||||
@@ -83,34 +81,72 @@ func (r *mutationResolver) CreateTrustCenterAccess(ctx context.Context, input ty
|
|||||||
|
|
||||||
// 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) {
|
||||||
if err := auth.ValidateTenantAccess(ctx, r, userTenantContextKey, input.DocumentID.TenantID()); err != nil {
|
privateTrustService, err := r.PrivateTrustService(ctx, input.DocumentID.TenantID())
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
trust := r.trustCenterSvc.WithTenant(input.DocumentID.TenantID())
|
|
||||||
|
|
||||||
pdf, err := trust.Documents.ExportPDF(ctx, input.DocumentID)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("cannot export document PDF: %w", err)
|
return nil, fmt.Errorf("cannot export document PDF: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hasAcceptedNDA := false
|
||||||
|
userData := UserFromContext(ctx)
|
||||||
|
if userData != nil {
|
||||||
|
hasAcceptedNDA = true
|
||||||
|
}
|
||||||
|
|
||||||
|
tokenData := TokenAccessFromContext(ctx)
|
||||||
|
if tokenData != nil {
|
||||||
|
tokenData := TokenAccessFromContext(ctx)
|
||||||
|
hasAcceptedNDA, err = privateTrustService.TrustCenterAccesses.HasAcceptedNonDisclosureAgreement(ctx, tokenData.TrustCenterID, tokenData.GetEmail())
|
||||||
|
if err != nil {
|
||||||
|
panic(fmt.Errorf("cannot check if user has accepted NDA: %w", err))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !hasAcceptedNDA {
|
||||||
|
return nil, fmt.Errorf("user has not accepted NDA")
|
||||||
|
}
|
||||||
|
|
||||||
|
pdf, err := privateTrustService.Documents.ExportPDF(ctx, input.DocumentID)
|
||||||
|
if err != nil {
|
||||||
|
panic(fmt.Errorf("cannot export document PDF: %w", err))
|
||||||
|
}
|
||||||
|
|
||||||
return &types.ExportDocumentPDFPayload{
|
return &types.ExportDocumentPDFPayload{
|
||||||
Data: fmt.Sprintf("data:application/pdf;base64,%s", base64.StdEncoding.EncodeToString(pdf)),
|
Data: fmt.Sprintf("data:application/pdf;base64,%s", base64.StdEncoding.EncodeToString(pdf)),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AcceptNonDisclosureAgreement is the resolver for the acceptNonDisclosureAgreement field.
|
||||||
|
func (r *mutationResolver) AcceptNonDisclosureAgreement(ctx context.Context, input types.AcceptNonDisclosureAgreementInput) (*types.AcceptNonDisclosureAgreementPayload, error) {
|
||||||
|
privateTrustService, err := r.PrivateTrustService(ctx, input.TrustCenterID.TenantID())
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("cannot accept NDA: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
tokenData := TokenAccessFromContext(ctx)
|
||||||
|
if tokenData == nil {
|
||||||
|
return nil, fmt.Errorf("token not found")
|
||||||
|
}
|
||||||
|
|
||||||
|
err = privateTrustService.TrustCenterAccesses.AcceptNonDisclosureAgreement(ctx, input.TrustCenterID, tokenData.GetEmail())
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("cannot accept NDA: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &types.AcceptNonDisclosureAgreementPayload{Success: true}, 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) {
|
||||||
trust := r.TrustService(ctx, obj.ID.TenantID())
|
publicTrustService := r.PublicTrustService(ctx, obj.ID.TenantID())
|
||||||
|
|
||||||
return trust.Organizations.GenerateLogoURL(ctx, obj.ID, 1*time.Hour)
|
return publicTrustService.Organizations.GenerateLogoURL(ctx, obj.ID, 1*time.Hour)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TrustCenterBySlug is the resolver for the trustCenterBySlug field.
|
// TrustCenterBySlug is the resolver for the trustCenterBySlug field.
|
||||||
func (r *queryResolver) TrustCenterBySlug(ctx context.Context, slug string) (*types.TrustCenter, error) {
|
func (r *queryResolver) TrustCenterBySlug(ctx context.Context, slug string) (*types.TrustCenter, error) {
|
||||||
publicTrust := r.trustCenterSvc.WithTenant(gid.NewTenantID())
|
rootTrustService := r.RootTrustService(ctx)
|
||||||
|
|
||||||
trustCenter, err := publicTrust.TrustCenters.GetBySlug(ctx, slug)
|
trustCenter, err := rootTrustService.TrustCenters.GetBySlug(ctx, slug)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
@@ -119,28 +155,48 @@ func (r *queryResolver) TrustCenterBySlug(ctx context.Context, slug string) (*ty
|
|||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
result := types.NewTrustCenter(trustCenter)
|
publicTrustService := r.PublicTrustService(ctx, trustCenter.TenantID)
|
||||||
|
trustCenter, file, err := publicTrustService.TrustCenters.Get(ctx, trustCenter.ID)
|
||||||
|
if err != nil {
|
||||||
|
panic(fmt.Errorf("cannot get trust center: %w", err))
|
||||||
|
}
|
||||||
|
|
||||||
orgTrust := r.trustCenterSvc.WithTenant(trustCenter.TenantID)
|
org, err := publicTrustService.Organizations.Get(ctx, trustCenter.OrganizationID)
|
||||||
org, err := orgTrust.Organizations.Get(ctx, trustCenter.OrganizationID)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(fmt.Errorf("cannot get organization: %w", err))
|
panic(fmt.Errorf("cannot get organization: %w", err))
|
||||||
}
|
}
|
||||||
|
response := types.NewTrustCenter(trustCenter, file)
|
||||||
|
response.Organization = types.NewOrganization(org)
|
||||||
|
|
||||||
result.Organization = types.NewOrganization(org)
|
return response, nil
|
||||||
|
|
||||||
return result, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// DownloadURL is the resolver for the downloadUrl field.
|
// DownloadURL is the resolver for the downloadUrl field.
|
||||||
func (r *reportResolver) DownloadURL(ctx context.Context, obj *types.Report) (*string, error) {
|
func (r *reportResolver) DownloadURL(ctx context.Context, obj *types.Report) (*string, error) {
|
||||||
if err := auth.ValidateTenantAccess(ctx, r, userTenantContextKey, obj.ID.TenantID()); err != nil {
|
privateTrustService, err := r.PrivateTrustService(ctx, obj.ID.TenantID())
|
||||||
return nil, err
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("cannot generate download URL: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
trust := r.TrustService(ctx, obj.ID.TenantID())
|
hasAcceptedNDA := false
|
||||||
|
userData := UserFromContext(ctx)
|
||||||
|
if userData != nil {
|
||||||
|
hasAcceptedNDA = true
|
||||||
|
}
|
||||||
|
|
||||||
url, err := trust.Reports.GenerateDownloadURL(ctx, obj.ID, r.trustAuthCfg.ReportURLDuration)
|
tokenData := TokenAccessFromContext(ctx)
|
||||||
|
if tokenData != nil {
|
||||||
|
hasAcceptedNDA, err = privateTrustService.TrustCenterAccesses.HasAcceptedNonDisclosureAgreement(ctx, tokenData.TrustCenterID, tokenData.GetEmail())
|
||||||
|
if err != nil {
|
||||||
|
panic(fmt.Errorf("cannot check if user has accepted NDA: %w", err))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !hasAcceptedNDA {
|
||||||
|
return nil, fmt.Errorf("user has not accepted NDA")
|
||||||
|
}
|
||||||
|
|
||||||
|
url, err := privateTrustService.Reports.GenerateDownloadURL(ctx, obj.ID, r.trustAuthCfg.ReportURLDuration)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(fmt.Errorf("cannot generate download URL: %w", err))
|
panic(fmt.Errorf("cannot generate download URL: %w", err))
|
||||||
}
|
}
|
||||||
@@ -148,6 +204,21 @@ func (r *reportResolver) DownloadURL(ctx context.Context, obj *types.Report) (*s
|
|||||||
return url, nil
|
return url, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NdaFileURL is the resolver for the ndaFileUrl field.
|
||||||
|
func (r *trustCenterResolver) NdaFileURL(ctx context.Context, obj *types.TrustCenter) (*string, error) {
|
||||||
|
privateTrustService, err := r.PrivateTrustService(ctx, obj.ID.TenantID())
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to get private trust service: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fileURL, err := privateTrustService.TrustCenters.GenerateNDAFileURL(ctx, obj.ID, 15*time.Minute)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to generate NDA file URL: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &fileURL, nil
|
||||||
|
}
|
||||||
|
|
||||||
// Organization is the resolver for the organization field.
|
// Organization is the resolver for the organization field.
|
||||||
func (r *trustCenterResolver) Organization(ctx context.Context, obj *types.TrustCenter) (*types.Organization, error) {
|
func (r *trustCenterResolver) Organization(ctx context.Context, obj *types.TrustCenter) (*types.Organization, error) {
|
||||||
return obj.Organization, nil
|
return obj.Organization, nil
|
||||||
@@ -155,15 +226,41 @@ func (r *trustCenterResolver) Organization(ctx context.Context, obj *types.Trust
|
|||||||
|
|
||||||
// IsUserAuthenticated is the resolver for the isUserAuthenticated field.
|
// IsUserAuthenticated is the resolver for the isUserAuthenticated field.
|
||||||
func (r *trustCenterResolver) IsUserAuthenticated(ctx context.Context, obj *types.TrustCenter) (bool, error) {
|
func (r *trustCenterResolver) IsUserAuthenticated(ctx context.Context, obj *types.TrustCenter) (bool, error) {
|
||||||
if err := auth.ValidateTenantAccess(ctx, r, userTenantContextKey, obj.Organization.ID.TenantID()); err != nil {
|
_, err := r.PrivateTrustService(ctx, obj.ID.TenantID())
|
||||||
|
if err != nil {
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HasAcceptedNonDisclosureAgreement is the resolver for the hasAcceptedNonDisclosureAgreement field.
|
||||||
|
func (r *trustCenterResolver) HasAcceptedNonDisclosureAgreement(ctx context.Context, obj *types.TrustCenter) (bool, error) {
|
||||||
|
privateTrustService, err := r.PrivateTrustService(ctx, obj.ID.TenantID())
|
||||||
|
if err != nil {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
userData := UserFromContext(ctx)
|
||||||
|
if userData != nil {
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
tokenData := TokenAccessFromContext(ctx)
|
||||||
|
if tokenData != nil {
|
||||||
|
hasAcceptedNDA, err := privateTrustService.TrustCenterAccesses.HasAcceptedNonDisclosureAgreement(ctx, obj.ID, tokenData.GetEmail())
|
||||||
|
if err != nil {
|
||||||
|
panic(fmt.Errorf("cannot check if user has accepted NDA: %w", err))
|
||||||
|
}
|
||||||
|
return hasAcceptedNDA, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
panic(fmt.Errorf("no user or token data found"))
|
||||||
|
}
|
||||||
|
|
||||||
// Documents is the resolver for the documents field.
|
// Documents is the resolver for the documents field.
|
||||||
func (r *trustCenterResolver) Documents(ctx context.Context, obj *types.TrustCenter, first *int, after *page.CursorKey, last *int, before *page.CursorKey) (*types.DocumentConnection, error) {
|
func (r *trustCenterResolver) Documents(ctx context.Context, obj *types.TrustCenter, first *int, after *page.CursorKey, last *int, before *page.CursorKey) (*types.DocumentConnection, error) {
|
||||||
trust := r.trustCenterSvc.WithTenant(obj.Organization.ID.TenantID())
|
publicTrustService := r.PublicTrustService(ctx, obj.ID.TenantID())
|
||||||
|
|
||||||
pageOrderBy := page.OrderBy[coredata.DocumentOrderField]{
|
pageOrderBy := page.OrderBy[coredata.DocumentOrderField]{
|
||||||
Field: coredata.DocumentOrderFieldTitle,
|
Field: coredata.DocumentOrderFieldTitle,
|
||||||
@@ -171,7 +268,7 @@ func (r *trustCenterResolver) Documents(ctx context.Context, obj *types.TrustCen
|
|||||||
}
|
}
|
||||||
cursor := types.NewCursor(first, after, last, before, pageOrderBy)
|
cursor := types.NewCursor(first, after, last, before, pageOrderBy)
|
||||||
|
|
||||||
documentPage, err := trust.Documents.ListForOrganizationId(ctx, obj.Organization.ID, cursor)
|
documentPage, err := publicTrustService.Documents.ListForOrganizationId(ctx, obj.Organization.ID, cursor)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(fmt.Errorf("cannot list public documents: %w", err))
|
panic(fmt.Errorf("cannot list public documents: %w", err))
|
||||||
}
|
}
|
||||||
@@ -181,7 +278,7 @@ func (r *trustCenterResolver) Documents(ctx context.Context, obj *types.TrustCen
|
|||||||
|
|
||||||
// Audits is the resolver for the audits field.
|
// Audits is the resolver for the audits field.
|
||||||
func (r *trustCenterResolver) Audits(ctx context.Context, obj *types.TrustCenter, first *int, after *page.CursorKey, last *int, before *page.CursorKey) (*types.AuditConnection, error) {
|
func (r *trustCenterResolver) Audits(ctx context.Context, obj *types.TrustCenter, first *int, after *page.CursorKey, last *int, before *page.CursorKey) (*types.AuditConnection, error) {
|
||||||
trust := r.trustCenterSvc.WithTenant(obj.Organization.ID.TenantID())
|
publicTrustService := r.PublicTrustService(ctx, obj.ID.TenantID())
|
||||||
|
|
||||||
pageOrderBy := page.OrderBy[coredata.AuditOrderField]{
|
pageOrderBy := page.OrderBy[coredata.AuditOrderField]{
|
||||||
Field: coredata.AuditOrderFieldValidFrom,
|
Field: coredata.AuditOrderFieldValidFrom,
|
||||||
@@ -189,7 +286,7 @@ func (r *trustCenterResolver) Audits(ctx context.Context, obj *types.TrustCenter
|
|||||||
}
|
}
|
||||||
cursor := types.NewCursor(first, after, last, before, pageOrderBy)
|
cursor := types.NewCursor(first, after, last, before, pageOrderBy)
|
||||||
|
|
||||||
auditPage, err := trust.Audits.ListForOrganizationId(ctx, obj.Organization.ID, cursor)
|
auditPage, err := publicTrustService.Audits.ListForOrganizationId(ctx, obj.Organization.ID, cursor)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(fmt.Errorf("cannot list public audits: %w", err))
|
panic(fmt.Errorf("cannot list public audits: %w", err))
|
||||||
}
|
}
|
||||||
@@ -199,7 +296,7 @@ func (r *trustCenterResolver) Audits(ctx context.Context, obj *types.TrustCenter
|
|||||||
|
|
||||||
// Vendors is the resolver for the vendors field.
|
// Vendors is the resolver for the vendors field.
|
||||||
func (r *trustCenterResolver) Vendors(ctx context.Context, obj *types.TrustCenter, first *int, after *page.CursorKey, last *int, before *page.CursorKey) (*types.VendorConnection, error) {
|
func (r *trustCenterResolver) Vendors(ctx context.Context, obj *types.TrustCenter, first *int, after *page.CursorKey, last *int, before *page.CursorKey) (*types.VendorConnection, error) {
|
||||||
trust := r.trustCenterSvc.WithTenant(obj.Organization.ID.TenantID())
|
publicTrustService := r.PublicTrustService(ctx, obj.ID.TenantID())
|
||||||
|
|
||||||
pageOrderBy := page.OrderBy[coredata.VendorOrderField]{
|
pageOrderBy := page.OrderBy[coredata.VendorOrderField]{
|
||||||
Field: coredata.VendorOrderFieldName,
|
Field: coredata.VendorOrderFieldName,
|
||||||
@@ -207,7 +304,7 @@ func (r *trustCenterResolver) Vendors(ctx context.Context, obj *types.TrustCente
|
|||||||
}
|
}
|
||||||
cursor := types.NewCursor(first, after, last, before, pageOrderBy)
|
cursor := types.NewCursor(first, after, last, before, pageOrderBy)
|
||||||
|
|
||||||
vendorPage, err := trust.Vendors.ListForOrganizationId(ctx, obj.Organization.ID, cursor)
|
vendorPage, err := publicTrustService.Vendors.ListForOrganizationId(ctx, obj.Organization.ID, cursor)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(fmt.Errorf("cannot list public vendors: %w", err))
|
panic(fmt.Errorf("cannot list public vendors: %w", err))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ package trust
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/mail"
|
"net/mail"
|
||||||
@@ -23,8 +24,6 @@ import (
|
|||||||
|
|
||||||
"github.com/getprobo/probo/pkg/coredata"
|
"github.com/getprobo/probo/pkg/coredata"
|
||||||
"github.com/getprobo/probo/pkg/gid"
|
"github.com/getprobo/probo/pkg/gid"
|
||||||
"github.com/getprobo/probo/pkg/probo"
|
|
||||||
"github.com/getprobo/probo/pkg/statelesstoken"
|
|
||||||
"github.com/getprobo/probo/pkg/usrmgr"
|
"github.com/getprobo/probo/pkg/usrmgr"
|
||||||
"go.gearno.de/kit/pg"
|
"go.gearno.de/kit/pg"
|
||||||
)
|
)
|
||||||
@@ -48,20 +47,12 @@ const (
|
|||||||
|
|
||||||
func (s TrustCenterAccessService) ValidateToken(
|
func (s TrustCenterAccessService) ValidateToken(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
tokenString string,
|
trustCenterID gid.GID,
|
||||||
) (*probo.TrustCenterAccessData, error) {
|
email string,
|
||||||
token, err := statelesstoken.ValidateToken[probo.TrustCenterAccessData](
|
) error {
|
||||||
s.svc.tokenSecret,
|
return s.svc.pg.WithConn(ctx, func(conn pg.Conn) error {
|
||||||
TokenTypeTrustCenterAccess,
|
access := &coredata.TrustCenterAccess{}
|
||||||
tokenString,
|
err := access.LoadByTrustCenterIDAndEmail(ctx, conn, s.svc.scope, trustCenterID, email)
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("cannot validate trust center access token: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
access := &coredata.TrustCenterAccess{}
|
|
||||||
err = s.svc.pg.WithConn(ctx, func(conn pg.Conn) error {
|
|
||||||
err := access.LoadByTrustCenterIDAndEmail(ctx, conn, s.svc.scope, token.Data.TrustCenterID, token.Data.Email)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("cannot load trust center access: %w", err)
|
return fmt.Errorf("cannot load trust center access: %w", err)
|
||||||
}
|
}
|
||||||
@@ -72,12 +63,6 @@ func (s TrustCenterAccessService) ValidateToken(
|
|||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &token.Data, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s TrustCenterAccessService) Create(
|
func (s TrustCenterAccessService) Create(
|
||||||
@@ -115,14 +100,15 @@ func (s TrustCenterAccessService) Create(
|
|||||||
}
|
}
|
||||||
|
|
||||||
access = &coredata.TrustCenterAccess{
|
access = &coredata.TrustCenterAccess{
|
||||||
ID: gid.New(s.svc.scope.GetTenantID(), coredata.TrustCenterAccessEntityType),
|
ID: gid.New(s.svc.scope.GetTenantID(), coredata.TrustCenterAccessEntityType),
|
||||||
TenantID: s.svc.scope.GetTenantID(),
|
TenantID: s.svc.scope.GetTenantID(),
|
||||||
TrustCenterID: req.TrustCenterID,
|
TrustCenterID: req.TrustCenterID,
|
||||||
Email: req.Email,
|
Email: req.Email,
|
||||||
Name: req.Name,
|
Name: req.Name,
|
||||||
Active: false,
|
Active: false,
|
||||||
CreatedAt: now,
|
HasAcceptedNonDisclosureAgreement: false,
|
||||||
UpdatedAt: now,
|
CreatedAt: now,
|
||||||
|
UpdatedAt: now,
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := access.Insert(ctx, tx, s.svc.scope); err != nil {
|
if err := access.Insert(ctx, tx, s.svc.scope); err != nil {
|
||||||
@@ -137,3 +123,48 @@ func (s TrustCenterAccessService) Create(
|
|||||||
|
|
||||||
return access, nil
|
return access, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s TrustCenterAccessService) HasAcceptedNonDisclosureAgreement(ctx context.Context, trustCenterID gid.GID, email string) (bool, error) {
|
||||||
|
access := &coredata.TrustCenterAccess{}
|
||||||
|
err := s.svc.pg.WithConn(ctx, func(conn pg.Conn) error {
|
||||||
|
err := access.LoadByTrustCenterIDAndEmail(ctx, conn, s.svc.scope, trustCenterID, email)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("cannot load trust center access: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return access.HasAcceptedNonDisclosureAgreement, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s TrustCenterAccessService) AcceptNonDisclosureAgreement(ctx context.Context, trustCenterID gid.GID, email string) error {
|
||||||
|
return s.svc.pg.WithTx(ctx, func(tx pg.Conn) error {
|
||||||
|
access := &coredata.TrustCenterAccess{}
|
||||||
|
if err := access.LoadByTrustCenterIDAndEmail(ctx, tx, s.svc.scope, trustCenterID, email); err != nil {
|
||||||
|
return fmt.Errorf("cannot load trust center access: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
acceptationLogs, err := json.Marshal(map[string]string{
|
||||||
|
"email": email,
|
||||||
|
"timestamp": time.Now().Format(time.RFC3339),
|
||||||
|
"ip": ctx.Value(coredata.ContextKeyIPAddress).(string),
|
||||||
|
})
|
||||||
|
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
|
||||||
|
if err := access.Update(ctx, tx, s.svc.scope); err != nil {
|
||||||
|
return fmt.Errorf("cannot update trust center access: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
@@ -16,10 +16,14 @@ package trust
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net/url"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go-v2/aws"
|
||||||
|
"github.com/aws/aws-sdk-go-v2/service/s3"
|
||||||
"github.com/getprobo/probo/pkg/coredata"
|
"github.com/getprobo/probo/pkg/coredata"
|
||||||
|
"github.com/getprobo/probo/pkg/gid"
|
||||||
"go.gearno.de/kit/pg"
|
"go.gearno.de/kit/pg"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -51,3 +55,88 @@ func (s TrustCenterService) GetBySlug(
|
|||||||
|
|
||||||
return trustCenter, nil
|
return trustCenter, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s TrustCenterService) Get(
|
||||||
|
ctx context.Context,
|
||||||
|
trustCenterID gid.GID,
|
||||||
|
) (*coredata.TrustCenter, *coredata.File, error) {
|
||||||
|
var trustCenter *coredata.TrustCenter
|
||||||
|
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 {
|
||||||
|
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, nil, fmt.Errorf("cannot load trust center: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return trustCenter, file, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s TrustCenterService) GenerateNDAFileURL(
|
||||||
|
ctx context.Context,
|
||||||
|
trustCenterID gid.GID,
|
||||||
|
expiresIn time.Duration,
|
||||||
|
) (string, 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 fmt.Errorf("no NDA file found")
|
||||||
|
}
|
||||||
|
|
||||||
|
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 "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
presignClient := s3.NewPresignClient(s.svc.s3)
|
||||||
|
|
||||||
|
encodedFilename := url.QueryEscape(file.FileName)
|
||||||
|
contentDisposition := fmt.Sprintf("attachment; filename=\"%s\"; filename*=UTF-8''%s",
|
||||||
|
encodedFilename, encodedFilename)
|
||||||
|
|
||||||
|
presignedReq, err := presignClient.PresignGetObject(ctx, &s3.GetObjectInput{
|
||||||
|
Bucket: aws.String(s.svc.bucket),
|
||||||
|
Key: aws.String(file.FileKey),
|
||||||
|
ResponseCacheControl: aws.String("max-age=3600, public"),
|
||||||
|
ResponseContentDisposition: aws.String(contentDisposition),
|
||||||
|
}, func(opts *s3.PresignOptions) {
|
||||||
|
opts.Expires = expiresIn
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("cannot presign GetObject request: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return presignedReq.URL, nil
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user