Skip to content

Commit fd0b60a

Browse files
committed
feat; Fix regression in password masking
1 parent 541e91a commit fd0b60a

File tree

5 files changed

+31
-42
lines changed

5 files changed

+31
-42
lines changed

src/components/AddNode/GuidedConfig.tsx

Lines changed: 7 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -39,18 +39,13 @@ import {
3939
} from "../../api/common";
4040
import { useAppDispatch, useAppSelector } from "../../store/hooks";
4141
import { fetchParamsAndComputeEnv } from "../../store/plugin/pluginSlice";
42-
import { Alert } from "../Antd";
4342
import { ClipboardCopyFixed, ErrorAlert } from "../Common";
4443
import ComputeEnvironments from "./ComputeEnvironment";
4544
import RequiredParam from "./RequiredParam";
4645
import SimpleDropdown from "./SimpleDropdown";
4746
import { AddNodeContext } from "./context";
4847
import { type InputIndex, Types } from "./types";
49-
import {
50-
handleGetTokens,
51-
maskPasswordValue,
52-
unpackParametersIntoString,
53-
} from "./utils";
48+
import { handleGetTokens, unpackParametersIntoString } from "./utils";
5449

5550
const advancedConfigList = [
5651
{
@@ -389,9 +384,10 @@ const CheckboxComponent = () => {
389384
? customQuote(value)
390385
: value;
391386
const [id, flag] = paramsRequiredFetched[param_name];
392-
const maskedValue = maskPasswordValue(flag, quotedValue);
387+
// Store the original value, not the masked one
388+
// Masking is only for display purposes
393389
requiredInput[id] = {
394-
value: maskedValue,
390+
value: quotedValue,
395391
flag,
396392
type,
397393
placeholder: "",
@@ -404,9 +400,9 @@ const CheckboxComponent = () => {
404400
: value;
405401

406402
const flag = paramsDropdownFetched[param_name];
407-
const maskedValue = maskPasswordValue(flag, quotedValue);
403+
// Store the original value for dropdown parameters too, not masked version
408404
dropdownInput[v4()] = {
409-
value: maskedValue,
405+
value: quotedValue,
410406
flag,
411407
type,
412408
placeholder: "",
@@ -752,14 +748,7 @@ const AdvancedConfiguration = () => {
752748
</Dropdown>
753749
)}
754750
<HelperText style={{ marginTop: "0.25em" }}>
755-
<HelperTextItem>
756-
<div
757-
// biome-ignore lint/security/noDangerouslySetInnerHtml: <explanation>
758-
dangerouslySetInnerHTML={{
759-
__html: `${config.helper_text}`,
760-
}}
761-
/>
762-
</HelperTextItem>
751+
<HelperTextItem>{config.helper_text}</HelperTextItem>
763752
</HelperText>
764753
</FormGroup>
765754
</Form>

src/components/AddNode/RequiredParam.tsx

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,13 @@ import { type FormEvent, useContext, useEffect, useRef } from "react";
44
import { AddNodeContext } from "./context";
55
import type { RequiredParamProp } from "./types";
66
import { Types } from "./types";
7-
import { maskPasswordValue } from "./utils";
87

98
const RequiredParam: React.FC<RequiredParamProp> = ({ param }) => {
109
const { state, dispatch } = useContext(AddNodeContext);
1110
const { requiredInput } = state;
1211
const inputElement = useRef<HTMLInputElement>(null);
1312

1413
const value = requiredInput?.[param.data.id]?.value ?? "";
15-
// Mask password values for display
16-
const displayValue = maskPasswordValue(param.data.flag, value);
1714

1815
const handleInputChange = (value: string) => {
1916
const { id, flag, help: placeholder, type } = param.data;
@@ -48,10 +45,14 @@ const RequiredParam: React.FC<RequiredParamProp> = ({ param }) => {
4845
<TextInput
4946
className="required-params__textInput"
5047
ref={inputElement}
51-
type="text"
48+
type={
49+
param.data.flag?.toLowerCase().includes("password")
50+
? "password"
51+
: "text"
52+
}
5253
aria-label="required-parameters"
5354
placeholder={param.data.help}
54-
value={displayValue}
55+
value={value}
5556
id={param.data.name}
5657
onChange={(_e, value: string) => handleInputChange(value)}
5758
/>

src/components/AddNode/SimpleDropdown.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import {
1010
import React, { useContext, useEffect } from "react";
1111
import { CloseIcon } from "../Icons";
1212
import type { SimpleDropdownProps, SimpleDropdownState } from "./types";
13-
import { maskPasswordValue, unPackForKeyValue } from "./utils";
13+
import { unPackForKeyValue } from "./utils";
1414

1515
import { v4 } from "uuid";
1616
import { AddNodeContext } from "./context";
@@ -144,8 +144,6 @@ const SimpleDropdown = ({ id, params }: SimpleDropdownProps) => {
144144
return parameters;
145145
};
146146

147-
const displayValue = maskPasswordValue(paramFlag, value);
148-
149147
return (
150148
<>
151149
<div className="plugin-configuration">
@@ -176,12 +174,14 @@ const SimpleDropdown = ({ id, params }: SimpleDropdownProps) => {
176174
</Dropdown>
177175
<TextInput
178176
id={paramFlag}
179-
type="text"
177+
type={
178+
paramFlag?.toLowerCase().includes("password") ? "password" : "text"
179+
}
180180
aria-label="text"
181181
className="plugin-configuration__input"
182182
onChange={handleInputChange}
183183
placeholder={placeholder}
184-
value={displayValue}
184+
value={value}
185185
isDisabled={
186186
type === "boolean" || (params && params.dropdown.length === 0)
187187
}

src/components/AddNode/utils.ts

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ export const unpackParametersIntoObject = (input: InputType) => {
2020
for (const parameter in input) {
2121
const [flag, value, type] = unPackForKeyValue(input[parameter]);
2222

23-
// Store the original value - masking will happen during display
2423
result[flag] = {
2524
value,
2625
type,
@@ -30,22 +29,18 @@ export const unpackParametersIntoObject = (input: InputType) => {
3029
return result;
3130
};
3231

33-
export const maskPasswordValue = (flag: string, value: string): string => {
34-
// Check if flag or parameter name contains "password" (case insensitive)
35-
return flag.toLowerCase().includes("password")
36-
? "*".repeat(value ? value.length : 0)
37-
: value;
38-
};
39-
4032
export const unpackParametersIntoString = (input: InputType) => {
4133
let string = "";
4234

4335
for (const parameter in input) {
4436
const flag = input[parameter].flag;
4537
const value = input[parameter].value;
4638

47-
// Use the maskPasswordValue function to mask passwords (checks flag name)
48-
const displayValue = maskPasswordValue(flag, value);
39+
// Check if this is a password parameter and mask it with asterisks for display
40+
const isPassword = flag?.toLowerCase().includes("password");
41+
const displayValue = isPassword
42+
? "*".repeat(value ? value.length : 0)
43+
: value;
4944

5045
string += `${flag} ${displayValue} `;
5146
}

src/components/NodeDetails/NodeDetails.tsx

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -310,21 +310,25 @@ function getCommand(
310310
const paramName = instanceParam.data.param_name;
311311

312312
// Check if parameter name contains "password" (case insensitive)
313-
const isPassword = paramName.toLowerCase().includes("password");
313+
const isPassword =
314+
paramName.toLowerCase().includes("password") ||
315+
pluginParam.data.flag?.toLowerCase().includes("password");
314316

315317
// If it's a password, mask the value with asterisks of the same length
316318
const displayValue = isPassword
317319
? "*".repeat(value ? value.length : 0)
318320
: value;
319321

320-
const safeValue =
321-
isString && needsQuoting(displayValue)
322+
// For password fields, ensure the masked value is used consistently
323+
const safeValue = isPassword
324+
? displayValue
325+
: isString && needsQuoting(displayValue)
322326
? customQuote(displayValue)
323327
: displayValue;
324328

325329
modifiedParams.push({
326330
name: pluginParam.data.flag,
327-
value: isBoolean ? " " : isString ? safeValue : displayValue,
331+
value: isBoolean ? " " : safeValue,
328332
});
329333
}
330334
}

0 commit comments

Comments
 (0)