Azure Vault credential support (#3394)
This commit is contained in:
@@ -50,6 +50,7 @@ import {
|
||||
ContextParameterYAML,
|
||||
CredentialParameterYAML,
|
||||
OnePasswordCredentialParameterYAML,
|
||||
AzureVaultCredentialParameterYAML,
|
||||
ParameterYAML,
|
||||
WorkflowParameterYAML,
|
||||
} from "../types/workflowYamlTypes";
|
||||
@@ -65,6 +66,7 @@ import {
|
||||
parameterIsSkyvernCredential,
|
||||
parameterIsOnePasswordCredential,
|
||||
parameterIsBitwardenCredential,
|
||||
parameterIsAzureVaultCredential,
|
||||
} from "./types";
|
||||
import "./reactFlowOverrideStyles.css";
|
||||
import {
|
||||
@@ -90,6 +92,7 @@ function convertToParametersYAML(
|
||||
| BitwardenSensitiveInformationParameterYAML
|
||||
| BitwardenCreditCardDataParameterYAML
|
||||
| OnePasswordCredentialParameterYAML
|
||||
| AzureVaultCredentialParameterYAML
|
||||
| CredentialParameterYAML
|
||||
> {
|
||||
return parameters
|
||||
@@ -103,6 +106,7 @@ function convertToParametersYAML(
|
||||
| BitwardenSensitiveInformationParameterYAML
|
||||
| BitwardenCreditCardDataParameterYAML
|
||||
| OnePasswordCredentialParameterYAML
|
||||
| AzureVaultCredentialParameterYAML
|
||||
| CredentialParameterYAML
|
||||
| undefined => {
|
||||
if (parameter.parameterType === WorkflowEditorParameterTypes.Workflow) {
|
||||
@@ -191,6 +195,16 @@ function convertToParametersYAML(
|
||||
vault_id: parameter.vaultId,
|
||||
item_id: parameter.itemId,
|
||||
};
|
||||
} else if (parameterIsAzureVaultCredential(parameter)) {
|
||||
return {
|
||||
parameter_type: WorkflowParameterTypes.Azure_Vault_Credential,
|
||||
key: parameter.key,
|
||||
description: parameter.description || null,
|
||||
vault_name: parameter.vaultName,
|
||||
username_key: parameter.usernameKey,
|
||||
password_key: parameter.passwordKey,
|
||||
totp_secret_key: parameter.totpSecretKey,
|
||||
};
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
@@ -205,6 +219,7 @@ function convertToParametersYAML(
|
||||
| BitwardenSensitiveInformationParameterYAML
|
||||
| BitwardenCreditCardDataParameterYAML
|
||||
| OnePasswordCredentialParameterYAML
|
||||
| AzureVaultCredentialParameterYAML
|
||||
| CredentialParameterYAML
|
||||
| undefined,
|
||||
): param is
|
||||
@@ -214,6 +229,7 @@ function convertToParametersYAML(
|
||||
| BitwardenSensitiveInformationParameterYAML
|
||||
| BitwardenCreditCardDataParameterYAML
|
||||
| OnePasswordCredentialParameterYAML
|
||||
| AzureVaultCredentialParameterYAML
|
||||
| CredentialParameterYAML => param !== undefined,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { SwitchBar } from "@/components/SwitchBar";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Checkbox } from "@/components/ui/checkbox";
|
||||
import { Input } from "@/components/ui/input";
|
||||
@@ -81,7 +80,7 @@ function WorkflowParameterAddPanel({ type, onClose, onSave }: Props) {
|
||||
>(undefined);
|
||||
|
||||
const [credentialType, setCredentialType] = useState<
|
||||
"bitwarden" | "skyvern" | "onepassword"
|
||||
"bitwarden" | "skyvern" | "onepassword" | "azurevault"
|
||||
>("skyvern");
|
||||
const [vaultId, setVaultId] = useState("");
|
||||
const [itemId, setItemId] = useState("");
|
||||
@@ -93,6 +92,11 @@ function WorkflowParameterAddPanel({ type, onClose, onSave }: Props) {
|
||||
|
||||
const [credentialId, setCredentialId] = useState("");
|
||||
|
||||
const [azureVaultName, setAzureVaultName] = useState("");
|
||||
const [azureUsernameKey, setAzureUsernameKey] = useState("");
|
||||
const [azurePasswordKey, setAzurePasswordKey] = useState("");
|
||||
const [azureTotpSecretKey, setAzureTotpKey] = useState("");
|
||||
|
||||
return (
|
||||
<ScrollArea>
|
||||
<ScrollAreaViewport className="max-h-[500px]">
|
||||
@@ -199,19 +203,37 @@ function WorkflowParameterAddPanel({ type, onClose, onSave }: Props) {
|
||||
</>
|
||||
)}
|
||||
{type === "credential" && (
|
||||
<SwitchBar
|
||||
value={credentialType}
|
||||
onChange={(value) => {
|
||||
setCredentialType(
|
||||
value as "bitwarden" | "skyvern" | "onepassword",
|
||||
);
|
||||
}}
|
||||
options={[
|
||||
{ label: "Skyvern", value: "skyvern" },
|
||||
{ label: "Bitwarden", value: "bitwarden" },
|
||||
{ label: "1Password", value: "onepassword" },
|
||||
]}
|
||||
/>
|
||||
<>
|
||||
<div className="space-y-1">
|
||||
<Label className="text-xs text-slate-300">
|
||||
Credential Type
|
||||
</Label>
|
||||
<Select
|
||||
value={credentialType}
|
||||
onValueChange={(value) => {
|
||||
setCredentialType(
|
||||
value as
|
||||
| "bitwarden"
|
||||
| "skyvern"
|
||||
| "onepassword"
|
||||
| "azurevault",
|
||||
);
|
||||
}}
|
||||
>
|
||||
<SelectTrigger className="w-full">
|
||||
<SelectValue placeholder="Select a type" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectGroup>
|
||||
<SelectItem value="skyvern">Skyvern</SelectItem>
|
||||
<SelectItem value="bitwarden">Bitwarden</SelectItem>
|
||||
<SelectItem value="onepassword">1Password</SelectItem>
|
||||
<SelectItem value="azurevault">Azure Vault</SelectItem>
|
||||
</SelectGroup>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
{type === "credential" && credentialType === "bitwarden" && (
|
||||
<>
|
||||
@@ -260,6 +282,41 @@ function WorkflowParameterAddPanel({ type, onClose, onSave }: Props) {
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
{type === "credential" && credentialType === "azurevault" && (
|
||||
<>
|
||||
<div className="space-y-1">
|
||||
<Label className="text-xs text-slate-300">Vault Name</Label>
|
||||
<Input
|
||||
value={azureVaultName}
|
||||
onChange={(e) => setAzureVaultName(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
<div className="space-y-1">
|
||||
<Label className="text-xs text-slate-300">Username Key</Label>
|
||||
<Input
|
||||
autoComplete="off"
|
||||
value={azureUsernameKey}
|
||||
onChange={(e) => setAzureUsernameKey(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
<div className="space-y-1">
|
||||
<Label className="text-xs text-slate-300">Password Key</Label>
|
||||
<Input
|
||||
value={azurePasswordKey}
|
||||
onChange={(e) => setAzurePasswordKey(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
<div className="space-y-1">
|
||||
<Label className="text-xs text-slate-300">
|
||||
TOTP Secret Key
|
||||
</Label>
|
||||
<Input
|
||||
value={azureTotpSecretKey}
|
||||
onChange={(e) => setAzureTotpKey(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
{type === "context" && (
|
||||
<div className="space-y-1">
|
||||
<Label className="text-xs text-slate-300">Source Parameter</Label>
|
||||
@@ -427,6 +484,31 @@ function WorkflowParameterAddPanel({ type, onClose, onSave }: Props) {
|
||||
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({
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { SwitchBar } from "@/components/SwitchBar";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Checkbox } from "@/components/ui/checkbox";
|
||||
import { Input } from "@/components/ui/input";
|
||||
@@ -28,6 +27,7 @@ import {
|
||||
parameterIsSkyvernCredential,
|
||||
parameterIsOnePasswordCredential,
|
||||
ParametersState,
|
||||
parameterIsAzureVaultCredential,
|
||||
} from "../types";
|
||||
import { getDefaultValueForParameterType } from "../workflowEditorUtils";
|
||||
import { validateBitwardenLoginCredential } from "./util";
|
||||
@@ -82,14 +82,19 @@ function WorkflowParameterEditPanel({
|
||||
const isOnePasswordCredential =
|
||||
initialValues.parameterType === "onepassword" &&
|
||||
parameterIsOnePasswordCredential(initialValues);
|
||||
const isAzureVaultCredential =
|
||||
initialValues.parameterType === "credential" &&
|
||||
parameterIsAzureVaultCredential(initialValues);
|
||||
const [credentialType, setCredentialType] = useState<
|
||||
"bitwarden" | "skyvern" | "onepassword"
|
||||
"bitwarden" | "skyvern" | "onepassword" | "azurevault"
|
||||
>(
|
||||
isBitwardenCredential
|
||||
? "bitwarden"
|
||||
: isOnePasswordCredential
|
||||
? "onepassword"
|
||||
: "skyvern",
|
||||
: isAzureVaultCredential
|
||||
? "azurevault"
|
||||
: "skyvern",
|
||||
);
|
||||
const [urlParameterKey, setUrlParameterKey] = useState(
|
||||
isBitwardenCredential ? initialValues.urlParameterKey ?? "" : "",
|
||||
@@ -163,6 +168,19 @@ function WorkflowParameterEditPanel({
|
||||
const [bitwardenLoginCredentialItemId, setBitwardenLoginCredentialItemId] =
|
||||
useState(isBitwardenCredential ? initialValues.itemId ?? "" : "");
|
||||
|
||||
const [azureVaultName, setAzureVaultName] = useState(
|
||||
isAzureVaultCredential ? initialValues.vaultName : "",
|
||||
);
|
||||
const [azureUsernameKey, setAzureUsernameKey] = useState(
|
||||
isAzureVaultCredential ? initialValues.usernameKey : "",
|
||||
);
|
||||
const [azurePasswordKey, setAzurePasswordKey] = useState(
|
||||
isAzureVaultCredential ? initialValues.passwordKey : "",
|
||||
);
|
||||
const [azureTotpSecretKey, setAzureTotpKey] = useState(
|
||||
isAzureVaultCredential ? initialValues.totpSecretKey ?? "" : "",
|
||||
);
|
||||
|
||||
return (
|
||||
<ScrollArea>
|
||||
<ScrollAreaViewport className="max-h-[500px]">
|
||||
@@ -269,19 +287,37 @@ function WorkflowParameterEditPanel({
|
||||
</>
|
||||
)}
|
||||
{type === "credential" && (
|
||||
<SwitchBar
|
||||
value={credentialType}
|
||||
onChange={(value) => {
|
||||
setCredentialType(
|
||||
value as "bitwarden" | "skyvern" | "onepassword",
|
||||
);
|
||||
}}
|
||||
options={[
|
||||
{ label: "Skyvern", value: "skyvern" },
|
||||
{ label: "Bitwarden", value: "bitwarden" },
|
||||
{ label: "1Password", value: "onepassword" },
|
||||
]}
|
||||
/>
|
||||
<>
|
||||
<div className="space-y-1">
|
||||
<Label className="text-xs text-slate-300">
|
||||
Credential Type
|
||||
</Label>
|
||||
<Select
|
||||
value={credentialType}
|
||||
onValueChange={(value) => {
|
||||
setCredentialType(
|
||||
value as
|
||||
| "bitwarden"
|
||||
| "skyvern"
|
||||
| "onepassword"
|
||||
| "azurevault",
|
||||
);
|
||||
}}
|
||||
>
|
||||
<SelectTrigger className="w-full">
|
||||
<SelectValue placeholder="Select a type" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectGroup>
|
||||
<SelectItem value="skyvern">Skyvern</SelectItem>
|
||||
<SelectItem value="bitwarden">Bitwarden</SelectItem>
|
||||
<SelectItem value="onepassword">1Password</SelectItem>
|
||||
<SelectItem value="azurevault">Azure Vault</SelectItem>
|
||||
</SelectGroup>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
{type === "credential" && credentialType === "bitwarden" && (
|
||||
<>
|
||||
@@ -330,6 +366,41 @@ function WorkflowParameterEditPanel({
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
{type === "credential" && credentialType === "azurevault" && (
|
||||
<>
|
||||
<div className="space-y-1">
|
||||
<Label className="text-xs text-slate-300">Vault Name</Label>
|
||||
<Input
|
||||
value={azureVaultName}
|
||||
onChange={(e) => setAzureVaultName(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
<div className="space-y-1">
|
||||
<Label className="text-xs text-slate-300">Username Key</Label>
|
||||
<Input
|
||||
autoComplete="off"
|
||||
value={azureUsernameKey}
|
||||
onChange={(e) => setAzureUsernameKey(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
<div className="space-y-1">
|
||||
<Label className="text-xs text-slate-300">Password Key</Label>
|
||||
<Input
|
||||
value={azurePasswordKey}
|
||||
onChange={(e) => setAzurePasswordKey(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
<div className="space-y-1">
|
||||
<Label className="text-xs text-slate-300">
|
||||
TOTP Secret Key
|
||||
</Label>
|
||||
<Input
|
||||
value={azureTotpSecretKey}
|
||||
onChange={(e) => setAzureTotpKey(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
{type === "context" && (
|
||||
<div className="space-y-1">
|
||||
<Label className="text-xs text-slate-300">Source Parameter</Label>
|
||||
@@ -484,6 +555,31 @@ function WorkflowParameterEditPanel({
|
||||
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 (!collectionId) {
|
||||
toast({
|
||||
|
||||
@@ -24,6 +24,16 @@ export type OnePasswordCredential = {
|
||||
itemId: string;
|
||||
};
|
||||
|
||||
export type AzureVaultCredential = {
|
||||
key: string;
|
||||
description?: string | null;
|
||||
parameterType: "credential";
|
||||
vaultName: string;
|
||||
usernameKey: string;
|
||||
passwordKey: string;
|
||||
totpSecretKey: string | null;
|
||||
};
|
||||
|
||||
export function parameterIsBitwardenCredential(
|
||||
parameter: CredentialParameterState,
|
||||
): parameter is BitwardenLoginCredential {
|
||||
@@ -42,10 +52,21 @@ export function parameterIsOnePasswordCredential(
|
||||
return "vaultId" in parameter && "itemId" in parameter;
|
||||
}
|
||||
|
||||
export function parameterIsAzureVaultCredential(
|
||||
parameter: CredentialParameterState,
|
||||
): parameter is AzureVaultCredential {
|
||||
return (
|
||||
"vaultName" in parameter &&
|
||||
"usernameKey" in parameter &&
|
||||
"passwordKey" in parameter
|
||||
);
|
||||
}
|
||||
|
||||
export type CredentialParameterState =
|
||||
| BitwardenLoginCredential
|
||||
| SkyvernCredential
|
||||
| OnePasswordCredential;
|
||||
| OnePasswordCredential
|
||||
| AzureVaultCredential;
|
||||
|
||||
export type ParametersState = Array<
|
||||
| {
|
||||
|
||||
@@ -79,6 +79,19 @@ const getInitialParameters = (workflow: WorkflowApiResponse) => {
|
||||
itemId: parameter.item_id,
|
||||
description: parameter.description,
|
||||
};
|
||||
} else if (
|
||||
parameter.parameter_type ===
|
||||
WorkflowParameterTypes.Azure_Vault_Credential
|
||||
) {
|
||||
return {
|
||||
key: parameter.key,
|
||||
parameterType: WorkflowEditorParameterTypes.Credential,
|
||||
vaultName: parameter.vault_name,
|
||||
usernameKey: parameter.username_key,
|
||||
passwordKey: parameter.password_key,
|
||||
totpSecretKey: parameter.totp_secret_key,
|
||||
description: parameter.description,
|
||||
};
|
||||
} else if (
|
||||
parameter.parameter_type ===
|
||||
WorkflowParameterTypes.Bitwarden_Login_Credential
|
||||
|
||||
@@ -1805,6 +1805,16 @@ function convertParametersToParameterYAML(
|
||||
item_id: parameter.item_id,
|
||||
};
|
||||
}
|
||||
case WorkflowParameterTypes.Azure_Vault_Credential: {
|
||||
return {
|
||||
...base,
|
||||
parameter_type: WorkflowParameterTypes.Azure_Vault_Credential,
|
||||
vault_name: parameter.vault_name,
|
||||
username_key: parameter.username_key,
|
||||
password_key: parameter.password_key,
|
||||
totp_secret_key: parameter.totp_secret_key,
|
||||
};
|
||||
}
|
||||
}
|
||||
})
|
||||
.filter(Boolean);
|
||||
|
||||
Reference in New Issue
Block a user