Add vendor risk assement
Signed-off-by: Bryan Frimin <bryan@getprobo.com>
This commit is contained in:
18
CHANGELOG.md
18
CHANGELOG.md
@@ -4,6 +4,24 @@ All notable changes to this project will be documented in this file.
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Added
|
||||
|
||||
- New "Risk assessments" tab for vendors that allows you to:
|
||||
- View all risk assessments for a vendor in one place
|
||||
- Create new risk assessments with data sensitivity and business impact ratings
|
||||
- Track assessment expiration dates
|
||||
- Automatic people record creation when accepting invitations
|
||||
- New vendors in the built-in lists
|
||||
- Introduced a connector framework enabling integration with external
|
||||
services:
|
||||
- Add OAuth2 connector implementation
|
||||
|
||||
### Changed
|
||||
|
||||
- Completely redesigned vendor detail page with a cleaner, more intuitive layout
|
||||
- Improved compliance reports table with better file size formatting and date display
|
||||
- People may be linked to user
|
||||
|
||||
## [0.12.0] - 2025-04-20
|
||||
|
||||
### Added
|
||||
|
||||
@@ -85,7 +85,6 @@ const vendorListFragment = graphql`
|
||||
description
|
||||
createdAt
|
||||
updatedAt
|
||||
riskTier
|
||||
}
|
||||
}
|
||||
pageInfo {
|
||||
@@ -111,7 +110,6 @@ const createVendorMutation = graphql`
|
||||
description
|
||||
createdAt
|
||||
updatedAt
|
||||
riskTier
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -322,8 +320,6 @@ function ListVendorContent({
|
||||
statusPageUrl: vendor.statusPageUrl,
|
||||
termsOfServiceUrl: vendor.termsOfServiceUrl,
|
||||
serviceStartAt: new Date().toISOString(),
|
||||
serviceCriticality: "LOW",
|
||||
riskTier: "GENERAL",
|
||||
},
|
||||
},
|
||||
onCompleted() {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* @generated SignedSource<<178462391e73ba2adb212005c3813f33>>
|
||||
* @generated SignedSource<<ccdef4cce3d167b401f6d89dea1dde33>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
@@ -9,8 +9,6 @@
|
||||
// @ts-nocheck
|
||||
|
||||
import { ConcreteRequest } from 'relay-runtime';
|
||||
export type RiskTier = "CRITICAL" | "GENERAL" | "SIGNIFICANT";
|
||||
export type ServiceCriticality = "HIGH" | "LOW" | "MEDIUM";
|
||||
export type CreateVendorInput = {
|
||||
businessOwnerId?: string | null | undefined;
|
||||
category?: string | null | undefined;
|
||||
@@ -22,10 +20,8 @@ export type CreateVendorInput = {
|
||||
name: string;
|
||||
organizationId: string;
|
||||
privacyPolicyUrl?: string | null | undefined;
|
||||
riskTier: RiskTier;
|
||||
securityOwnerId?: string | null | undefined;
|
||||
securityPageUrl?: string | null | undefined;
|
||||
serviceCriticality: ServiceCriticality;
|
||||
serviceLevelAgreementUrl?: string | null | undefined;
|
||||
serviceStartAt: string;
|
||||
serviceTerminationAt?: string | null | undefined;
|
||||
@@ -46,7 +42,6 @@ export type ListVendorViewCreateVendorMutation$data = {
|
||||
readonly description: string | null | undefined;
|
||||
readonly id: string;
|
||||
readonly name: string;
|
||||
readonly riskTier: RiskTier;
|
||||
readonly updatedAt: string;
|
||||
};
|
||||
};
|
||||
@@ -125,13 +120,6 @@ v3 = {
|
||||
"kind": "ScalarField",
|
||||
"name": "updatedAt",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "riskTier",
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
@@ -205,16 +193,16 @@ return {
|
||||
]
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "6b3c93935ce5b90fead6aadd70992667",
|
||||
"cacheID": "03c1d61a3a252ca74bd8da1821f1e0b9",
|
||||
"id": null,
|
||||
"metadata": {},
|
||||
"name": "ListVendorViewCreateVendorMutation",
|
||||
"operationKind": "mutation",
|
||||
"text": "mutation ListVendorViewCreateVendorMutation(\n $input: CreateVendorInput!\n) {\n createVendor(input: $input) {\n vendorEdge {\n node {\n id\n name\n description\n createdAt\n updatedAt\n riskTier\n }\n }\n }\n}\n"
|
||||
"text": "mutation ListVendorViewCreateVendorMutation(\n $input: CreateVendorInput!\n) {\n createVendor(input: $input) {\n vendorEdge {\n node {\n id\n name\n description\n createdAt\n updatedAt\n }\n }\n }\n}\n"
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "d75423060ceec238c1cc6b38f79be4e1";
|
||||
(node as any).hash = "05ca888317537533f7345000f0948c0c";
|
||||
|
||||
export default node;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* @generated SignedSource<<49f537ed24daee25a89fb244341ba874>>
|
||||
* @generated SignedSource<<a59c7eee4b53c2b74df89a2fa693d9cd>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
@@ -224,13 +224,6 @@ return {
|
||||
"name": "updatedAt",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "riskTier",
|
||||
"storageKey": null
|
||||
},
|
||||
(v10/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
@@ -320,16 +313,16 @@ return {
|
||||
]
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "f48cd9d88c871edac4c400dc2fa20e9a",
|
||||
"cacheID": "b4165eeba6363c964b11f14f678d5338",
|
||||
"id": null,
|
||||
"metadata": {},
|
||||
"name": "ListVendorViewPaginationQuery",
|
||||
"operationKind": "query",
|
||||
"text": "query ListVendorViewPaginationQuery(\n $after: CursorKey\n $before: CursorKey\n $first: Int\n $last: Int\n $id: ID!\n) {\n node(id: $id) {\n __typename\n ...ListVendorView_vendors_pbnwq\n id\n }\n}\n\nfragment ListVendorView_vendors_pbnwq on Organization {\n vendors(first: $first, after: $after, last: $last, before: $before, orderBy: {direction: ASC, field: NAME}) {\n edges {\n node {\n id\n name\n description\n createdAt\n updatedAt\n riskTier\n __typename\n }\n cursor\n }\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n }\n id\n}\n"
|
||||
"text": "query ListVendorViewPaginationQuery(\n $after: CursorKey\n $before: CursorKey\n $first: Int\n $last: Int\n $id: ID!\n) {\n node(id: $id) {\n __typename\n ...ListVendorView_vendors_pbnwq\n id\n }\n}\n\nfragment ListVendorView_vendors_pbnwq on Organization {\n vendors(first: $first, after: $after, last: $last, before: $before, orderBy: {direction: ASC, field: NAME}) {\n edges {\n node {\n id\n name\n description\n createdAt\n updatedAt\n __typename\n }\n cursor\n }\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n }\n id\n}\n"
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "6e3badec3308017fd318d4bd1dc41b44";
|
||||
(node as any).hash = "477e430705f0f3cbadb8dfac89e24629";
|
||||
|
||||
export default node;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* @generated SignedSource<<faaaba37922ca105627be876b05672a7>>
|
||||
* @generated SignedSource<<bdea7e121ea26a5af6985b4399be4bcc>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
@@ -226,13 +226,6 @@ return {
|
||||
"name": "updatedAt",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "riskTier",
|
||||
"storageKey": null
|
||||
},
|
||||
(v11/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
@@ -322,12 +315,12 @@ return {
|
||||
]
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "f0f91262680529a635110382be5a2b03",
|
||||
"cacheID": "d93a40f389769d5895b502cb8e7a2c16",
|
||||
"id": null,
|
||||
"metadata": {},
|
||||
"name": "ListVendorViewQuery",
|
||||
"operationKind": "query",
|
||||
"text": "query ListVendorViewQuery(\n $organizationId: ID!\n $first: Int\n $after: CursorKey\n $last: Int\n $before: CursorKey\n) {\n organization: node(id: $organizationId) {\n __typename\n id\n ...ListVendorView_vendors_pbnwq\n }\n}\n\nfragment ListVendorView_vendors_pbnwq on Organization {\n vendors(first: $first, after: $after, last: $last, before: $before, orderBy: {direction: ASC, field: NAME}) {\n edges {\n node {\n id\n name\n description\n createdAt\n updatedAt\n riskTier\n __typename\n }\n cursor\n }\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n }\n id\n}\n"
|
||||
"text": "query ListVendorViewQuery(\n $organizationId: ID!\n $first: Int\n $after: CursorKey\n $last: Int\n $before: CursorKey\n) {\n organization: node(id: $organizationId) {\n __typename\n id\n ...ListVendorView_vendors_pbnwq\n }\n}\n\nfragment ListVendorView_vendors_pbnwq on Organization {\n vendors(first: $first, after: $after, last: $last, before: $before, orderBy: {direction: ASC, field: NAME}) {\n edges {\n node {\n id\n name\n description\n createdAt\n updatedAt\n __typename\n }\n cursor\n }\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n }\n id\n}\n"
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* @generated SignedSource<<b85fbf05b6b7f76bd8ceb87383bfd4b3>>
|
||||
* @generated SignedSource<<1ea33fd638cd871d891e3cd41e1f3372>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
@@ -9,7 +9,6 @@
|
||||
// @ts-nocheck
|
||||
|
||||
import { ReaderFragment } from 'relay-runtime';
|
||||
export type RiskTier = "CRITICAL" | "GENERAL" | "SIGNIFICANT";
|
||||
import { FragmentRefs } from "relay-runtime";
|
||||
export type ListVendorView_vendors$data = {
|
||||
readonly id: string;
|
||||
@@ -21,7 +20,6 @@ export type ListVendorView_vendors$data = {
|
||||
readonly description: string | null | undefined;
|
||||
readonly id: string;
|
||||
readonly name: string;
|
||||
readonly riskTier: RiskTier;
|
||||
readonly updatedAt: string;
|
||||
};
|
||||
}>;
|
||||
@@ -169,13 +167,6 @@ return {
|
||||
"name": "updatedAt",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "riskTier",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
@@ -257,6 +248,6 @@ return {
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "6e3badec3308017fd318d4bd1dc41b44";
|
||||
(node as any).hash = "477e430705f0f3cbadb8dfac89e24629";
|
||||
|
||||
export default node;
|
||||
|
||||
238
apps/console/src/pages/organizations/vendors/__generated__/VendorViewCreateRiskAssessmentMutation.graphql.ts
generated
vendored
Normal file
238
apps/console/src/pages/organizations/vendors/__generated__/VendorViewCreateRiskAssessmentMutation.graphql.ts
generated
vendored
Normal file
@@ -0,0 +1,238 @@
|
||||
/**
|
||||
* @generated SignedSource<<8372d50934049d43afb678c894f40dbd>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { ConcreteRequest } from 'relay-runtime';
|
||||
export type BusinessImpact = "CRITICAL" | "HIGH" | "LOW" | "MEDIUM";
|
||||
export type DataSensitivity = "CRITICAL" | "HIGH" | "LOW" | "MEDIUM" | "NONE";
|
||||
export type CreateVendorRiskAssessmentInput = {
|
||||
assessedBy: string;
|
||||
attachments?: ReadonlyArray<string> | null | undefined;
|
||||
businessImpact: BusinessImpact;
|
||||
dataSensitivity: DataSensitivity;
|
||||
expiresAt: string;
|
||||
notes?: string | null | undefined;
|
||||
vendorId: string;
|
||||
};
|
||||
export type VendorViewCreateRiskAssessmentMutation$variables = {
|
||||
connections: ReadonlyArray<string>;
|
||||
input: CreateVendorRiskAssessmentInput;
|
||||
};
|
||||
export type VendorViewCreateRiskAssessmentMutation$data = {
|
||||
readonly createVendorRiskAssessment: {
|
||||
readonly vendorRiskAssessmentEdge: {
|
||||
readonly node: {
|
||||
readonly assessedAt: string;
|
||||
readonly assessedBy: {
|
||||
readonly fullName: string;
|
||||
readonly id: string;
|
||||
};
|
||||
readonly businessImpact: BusinessImpact;
|
||||
readonly createdAt: string;
|
||||
readonly dataSensitivity: DataSensitivity;
|
||||
readonly expiresAt: string;
|
||||
readonly id: string;
|
||||
readonly notes: string | null | undefined;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
export type VendorViewCreateRiskAssessmentMutation = {
|
||||
response: VendorViewCreateRiskAssessmentMutation$data;
|
||||
variables: VendorViewCreateRiskAssessmentMutation$variables;
|
||||
};
|
||||
|
||||
const node: ConcreteRequest = (function(){
|
||||
var v0 = {
|
||||
"defaultValue": null,
|
||||
"kind": "LocalArgument",
|
||||
"name": "connections"
|
||||
},
|
||||
v1 = {
|
||||
"defaultValue": null,
|
||||
"kind": "LocalArgument",
|
||||
"name": "input"
|
||||
},
|
||||
v2 = [
|
||||
{
|
||||
"kind": "Variable",
|
||||
"name": "input",
|
||||
"variableName": "input"
|
||||
}
|
||||
],
|
||||
v3 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "id",
|
||||
"storageKey": null
|
||||
},
|
||||
v4 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "VendorRiskAssessmentEdge",
|
||||
"kind": "LinkedField",
|
||||
"name": "vendorRiskAssessmentEdge",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "VendorRiskAssessment",
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v3/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "assessedAt",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "expiresAt",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "dataSensitivity",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "businessImpact",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "notes",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "People",
|
||||
"kind": "LinkedField",
|
||||
"name": "assessedBy",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v3/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "fullName",
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "createdAt",
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
};
|
||||
return {
|
||||
"fragment": {
|
||||
"argumentDefinitions": [
|
||||
(v0/*: any*/),
|
||||
(v1/*: any*/)
|
||||
],
|
||||
"kind": "Fragment",
|
||||
"metadata": null,
|
||||
"name": "VendorViewCreateRiskAssessmentMutation",
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v2/*: any*/),
|
||||
"concreteType": "CreateVendorRiskAssessmentPayload",
|
||||
"kind": "LinkedField",
|
||||
"name": "createVendorRiskAssessment",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v4/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"type": "Mutation",
|
||||
"abstractKey": null
|
||||
},
|
||||
"kind": "Request",
|
||||
"operation": {
|
||||
"argumentDefinitions": [
|
||||
(v1/*: any*/),
|
||||
(v0/*: any*/)
|
||||
],
|
||||
"kind": "Operation",
|
||||
"name": "VendorViewCreateRiskAssessmentMutation",
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v2/*: any*/),
|
||||
"concreteType": "CreateVendorRiskAssessmentPayload",
|
||||
"kind": "LinkedField",
|
||||
"name": "createVendorRiskAssessment",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v4/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"filters": null,
|
||||
"handle": "appendEdge",
|
||||
"key": "",
|
||||
"kind": "LinkedHandle",
|
||||
"name": "vendorRiskAssessmentEdge",
|
||||
"handleArgs": [
|
||||
{
|
||||
"kind": "Variable",
|
||||
"name": "connections",
|
||||
"variableName": "connections"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
]
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "1238320b8db75088917d0e5796652f50",
|
||||
"id": null,
|
||||
"metadata": {},
|
||||
"name": "VendorViewCreateRiskAssessmentMutation",
|
||||
"operationKind": "mutation",
|
||||
"text": "mutation VendorViewCreateRiskAssessmentMutation(\n $input: CreateVendorRiskAssessmentInput!\n) {\n createVendorRiskAssessment(input: $input) {\n vendorRiskAssessmentEdge {\n node {\n id\n assessedAt\n expiresAt\n dataSensitivity\n businessImpact\n notes\n assessedBy {\n id\n fullName\n }\n createdAt\n }\n }\n }\n}\n"
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "7def769f97c5a728a7331756a6e3c5b2";
|
||||
|
||||
export default node;
|
||||
263
apps/console/src/pages/organizations/vendors/__generated__/VendorViewQuery.graphql.ts
generated
vendored
263
apps/console/src/pages/organizations/vendors/__generated__/VendorViewQuery.graphql.ts
generated
vendored
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* @generated SignedSource<<62c3cb3473246b0326ff4cbd4cc4f940>>
|
||||
* @generated SignedSource<<bbfa9d7b4ab300f8ab96380582d2d9b7>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
@@ -10,8 +10,8 @@
|
||||
|
||||
import { ConcreteRequest } from 'relay-runtime';
|
||||
import { FragmentRefs } from "relay-runtime";
|
||||
export type RiskTier = "CRITICAL" | "GENERAL" | "SIGNIFICANT";
|
||||
export type ServiceCriticality = "HIGH" | "LOW" | "MEDIUM";
|
||||
export type BusinessImpact = "CRITICAL" | "HIGH" | "LOW" | "MEDIUM";
|
||||
export type DataSensitivity = "CRITICAL" | "HIGH" | "LOW" | "MEDIUM" | "NONE";
|
||||
export type VendorViewQuery$variables = {
|
||||
organizationId: string;
|
||||
vendorId: string;
|
||||
@@ -44,13 +44,28 @@ export type VendorViewQuery$data = {
|
||||
readonly legalName?: string | null | undefined;
|
||||
readonly name?: string;
|
||||
readonly privacyPolicyUrl?: string | null | undefined;
|
||||
readonly riskTier?: RiskTier;
|
||||
readonly riskAssessments?: {
|
||||
readonly edges: ReadonlyArray<{
|
||||
readonly node: {
|
||||
readonly assessedAt: string;
|
||||
readonly assessedBy: {
|
||||
readonly fullName: string;
|
||||
readonly id: string;
|
||||
};
|
||||
readonly businessImpact: BusinessImpact;
|
||||
readonly createdAt: string;
|
||||
readonly dataSensitivity: DataSensitivity;
|
||||
readonly expiresAt: string;
|
||||
readonly id: string;
|
||||
readonly notes: string | null | undefined;
|
||||
};
|
||||
}>;
|
||||
};
|
||||
readonly securityOwner?: {
|
||||
readonly fullName: string;
|
||||
readonly id: string;
|
||||
} | null | undefined;
|
||||
readonly securityPageUrl?: string | null | undefined;
|
||||
readonly serviceCriticality?: ServiceCriticality;
|
||||
readonly serviceLevelAgreementUrl?: string | null | undefined;
|
||||
readonly serviceStartAt?: string;
|
||||
readonly serviceTerminationAt?: string | null | undefined;
|
||||
@@ -126,153 +141,139 @@ v8 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "serviceCriticality",
|
||||
"name": "statusPageUrl",
|
||||
"storageKey": null
|
||||
},
|
||||
v9 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "riskTier",
|
||||
"name": "termsOfServiceUrl",
|
||||
"storageKey": null
|
||||
},
|
||||
v10 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "statusPageUrl",
|
||||
"name": "privacyPolicyUrl",
|
||||
"storageKey": null
|
||||
},
|
||||
v11 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "termsOfServiceUrl",
|
||||
"name": "serviceLevelAgreementUrl",
|
||||
"storageKey": null
|
||||
},
|
||||
v12 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "privacyPolicyUrl",
|
||||
"name": "dataProcessingAgreementUrl",
|
||||
"storageKey": null
|
||||
},
|
||||
v13 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "serviceLevelAgreementUrl",
|
||||
"name": "securityPageUrl",
|
||||
"storageKey": null
|
||||
},
|
||||
v14 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "dataProcessingAgreementUrl",
|
||||
"name": "trustPageUrl",
|
||||
"storageKey": null
|
||||
},
|
||||
v15 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "securityPageUrl",
|
||||
"name": "certifications",
|
||||
"storageKey": null
|
||||
},
|
||||
v16 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "trustPageUrl",
|
||||
"name": "headquarterAddress",
|
||||
"storageKey": null
|
||||
},
|
||||
v17 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "certifications",
|
||||
"name": "legalName",
|
||||
"storageKey": null
|
||||
},
|
||||
v18 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "headquarterAddress",
|
||||
"name": "websiteUrl",
|
||||
"storageKey": null
|
||||
},
|
||||
v19 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "legalName",
|
||||
"storageKey": null
|
||||
},
|
||||
v20 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "websiteUrl",
|
||||
"storageKey": null
|
||||
},
|
||||
v21 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "fullName",
|
||||
"storageKey": null
|
||||
},
|
||||
v22 = [
|
||||
v20 = [
|
||||
(v3/*: any*/),
|
||||
(v21/*: any*/)
|
||||
(v19/*: any*/)
|
||||
],
|
||||
v23 = {
|
||||
v21 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "People",
|
||||
"kind": "LinkedField",
|
||||
"name": "businessOwner",
|
||||
"plural": false,
|
||||
"selections": (v22/*: any*/),
|
||||
"selections": (v20/*: any*/),
|
||||
"storageKey": null
|
||||
},
|
||||
v24 = {
|
||||
v22 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "People",
|
||||
"kind": "LinkedField",
|
||||
"name": "securityOwner",
|
||||
"plural": false,
|
||||
"selections": (v22/*: any*/),
|
||||
"selections": (v20/*: any*/),
|
||||
"storageKey": null
|
||||
},
|
||||
v25 = {
|
||||
v23 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "createdAt",
|
||||
"storageKey": null
|
||||
},
|
||||
v26 = {
|
||||
v24 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "updatedAt",
|
||||
"storageKey": null
|
||||
},
|
||||
v27 = {
|
||||
v25 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "__typename",
|
||||
"storageKey": null
|
||||
},
|
||||
v28 = {
|
||||
v26 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "cursor",
|
||||
"storageKey": null
|
||||
},
|
||||
v29 = {
|
||||
v27 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "PageInfo",
|
||||
@@ -297,7 +298,7 @@ v29 = {
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
v30 = [
|
||||
v28 = [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
@@ -350,34 +351,108 @@ v30 = [
|
||||
"name": "fileSize",
|
||||
"storageKey": null
|
||||
},
|
||||
(v25/*: any*/),
|
||||
(v27/*: any*/)
|
||||
(v23/*: any*/),
|
||||
(v25/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
(v28/*: any*/)
|
||||
(v26/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
(v29/*: any*/)
|
||||
(v27/*: any*/)
|
||||
],
|
||||
v31 = [
|
||||
v29 = [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "VendorRiskAssessmentEdge",
|
||||
"kind": "LinkedField",
|
||||
"name": "edges",
|
||||
"plural": true,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "VendorRiskAssessment",
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v3/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "assessedAt",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "expiresAt",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "dataSensitivity",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "businessImpact",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "notes",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "People",
|
||||
"kind": "LinkedField",
|
||||
"name": "assessedBy",
|
||||
"plural": false,
|
||||
"selections": (v20/*: any*/),
|
||||
"storageKey": null
|
||||
},
|
||||
(v23/*: any*/),
|
||||
(v25/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
(v26/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
(v27/*: any*/)
|
||||
],
|
||||
v30 = [
|
||||
{
|
||||
"kind": "Variable",
|
||||
"name": "id",
|
||||
"variableName": "organizationId"
|
||||
}
|
||||
],
|
||||
v32 = {
|
||||
v31 = {
|
||||
"kind": "Literal",
|
||||
"name": "first",
|
||||
"value": 100
|
||||
},
|
||||
v33 = [
|
||||
(v32/*: any*/)
|
||||
v32 = [
|
||||
(v31/*: any*/)
|
||||
],
|
||||
v34 = [
|
||||
(v32/*: any*/),
|
||||
v33 = [
|
||||
(v31/*: any*/),
|
||||
{
|
||||
"kind": "Literal",
|
||||
"name": "orderBy",
|
||||
@@ -424,12 +499,10 @@ return {
|
||||
(v16/*: any*/),
|
||||
(v17/*: any*/),
|
||||
(v18/*: any*/),
|
||||
(v19/*: any*/),
|
||||
(v20/*: any*/),
|
||||
(v21/*: any*/),
|
||||
(v22/*: any*/),
|
||||
(v23/*: any*/),
|
||||
(v24/*: any*/),
|
||||
(v25/*: any*/),
|
||||
(v26/*: any*/),
|
||||
{
|
||||
"alias": "complianceReports",
|
||||
"args": null,
|
||||
@@ -437,7 +510,17 @@ return {
|
||||
"kind": "LinkedField",
|
||||
"name": "__VendorView_complianceReports_connection",
|
||||
"plural": false,
|
||||
"selections": (v30/*: any*/),
|
||||
"selections": (v28/*: any*/),
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": "riskAssessments",
|
||||
"args": null,
|
||||
"concreteType": "VendorRiskAssessmentConnection",
|
||||
"kind": "LinkedField",
|
||||
"name": "__VendorView_riskAssessments_connection",
|
||||
"plural": false,
|
||||
"selections": (v29/*: any*/),
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
@@ -449,7 +532,7 @@ return {
|
||||
},
|
||||
{
|
||||
"alias": "organization",
|
||||
"args": (v31/*: any*/),
|
||||
"args": (v30/*: any*/),
|
||||
"concreteType": null,
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
@@ -484,7 +567,7 @@ return {
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v27/*: any*/),
|
||||
(v25/*: any*/),
|
||||
(v3/*: any*/),
|
||||
{
|
||||
"kind": "InlineFragment",
|
||||
@@ -504,30 +587,47 @@ return {
|
||||
(v16/*: any*/),
|
||||
(v17/*: any*/),
|
||||
(v18/*: any*/),
|
||||
(v19/*: any*/),
|
||||
(v20/*: any*/),
|
||||
(v21/*: any*/),
|
||||
(v22/*: any*/),
|
||||
(v23/*: any*/),
|
||||
(v24/*: any*/),
|
||||
(v25/*: any*/),
|
||||
(v26/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v33/*: any*/),
|
||||
"args": (v32/*: any*/),
|
||||
"concreteType": "VendorComplianceReportConnection",
|
||||
"kind": "LinkedField",
|
||||
"name": "complianceReports",
|
||||
"plural": false,
|
||||
"selections": (v30/*: any*/),
|
||||
"selections": (v28/*: any*/),
|
||||
"storageKey": "complianceReports(first:100)"
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v33/*: any*/),
|
||||
"args": (v32/*: any*/),
|
||||
"filters": null,
|
||||
"handle": "connection",
|
||||
"key": "VendorView_complianceReports",
|
||||
"kind": "LinkedHandle",
|
||||
"name": "complianceReports"
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v32/*: any*/),
|
||||
"concreteType": "VendorRiskAssessmentConnection",
|
||||
"kind": "LinkedField",
|
||||
"name": "riskAssessments",
|
||||
"plural": false,
|
||||
"selections": (v29/*: any*/),
|
||||
"storageKey": "riskAssessments(first:100)"
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v32/*: any*/),
|
||||
"filters": null,
|
||||
"handle": "connection",
|
||||
"key": "VendorView_riskAssessments",
|
||||
"kind": "LinkedHandle",
|
||||
"name": "riskAssessments"
|
||||
}
|
||||
],
|
||||
"type": "Vendor",
|
||||
@@ -538,20 +638,20 @@ return {
|
||||
},
|
||||
{
|
||||
"alias": "organization",
|
||||
"args": (v31/*: any*/),
|
||||
"args": (v30/*: any*/),
|
||||
"concreteType": null,
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v27/*: any*/),
|
||||
(v25/*: any*/),
|
||||
(v3/*: any*/),
|
||||
{
|
||||
"kind": "InlineFragment",
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v34/*: any*/),
|
||||
"args": (v33/*: any*/),
|
||||
"concreteType": "PeopleConnection",
|
||||
"kind": "LinkedField",
|
||||
"name": "peoples",
|
||||
@@ -574,7 +674,7 @@ return {
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v3/*: any*/),
|
||||
(v21/*: any*/),
|
||||
(v19/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
@@ -582,21 +682,21 @@ return {
|
||||
"name": "primaryEmailAddress",
|
||||
"storageKey": null
|
||||
},
|
||||
(v27/*: any*/)
|
||||
(v25/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
(v28/*: any*/)
|
||||
(v26/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
(v29/*: any*/)
|
||||
(v27/*: any*/)
|
||||
],
|
||||
"storageKey": "peoples(first:100,orderBy:{\"direction\":\"ASC\",\"field\":\"FULL_NAME\"})"
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v34/*: any*/),
|
||||
"args": (v33/*: any*/),
|
||||
"filters": [
|
||||
"orderBy"
|
||||
],
|
||||
@@ -615,7 +715,7 @@ return {
|
||||
]
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "337beb9fa1d1d29bcd974229385d8e7a",
|
||||
"cacheID": "5df12f781d305bd4bd6b6c0ccb4d947e",
|
||||
"id": null,
|
||||
"metadata": {
|
||||
"connection": [
|
||||
@@ -627,16 +727,25 @@ return {
|
||||
"node",
|
||||
"complianceReports"
|
||||
]
|
||||
},
|
||||
{
|
||||
"count": null,
|
||||
"cursor": null,
|
||||
"direction": "forward",
|
||||
"path": [
|
||||
"node",
|
||||
"riskAssessments"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"name": "VendorViewQuery",
|
||||
"operationKind": "query",
|
||||
"text": "query VendorViewQuery(\n $vendorId: ID!\n $organizationId: ID!\n) {\n node(id: $vendorId) {\n __typename\n ... on Vendor {\n id\n name\n description\n serviceStartAt\n serviceTerminationAt\n serviceCriticality\n riskTier\n statusPageUrl\n termsOfServiceUrl\n privacyPolicyUrl\n serviceLevelAgreementUrl\n dataProcessingAgreementUrl\n securityPageUrl\n trustPageUrl\n certifications\n headquarterAddress\n legalName\n websiteUrl\n businessOwner {\n id\n fullName\n }\n securityOwner {\n id\n fullName\n }\n createdAt\n updatedAt\n complianceReports(first: 100) {\n edges {\n node {\n id\n reportName\n reportDate\n validUntil\n fileUrl\n fileSize\n createdAt\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n }\n id\n }\n organization: node(id: $organizationId) {\n __typename\n ...PeopleSelector_organization\n id\n }\n}\n\nfragment PeopleSelector_organization on Organization {\n id\n peoples(first: 100, orderBy: {direction: ASC, field: FULL_NAME}) {\n edges {\n node {\n id\n fullName\n primaryEmailAddress\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n}\n"
|
||||
"text": "query VendorViewQuery(\n $vendorId: ID!\n $organizationId: ID!\n) {\n node(id: $vendorId) {\n __typename\n ... on Vendor {\n id\n name\n description\n serviceStartAt\n serviceTerminationAt\n statusPageUrl\n termsOfServiceUrl\n privacyPolicyUrl\n serviceLevelAgreementUrl\n dataProcessingAgreementUrl\n securityPageUrl\n trustPageUrl\n certifications\n headquarterAddress\n legalName\n websiteUrl\n businessOwner {\n id\n fullName\n }\n securityOwner {\n id\n fullName\n }\n createdAt\n updatedAt\n complianceReports(first: 100) {\n edges {\n node {\n id\n reportName\n reportDate\n validUntil\n fileUrl\n fileSize\n createdAt\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n riskAssessments(first: 100) {\n edges {\n node {\n id\n assessedAt\n expiresAt\n dataSensitivity\n businessImpact\n notes\n assessedBy {\n id\n fullName\n }\n createdAt\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n }\n id\n }\n organization: node(id: $organizationId) {\n __typename\n ...PeopleSelector_organization\n id\n }\n}\n\nfragment PeopleSelector_organization on Organization {\n id\n peoples(first: 100, orderBy: {direction: ASC, field: FULL_NAME}) {\n edges {\n node {\n id\n fullName\n primaryEmailAddress\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n}\n"
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "4a621712e4dfaebf9ad42232ba7f713a";
|
||||
(node as any).hash = "2b856ea721d1bfb6b853fc281ee1aac6";
|
||||
|
||||
export default node;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* @generated SignedSource<<e8b13d28eed7587f5fbefcc073c53dc4>>
|
||||
* @generated SignedSource<<574565aac89550e684dc54b21327b565>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
@@ -9,8 +9,6 @@
|
||||
// @ts-nocheck
|
||||
|
||||
import { ConcreteRequest } from 'relay-runtime';
|
||||
export type RiskTier = "CRITICAL" | "GENERAL" | "SIGNIFICANT";
|
||||
export type ServiceCriticality = "HIGH" | "LOW" | "MEDIUM";
|
||||
export type UpdateVendorInput = {
|
||||
businessOwnerId?: string | null | undefined;
|
||||
category?: string | null | undefined;
|
||||
@@ -22,10 +20,8 @@ export type UpdateVendorInput = {
|
||||
legalName?: string | null | undefined;
|
||||
name?: string | null | undefined;
|
||||
privacyPolicyUrl?: string | null | undefined;
|
||||
riskTier?: RiskTier | null | undefined;
|
||||
securityOwnerId?: string | null | undefined;
|
||||
securityPageUrl?: string | null | undefined;
|
||||
serviceCriticality?: ServiceCriticality | null | undefined;
|
||||
serviceLevelAgreementUrl?: string | null | undefined;
|
||||
serviceStartAt?: string | null | undefined;
|
||||
serviceTerminationAt?: string | null | undefined;
|
||||
@@ -52,13 +48,11 @@ export type VendorViewUpdateVendorMutation$data = {
|
||||
readonly legalName: string | null | undefined;
|
||||
readonly name: string;
|
||||
readonly privacyPolicyUrl: string | null | undefined;
|
||||
readonly riskTier: RiskTier;
|
||||
readonly securityOwner: {
|
||||
readonly fullName: string;
|
||||
readonly id: string;
|
||||
} | null | undefined;
|
||||
readonly securityPageUrl: string | null | undefined;
|
||||
readonly serviceCriticality: ServiceCriticality;
|
||||
readonly serviceLevelAgreementUrl: string | null | undefined;
|
||||
readonly serviceStartAt: string;
|
||||
readonly serviceTerminationAt: string | null | undefined;
|
||||
@@ -152,20 +146,6 @@ v3 = [
|
||||
"name": "serviceTerminationAt",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "serviceCriticality",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "riskTier",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
@@ -295,16 +275,16 @@ return {
|
||||
"selections": (v3/*: any*/)
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "d582aaaddaa73ef8e0fdef172364c64e",
|
||||
"cacheID": "9e2c4c33246b4aa469cdd737be1e690a",
|
||||
"id": null,
|
||||
"metadata": {},
|
||||
"name": "VendorViewUpdateVendorMutation",
|
||||
"operationKind": "mutation",
|
||||
"text": "mutation VendorViewUpdateVendorMutation(\n $input: UpdateVendorInput!\n) {\n updateVendor(input: $input) {\n vendor {\n id\n name\n description\n serviceStartAt\n serviceTerminationAt\n serviceCriticality\n riskTier\n statusPageUrl\n termsOfServiceUrl\n privacyPolicyUrl\n serviceLevelAgreementUrl\n dataProcessingAgreementUrl\n securityPageUrl\n trustPageUrl\n certifications\n headquarterAddress\n legalName\n websiteUrl\n businessOwner {\n id\n fullName\n }\n securityOwner {\n id\n fullName\n }\n updatedAt\n }\n }\n}\n"
|
||||
"text": "mutation VendorViewUpdateVendorMutation(\n $input: UpdateVendorInput!\n) {\n updateVendor(input: $input) {\n vendor {\n id\n name\n description\n serviceStartAt\n serviceTerminationAt\n statusPageUrl\n termsOfServiceUrl\n privacyPolicyUrl\n serviceLevelAgreementUrl\n dataProcessingAgreementUrl\n securityPageUrl\n trustPageUrl\n certifications\n headquarterAddress\n legalName\n websiteUrl\n businessOwner {\n id\n fullName\n }\n securityOwner {\n id\n fullName\n }\n updatedAt\n }\n }\n}\n"
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "627ef1694ebc04845b019bb65dd72c97";
|
||||
(node as any).hash = "58c28ca0307e1b27f2ebb72c3c2e7535";
|
||||
|
||||
export default node;
|
||||
|
||||
3
pkg/coredata/migrations/20250422T004000Z.sql
Normal file
3
pkg/coredata/migrations/20250422T004000Z.sql
Normal file
@@ -0,0 +1,3 @@
|
||||
ALTER TABLE risk_assessments RENAME TO vendor_risk_assessments;
|
||||
|
||||
ALTER TABLE vendor_risk_assessments ADD COLUMN assessed_at TIMESTAMP WITH TIME ZONE NOT NULL;
|
||||
1
pkg/coredata/migrations/20250422T004300Z.sql
Normal file
1
pkg/coredata/migrations/20250422T004300Z.sql
Normal file
@@ -0,0 +1 @@
|
||||
ALTER TABLE vendor_risk_assessments ADD COLUMN assessed_by TEXT NOT NULL;
|
||||
@@ -90,7 +90,7 @@ func (r VendorRiskAssessment) Insert(
|
||||
) error {
|
||||
q := `
|
||||
INSERT INTO
|
||||
risk_assessments (
|
||||
vendor_risk_assessments (
|
||||
tenant_id,
|
||||
id,
|
||||
vendor_id,
|
||||
@@ -165,7 +165,7 @@ SELECT
|
||||
created_at,
|
||||
updated_at
|
||||
FROM
|
||||
risk_assessments
|
||||
vendor_risk_assessments
|
||||
WHERE
|
||||
%s
|
||||
AND id = @id
|
||||
@@ -216,7 +216,7 @@ SELECT
|
||||
created_at,
|
||||
updated_at
|
||||
FROM
|
||||
risk_assessments
|
||||
vendor_risk_assessments
|
||||
WHERE
|
||||
%s
|
||||
AND vendor_id = @vendor_id
|
||||
@@ -270,7 +270,7 @@ SELECT
|
||||
created_at,
|
||||
updated_at
|
||||
FROM
|
||||
risk_assessments
|
||||
vendor_risk_assessments
|
||||
WHERE
|
||||
%s
|
||||
AND vendor_id = @vendor_id
|
||||
|
||||
@@ -19,6 +19,7 @@ import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/getprobo/probo/pkg/probo"
|
||||
"github.com/getprobo/probo/pkg/usrmgr"
|
||||
"go.gearno.de/kit/httpserver"
|
||||
)
|
||||
@@ -33,7 +34,7 @@ type (
|
||||
}
|
||||
)
|
||||
|
||||
func InvitationConfirmationHandler(usrmgrSvc *usrmgr.Service, authCfg AuthConfig) http.HandlerFunc {
|
||||
func InvitationConfirmationHandler(usrmgrSvc *usrmgr.Service, proboSvc *probo.Service, authCfg AuthConfig) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req InvitationConfirmationRequest
|
||||
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
||||
@@ -41,7 +42,7 @@ func InvitationConfirmationHandler(usrmgrSvc *usrmgr.Service, authCfg AuthConfig
|
||||
return
|
||||
}
|
||||
|
||||
err := usrmgrSvc.ConfirmInvitation(r.Context(), req.Token, req.Password)
|
||||
_, err := usrmgrSvc.ConfirmInvitation(r.Context(), req.Token, req.Password)
|
||||
if err != nil {
|
||||
httpserver.RenderError(w, http.StatusInternalServerError, err)
|
||||
return
|
||||
|
||||
@@ -80,7 +80,7 @@ func NewMux(proboSvc *probo.Service, usrmgrSvc *usrmgr.Service, authCfg AuthConf
|
||||
r.Post("/auth/register", SignUpHandler(usrmgrSvc, authCfg))
|
||||
r.Post("/auth/login", SignInHandler(usrmgrSvc, authCfg))
|
||||
r.Delete("/auth/logout", SignOutHandler(usrmgrSvc, authCfg))
|
||||
r.Post("/auth/invitation", InvitationConfirmationHandler(usrmgrSvc, authCfg))
|
||||
r.Post("/auth/invitation", InvitationConfirmationHandler(usrmgrSvc, proboSvc, authCfg))
|
||||
r.Post("/auth/forget-password", ForgetPasswordHandler(usrmgrSvc, authCfg))
|
||||
r.Post("/auth/reset-password", ResetPasswordHandler(usrmgrSvc, authCfg))
|
||||
|
||||
|
||||
@@ -1585,7 +1585,27 @@ func (r *vendorResolver) ComplianceReports(ctx context.Context, obj *types.Vendo
|
||||
|
||||
// RiskAssessments is the resolver for the riskAssessments field.
|
||||
func (r *vendorResolver) RiskAssessments(ctx context.Context, obj *types.Vendor, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.VendorRiskAssessmentOrder) (*types.VendorRiskAssessmentConnection, error) {
|
||||
panic(fmt.Errorf("not implemented: RiskAssessments - riskAssessments"))
|
||||
svc := GetTenantService(ctx, r.proboSvc, obj.ID.TenantID())
|
||||
|
||||
pageOrderBy := page.OrderBy[coredata.VendorRiskAssessmentOrderField]{
|
||||
Field: coredata.VendorRiskAssessmentOrderFieldCreatedAt,
|
||||
Direction: page.OrderDirectionDesc,
|
||||
}
|
||||
if orderBy != nil {
|
||||
pageOrderBy = page.OrderBy[coredata.VendorRiskAssessmentOrderField]{
|
||||
Field: orderBy.Field,
|
||||
Direction: orderBy.Direction,
|
||||
}
|
||||
}
|
||||
|
||||
cursor := types.NewCursor(first, after, last, before, pageOrderBy)
|
||||
|
||||
page, err := svc.Vendors.ListRiskAssessments(ctx, obj.ID, cursor)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("failed to list vendor risk assessments: %w", err))
|
||||
}
|
||||
|
||||
return types.NewVendorRiskAssessmentConnection(page), nil
|
||||
}
|
||||
|
||||
// BusinessOwner is the resolver for the businessOwner field.
|
||||
|
||||
@@ -710,31 +710,32 @@ func (s Service) InviteUser(
|
||||
)
|
||||
}
|
||||
|
||||
func (s Service) ConfirmInvitation(ctx context.Context, tokenString string, password string) error {
|
||||
func (s Service) ConfirmInvitation(ctx context.Context, tokenString string, password string) (*coredata.User, error) {
|
||||
token, err := statelesstoken.ValidateToken[InvitationData](
|
||||
s.tokenSecret,
|
||||
TokenTypeOrganizationInvitation,
|
||||
tokenString,
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot validate organization invitation token: %w", err)
|
||||
return nil, fmt.Errorf("cannot validate organization invitation token: %w", err)
|
||||
}
|
||||
|
||||
if len(password) < 8 {
|
||||
return &ErrInvalidPassword{len(password)}
|
||||
return nil, &ErrInvalidPassword{len(password)}
|
||||
}
|
||||
|
||||
now := time.Now()
|
||||
|
||||
hashedPassword, err := s.hp.HashPassword([]byte(password))
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot hash password: %w", err)
|
||||
return nil, fmt.Errorf("cannot hash password: %w", err)
|
||||
}
|
||||
|
||||
return s.pg.WithTx(
|
||||
user := &coredata.User{}
|
||||
|
||||
err = s.pg.WithTx(
|
||||
ctx,
|
||||
func(tx pg.Conn) error {
|
||||
user := &coredata.User{}
|
||||
|
||||
if err := user.LoadByEmail(ctx, tx, token.Data.Email); err != nil {
|
||||
var errUserNotFound *coredata.ErrUserNotFound
|
||||
@@ -766,9 +767,31 @@ func (s Service) ConfirmInvitation(ctx context.Context, tokenString string, pass
|
||||
return fmt.Errorf("cannot insert user organization: %w", err)
|
||||
}
|
||||
|
||||
people := coredata.People{
|
||||
OrganizationID: token.Data.OrganizationID,
|
||||
UserID: &user.ID,
|
||||
FullName: token.Data.FullName,
|
||||
PrimaryEmailAddress: token.Data.Email,
|
||||
Kind: coredata.PeopleKindEmployee,
|
||||
CreatedAt: now,
|
||||
UpdatedAt: now,
|
||||
}
|
||||
|
||||
scope := coredata.NewScope(token.Data.OrganizationID.TenantID())
|
||||
|
||||
if err := people.Insert(ctx, tx, scope); err != nil {
|
||||
return fmt.Errorf("cannot insert people: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return user, nil
|
||||
}
|
||||
|
||||
func (s Service) RemoveUser(ctx context.Context, organizationID gid.GID, userID gid.GID) error {
|
||||
|
||||
Reference in New Issue
Block a user