diff --git a/openmetadata-ui/src/main/resources/ui/src/components/common/Form/JSONSchema/JsonSchemaWidgets/PasswordWidget.test.tsx b/openmetadata-ui/src/main/resources/ui/src/components/common/Form/JSONSchema/JsonSchemaWidgets/PasswordWidget.test.tsx index f0480989280..cf705f7a21b 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/common/Form/JSONSchema/JsonSchemaWidgets/PasswordWidget.test.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/common/Form/JSONSchema/JsonSchemaWidgets/PasswordWidget.test.tsx @@ -90,7 +90,25 @@ describe('Test PasswordWidget Component', () => { fireEvent.change(passwordInput, { target: { value: 'password' } }); - expect(mockOnChange).toHaveBeenCalled(); + expect(mockOnChange).toHaveBeenCalledWith('password'); + }); + + it('Should call onChange with asterisk', async () => { + render(); + + const passwordInput = screen.getByTestId('password-input-widget'); + + fireEvent.change(passwordInput, { target: { value: '*******' } }); + + expect(mockOnChange).toHaveBeenCalledWith('*******'); + }); + + it('Should not show password if the value is masked', async () => { + render(); + + const passwordInput = screen.getByTestId('password-input-widget'); + + expect(passwordInput).toHaveValue(''); }); it('Should render FileWidget component if uiFieldType is file', async () => { diff --git a/openmetadata-ui/src/main/resources/ui/src/components/common/Form/JSONSchema/JsonSchemaWidgets/PasswordWidget.tsx b/openmetadata-ui/src/main/resources/ui/src/components/common/Form/JSONSchema/JsonSchemaWidgets/PasswordWidget.tsx index f1a733495a2..8a4402478c3 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/common/Form/JSONSchema/JsonSchemaWidgets/PasswordWidget.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/common/Form/JSONSchema/JsonSchemaWidgets/PasswordWidget.tsx @@ -12,10 +12,19 @@ */ import { WidgetProps } from '@rjsf/utils'; import { Input } from 'antd'; -import React, { FC } from 'react'; +import React, { FC, useMemo } from 'react'; +import { ALL_ASTERISKS_REGEX } from '../../../../../constants/regex.constants'; import FileUploadWidget from './FileUploadWidget'; const PasswordWidget: FC = (props) => { + const passwordWidgetValue = useMemo(() => { + if (ALL_ASTERISKS_REGEX.test(props.value)) { + return undefined; // Do not show the password if it is masked + } else { + return props.value; + } + }, [props.value]); + if (props.schema.uiFieldType === 'file') { return ; } @@ -23,7 +32,7 @@ const PasswordWidget: FC = (props) => { const { onFocus, onBlur, onChange, ...rest } = props; return ( - = (props) => { placeholder={rest.placeholder} readOnly={rest.readonly} required={rest.required} - value={rest.value} + value={passwordWidgetValue} onBlur={() => onBlur(rest.id, rest.value)} onChange={(e) => onChange(e.target.value)} onFocus={() => onFocus(rest.id, rest.value)} diff --git a/openmetadata-ui/src/main/resources/ui/src/constants/regex.constants.ts b/openmetadata-ui/src/main/resources/ui/src/constants/regex.constants.ts index 35ae8004e4e..fe8adf13a08 100644 --- a/openmetadata-ui/src/main/resources/ui/src/constants/regex.constants.ts +++ b/openmetadata-ui/src/main/resources/ui/src/constants/regex.constants.ts @@ -52,3 +52,5 @@ export const HEX_COLOR_CODE_REGEX = /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/; export const TASK_SANITIZE_VALUE_REGEX = /^"|"$/g; export const TIMESTAMP_UNIX_IN_MILLISECONDS_REGEX = /^\d{13}$/; + +export const ALL_ASTERISKS_REGEX = /^\*+$/; diff --git a/openmetadata-ui/src/main/resources/ui/src/mocks/Widgets.mock.ts b/openmetadata-ui/src/main/resources/ui/src/mocks/Widgets.mock.ts index d7a5715ab3d..33ad6a4e978 100644 --- a/openmetadata-ui/src/main/resources/ui/src/mocks/Widgets.mock.ts +++ b/openmetadata-ui/src/main/resources/ui/src/mocks/Widgets.mock.ts @@ -32,7 +32,7 @@ export const MOCK_PASSWORD_WIDGET = { formate: 'password', }, uiSchema: {}, - value: 'testing', + value: '******', }; export const MOCK_SSL_FILE_CONTENT = `-----BEGIN CERTIFICATE-----MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w04=-----END CERTIFICATE-----`;