consolidate credential parameters into unified entry point with guided type/source flow & tooltips (#4497)

This commit is contained in:
Celal Zamanoglu
2026-01-20 17:32:41 +03:00
committed by GitHub
parent 62ab3d4b87
commit 9ffa03c16a
2 changed files with 453 additions and 259 deletions

View File

@@ -50,6 +50,36 @@ const workflowParameterTypeOptions = [
{ label: "JSON", value: WorkflowParameterValueType.JSON }, { label: "JSON", value: WorkflowParameterValueType.JSON },
]; ];
type CredentialDataType = "password" | "secret" | "creditCard";
type CredentialSource = "bitwarden" | "skyvern" | "onepassword" | "azurevault";
// Determine available sources based on credential data type
function getAvailableSourcesForDataType(
dataType: CredentialDataType,
isCloud: boolean,
): Array<{ value: CredentialSource; label: string }> {
switch (dataType) {
case "password":
return [
...(isCloud ? [{ value: "skyvern" as const, label: "Skyvern" }] : []),
{ value: "bitwarden" as const, label: "Bitwarden" },
{ value: "onepassword" as const, label: "1Password" },
{ value: "azurevault" as const, label: "Azure Key Vault" },
];
case "secret":
return [
...(isCloud ? [{ value: "skyvern" as const, label: "Skyvern" }] : []),
{ value: "bitwarden" as const, label: "Bitwarden" },
];
case "creditCard":
return [
...(isCloud ? [{ value: "skyvern" as const, label: "Skyvern" }] : []),
{ value: "bitwarden" as const, label: "Bitwarden" },
{ value: "onepassword" as const, label: "1Password" },
];
}
}
function header(type: WorkflowEditorParameterType, isEdit: boolean) { function header(type: WorkflowEditorParameterType, isEdit: boolean) {
const prefix = isEdit ? "Edit" : "Add"; const prefix = isEdit ? "Edit" : "Add";
if (type === "workflow") { if (type === "workflow") {
@@ -58,15 +88,38 @@ function header(type: WorkflowEditorParameterType, isEdit: boolean) {
if (type === "credential") { if (type === "credential") {
return `${prefix} Credential Parameter`; return `${prefix} Credential Parameter`;
} }
if (type === "secret") {
return `${prefix} Secret Parameter`;
}
if (type === "creditCardData") {
return `${prefix} Credit Card Parameter`;
}
return `${prefix} Context Parameter`; return `${prefix} Context Parameter`;
} }
// Helper to detect initial credential data type from existing parameter
function detectInitialCredentialDataType(
initialValues: ParametersState[number] | undefined,
): CredentialDataType {
if (!initialValues) return "password";
if (initialValues.parameterType === "secret") return "secret";
if (initialValues.parameterType === "creditCardData") return "creditCard";
return "password";
}
// Helper to detect initial credential source from existing parameter
function detectInitialCredentialSource(
initialValues: ParametersState[number] | undefined,
): CredentialSource {
if (!initialValues) return "bitwarden";
if (initialValues.parameterType === "secret") return "bitwarden";
if (initialValues.parameterType === "creditCardData") return "bitwarden";
if (initialValues.parameterType === "onepassword") return "onepassword";
if (initialValues.parameterType === "credential") {
if (parameterIsSkyvernCredential(initialValues)) return "skyvern";
if (parameterIsBitwardenCredential(initialValues)) return "bitwarden";
if (parameterIsAzureVaultCredential(initialValues)) return "azurevault";
}
return "bitwarden";
}
function WorkflowParameterEditPanel({ function WorkflowParameterEditPanel({
type, type,
onClose, onClose,
@@ -83,6 +136,8 @@ function WorkflowParameterEditPanel({
const isEditMode = !!initialValues; const isEditMode = !!initialValues;
const [key, setKey] = useState(initialValues?.key ?? ""); const [key, setKey] = useState(initialValues?.key ?? "");
const hasWhitespace = /\s/.test(key); const hasWhitespace = /\s/.test(key);
// Detect initial values for backward compatibility
const isBitwardenCredential = const isBitwardenCredential =
initialValues?.parameterType === "credential" && initialValues?.parameterType === "credential" &&
parameterIsBitwardenCredential(initialValues); parameterIsBitwardenCredential(initialValues);
@@ -95,17 +150,16 @@ function WorkflowParameterEditPanel({
const isAzureVaultCredential = const isAzureVaultCredential =
initialValues?.parameterType === "credential" && initialValues?.parameterType === "credential" &&
parameterIsAzureVaultCredential(initialValues); parameterIsAzureVaultCredential(initialValues);
const [credentialType, setCredentialType] = useState<
"bitwarden" | "skyvern" | "onepassword" | "azurevault" // New unified credential state
>( const [credentialDataType, setCredentialDataType] =
isBitwardenCredential useState<CredentialDataType>(
? "bitwarden" detectInitialCredentialDataType(initialValues),
: isOnePasswordCredential );
? "onepassword" const [credentialSource, setCredentialSource] = useState<CredentialSource>(
: isAzureVaultCredential detectInitialCredentialSource(initialValues),
? "azurevault"
: "skyvern",
); );
const [urlParameterKey, setUrlParameterKey] = useState( const [urlParameterKey, setUrlParameterKey] = useState(
isBitwardenCredential ? initialValues?.urlParameterKey ?? "" : "", isBitwardenCredential ? initialValues?.urlParameterKey ?? "" : "",
); );
@@ -191,6 +245,43 @@ function WorkflowParameterEditPanel({
isAzureVaultCredential ? initialValues.totpSecretKey ?? "" : "", isAzureVaultCredential ? initialValues.totpSecretKey ?? "" : "",
); );
// Handle credential data type change - reset source to first available
const handleCredentialDataTypeChange = (newDataType: CredentialDataType) => {
setCredentialDataType(newDataType);
const availableSources = getAvailableSourcesForDataType(
newDataType,
isCloud,
);
if (!availableSources.find((s) => s.value === credentialSource)) {
setCredentialSource(availableSources[0]?.value ?? "bitwarden");
}
};
const availableSources = getAvailableSourcesForDataType(
credentialDataType,
isCloud,
);
// Determine what fields to show based on credential data type and source
const showBitwardenPasswordFields =
type === "credential" &&
credentialDataType === "password" &&
credentialSource === "bitwarden";
const showBitwardenSecretFields =
type === "credential" &&
credentialDataType === "secret" &&
credentialSource === "bitwarden";
const showBitwardenCreditCardFields =
type === "credential" &&
credentialDataType === "creditCard" &&
credentialSource === "bitwarden";
const showOnePasswordFields =
type === "credential" && credentialSource === "onepassword";
const showAzureVaultFields =
type === "credential" && credentialSource === "azurevault";
const showSkyvernCredentialSelector =
type === "credential" && credentialSource === "skyvern" && isCloud;
return ( return (
<ScrollArea> <ScrollArea>
<ScrollAreaViewport className="max-h-[500px]"> <ScrollAreaViewport className="max-h-[500px]">
@@ -301,40 +392,68 @@ function WorkflowParameterEditPanel({
</div> </div>
</> </>
)} )}
{/* Credential Parameter - Unified Flow */}
{type === "credential" && ( {type === "credential" && (
<> <>
{/* Step 1: Credential Type */}
<div className="space-y-1"> <div className="space-y-1">
<Label className="text-xs text-slate-300"> <div className="flex gap-2">
Credential Type <Label className="text-xs text-slate-300">
</Label> Credential Type
</Label>
<HelpTooltip content="Select the type of credential you want to use. Password for login credentials, Secret for sensitive data fields, Credit Card for payment information." />
</div>
<Select <Select
value={credentialType} value={credentialDataType}
onValueChange={(value) => { onValueChange={(value) =>
setCredentialType( handleCredentialDataTypeChange(value as CredentialDataType)
value as }
| "bitwarden"
| "skyvern"
| "onepassword"
| "azurevault",
);
}}
> >
<SelectTrigger className="w-full"> <SelectTrigger className="w-full">
<SelectValue placeholder="Select a type" /> <SelectValue placeholder="Select credential type" />
</SelectTrigger> </SelectTrigger>
<SelectContent> <SelectContent>
<SelectGroup> <SelectGroup>
<SelectItem value="skyvern">Skyvern</SelectItem> <SelectItem value="password">Password</SelectItem>
<SelectItem value="bitwarden">Bitwarden</SelectItem> <SelectItem value="secret">Secret</SelectItem>
<SelectItem value="onepassword">1Password</SelectItem> <SelectItem value="creditCard">Credit Card</SelectItem>
<SelectItem value="azurevault">Azure Vault</SelectItem> </SelectGroup>
</SelectContent>
</Select>
</div>
{/* Step 2: Source */}
<div className="space-y-1">
<div className="flex gap-2">
<Label className="text-xs text-slate-300">Source</Label>
<HelpTooltip content="Select where your credentials are stored. Skyvern uses managed credentials, while Bitwarden, 1Password, and Azure Key Vault connect directly to your vault." />
</div>
<Select
value={credentialSource}
onValueChange={(value) =>
setCredentialSource(value as CredentialSource)
}
>
<SelectTrigger className="w-full">
<SelectValue placeholder="Select source" />
</SelectTrigger>
<SelectContent>
<SelectGroup>
{availableSources.map((source) => (
<SelectItem key={source.value} value={source.value}>
{source.label}
</SelectItem>
))}
</SelectGroup> </SelectGroup>
</SelectContent> </SelectContent>
</Select> </Select>
</div> </div>
</> </>
)} )}
{type === "credential" && credentialType === "bitwarden" && (
{/* Bitwarden Password Fields */}
{showBitwardenPasswordFields && (
<> <>
<div className="space-y-1"> <div className="space-y-1">
<div className="flex gap-2"> <div className="flex gap-2">
@@ -351,9 +470,9 @@ function WorkflowParameterEditPanel({
<div className="space-y-1"> <div className="space-y-1">
<div className="flex gap-2"> <div className="flex gap-2">
<Label className="text-xs text-slate-300"> <Label className="text-xs text-slate-300">
Collection ID Bitwarden Collection ID
</Label> </Label>
<HelpTooltip content="The Bitwarden collection ID. You can find this in the URL when viewing a collection in Bitwarden." /> <HelpTooltip content="The Bitwarden collection ID. You can find this in the URL when viewing a collection in Bitwarden (e.g., https://vault.bitwarden.com/#/organizations/.../collections/[COLLECTION_ID])." />
</div> </div>
<Input <Input
value={bitwardenCollectionId} value={bitwardenCollectionId}
@@ -362,8 +481,10 @@ function WorkflowParameterEditPanel({
</div> </div>
<div className="space-y-1"> <div className="space-y-1">
<div className="flex gap-2"> <div className="flex gap-2">
<Label className="text-xs text-slate-300">Item ID</Label> <Label className="text-xs text-slate-300">
<HelpTooltip content="The Bitwarden item ID. You can find this in the URL when viewing the item in Bitwarden." /> Bitwarden Item ID
</Label>
<HelpTooltip content="The Bitwarden item ID. You can find this in the URL when viewing the item in Bitwarden (e.g., https://vault.bitwarden.com/#/vault?itemId=[ITEM_ID])." />
</div> </div>
<Input <Input
value={bitwardenLoginCredentialItemId} value={bitwardenLoginCredentialItemId}
@@ -374,12 +495,89 @@ function WorkflowParameterEditPanel({
</div> </div>
</> </>
)} )}
{type === "credential" && credentialType === "onepassword" && (
{/* Bitwarden Secret Fields */}
{showBitwardenSecretFields && (
<> <>
<div className="space-y-1"> <div className="space-y-1">
<div className="flex gap-2"> <div className="flex gap-2">
<Label className="text-xs text-slate-300">Vault ID</Label> <Label className="text-xs text-slate-300">
<HelpTooltip content="You can find the Vault ID and Item ID in the URL when viewing the item in 1Password on the web." /> Bitwarden Collection ID
</Label>
<HelpTooltip content="Required. The Bitwarden collection ID containing the identity item. You can find this in the URL when viewing a collection in Bitwarden." />
</div>
<Input
value={bitwardenCollectionId}
onChange={(e) => setBitwardenCollectionId(e.target.value)}
/>
</div>
<div className="space-y-1">
<div className="flex gap-2">
<Label className="text-xs text-slate-300">Identity Key</Label>
<HelpTooltip content="The key used to identify which identity to use from Bitwarden (e.g., the identity name or a custom identifier)." />
</div>
<Input
value={identityKey}
onChange={(e) => setIdentityKey(e.target.value)}
/>
</div>
<div className="space-y-1">
<div className="flex gap-2">
<Label className="text-xs text-slate-300">
Identity Fields
</Label>
<HelpTooltip content="Comma-separated list of field names to extract from the Bitwarden identity (e.g., 'ssn, address, phone')." />
</div>
<Input
value={identityFields}
onChange={(e) => setIdentityFields(e.target.value)}
placeholder="field1, field2, field3"
/>
</div>
</>
)}
{/* Bitwarden Credit Card Fields */}
{showBitwardenCreditCardFields && (
<>
<div className="space-y-1">
<div className="flex gap-2">
<Label className="text-xs text-slate-300">
Bitwarden Collection ID
</Label>
<HelpTooltip content="Required. The Bitwarden collection ID containing the credit card. You can find this in the URL when viewing a collection in Bitwarden." />
</div>
<Input
value={bitwardenCollectionId}
onChange={(e) => setBitwardenCollectionId(e.target.value)}
/>
</div>
<div className="space-y-1">
<div className="flex gap-2">
<Label className="text-xs text-slate-300">
Bitwarden Item ID
</Label>
<HelpTooltip content="Required. The Bitwarden item ID of the credit card. You can find this in the URL when viewing the item in Bitwarden." />
</div>
<Input
value={sensitiveInformationItemId}
onChange={(e) =>
setSensitiveInformationItemId(e.target.value)
}
/>
</div>
</>
)}
{/* 1Password Fields */}
{showOnePasswordFields && (
<>
<div className="space-y-1">
<div className="flex gap-2">
<Label className="text-xs text-slate-300">
1Password Vault ID
</Label>
<HelpTooltip content="You can find the Vault ID in the URL when viewing the vault in 1Password on the web (e.g., https://my.1password.com/vaults/[VAULT_ID])." />
</div> </div>
<Input <Input
value={opVaultId} value={opVaultId}
@@ -388,29 +586,37 @@ function WorkflowParameterEditPanel({
</div> </div>
<div className="space-y-1"> <div className="space-y-1">
<div className="flex gap-2"> <div className="flex gap-2">
<Label className="text-xs text-slate-300">Item ID</Label> <Label className="text-xs text-slate-300">
<HelpTooltip content="Supports all 1Password item types: Logins, Passwords, Credit Cards, Secure Notes, and more." /> 1Password Item ID
</Label>
<HelpTooltip content="You can find the Item ID in the URL when viewing the item in 1Password on the web. Supports all item types: Logins, Passwords, Credit Cards, Secure Notes, and more." />
</div> </div>
<Input <Input
value={opItemId} value={opItemId}
onChange={(e) => setOpItemId(e.target.value)} onChange={(e) => setOpItemId(e.target.value)}
/> />
</div> </div>
<div className="rounded-md bg-slate-800 p-2"> {credentialDataType === "creditCard" && (
<div className="space-y-1 text-xs text-slate-400"> <div className="rounded-md bg-slate-800 p-2">
Credit Cards: Due to a 1Password limitation, add the <div className="space-y-1 text-xs text-slate-400">
expiration date as a separate text field named Expire Date Credit Cards: Due to a 1Password limitation, add the
in the format MM/YYYY (e.g. 09/2027). expiration date as a separate text field named "Expire Date"
in the format MM/YYYY (e.g. 09/2027).
</div>
</div> </div>
</div> )}
</> </>
)} )}
{type === "credential" && credentialType === "azurevault" && (
{/* Azure Key Vault Fields */}
{showAzureVaultFields && (
<> <>
<div className="space-y-1"> <div className="space-y-1">
<div className="flex gap-2"> <div className="flex gap-2">
<Label className="text-xs text-slate-300">Vault Name</Label> <Label className="text-xs text-slate-300">
<HelpTooltip content="The name of your Azure Key Vault instance." /> Azure Key Vault Name
</Label>
<HelpTooltip content="The name of your Azure Key Vault instance (e.g., 'my-company-vault'). This is the name you see in the Azure portal." />
</div> </div>
<Input <Input
value={azureVaultName} value={azureVaultName}
@@ -419,8 +625,10 @@ function WorkflowParameterEditPanel({
</div> </div>
<div className="space-y-1"> <div className="space-y-1">
<div className="flex gap-2"> <div className="flex gap-2">
<Label className="text-xs text-slate-300">Username Key</Label> <Label className="text-xs text-slate-300">
<HelpTooltip content="The secret name in Azure Key Vault that stores the username." /> Azure Username Secret Key
</Label>
<HelpTooltip content="The secret name in Azure Key Vault that stores the username (e.g., 'my-app-username')." />
</div> </div>
<Input <Input
autoComplete="off" autoComplete="off"
@@ -430,8 +638,10 @@ function WorkflowParameterEditPanel({
</div> </div>
<div className="space-y-1"> <div className="space-y-1">
<div className="flex gap-2"> <div className="flex gap-2">
<Label className="text-xs text-slate-300">Password Key</Label> <Label className="text-xs text-slate-300">
<HelpTooltip content="The secret name in Azure Key Vault that stores the password." /> Azure Password Secret Key
</Label>
<HelpTooltip content="The secret name in Azure Key Vault that stores the password (e.g., 'my-app-password')." />
</div> </div>
<Input <Input
value={azurePasswordKey} value={azurePasswordKey}
@@ -441,7 +651,7 @@ function WorkflowParameterEditPanel({
<div className="space-y-1"> <div className="space-y-1">
<div className="flex gap-2"> <div className="flex gap-2">
<Label className="text-xs text-slate-300"> <Label className="text-xs text-slate-300">
TOTP Secret Key Azure TOTP Secret Key
</Label> </Label>
<HelpTooltip content="Optional. The secret name in Azure Key Vault that stores the TOTP secret for two-factor authentication." /> <HelpTooltip content="Optional. The secret name in Azure Key Vault that stores the TOTP secret for two-factor authentication." />
</div> </div>
@@ -452,6 +662,23 @@ function WorkflowParameterEditPanel({
</div> </div>
</> </>
)} )}
{/* Skyvern Managed Credential Selector */}
{showSkyvernCredentialSelector && (
<div className="space-y-1">
<div className="flex gap-2">
<Label className="text-xs text-slate-300">
Skyvern Credential
</Label>
<HelpTooltip content="Select a credential from your Skyvern credential store. These are managed credentials you've previously added to Skyvern." />
</div>
<CredentialParameterSourceSelector
value={credentialId}
onChange={(value) => setCredentialId(value)}
/>
</div>
)}
{type === "context" && ( {type === "context" && (
<div className="space-y-1"> <div className="space-y-1">
<Label className="text-xs text-slate-300">Source Parameter</Label> <Label className="text-xs text-slate-300">Source Parameter</Label>
@@ -461,67 +688,7 @@ function WorkflowParameterEditPanel({
/> />
</div> </div>
)} )}
{type === "secret" && (
<>
<div className="space-y-1">
<Label className="text-xs text-slate-300">Identity Key</Label>
<Input
value={identityKey}
onChange={(e) => setIdentityKey(e.target.value)}
/>
</div>
<div className="space-y-1">
<Label className="text-xs text-slate-300">
Identity Fields
</Label>
<Input
value={identityFields}
onChange={(e) => setIdentityFields(e.target.value)}
/>
</div>
<div className="space-y-1">
<Label className="text-xs text-slate-300">Collection ID</Label>
<Input
value={bitwardenCollectionId}
onChange={(e) => setBitwardenCollectionId(e.target.value)}
/>
</div>
</>
)}
{type === "creditCardData" && (
<>
<div className="space-y-1">
<Label className="text-xs text-slate-300">Collection ID</Label>
<Input
value={bitwardenCollectionId}
onChange={(e) => setBitwardenCollectionId(e.target.value)}
/>
</div>
<div className="space-y-1">
<Label className="text-xs text-slate-300">Item ID</Label>
<Input
value={sensitiveInformationItemId}
onChange={(e) =>
setSensitiveInformationItemId(e.target.value)
}
/>
</div>
</>
)}
{
// temporarily cloud only
type === "credential" &&
credentialType === "skyvern" &&
isCloud && (
<div className="space-y-1">
<Label className="text-xs text-slate-300">Credential</Label>
<CredentialParameterSourceSelector
value={credentialId}
onChange={(value) => setCredentialId(value)}
/>
</div>
)
}
<div className="flex justify-end"> <div className="flex justify-end">
<Button <Button
onClick={() => { onClick={() => {
@@ -550,6 +717,8 @@ function WorkflowParameterEditPanel({
}); });
return; return;
} }
// Handle workflow parameters
if (type === "workflow") { if (type === "workflow") {
if ( if (
parameterType === "json" && parameterType === "json" &&
@@ -601,111 +770,10 @@ function WorkflowParameterEditPanel({
? defaultValue ? defaultValue
: null, : null,
}); });
return;
} }
if (type === "credential" && credentialType === "bitwarden") {
const errorMessage = validateBitwardenLoginCredential( // Handle context parameters
bitwardenCollectionId,
bitwardenLoginCredentialItemId,
urlParameterKey,
);
if (errorMessage) {
toast({
variant: "destructive",
title: "Failed to save parameter",
description: errorMessage,
});
return;
}
onSave({
key,
parameterType: "credential",
itemId:
bitwardenLoginCredentialItemId === ""
? null
: bitwardenLoginCredentialItemId,
urlParameterKey:
urlParameterKey === "" ? null : urlParameterKey,
collectionId:
bitwardenCollectionId === ""
? null
: bitwardenCollectionId,
description,
});
}
if (type === "credential" && credentialType === "onepassword") {
if (opVaultId.trim() === "" || opItemId.trim() === "") {
toast({
variant: "destructive",
title: "Failed to save parameter",
description: "Vault ID and Item ID are required",
});
return;
}
onSave({
key,
parameterType: "onepassword",
vaultId: opVaultId,
itemId: opItemId,
description,
});
}
if (type === "credential" && credentialType === "azurevault") {
if (
azureVaultName.trim() === "" ||
azureUsernameKey.trim() === "" ||
azurePasswordKey.trim() === ""
) {
toast({
variant: "destructive",
title: "Failed to add parameter",
description:
"Azure Vault Name, Username Key and Password Key are required",
});
return;
}
onSave({
key,
parameterType: "credential",
vaultName: azureVaultName,
usernameKey: azureUsernameKey,
passwordKey: azurePasswordKey,
totpSecretKey:
azureTotpSecretKey === "" ? null : azureTotpSecretKey,
description: description,
});
}
if (type === "secret" || type === "creditCardData") {
if (!bitwardenCollectionId) {
toast({
variant: "destructive",
title: "Failed to save parameter",
description: "Collection ID is required",
});
return;
}
}
if (type === "secret") {
onSave({
key,
parameterType: "secret",
collectionId: bitwardenCollectionId,
identityFields: identityFields
.split(",")
.filter((s) => s.length > 0)
.map((field) => field.trim()),
identityKey,
description,
});
}
if (type === "creditCardData") {
onSave({
key,
parameterType: "creditCardData",
collectionId: bitwardenCollectionId,
itemId: sensitiveInformationItemId,
description,
});
}
if (type === "context") { if (type === "context") {
if (!sourceParameterKey) { if (!sourceParameterKey) {
toast({ toast({
@@ -721,22 +789,166 @@ function WorkflowParameterEditPanel({
sourceParameterKey, sourceParameterKey,
description, description,
}); });
return;
} }
if (type === "credential" && credentialType === "skyvern") {
if (!credentialId) { // Handle credential parameters based on type + source combination
toast({ if (type === "credential") {
variant: "destructive", // Skyvern managed credentials
title: "Failed to save parameter", if (credentialSource === "skyvern") {
description: "Credential is required", if (!credentialId) {
toast({
variant: "destructive",
title: "Failed to save parameter",
description: "Credential is required",
});
return;
}
onSave({
key,
parameterType: "credential",
credentialId,
description,
});
return;
}
// Bitwarden credentials
if (credentialSource === "bitwarden") {
// Password type
if (credentialDataType === "password") {
const errorMessage = validateBitwardenLoginCredential(
bitwardenCollectionId,
bitwardenLoginCredentialItemId,
urlParameterKey,
);
if (errorMessage) {
toast({
variant: "destructive",
title: "Failed to save parameter",
description: errorMessage,
});
return;
}
onSave({
key,
parameterType: "credential",
itemId:
bitwardenLoginCredentialItemId === ""
? null
: bitwardenLoginCredentialItemId,
urlParameterKey:
urlParameterKey === "" ? null : urlParameterKey,
collectionId:
bitwardenCollectionId === ""
? null
: bitwardenCollectionId,
description,
});
return;
}
// Secret type
if (credentialDataType === "secret") {
if (!bitwardenCollectionId) {
toast({
variant: "destructive",
title: "Failed to save parameter",
description: "Bitwarden Collection ID is required",
});
return;
}
onSave({
key,
parameterType: "secret",
collectionId: bitwardenCollectionId,
identityFields: identityFields
.split(",")
.filter((s) => s.length > 0)
.map((field) => field.trim()),
identityKey,
description,
});
return;
}
// Credit Card type
if (credentialDataType === "creditCard") {
if (!bitwardenCollectionId) {
toast({
variant: "destructive",
title: "Failed to save parameter",
description: "Bitwarden Collection ID is required",
});
return;
}
if (!sensitiveInformationItemId) {
toast({
variant: "destructive",
title: "Failed to save parameter",
description: "Bitwarden Item ID is required",
});
return;
}
onSave({
key,
parameterType: "creditCardData",
collectionId: bitwardenCollectionId,
itemId: sensitiveInformationItemId,
description,
});
return;
}
}
// 1Password credentials
if (credentialSource === "onepassword") {
if (opVaultId.trim() === "" || opItemId.trim() === "") {
toast({
variant: "destructive",
title: "Failed to save parameter",
description:
"1Password Vault ID and Item ID are required",
});
return;
}
onSave({
key,
parameterType: "onepassword",
vaultId: opVaultId,
itemId: opItemId,
description,
});
return;
}
// Azure Key Vault credentials
if (credentialSource === "azurevault") {
if (
azureVaultName.trim() === "" ||
azureUsernameKey.trim() === "" ||
azurePasswordKey.trim() === ""
) {
toast({
variant: "destructive",
title: "Failed to add parameter",
description:
"Azure Vault Name, Username Key and Password Key are required",
});
return;
}
onSave({
key,
parameterType: "credential",
vaultName: azureVaultName,
usernameKey: azureUsernameKey,
passwordKey: azurePasswordKey,
totpSecretKey:
azureTotpSecretKey === "" ? null : azureTotpSecretKey,
description: description,
}); });
return; return;
} }
onSave({
key,
parameterType: "credential",
credentialId,
description,
});
} }
}} }}
> >

View File

@@ -105,28 +105,6 @@ function WorkflowParametersPanel({ onMouseDownCapture }: Props) {
> >
Credential Parameter Credential Parameter
</DropdownMenuItem> </DropdownMenuItem>
<DropdownMenuItem
onClick={() => {
setOperationPanelState({
active: true,
operation: "add",
type: WorkflowEditorParameterTypes.Secret,
});
}}
>
Secret Parameter
</DropdownMenuItem>
<DropdownMenuItem
onClick={() => {
setOperationPanelState({
active: true,
operation: "add",
type: WorkflowEditorParameterTypes.CreditCardData,
});
}}
>
Credit Card Parameter
</DropdownMenuItem>
</DropdownMenuContent> </DropdownMenuContent>
</DropdownMenu> </DropdownMenu>
@@ -149,7 +127,9 @@ function WorkflowParametersPanel({ onMouseDownCapture }: Props) {
</span> </span>
) : ( ) : (
<span className="text-sm text-slate-400"> <span className="text-sm text-slate-400">
{parameter.parameterType === "onepassword" {parameter.parameterType === "onepassword" ||
parameter.parameterType === "secret" ||
parameter.parameterType === "creditCardData"
? "credential" ? "credential"
: parameter.parameterType} : parameter.parameterType}
</span> </span>
@@ -164,7 +144,9 @@ function WorkflowParametersPanel({ onMouseDownCapture }: Props) {
operation: "edit", operation: "edit",
parameter: parameter, parameter: parameter,
type: type:
parameter.parameterType === "onepassword" parameter.parameterType === "onepassword" ||
parameter.parameterType === "secret" ||
parameter.parameterType === "creditCardData"
? WorkflowEditorParameterTypes.Credential ? WorkflowEditorParameterTypes.Credential
: parameter.parameterType, : parameter.parameterType,
}); });