Only select all secret value on edit but no view permissions, and keep the select until user starts writting

This commit is contained in:
carlosmonastyrski
2025-05-22 11:41:35 -03:00
parent e0322c8a7f
commit 6a23583391
5 changed files with 47 additions and 31 deletions
+27 -27
View File
@@ -18,44 +18,44 @@ export const getDefaultOnPremFeatures = (): TFeatureSet => ({
environmentsUsed: 0, environmentsUsed: 0,
identityLimit: null, identityLimit: null,
identitiesUsed: 0, identitiesUsed: 0,
dynamicSecret: false, dynamicSecret: true,
secretVersioning: true, secretVersioning: true,
pitRecovery: false, pitRecovery: true,
ipAllowlisting: false, ipAllowlisting: true,
rbac: false, rbac: true,
githubOrgSync: false, githubOrgSync: true,
customRateLimits: false, customRateLimits: true,
customAlerts: false, customAlerts: true,
secretAccessInsights: false, secretAccessInsights: true,
auditLogs: false, auditLogs: true,
auditLogsRetentionDays: 0, auditLogsRetentionDays: 0,
auditLogStreams: false, auditLogStreams: true,
auditLogStreamLimit: 3, auditLogStreamLimit: 3,
samlSSO: false, samlSSO: true,
hsm: false, hsm: true,
oidcSSO: false, oidcSSO: true,
scim: false, scim: true,
ldap: false, ldap: true,
groups: false, groups: true,
status: null, status: null,
trial_end: null, trial_end: null,
has_used_trial: true, has_used_trial: true,
secretApproval: false, secretApproval: true,
secretRotation: false, secretRotation: true,
caCrl: false, caCrl: true,
instanceUserManagement: false, instanceUserManagement: true,
externalKms: false, externalKms: true,
rateLimits: { rateLimits: {
readLimit: 60, readLimit: 60,
writeLimit: 200, writeLimit: 200,
secretsLimit: 40 secretsLimit: 40
}, },
pkiEst: false, pkiEst: true,
enforceMfa: false, enforceMfa: true,
projectTemplates: false, projectTemplates: true,
kmip: false, kmip: true,
gateway: false, gateway: true,
sshHostGroups: false sshHostGroups: true
}); });
export const setupLicenseRequestWithStore = (baseURL: string, refreshUrl: string, licenseKey: string) => { export const setupLicenseRequestWithStore = (baseURL: string, refreshUrl: string, licenseKey: string) => {
@@ -51,6 +51,7 @@ type Props = Omit<TextareaHTMLAttributes<HTMLTextAreaElement>, "onChange" | "val
isVisible?: boolean; isVisible?: boolean;
isReadOnly?: boolean; isReadOnly?: boolean;
isDisabled?: boolean; isDisabled?: boolean;
canEditButNotView?: boolean;
secretPath?: string; secretPath?: string;
environment?: string; environment?: string;
containerClassName?: string; containerClassName?: string;
@@ -70,6 +71,7 @@ export const InfisicalSecretInput = forwardRef<HTMLTextAreaElement, Props>(
containerClassName, containerClassName,
secretPath: propSecretPath, secretPath: propSecretPath,
environment: propEnvironment, environment: propEnvironment,
canEditButNotView,
...props ...props
}, },
ref ref
@@ -273,6 +275,7 @@ export const InfisicalSecretInput = forwardRef<HTMLTextAreaElement, Props>(
<Popover.Trigger asChild> <Popover.Trigger asChild>
<SecretInput <SecretInput
{...props} {...props}
canEditButNotView={canEditButNotView}
ref={handleRef} ref={handleRef}
onKeyDown={handleKeyDown} onKeyDown={handleKeyDown}
value={value} value={value}
@@ -3,6 +3,7 @@ import { forwardRef, TextareaHTMLAttributes } from "react";
import { twMerge } from "tailwind-merge"; import { twMerge } from "tailwind-merge";
import { useToggle } from "@app/hooks"; import { useToggle } from "@app/hooks";
import { HIDDEN_SECRET_VALUE } from "@app/pages/secret-manager/SecretDashboardPage/components/SecretListView/SecretItem";
const REGEX = /(\${([a-zA-Z0-9-_.]+)})/g; const REGEX = /(\${([a-zA-Z0-9-_.]+)})/g;
const replaceContentWithDot = (str: string) => { const replaceContentWithDot = (str: string) => {
@@ -51,6 +52,7 @@ type Props = TextareaHTMLAttributes<HTMLTextAreaElement> & {
isReadOnly?: boolean; isReadOnly?: boolean;
isDisabled?: boolean; isDisabled?: boolean;
containerClassName?: string; containerClassName?: string;
canEditButNotView?: boolean;
}; };
const commonClassName = "font-mono text-sm caret-white border-none outline-none w-full break-all"; const commonClassName = "font-mono text-sm caret-white border-none outline-none w-full break-all";
@@ -66,6 +68,7 @@ export const SecretInput = forwardRef<HTMLTextAreaElement, Props>(
isDisabled, isDisabled,
isReadOnly, isReadOnly,
onFocus, onFocus,
canEditButNotView,
...props ...props
}, },
ref ref
@@ -93,7 +96,15 @@ export const SecretInput = forwardRef<HTMLTextAreaElement, Props>(
onFocus={(evt) => { onFocus={(evt) => {
onFocus?.(evt); onFocus?.(evt);
setIsSecretFocused.on(); setIsSecretFocused.on();
evt.currentTarget.select(); if (canEditButNotView && value === HIDDEN_SECRET_VALUE) {
evt.currentTarget.select();
}
}}
onMouseDown={(e) => {
if (canEditButNotView && value === HIDDEN_SECRET_VALUE) {
e.preventDefault();
e.currentTarget.select();
}
}} }}
disabled={isDisabled} disabled={isDisabled}
spellCheck={false} spellCheck={false}
@@ -232,6 +232,7 @@ export const SecretEditRow = ({
environment={environment} environment={environment}
isImport={isImportedSecret} isImport={isImportedSecret}
defaultValue={secretValueHidden ? "" : undefined} defaultValue={secretValueHidden ? "" : undefined}
canEditButNotView={secretValueHidden && !isOverride}
/> />
)} )}
/> />
@@ -58,7 +58,7 @@ import {
} from "./SecretListView.utils"; } from "./SecretListView.utils";
import { CollapsibleSecretImports } from "./CollapsibleSecretImports"; import { CollapsibleSecretImports } from "./CollapsibleSecretImports";
const hiddenValue = "******"; export const HIDDEN_SECRET_VALUE = "******";
type Props = { type Props = {
secret: SecretV3RawSanitized; secret: SecretV3RawSanitized;
@@ -122,7 +122,7 @@ export const SecretItem = memo(
const getDefaultValue = () => { const getDefaultValue = () => {
if (secret.secretValueHidden) { if (secret.secretValueHidden) {
return canEditSecretValue ? hiddenValue : ""; return canEditSecretValue ? HIDDEN_SECRET_VALUE : "";
} }
return secret.valueOverride || secret.value || ""; return secret.valueOverride || secret.value || "";
}; };
@@ -366,10 +366,11 @@ export const SecretItem = memo(
isReadOnly={isReadOnly || isRotatedSecret} isReadOnly={isReadOnly || isRotatedSecret}
key="secret-value" key="secret-value"
isVisible={isVisible && !secretValueHidden} isVisible={isVisible && !secretValueHidden}
canEditButNotView={secretValueHidden && !isOverriden}
environment={environment} environment={environment}
secretPath={secretPath} secretPath={secretPath}
{...field} {...field}
defaultValue={secretValueHidden ? hiddenValue : undefined} defaultValue={secretValueHidden ? HIDDEN_SECRET_VALUE : undefined}
containerClassName="py-1.5 rounded-md transition-all" containerClassName="py-1.5 rounded-md transition-all"
/> />
)} )}