From bdbbc657052dbae4be5e1ddd3383550b723b5ee1 Mon Sep 17 00:00:00 2001 From: Ryan Hopper-Lowe Date: Sun, 8 Dec 2024 00:29:10 -0600 Subject: [PATCH 1/2] feat: implement password input masking --- ui/admin/app/components/ui/input.tsx | 62 +++++++++++++++++++++++----- 1 file changed, 51 insertions(+), 11 deletions(-) diff --git a/ui/admin/app/components/ui/input.tsx b/ui/admin/app/components/ui/input.tsx index ae2bc45ac..281fa2d49 100644 --- a/ui/admin/app/components/ui/input.tsx +++ b/ui/admin/app/components/ui/input.tsx @@ -1,15 +1,20 @@ import { type VariantProps, cva } from "class-variance-authority"; +import { EyeIcon, EyeOffIcon } from "lucide-react"; import * as React from "react"; import { cn } from "~/lib/utils"; +import { buttonVariants } from "~/components/ui/button"; + const inputVariants = cva( - "flex h-9 w-full rounded-md px-3 bg-transparent border border-input text-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50", + cn( + "flex items-center h-9 w-full rounded-md bg-transparent border border-input text-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground has-[:focus-visible]:ring-1 has-[:focus-visible]:ring-ring has-[:disabled]:cursor-not-allowed has-[:disabled]:opacity-50" + ), { variants: { variant: { default: "", - ghost: "shadow-none cursor-pointer hover:border-primary px-0 mb-0 font-bold outline-none border-transparent focus:border-primary", + ghost: "shadow-none cursor-pointer hover:border-primary px-0 mb-0 font-bold outline-none border-transparent has-[:focus-visible]:border-primary", }, }, defaultVariants: { @@ -20,18 +25,53 @@ const inputVariants = cva( export interface InputProps extends React.InputHTMLAttributes, - VariantProps {} + VariantProps { + disableToggle?: boolean; +} const Input = React.forwardRef( - ({ className, variant, type, ...props }, ref) => { + ({ className, variant, type, disableToggle = false, ...props }, ref) => { + const isPassword = type === "password"; + const [isVisible, setIsVisible] = React.useState(false); + + const internalType = isPassword + ? isVisible && !disableToggle + ? "text" + : "password" + : type; + + const toggleVisible = React.useCallback( + () => setIsVisible((prev) => !prev), + [] + ); + return ( - +
+ + + {isPassword && !disableToggle && ( + + )} +
); } ); From e04c7390a5240cf7b058129293d739179ebca2d8 Mon Sep 17 00:00:00 2001 From: Ryan Hopper-Lowe Date: Sun, 8 Dec 2024 00:45:53 -0600 Subject: [PATCH 2/2] chore: hardcode list of sensitive model provider fields Determines which fields should be displayed as passwords when configuring a model provider Signed-off-by: Craig Jellick --- .../model-providers/ModelProviderForm.tsx | 47 +++++++++++-------- .../components/model-providers/constants.ts | 20 ++++++++ 2 files changed, 48 insertions(+), 19 deletions(-) diff --git a/ui/admin/app/components/model-providers/ModelProviderForm.tsx b/ui/admin/app/components/model-providers/ModelProviderForm.tsx index cdbb6559e..fffcc7165 100644 --- a/ui/admin/app/components/model-providers/ModelProviderForm.tsx +++ b/ui/admin/app/components/model-providers/ModelProviderForm.tsx @@ -22,6 +22,7 @@ import { ControlledInput } from "~/components/form/controlledInputs"; import { ModelProviderConfigurationLinks, ModelProviderRequiredTooltips, + ModelProviderSensitiveFields, } from "~/components/model-providers/constants"; import { Alert, AlertDescription, AlertTitle } from "~/components/ui/alert"; import { Button } from "~/components/ui/button"; @@ -211,26 +212,34 @@ export function ModelProviderForm({ className="flex flex-col gap-4" > {requiredConfigParamFields.fields.map( - (field, i) => ( -
- { + const type = ModelProviderSensitiveFields[ + field.name + ] + ? "password" + : "text"; + + return ( +
-
- ) + className="flex gap-2 items-center justify-center" + > + +
+ ); + } )} diff --git a/ui/admin/app/components/model-providers/constants.ts b/ui/admin/app/components/model-providers/constants.ts index ee402be4d..74839cc63 100644 --- a/ui/admin/app/components/model-providers/constants.ts +++ b/ui/admin/app/components/model-providers/constants.ts @@ -48,3 +48,23 @@ export const ModelProviderRequiredTooltips: { "Container that holds related Azure resources. Can typically be found in Azure Portal > Resource Groups > [OpenAI Resource Group] > Overview", }, }; + +export const ModelProviderSensitiveFields: Record = + { + // OpenAI + OTTO8_OPENAI_MODEL_PROVIDER_API_KEY: true, + + // Azure OpenAI + OTTO8_AZURE_OPENAI_MODEL_PROVIDER_ENDPOINT: false, + OTTO8_AZURE_OPENAI_MODEL_PROVIDER_CLIENT_ID: false, + OTTO8_AZURE_OPENAI_MODEL_PROVIDER_CLIENT_SECRET: true, + OTTO8_AZURE_OPENAI_MODEL_PROVIDER_TENANT_ID: false, + OTTO8_AZURE_OPENAI_MODEL_PROVIDER_SUBSCRIPTION_ID: false, + OTTO8_AZURE_OPENAI_MODEL_PROVIDER_RESOURCE_GROUP: false, + + // Anthropic + OTTO8_ANTHROPIC_MODEL_PROVIDER_API_KEY: true, + + // Voyage + OTTO8_VOYAGE_MODEL_PROVIDER_API_KEY: true, + };