chore: import upstream snapshot with attribution
CI / Migrate Dev DB (push) Has been skipped
CI / Detect Version (push) Has been cancelled
CI / Migrate DB (push) Has been cancelled
CI / Build Dev ECR (./docker/app.Dockerfile, ECR_APP) (push) Has been cancelled
CI / Build Dev ECR (./docker/db.Dockerfile, ECR_MIGRATIONS) (push) Has been cancelled
CI / Build Dev ECR (./docker/pii.Dockerfile, ECR_PII) (push) Has been cancelled
CI / Build Dev ECR (./docker/realtime.Dockerfile, ECR_REALTIME) (push) Has been cancelled
CI / Deploy Trigger.dev (Dev) (push) Has been cancelled
CI / Build AMD64 (./docker/app.Dockerfile, ECR_APP, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build AMD64 (./docker/db.Dockerfile, ECR_MIGRATIONS, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build AMD64 (./docker/pii.Dockerfile, ECR_PII, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build AMD64 (./docker/realtime.Dockerfile, ECR_REALTIME, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/app.Dockerfile, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/db.Dockerfile, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/pii.Dockerfile, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/realtime.Dockerfile, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Check Docs Changes (push) Has been cancelled
CI / Process Docs (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
CI / Test and Build (push) Has been cancelled
Publish CLI Package / publish-npm (push) Has been cancelled
Publish Python SDK / publish-pypi (push) Has been cancelled
Publish TypeScript SDK / publish-npm (push) Has been cancelled
CI / Migrate Dev DB (push) Has been skipped
CI / Detect Version (push) Has been cancelled
CI / Migrate DB (push) Has been cancelled
CI / Build Dev ECR (./docker/app.Dockerfile, ECR_APP) (push) Has been cancelled
CI / Build Dev ECR (./docker/db.Dockerfile, ECR_MIGRATIONS) (push) Has been cancelled
CI / Build Dev ECR (./docker/pii.Dockerfile, ECR_PII) (push) Has been cancelled
CI / Build Dev ECR (./docker/realtime.Dockerfile, ECR_REALTIME) (push) Has been cancelled
CI / Deploy Trigger.dev (Dev) (push) Has been cancelled
CI / Build AMD64 (./docker/app.Dockerfile, ECR_APP, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build AMD64 (./docker/db.Dockerfile, ECR_MIGRATIONS, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build AMD64 (./docker/pii.Dockerfile, ECR_PII, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build AMD64 (./docker/realtime.Dockerfile, ECR_REALTIME, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/app.Dockerfile, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/db.Dockerfile, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/pii.Dockerfile, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/realtime.Dockerfile, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Check Docs Changes (push) Has been cancelled
CI / Process Docs (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
CI / Test and Build (push) Has been cancelled
Publish CLI Package / publish-npm (push) Has been cancelled
Publish Python SDK / publish-pypi (push) Has been cancelled
Publish TypeScript SDK / publish-npm (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,740 @@
|
||||
import { z } from 'zod'
|
||||
import type {
|
||||
ContractBody,
|
||||
ContractBodyInput,
|
||||
ContractJsonResponse,
|
||||
} from '@/lib/api/contracts/types'
|
||||
import { defineRouteContract } from '@/lib/api/contracts/types'
|
||||
import { FileInputSchema } from '@/lib/uploads/utils/file-schemas'
|
||||
|
||||
const nullableString = z.string().nullable()
|
||||
const nullableNumber = z.number().nullable()
|
||||
const nullableBoolean = z.boolean().nullable()
|
||||
|
||||
const vantaPageInfoSchema = z
|
||||
.object({
|
||||
startCursor: nullableString,
|
||||
endCursor: nullableString,
|
||||
hasNextPage: z.boolean(),
|
||||
hasPreviousPage: z.boolean(),
|
||||
})
|
||||
.nullable()
|
||||
|
||||
const vantaOwnerSchema = z
|
||||
.object({
|
||||
id: nullableString,
|
||||
displayName: nullableString,
|
||||
emailAddress: nullableString,
|
||||
})
|
||||
.nullable()
|
||||
|
||||
const vantaCustomFieldsSchema = z.array(
|
||||
z.object({
|
||||
label: nullableString,
|
||||
value: z.union([z.string(), z.array(z.string())]).nullable(),
|
||||
})
|
||||
)
|
||||
|
||||
const vantaFrameworkSchema = z.object({
|
||||
id: nullableString,
|
||||
displayName: nullableString,
|
||||
shorthandName: nullableString,
|
||||
description: nullableString,
|
||||
numControlsCompleted: nullableNumber,
|
||||
numControlsTotal: nullableNumber,
|
||||
numDocumentsPassing: nullableNumber,
|
||||
numDocumentsTotal: nullableNumber,
|
||||
numTestsPassing: nullableNumber,
|
||||
numTestsTotal: nullableNumber,
|
||||
})
|
||||
|
||||
const vantaFrameworkDetailSchema = vantaFrameworkSchema.extend({
|
||||
requirementCategories: z.array(
|
||||
z.object({
|
||||
id: nullableString,
|
||||
name: nullableString,
|
||||
shorthand: nullableString,
|
||||
requirements: z.array(
|
||||
z.object({
|
||||
id: nullableString,
|
||||
name: nullableString,
|
||||
shorthand: nullableString,
|
||||
description: nullableString,
|
||||
controls: z.array(
|
||||
z.object({
|
||||
id: nullableString,
|
||||
externalId: nullableString,
|
||||
name: nullableString,
|
||||
description: nullableString,
|
||||
})
|
||||
),
|
||||
})
|
||||
),
|
||||
})
|
||||
),
|
||||
})
|
||||
|
||||
const vantaControlSchema = z.object({
|
||||
id: nullableString,
|
||||
externalId: nullableString,
|
||||
name: nullableString,
|
||||
description: nullableString,
|
||||
source: nullableString,
|
||||
domains: z.array(z.string()),
|
||||
owner: vantaOwnerSchema,
|
||||
role: nullableString,
|
||||
customFields: vantaCustomFieldsSchema,
|
||||
creationDate: nullableString,
|
||||
modificationDate: nullableString,
|
||||
})
|
||||
|
||||
const vantaControlDetailSchema = vantaControlSchema.extend({
|
||||
note: nullableString,
|
||||
status: nullableString,
|
||||
numDocumentsPassing: nullableNumber,
|
||||
numDocumentsTotal: nullableNumber,
|
||||
numTestsPassing: nullableNumber,
|
||||
numTestsTotal: nullableNumber,
|
||||
})
|
||||
|
||||
const vantaTestSchema = z.object({
|
||||
id: nullableString,
|
||||
name: nullableString,
|
||||
description: nullableString,
|
||||
failureDescription: nullableString,
|
||||
remediationDescription: nullableString,
|
||||
category: nullableString,
|
||||
status: nullableString,
|
||||
integrations: z.array(z.string()),
|
||||
lastTestRunDate: nullableString,
|
||||
latestFlipDate: nullableString,
|
||||
version: z.object({ major: nullableNumber, minor: nullableNumber }).nullable(),
|
||||
deactivatedStatusInfo: z
|
||||
.object({
|
||||
isDeactivated: nullableBoolean,
|
||||
deactivatedReason: nullableString,
|
||||
lastUpdatedDate: nullableString,
|
||||
})
|
||||
.nullable(),
|
||||
remediationStatusInfo: z
|
||||
.object({
|
||||
status: nullableString,
|
||||
soonestRemediateByDate: nullableString,
|
||||
itemCount: nullableNumber,
|
||||
})
|
||||
.nullable(),
|
||||
owner: vantaOwnerSchema,
|
||||
})
|
||||
|
||||
const vantaTestEntitySchema = z.object({
|
||||
id: nullableString,
|
||||
entityStatus: nullableString,
|
||||
displayName: nullableString,
|
||||
responseType: nullableString,
|
||||
deactivatedReason: nullableString,
|
||||
createdDate: nullableString,
|
||||
lastUpdatedDate: nullableString,
|
||||
})
|
||||
|
||||
const vantaDocumentSchema = z.object({
|
||||
id: nullableString,
|
||||
title: nullableString,
|
||||
description: nullableString,
|
||||
category: nullableString,
|
||||
ownerId: nullableString,
|
||||
isSensitive: nullableBoolean,
|
||||
uploadStatus: nullableString,
|
||||
uploadStatusDate: nullableString,
|
||||
url: nullableString,
|
||||
})
|
||||
|
||||
const vantaDocumentDetailSchema = vantaDocumentSchema.extend({
|
||||
note: nullableString,
|
||||
nextRenewalDate: nullableString,
|
||||
renewalCadence: nullableString,
|
||||
reminderWindow: nullableString,
|
||||
subscribers: z.array(z.string()),
|
||||
deactivatedStatus: z
|
||||
.object({
|
||||
isDeactivated: nullableBoolean,
|
||||
reason: nullableString,
|
||||
creationDate: nullableString,
|
||||
expiration: nullableString,
|
||||
})
|
||||
.nullable(),
|
||||
})
|
||||
|
||||
const vantaUploadedFileSchema = z.object({
|
||||
id: nullableString,
|
||||
fileName: nullableString,
|
||||
title: nullableString,
|
||||
description: nullableString,
|
||||
mimeType: nullableString,
|
||||
uploadedBy: z.object({ id: nullableString, type: nullableString }).nullable(),
|
||||
creationDate: nullableString,
|
||||
updatedDate: nullableString,
|
||||
deletionDate: nullableString,
|
||||
effectiveDate: nullableString,
|
||||
url: nullableString,
|
||||
})
|
||||
|
||||
const vantaPersonSchema = z.object({
|
||||
id: nullableString,
|
||||
userId: nullableString,
|
||||
emailAddress: nullableString,
|
||||
name: z
|
||||
.object({ first: nullableString, last: nullableString, display: nullableString })
|
||||
.nullable(),
|
||||
employment: z
|
||||
.object({
|
||||
status: nullableString,
|
||||
startDate: nullableString,
|
||||
endDate: nullableString,
|
||||
jobTitle: nullableString,
|
||||
})
|
||||
.nullable(),
|
||||
leaveInfo: z
|
||||
.object({ status: nullableString, startDate: nullableString, endDate: nullableString })
|
||||
.nullable(),
|
||||
groupIds: z.array(z.string()),
|
||||
tasksSummary: z
|
||||
.object({
|
||||
status: nullableString,
|
||||
dueDate: nullableString,
|
||||
completionDate: nullableString,
|
||||
})
|
||||
.nullable(),
|
||||
})
|
||||
|
||||
const vantaPolicySchema = z.object({
|
||||
id: nullableString,
|
||||
name: nullableString,
|
||||
description: nullableString,
|
||||
status: nullableString,
|
||||
approvedAtDate: nullableString,
|
||||
latestVersionStatus: nullableString,
|
||||
latestApprovedVersion: z
|
||||
.object({
|
||||
versionId: nullableString,
|
||||
documents: z.array(
|
||||
z.object({ language: nullableString, slugId: nullableString, url: nullableString })
|
||||
),
|
||||
})
|
||||
.nullable(),
|
||||
})
|
||||
|
||||
const vantaVendorSchema = z.object({
|
||||
id: nullableString,
|
||||
name: nullableString,
|
||||
status: nullableString,
|
||||
websiteUrl: nullableString,
|
||||
category: nullableString,
|
||||
servicesProvided: nullableString,
|
||||
additionalNotes: nullableString,
|
||||
accountManagerName: nullableString,
|
||||
accountManagerEmail: nullableString,
|
||||
securityOwnerUserId: nullableString,
|
||||
businessOwnerUserId: nullableString,
|
||||
inherentRiskLevel: nullableString,
|
||||
residualRiskLevel: nullableString,
|
||||
isRiskAutoScored: nullableBoolean,
|
||||
isVisibleToAuditors: nullableBoolean,
|
||||
riskAttributeIds: z.array(z.string()),
|
||||
vendorHeadquarters: nullableString,
|
||||
contractStartDate: nullableString,
|
||||
contractRenewalDate: nullableString,
|
||||
contractTerminationDate: nullableString,
|
||||
contractAmount: z.object({ amount: nullableNumber, currency: nullableString }).nullable(),
|
||||
nextSecurityReviewDueDate: nullableString,
|
||||
lastSecurityReviewCompletionDate: nullableString,
|
||||
authDetails: z
|
||||
.object({
|
||||
method: nullableString,
|
||||
passwordMFA: nullableBoolean,
|
||||
passwordMinimumLength: nullableNumber,
|
||||
passwordRequiresNumber: nullableBoolean,
|
||||
passwordRequiresSymbol: nullableBoolean,
|
||||
})
|
||||
.nullable(),
|
||||
customFields: vantaCustomFieldsSchema,
|
||||
latestDecision: z.object({ status: nullableString, lastUpdatedAt: nullableString }).nullable(),
|
||||
linkedTaskTrackerTaskProcurementRequest: z
|
||||
.object({ url: nullableString, service: nullableString })
|
||||
.nullable(),
|
||||
})
|
||||
|
||||
const vantaMonitoredComputerSchema = z.object({
|
||||
id: nullableString,
|
||||
integrationId: nullableString,
|
||||
lastCheckDate: nullableString,
|
||||
screenlock: nullableString,
|
||||
diskEncryption: nullableString,
|
||||
passwordManager: nullableString,
|
||||
antivirusInstallation: nullableString,
|
||||
operatingSystem: z.object({ type: nullableString, version: nullableString }).nullable(),
|
||||
owner: vantaOwnerSchema,
|
||||
serialNumber: nullableString,
|
||||
udid: nullableString,
|
||||
})
|
||||
|
||||
const vantaVulnerabilitySchema = z.object({
|
||||
id: nullableString,
|
||||
name: nullableString,
|
||||
description: nullableString,
|
||||
severity: nullableString,
|
||||
vulnerabilityType: nullableString,
|
||||
integrationId: nullableString,
|
||||
targetId: nullableString,
|
||||
packageIdentifier: nullableString,
|
||||
cvssSeverityScore: nullableNumber,
|
||||
scannerScore: nullableNumber,
|
||||
isFixable: nullableBoolean,
|
||||
fixedVersion: nullableString,
|
||||
remediateByDate: nullableString,
|
||||
firstDetectedDate: nullableString,
|
||||
sourceDetectedDate: nullableString,
|
||||
lastDetectedDate: nullableString,
|
||||
scanSource: nullableString,
|
||||
externalURL: nullableString,
|
||||
relatedVulns: z.array(z.string()),
|
||||
relatedUrls: z.array(z.string()),
|
||||
deactivateMetadata: z
|
||||
.object({
|
||||
isVulnDeactivatedIndefinitely: nullableBoolean,
|
||||
deactivatedUntilDate: nullableString,
|
||||
deactivationReason: nullableString,
|
||||
deactivatedOnDate: nullableString,
|
||||
deactivatedBy: nullableString,
|
||||
})
|
||||
.nullable(),
|
||||
})
|
||||
|
||||
const vantaVulnerabilityRemediationSchema = z.object({
|
||||
id: nullableString,
|
||||
vulnerabilityId: nullableString,
|
||||
vulnerableAssetId: nullableString,
|
||||
severity: nullableString,
|
||||
detectedDate: nullableString,
|
||||
slaDeadlineDate: nullableString,
|
||||
remediationDate: nullableString,
|
||||
})
|
||||
|
||||
const vantaVulnerableAssetSchema = z.object({
|
||||
id: nullableString,
|
||||
name: nullableString,
|
||||
assetType: nullableString,
|
||||
hasBeenScanned: nullableBoolean,
|
||||
imageScanTag: nullableString,
|
||||
scanners: z.array(
|
||||
z.object({
|
||||
resourceId: nullableString,
|
||||
integrationId: nullableString,
|
||||
targetId: nullableString,
|
||||
imageDigest: nullableString,
|
||||
imagePushedAtDate: nullableString,
|
||||
imageTags: z.array(z.string()),
|
||||
assetTags: z.array(z.object({ key: nullableString, value: nullableString })),
|
||||
parentAccountOrOrganization: nullableString,
|
||||
biosUuid: nullableString,
|
||||
ipv4s: z.array(z.string()),
|
||||
ipv6s: z.array(z.string()),
|
||||
macAddresses: z.array(z.string()),
|
||||
hostnames: z.array(z.string()),
|
||||
fqdns: z.array(z.string()),
|
||||
operatingSystems: z.array(z.string()),
|
||||
})
|
||||
),
|
||||
})
|
||||
|
||||
const vantaRiskScenarioSchema = z.object({
|
||||
riskId: nullableString,
|
||||
description: nullableString,
|
||||
likelihood: nullableNumber,
|
||||
impact: nullableNumber,
|
||||
residualLikelihood: nullableNumber,
|
||||
residualImpact: nullableNumber,
|
||||
categories: z.array(z.string()),
|
||||
ciaCategories: z.array(z.string()),
|
||||
treatment: nullableString,
|
||||
owner: nullableString,
|
||||
note: nullableString,
|
||||
riskRegister: nullableString,
|
||||
customFields: vantaCustomFieldsSchema,
|
||||
isArchived: nullableBoolean,
|
||||
reviewStatus: nullableString,
|
||||
requiredApprovers: z.array(z.string()),
|
||||
type: nullableString,
|
||||
identificationDate: nullableString,
|
||||
})
|
||||
|
||||
const VANTA_REGIONS = ['us', 'gov'] as const
|
||||
|
||||
const vantaBaseBodySchema = z.object({
|
||||
clientId: z.string().min(1, 'Client ID is required'),
|
||||
clientSecret: z.string().min(1, 'Client secret is required'),
|
||||
region: z.enum(VANTA_REGIONS).optional(),
|
||||
})
|
||||
|
||||
const vantaPaginationBodySchema = z.object({
|
||||
pageSize: z
|
||||
.number()
|
||||
.int()
|
||||
.min(1, 'pageSize must be at least 1')
|
||||
.max(100, 'pageSize must be at most 100')
|
||||
.optional(),
|
||||
pageCursor: z.string().min(1, 'pageCursor cannot be empty').optional(),
|
||||
})
|
||||
|
||||
const vantaListBaseBodySchema = vantaBaseBodySchema.extend(vantaPaginationBodySchema.shape)
|
||||
|
||||
const requiredId = (label: string) => z.string().trim().min(1, `${label} is required`)
|
||||
|
||||
const listFrameworksSchema = vantaListBaseBodySchema.extend({
|
||||
operation: z.literal('vanta_list_frameworks'),
|
||||
})
|
||||
|
||||
const getFrameworkSchema = vantaBaseBodySchema.extend({
|
||||
operation: z.literal('vanta_get_framework'),
|
||||
frameworkId: requiredId('Framework ID'),
|
||||
})
|
||||
|
||||
const listFrameworkControlsSchema = vantaListBaseBodySchema.extend({
|
||||
operation: z.literal('vanta_list_framework_controls'),
|
||||
frameworkId: requiredId('Framework ID'),
|
||||
})
|
||||
|
||||
const listControlsSchema = vantaListBaseBodySchema.extend({
|
||||
operation: z.literal('vanta_list_controls'),
|
||||
frameworkMatchesAny: z.string().optional(),
|
||||
})
|
||||
|
||||
const getControlSchema = vantaBaseBodySchema.extend({
|
||||
operation: z.literal('vanta_get_control'),
|
||||
controlId: requiredId('Control ID'),
|
||||
})
|
||||
|
||||
const listControlTestsSchema = vantaListBaseBodySchema.extend({
|
||||
operation: z.literal('vanta_list_control_tests'),
|
||||
controlId: requiredId('Control ID'),
|
||||
})
|
||||
|
||||
const listControlDocumentsSchema = vantaListBaseBodySchema.extend({
|
||||
operation: z.literal('vanta_list_control_documents'),
|
||||
controlId: requiredId('Control ID'),
|
||||
})
|
||||
|
||||
const listTestsSchema = vantaListBaseBodySchema.extend({
|
||||
operation: z.literal('vanta_list_tests'),
|
||||
statusFilter: z
|
||||
.enum(['OK', 'DEACTIVATED', 'NEEDS_ATTENTION', 'IN_PROGRESS', 'INVALID', 'NOT_APPLICABLE'])
|
||||
.optional(),
|
||||
frameworkFilter: z.string().optional(),
|
||||
integrationFilter: z.string().optional(),
|
||||
controlFilter: z.string().optional(),
|
||||
ownerFilter: z.string().optional(),
|
||||
categoryFilter: z
|
||||
.enum([
|
||||
'ACCOUNTS_ACCESS',
|
||||
'ACCOUNT_SECURITY',
|
||||
'ACCOUNT_SETUP',
|
||||
'COMPUTERS',
|
||||
'CUSTOM',
|
||||
'DATA_STORAGE',
|
||||
'EMPLOYEES',
|
||||
'INFRASTRUCTURE',
|
||||
'IT',
|
||||
'LOGGING',
|
||||
'MONITORING_ALERTS',
|
||||
'PEOPLE',
|
||||
'POLICIES',
|
||||
'RISK_ANALYSIS',
|
||||
'SECURITY_ALERT_MANAGEMENT',
|
||||
'SOFTWARE_DEVELOPMENT',
|
||||
'VENDORS',
|
||||
'VULNERABILITY_MANAGEMENT',
|
||||
])
|
||||
.optional(),
|
||||
isInRollout: z.boolean().optional(),
|
||||
})
|
||||
|
||||
const getTestSchema = vantaBaseBodySchema.extend({
|
||||
operation: z.literal('vanta_get_test'),
|
||||
testId: requiredId('Test ID'),
|
||||
})
|
||||
|
||||
const listTestEntitiesSchema = vantaListBaseBodySchema.extend({
|
||||
operation: z.literal('vanta_list_test_entities'),
|
||||
testId: requiredId('Test ID'),
|
||||
entityStatus: z.enum(['FAILING', 'DEACTIVATED']).optional(),
|
||||
})
|
||||
|
||||
const listDocumentsSchema = vantaListBaseBodySchema.extend({
|
||||
operation: z.literal('vanta_list_documents'),
|
||||
frameworkMatchesAny: z.string().optional(),
|
||||
statusMatchesAny: z.string().optional(),
|
||||
})
|
||||
|
||||
const getDocumentSchema = vantaBaseBodySchema.extend({
|
||||
operation: z.literal('vanta_get_document'),
|
||||
documentId: requiredId('Document ID'),
|
||||
})
|
||||
|
||||
const listDocumentUploadsSchema = vantaListBaseBodySchema.extend({
|
||||
operation: z.literal('vanta_list_document_uploads'),
|
||||
documentId: requiredId('Document ID'),
|
||||
})
|
||||
|
||||
const submitDocumentSchema = vantaBaseBodySchema.extend({
|
||||
operation: z.literal('vanta_submit_document'),
|
||||
documentId: requiredId('Document ID'),
|
||||
})
|
||||
|
||||
const listPeopleSchema = vantaListBaseBodySchema.extend({
|
||||
operation: z.literal('vanta_list_people'),
|
||||
emailAndNameFilter: z.string().optional(),
|
||||
employmentStatus: z.enum(['UPCOMING', 'CURRENT', 'ON_LEAVE', 'INACTIVE', 'FORMER']).optional(),
|
||||
groupIdsMatchesAny: z.string().optional(),
|
||||
tasksSummaryStatusMatchesAny: z.string().optional(),
|
||||
taskTypeMatchesAny: z.string().optional(),
|
||||
taskStatusMatchesAny: z.string().optional(),
|
||||
})
|
||||
|
||||
const getPersonSchema = vantaBaseBodySchema.extend({
|
||||
operation: z.literal('vanta_get_person'),
|
||||
personId: requiredId('Person ID'),
|
||||
})
|
||||
|
||||
const listPoliciesSchema = vantaListBaseBodySchema.extend({
|
||||
operation: z.literal('vanta_list_policies'),
|
||||
})
|
||||
|
||||
const getPolicySchema = vantaBaseBodySchema.extend({
|
||||
operation: z.literal('vanta_get_policy'),
|
||||
policyId: requiredId('Policy ID'),
|
||||
})
|
||||
|
||||
const listVendorsSchema = vantaListBaseBodySchema.extend({
|
||||
operation: z.literal('vanta_list_vendors'),
|
||||
name: z.string().optional(),
|
||||
statusMatchesAny: z.string().optional(),
|
||||
})
|
||||
|
||||
const getVendorSchema = vantaBaseBodySchema.extend({
|
||||
operation: z.literal('vanta_get_vendor'),
|
||||
vendorId: requiredId('Vendor ID'),
|
||||
})
|
||||
|
||||
const listMonitoredComputersSchema = vantaListBaseBodySchema.extend({
|
||||
operation: z.literal('vanta_list_monitored_computers'),
|
||||
complianceStatusFilterMatchesAny: z.string().optional(),
|
||||
})
|
||||
|
||||
const listVulnerabilitiesSchema = vantaListBaseBodySchema.extend({
|
||||
operation: z.literal('vanta_list_vulnerabilities'),
|
||||
q: z.string().optional(),
|
||||
severity: z.enum(['LOW', 'MEDIUM', 'HIGH', 'CRITICAL']).optional(),
|
||||
isFixAvailable: z.boolean().optional(),
|
||||
isDeactivated: z.boolean().optional(),
|
||||
includeVulnerabilitiesWithoutSlas: z.boolean().optional(),
|
||||
packageIdentifier: z.string().optional(),
|
||||
externalVulnerabilityId: z.string().optional(),
|
||||
integrationId: z.string().optional(),
|
||||
vulnerableAssetId: z.string().optional(),
|
||||
slaDeadlineAfterDate: z.string().optional(),
|
||||
slaDeadlineBeforeDate: z.string().optional(),
|
||||
})
|
||||
|
||||
const listVulnerabilityRemediationsSchema = vantaListBaseBodySchema.extend({
|
||||
operation: z.literal('vanta_list_vulnerability_remediations'),
|
||||
integrationId: z.string().optional(),
|
||||
severity: z.enum(['LOW', 'MEDIUM', 'HIGH', 'CRITICAL']).optional(),
|
||||
isRemediatedOnTime: z.boolean().optional(),
|
||||
remediatedAfterDate: z.string().optional(),
|
||||
remediatedBeforeDate: z.string().optional(),
|
||||
})
|
||||
|
||||
const listVulnerableAssetsSchema = vantaListBaseBodySchema.extend({
|
||||
operation: z.literal('vanta_list_vulnerable_assets'),
|
||||
q: z.string().optional(),
|
||||
integrationId: z.string().optional(),
|
||||
assetType: z
|
||||
.enum([
|
||||
'SERVER',
|
||||
'SERVERLESS_FUNCTION',
|
||||
'CONTAINER',
|
||||
'CONTAINER_REPOSITORY',
|
||||
'CONTAINER_REPOSITORY_IMAGE',
|
||||
'CODE_REPOSITORY',
|
||||
'MANIFEST_FILE',
|
||||
'WORKSTATION',
|
||||
'OTHER',
|
||||
])
|
||||
.optional(),
|
||||
assetExternalAccountId: z.string().optional(),
|
||||
})
|
||||
|
||||
const getVulnerableAssetSchema = vantaBaseBodySchema.extend({
|
||||
operation: z.literal('vanta_get_vulnerable_asset'),
|
||||
vulnerableAssetId: requiredId('Vulnerable asset ID'),
|
||||
})
|
||||
|
||||
const listRiskScenariosSchema = vantaListBaseBodySchema.extend({
|
||||
operation: z.literal('vanta_list_risk_scenarios'),
|
||||
searchString: z.string().optional(),
|
||||
includeIgnored: z.boolean().optional(),
|
||||
type: z.enum(['Risk Scenario', 'Enterprise Risk']).optional(),
|
||||
ownerMatchesAny: z.string().optional(),
|
||||
categoryMatchesAny: z.string().optional(),
|
||||
ciaCategoryMatchesAny: z.string().optional(),
|
||||
treatmentTypeMatchesAny: z.string().optional(),
|
||||
inherentScoreGroupMatchesAny: z.string().optional(),
|
||||
residualScoreGroupMatchesAny: z.string().optional(),
|
||||
reviewStatusMatchesAny: z.string().optional(),
|
||||
orderBy: z.enum(['description', 'createdAt']).optional(),
|
||||
})
|
||||
|
||||
const getRiskScenarioSchema = vantaBaseBodySchema.extend({
|
||||
operation: z.literal('vanta_get_risk_scenario'),
|
||||
riskScenarioId: requiredId('Risk scenario ID'),
|
||||
})
|
||||
|
||||
export const vantaQueryBodySchema = z.discriminatedUnion('operation', [
|
||||
listFrameworksSchema,
|
||||
getFrameworkSchema,
|
||||
listFrameworkControlsSchema,
|
||||
listControlsSchema,
|
||||
getControlSchema,
|
||||
listControlTestsSchema,
|
||||
listControlDocumentsSchema,
|
||||
listTestsSchema,
|
||||
getTestSchema,
|
||||
listTestEntitiesSchema,
|
||||
listDocumentsSchema,
|
||||
getDocumentSchema,
|
||||
listDocumentUploadsSchema,
|
||||
submitDocumentSchema,
|
||||
listPeopleSchema,
|
||||
getPersonSchema,
|
||||
listPoliciesSchema,
|
||||
getPolicySchema,
|
||||
listVendorsSchema,
|
||||
getVendorSchema,
|
||||
listMonitoredComputersSchema,
|
||||
listVulnerabilitiesSchema,
|
||||
listVulnerabilityRemediationsSchema,
|
||||
listVulnerableAssetsSchema,
|
||||
getVulnerableAssetSchema,
|
||||
listRiskScenariosSchema,
|
||||
getRiskScenarioSchema,
|
||||
])
|
||||
|
||||
const vantaQueryOutputSchema = z.union([
|
||||
z.object({ frameworks: z.array(vantaFrameworkSchema), pageInfo: vantaPageInfoSchema }),
|
||||
z.object({ framework: vantaFrameworkDetailSchema }),
|
||||
z.object({ controls: z.array(vantaControlSchema), pageInfo: vantaPageInfoSchema }),
|
||||
z.object({ control: vantaControlDetailSchema }),
|
||||
z.object({ tests: z.array(vantaTestSchema), pageInfo: vantaPageInfoSchema }),
|
||||
z.object({ test: vantaTestSchema }),
|
||||
z.object({ entities: z.array(vantaTestEntitySchema), pageInfo: vantaPageInfoSchema }),
|
||||
z.object({ documents: z.array(vantaDocumentSchema), pageInfo: vantaPageInfoSchema }),
|
||||
z.object({ document: vantaDocumentDetailSchema }),
|
||||
z.object({ uploads: z.array(vantaUploadedFileSchema), pageInfo: vantaPageInfoSchema }),
|
||||
z.object({ documentId: z.string(), submitted: z.boolean() }),
|
||||
z.object({ people: z.array(vantaPersonSchema), pageInfo: vantaPageInfoSchema }),
|
||||
z.object({ person: vantaPersonSchema }),
|
||||
z.object({ policies: z.array(vantaPolicySchema), pageInfo: vantaPageInfoSchema }),
|
||||
z.object({ policy: vantaPolicySchema }),
|
||||
z.object({ vendors: z.array(vantaVendorSchema), pageInfo: vantaPageInfoSchema }),
|
||||
z.object({ vendor: vantaVendorSchema }),
|
||||
z.object({ computers: z.array(vantaMonitoredComputerSchema), pageInfo: vantaPageInfoSchema }),
|
||||
z.object({
|
||||
vulnerabilities: z.array(vantaVulnerabilitySchema),
|
||||
pageInfo: vantaPageInfoSchema,
|
||||
}),
|
||||
z.object({
|
||||
remediations: z.array(vantaVulnerabilityRemediationSchema),
|
||||
pageInfo: vantaPageInfoSchema,
|
||||
}),
|
||||
z.object({ assets: z.array(vantaVulnerableAssetSchema), pageInfo: vantaPageInfoSchema }),
|
||||
z.object({ asset: vantaVulnerableAssetSchema }),
|
||||
z.object({ riskScenarios: z.array(vantaRiskScenarioSchema), pageInfo: vantaPageInfoSchema }),
|
||||
z.object({ riskScenario: vantaRiskScenarioSchema }),
|
||||
])
|
||||
|
||||
const vantaQueryResponseSchema = z.object({
|
||||
success: z.literal(true),
|
||||
output: vantaQueryOutputSchema,
|
||||
})
|
||||
|
||||
export const vantaQueryContract = defineRouteContract({
|
||||
method: 'POST',
|
||||
path: '/api/tools/vanta/query',
|
||||
body: vantaQueryBodySchema,
|
||||
response: { mode: 'json', schema: vantaQueryResponseSchema },
|
||||
})
|
||||
|
||||
const VANTA_MAX_UPLOAD_BYTES = 100 * 1024 * 1024
|
||||
/** Base64 length of the largest allowed upload (4 chars per 3 bytes). */
|
||||
const VANTA_MAX_UPLOAD_BASE64_LENGTH = Math.ceil(VANTA_MAX_UPLOAD_BYTES / 3) * 4
|
||||
|
||||
export const vantaUploadBodySchema = vantaBaseBodySchema.extend({
|
||||
documentId: requiredId('Document ID'),
|
||||
file: FileInputSchema.optional().nullable(),
|
||||
fileContent: z
|
||||
.string()
|
||||
.max(VANTA_MAX_UPLOAD_BASE64_LENGTH, 'fileContent exceeds the 100MB upload limit')
|
||||
.nullish(),
|
||||
fileName: z.string().nullish(),
|
||||
mimeType: z.string().nullish(),
|
||||
description: z.string().nullish(),
|
||||
effectiveAtDate: z.string().nullish(),
|
||||
})
|
||||
|
||||
const vantaUploadResponseSchema = z.object({
|
||||
success: z.literal(true),
|
||||
output: z.object({ upload: vantaUploadedFileSchema }),
|
||||
})
|
||||
|
||||
export const vantaUploadContract = defineRouteContract({
|
||||
method: 'POST',
|
||||
path: '/api/tools/vanta/upload',
|
||||
body: vantaUploadBodySchema,
|
||||
response: { mode: 'json', schema: vantaUploadResponseSchema },
|
||||
})
|
||||
|
||||
export const vantaDownloadBodySchema = vantaBaseBodySchema.extend({
|
||||
documentId: requiredId('Document ID'),
|
||||
uploadedFileId: requiredId('Uploaded file ID'),
|
||||
})
|
||||
|
||||
const vantaDownloadResponseSchema = z.object({
|
||||
success: z.literal(true),
|
||||
output: z.object({
|
||||
file: z.object({
|
||||
name: z.string(),
|
||||
mimeType: z.string(),
|
||||
data: z.string(),
|
||||
size: z.number(),
|
||||
}),
|
||||
name: z.string(),
|
||||
mimeType: z.string(),
|
||||
size: z.number(),
|
||||
}),
|
||||
})
|
||||
|
||||
export const vantaDownloadContract = defineRouteContract({
|
||||
method: 'POST',
|
||||
path: '/api/tools/vanta/download',
|
||||
body: vantaDownloadBodySchema,
|
||||
response: { mode: 'json', schema: vantaDownloadResponseSchema },
|
||||
})
|
||||
|
||||
export type VantaQueryBody = ContractBody<typeof vantaQueryContract>
|
||||
export type VantaQueryBodyInput = ContractBodyInput<typeof vantaQueryContract>
|
||||
export type VantaQueryResponse = ContractJsonResponse<typeof vantaQueryContract>
|
||||
export type VantaUploadBody = ContractBody<typeof vantaUploadContract>
|
||||
export type VantaUploadBodyInput = ContractBodyInput<typeof vantaUploadContract>
|
||||
export type VantaUploadResponse = ContractJsonResponse<typeof vantaUploadContract>
|
||||
export type VantaDownloadBody = ContractBody<typeof vantaDownloadContract>
|
||||
export type VantaDownloadBodyInput = ContractBodyInput<typeof vantaDownloadContract>
|
||||
export type VantaDownloadResponse = ContractJsonResponse<typeof vantaDownloadContract>
|
||||
Reference in New Issue
Block a user