vault/ui/app/forms/sync/resolver.ts
Vault Automation 31fb778a51
[UI] VAULT-42756 - Secret sync WIF implementation (#14001) (#14167)
* VAULT-42427 - initial code updates for aws form

* VAULT-42756 - implemented wif support for secret sync

* VAULT-42756 - added acceptance and integration test cases for WIF support

* refactor: streamline WIF credential handling and enhance destination details management

* added changelog

* fixed review comments

* updated changelog

* fixed failing tests

* fixed review comments

* fixed validation for Edit scenario

* fixed region field to have no default value selected

* Refactor: updated string literals with centralized enums and some other refactors

Co-authored-by: mohit-hashicorp <mohit.ojha@hashicorp.com>
2026-04-22 12:46:13 +05:30

137 lines
4.3 KiB
TypeScript

/**
* Copyright IBM Corp. 2016, 2025
* SPDX-License-Identifier: BUSL-1.1
*/
import AwsSmForm from './aws-sm';
import AzureKvForm from './azure-kv';
import GcpSmForm from './gcp-sm';
import GhForm from './gh';
import VercelProjectForm from './vercel-project';
import { DestinationType, CredentialType } from 'sync/utils/constants';
import type { DestinationConnectionDetails } from 'vault/sync';
import type { FormOptions } from '../form';
import type { Validations } from 'vault/app-types';
// given the differences in form fields across destination types, each type has a specific form class
// to make it easier in routes, this resolver will instantiate a new instance of the correct form class for a given type
export default function destinationFormResolver(type: DestinationType, data = {}, options?: FormOptions) {
const validations: Validations = {
name: [
{ type: 'presence', message: 'Name is required.' },
{ type: 'containsWhiteSpace', message: 'Name cannot contain whitespace.' },
],
role_arn: [
{
validator({ role_arn, credential_type }: DestinationConnectionDetails) {
if (type === DestinationType.AwsSm && credential_type === CredentialType.WIF) {
return !!role_arn;
}
return true;
},
message: 'Role ARN is required.',
},
],
identity_token_audience: [
{
validator({ identity_token_audience, credential_type }: DestinationConnectionDetails) {
if (credential_type === CredentialType.WIF) {
return !!identity_token_audience;
}
return true;
},
message: 'Identity token audience is required.',
},
],
key_vault_uri: [
{
validator({ key_vault_uri }: DestinationConnectionDetails) {
if (type === DestinationType.AzureKv) {
return !!key_vault_uri;
}
return true;
},
message: 'Key Vault URI is required.',
},
],
tenant_id: [
{
validator({ tenant_id }: DestinationConnectionDetails) {
if (type === DestinationType.AzureKv) {
return !!tenant_id;
}
return true;
},
message: 'Tenant ID is required.',
},
],
client_id: [
{
validator({ client_id }: DestinationConnectionDetails) {
if (type === DestinationType.AzureKv) {
return !!client_id;
}
return true;
},
message: 'Client ID is required.',
},
],
project_id: [
{
validator({ project_id, credential_type }: DestinationConnectionDetails) {
if (type === DestinationType.GcpSm && credential_type === CredentialType.WIF) {
return !!project_id;
}
return true;
},
message: 'Project ID is required.',
},
],
service_account_email: [
{
validator({ service_account_email, credential_type }: DestinationConnectionDetails) {
if (type === DestinationType.GcpSm && credential_type === CredentialType.WIF) {
return !!service_account_email;
}
return true;
},
message: 'Service account email is required.',
},
],
};
if (type === DestinationType.AwsSm) {
return new AwsSmForm(data, options, validations);
}
if (type === DestinationType.AzureKv) {
return new AzureKvForm(data, options, validations);
}
if (type === DestinationType.GcpSm) {
return new GcpSmForm(data, options, validations);
}
if (type === DestinationType.Gh) {
return new GhForm(data, options, validations);
}
if (type === DestinationType.VercelProject) {
const teamId = (data as VercelProjectForm['data'])['team_id'];
validations['team_id'] = [
{
validator: (formData: VercelProjectForm['data']) => {
if (!options?.isNew && formData['team_id'] !== teamId) {
return false;
}
return true;
},
message: 'Team ID should only be updated if the project was transferred to another account.',
level: 'warn',
},
];
validations['deployment_environments'] = [
{ type: 'presence', message: 'At least one environment is required.' },
];
return new VercelProjectForm(data, options, validations);
}
throw new Error(`Unknown destination type: ${type}`);
}