[Frontend] Add SECRET credential type for storing generic sensitive values (#4258)

This commit is contained in:
Marc Kelechava
2025-12-10 08:56:12 -08:00
committed by GitHub
parent e953dad878
commit 0207d13855
9 changed files with 283 additions and 66 deletions

View File

@@ -10,6 +10,7 @@ import {
CredentialModalTypes,
} from "./useCredentialModalState";
import { PasswordCredentialContent } from "./PasswordCredentialContent";
import { SecretCredentialContent } from "./SecretCredentialContent";
import { useState, useEffect } from "react";
import { Button } from "@/components/ui/button";
import { CreditCardCredentialContent } from "./CreditCardCredentialContent";
@@ -40,6 +41,12 @@ const CREDIT_CARD_CREDENTIAL_INITIAL_VALUES = {
cardHolderName: "",
};
const SECRET_CREDENTIAL_INITIAL_VALUES = {
name: "",
secretLabel: "",
secretValue: "",
};
// Function to generate a unique credential name
function generateDefaultCredentialName(existingNames: string[]): string {
const baseName = "credentials";
@@ -73,6 +80,9 @@ function CredentialsModal({ onCredentialCreated }: Props) {
const [creditCardCredentialValues, setCreditCardCredentialValues] = useState(
CREDIT_CARD_CREDENTIAL_INITIAL_VALUES,
);
const [secretCredentialValues, setSecretCredentialValues] = useState(
SECRET_CREDENTIAL_INITIAL_VALUES,
);
// Set default name when modal opens
useEffect(() => {
@@ -88,12 +98,17 @@ function CredentialsModal({ onCredentialCreated }: Props) {
...prev,
name: defaultName,
}));
setSecretCredentialValues((prev) => ({
...prev,
name: defaultName,
}));
}
}, [isOpen, credentials]);
function reset() {
setPasswordCredentialValues(PASSWORD_CREDENTIAL_INITIAL_VALUES);
setCreditCardCredentialValues(CREDIT_CARD_CREDENTIAL_INITIAL_VALUES);
setSecretCredentialValues(SECRET_CREDENTIAL_INITIAL_VALUES);
}
const createCredentialMutation = useMutation({
@@ -128,7 +143,9 @@ function CredentialsModal({ onCredentialCreated }: Props) {
const name =
type === CredentialModalTypes.PASSWORD
? passwordCredentialValues.name.trim()
: creditCardCredentialValues.name.trim();
: type === CredentialModalTypes.CREDIT_CARD
? creditCardCredentialValues.name.trim()
: secretCredentialValues.name.trim();
if (name === "") {
toast({
title: "Error",
@@ -219,9 +236,55 @@ function CredentialsModal({ onCredentialCreated }: Props) {
card_holder_name: cardHolderName,
},
});
} else if (type === CredentialModalTypes.SECRET) {
const secretValue = secretCredentialValues.secretValue.trim();
const secretLabel = secretCredentialValues.secretLabel.trim();
if (secretValue === "") {
toast({
title: "Error",
description: "Secret value is required",
variant: "destructive",
});
return;
}
createCredentialMutation.mutate({
name,
credential_type: "secret",
credential: {
secret_value: secretValue,
secret_label: secretLabel === "" ? null : secretLabel,
},
});
}
};
const credentialContent = (() => {
if (type === CredentialModalTypes.PASSWORD) {
return (
<PasswordCredentialContent
values={passwordCredentialValues}
onChange={setPasswordCredentialValues}
/>
);
}
if (type === CredentialModalTypes.CREDIT_CARD) {
return (
<CreditCardCredentialContent
values={creditCardCredentialValues}
onChange={setCreditCardCredentialValues}
/>
);
}
return (
<SecretCredentialContent
values={secretCredentialValues}
onChange={setSecretCredentialValues}
/>
);
})();
return (
<Dialog
open={isOpen}
@@ -236,17 +299,7 @@ function CredentialsModal({ onCredentialCreated }: Props) {
<DialogHeader>
<DialogTitle className="font-bold">Add Credential</DialogTitle>
</DialogHeader>
{type === CredentialModalTypes.PASSWORD ? (
<PasswordCredentialContent
values={passwordCredentialValues}
onChange={setPasswordCredentialValues}
/>
) : (
<CreditCardCredentialContent
values={creditCardCredentialValues}
onChange={setCreditCardCredentialValues}
/>
)}
{credentialContent}
<DialogFooter>
<Button
onClick={handleSave}