This is an automated email from the ASF dual-hosted git repository.

marat pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-karavan.git

commit 1f8a5c3435b8dbf04b65b76bc4ca42c95f436492
Author: Marat Gubaidullin <[email protected]>
AuthorDate: Tue Nov 26 19:13:06 2024 -0500

    Sensitive fields validator in Beans
---
 .../designer/property/property/BeanProperties.tsx  | 75 ++++++++++------------
 .../property/property/ComponentPropertyField.tsx   | 12 +---
 .../property/property/KameletPropertyField.tsx     | 10 +--
 .../webui/src/designer/utils/ValidatorUtils.ts     | 29 +++++++++
 karavan-app/src/main/webui/src/util/StringUtils.ts | 17 +++++
 karavan-designer/public/example/demo.camel.yaml    | 27 +++-----
 .../designer/property/property/BeanProperties.tsx  | 75 ++++++++++------------
 .../property/property/ComponentPropertyField.tsx   | 12 +---
 .../property/property/KameletPropertyField.tsx     | 10 +--
 .../src/designer/utils/ValidatorUtils.ts           | 29 +++++++++
 .../designer/property/property/BeanProperties.tsx  | 75 ++++++++++------------
 .../property/property/ComponentPropertyField.tsx   | 12 +---
 .../property/property/KameletPropertyField.tsx     | 10 +--
 karavan-space/src/designer/utils/ValidatorUtils.ts | 29 +++++++++
 14 files changed, 223 insertions(+), 199 deletions(-)

diff --git 
a/karavan-app/src/main/webui/src/designer/property/property/BeanProperties.tsx 
b/karavan-app/src/main/webui/src/designer/property/property/BeanProperties.tsx
index 34c93cca..d49cd985 100644
--- 
a/karavan-app/src/main/webui/src/designer/property/property/BeanProperties.tsx
+++ 
b/karavan-app/src/main/webui/src/designer/property/property/BeanProperties.tsx
@@ -16,13 +16,18 @@
  */
 import React, {useEffect, useState} from 'react';
 import {
-    TextInput, Button, Tooltip, Popover, InputGroup, InputGroupItem, 
capitalize,
+    Button,
+    capitalize,
+    InputGroup,
+    InputGroupItem,
+    Popover,
+    TextInput,
+    Tooltip,
+    ValidatedOptions,
 } from '@patternfly/react-core';
 import '../../karavan.css';
 import "@patternfly/patternfly/patternfly.css";
-import {
-    BeanFactoryDefinition,
-} from "karavan-core/lib/model/CamelDefinition";
+import {BeanFactoryDefinition,} from "karavan-core/lib/model/CamelDefinition";
 import {CamelUtil} from "karavan-core/lib/api/CamelUtil";
 import {SensitiveKeys} from "karavan-core/lib/model/CamelMetadata";
 import {v4 as uuidv4} from "uuid";
@@ -31,13 +36,11 @@ import AddIcon from 
"@patternfly/react-icons/dist/js/icons/plus-circle-icon";
 import HelpIcon from "@patternfly/react-icons/dist/js/icons/help-icon";
 import {InfrastructureSelector} from "./InfrastructureSelector";
 import {InfrastructureAPI} from "../../utils/InfrastructureAPI";
-import ShowIcon from "@patternfly/react-icons/dist/js/icons/eye-icon";
-import HideIcon from "@patternfly/react-icons/dist/js/icons/eye-slash-icon";
 import DockerIcon from "@patternfly/react-icons/dist/js/icons/docker-icon";
 import {useDesignerStore} from "../../DesignerStore";
 import {shallow} from "zustand/shallow";
 import {KubernetesIcon} from "../../icons/ComponentIcons";
-
+import {isSensitiveFieldValid} from "../../utils/ValidatorUtils";
 
 interface Props {
     type: 'constructors' | 'properties'
@@ -51,26 +54,26 @@ export function BeanProperties (props: Props) {
     const [infrastructureSelector, setInfrastructureSelector] = 
useState<boolean>(false);
     const [infrastructureSelectorProperty, setInfrastructureSelectorProperty] 
= useState<string | undefined>(undefined);
     const [infrastructureSelectorUuid, setInfrastructureSelectorUuid] = 
useState<string | undefined>(undefined);
-    const [properties, setProperties] = useState<Map<string, [string, string, 
boolean]>>(new Map<string, [string, string, boolean]>());
-    const [constructors, setConstructors] = useState<Map<string, [number, 
string, boolean]>>(new Map<string, [number, string, boolean]>());
+    const [properties, setProperties] = useState<Map<string, [string, 
string]>>(new Map<string, [string, string]>());
+    const [constructors, setConstructors] = useState<Map<string, [number, 
string]>>(new Map<string, [number, string]>());
 
     useEffect(()=> {
         setProperties(preparePropertiesMap((selectedStep as 
BeanFactoryDefinition)?.properties))
         setConstructors(prepareConstructorsMap((selectedStep as 
BeanFactoryDefinition)?.constructors))
     }, [selectedStep?.uuid])
 
-    function preparePropertiesMap (properties: any): Map<string, [string, 
string, boolean]>  {
-        const result = new Map<string, [string, string, boolean]>();
+    function preparePropertiesMap (properties: any): Map<string, [string, 
string]>  {
+        const result = new Map<string, [string, string]>();
         if (properties) {
-            Object.keys(properties).forEach((k, i, a) => result.set(uuidv4(), 
[k, properties[k], false]));
+            Object.keys(properties).forEach((k, i, a) => result.set(uuidv4(), 
[k, properties[k]]));
         }
         return result;
     }
 
-    function prepareConstructorsMap (constructors: any): Map<string, [number, 
string, boolean]>  {
-        const result = new Map<string, [number, string, boolean]>();
+    function prepareConstructorsMap (constructors: any): Map<string, [number, 
string]>  {
+        const result = new Map<string, [number, string]>();
         if (constructors) {
-            Object.keys(constructors).forEach((k, i, a) => 
result.set(uuidv4(), [parseInt(k), constructors[k], false]));
+            Object.keys(constructors).forEach((k, i, a) => 
result.set(uuidv4(), [parseInt(k), constructors[k]]));
         }
         return result;
     }
@@ -103,17 +106,17 @@ export function BeanProperties (props: Props) {
         }
     }
 
-    function propertyChanged (uuid: string, key: string, value: string, 
showPassword: boolean)  {
+    function propertyChanged (uuid: string, key: string, value: string)  {
         setProperties(prevState => {
-            prevState.set(uuid, [key, value, showPassword]);
+            prevState.set(uuid, [key, value]);
             return prevState;
         });
         onBeanPropertyUpdate();
     }
 
-    function constructorChanged (uuid: string, key: number, value: string, 
showPassword: boolean)  {
+    function constructorChanged (uuid: string, key: number, value: string)  {
         setConstructors(prevState => {
-            prevState.set(uuid, [key, value, showPassword]);
+            prevState.set(uuid, [key, value]);
             return prevState;
         });
         onBeanConstructorsUpdate();
@@ -140,7 +143,7 @@ export function BeanProperties (props: Props) {
         const uuid = infrastructureSelectorUuid;
         if (propertyId && uuid){
             if (value.startsWith("config") || value.startsWith("secret")) 
value = "{{" + value + "}}";
-            propertyChanged(uuid, propertyId, value, false);
+            propertyChanged(uuid, propertyId, value);
             setInfrastructureSelector(false);
             setInfrastructureSelectorProperty(undefined);
         }
@@ -201,20 +204,19 @@ export function BeanProperties (props: Props) {
                     const i = v[0];
                     const key = v[1][0];
                     const value = v[1][1];
-                    const showPassword = v[1][2];
                     const isSecret = false;
                     return (
                         <div key={"key-" + i} className="bean-property">
                             <TextInput placeholder="Argument Index" 
className="text-field" isRequired type="text" id={"key-" + i}
                                        name={"key-" + i} value={key}
                                        onChange={(_, beanFieldName) => {
-                                           constructorChanged(i, 
parseInt(beanFieldName) , value, showPassword)
+                                           constructorChanged(i, 
parseInt(beanFieldName) , value)
                                        }}/>
                             <InputGroup>
                                 <InputGroupItem isFill>
                                     <TextInput
                                         placeholder="Argument Value"
-                                        type={isSecret && !showPassword ? 
"password" : "text"}
+                                        type='text'
                                         autoComplete="off"
                                         className="text-field"
                                         isRequired
@@ -222,14 +224,9 @@ export function BeanProperties (props: Props) {
                                         name={"value-" + i}
                                         value={value}
                                         onChange={(_, value) => {
-                                            constructorChanged(i, key, value, 
showPassword)
+                                            constructorChanged(i, key, value)
                                         }}/>
                                 </InputGroupItem>
-                                {isSecret && <Tooltip position="bottom-end" 
content={showPassword ? "Hide" : "Show"}>
-                                    <Button variant="control" onClick={e => 
constructorChanged(i, key, value, !showPassword)}>
-                                        {showPassword ? <ShowIcon/> : 
<HideIcon/>}
-                                    </Button>
-                                </Tooltip>}
                             </InputGroup>
                             <Button variant="link" className="delete-button" 
onClick={e => constructorDeleted(i)}>
                                 <DeleteIcon/>
@@ -237,7 +234,7 @@ export function BeanProperties (props: Props) {
                         </div>
                     )
                 })}
-                <Button variant="link" className="add-button" onClick={e => 
constructorChanged(uuidv4(), constructors.size, '', false)}>
+                <Button variant="link" className="add-button" onClick={e => 
constructorChanged(uuidv4(), constructors.size, '')}>
                     <AddIcon/>Add argument</Button>
             </>
         )
@@ -250,8 +247,8 @@ export function BeanProperties (props: Props) {
                     const i = v[0];
                     const key = v[1][0];
                     const value = v[1][1];
-                    const showPassword = v[1][2];
                     const isSecret = key !== undefined && 
SensitiveKeys.includes(key.toLowerCase());
+                    const validated = (isSecret && 
!isSensitiveFieldValid(value)) ? ValidatedOptions.error : 
ValidatedOptions.default;
                     const inInfrastructure = InfrastructureAPI.infrastructure 
!== 'local';
                     const icon = InfrastructureAPI.infrastructure === 
'kubernetes' ? KubernetesIcon("infra-button"): <DockerIcon/>
                     return (
@@ -259,11 +256,11 @@ export function BeanProperties (props: Props) {
                             <TextInput placeholder="Bean Field Name" 
className="text-field" isRequired type="text" id={"key-" + i}
                                        name={"key-" + i} value={key}
                                        onChange={(_, beanFieldName) => {
-                                           propertyChanged(i, beanFieldName, 
value, showPassword)
+                                           propertyChanged(i, beanFieldName, 
value)
                                        }}/>
                             <InputGroup>
                                 {inInfrastructure &&
-                                    <Tooltip position="bottom-end" 
content={"Select from " + capitalize(InfrastructureAPI.infrastructure)}>
+                                    <Tooltip position="bottom-end" 
content={'Select from ' + capitalize(InfrastructureAPI.infrastructure)}>
                                         <Button variant="control" onClick={e 
=> openInfrastructureSelector(i, key)}>
                                             {icon}
                                         </Button>
@@ -271,28 +268,24 @@ export function BeanProperties (props: Props) {
                                 <InputGroupItem isFill>
                                     <TextInput
                                         placeholder="Bean Field Value"
-                                        type={isSecret && !showPassword ? 
"password" : "text"}
+                                        type='text'
                                         autoComplete="off"
                                         className="text-field"
                                         isRequired
+                                        validated={validated}
                                         id={"value-" + i}
                                         name={"value-" + i}
                                         value={value}
                                         onChange={(_, value) => {
-                                            propertyChanged(i, key, value, 
showPassword)
+                                            propertyChanged(i, key, value)
                                         }}/>
                                 </InputGroupItem>
-                                {isSecret && <Tooltip position="bottom-end" 
content={showPassword ? "Hide" : "Show"}>
-                                    <Button variant="control" onClick={e => 
propertyChanged(i, key, value, !showPassword)}>
-                                        {showPassword ? <ShowIcon/> : 
<HideIcon/>}
-                                    </Button>
-                                </Tooltip>}
                             </InputGroup>
                             <Button variant="link" className="delete-button" 
onClick={e => propertyDeleted(i)}><DeleteIcon/></Button>
                         </div>
                     )
                 })}
-                <Button variant="link" className="add-button" onClick={e => 
propertyChanged(uuidv4(), '', '', false)}>
+                <Button variant="link" className="add-button" onClick={e => 
propertyChanged(uuidv4(), '', '')}>
                     <AddIcon/>Add property</Button>
             </>
         )
diff --git 
a/karavan-app/src/main/webui/src/designer/property/property/ComponentPropertyField.tsx
 
b/karavan-app/src/main/webui/src/designer/property/property/ComponentPropertyField.tsx
index 27e22780..57ff7d4c 100644
--- 
a/karavan-app/src/main/webui/src/designer/property/property/ComponentPropertyField.tsx
+++ 
b/karavan-app/src/main/webui/src/designer/property/property/ComponentPropertyField.tsx
@@ -78,7 +78,6 @@ export function ComponentPropertyField(props: Props) {
 
     const [selectStatus, setSelectStatus] = useState<Map<string, boolean>>(new 
Map<string, boolean>());
     const [showEditor, setShowEditor] = useState<boolean>(false);
-    const [showPassword, setShowPassword] = useState<boolean>(false);
     const [infrastructureSelector, setInfrastructureSelector] = 
useState<boolean>(false);
     const [infrastructureSelectorProperty, setInfrastructureSelectorProperty] 
= useState<string | undefined>(undefined);
     const [id, setId] = useState<string>(prefix + "-" + props.property.name);
@@ -266,7 +265,7 @@ export function ComponentPropertyField(props: Props) {
                 </Tooltip>}
             {(!showEditor || property.secret) &&
                 <TextInput className="text-field" isRequired ref={ref}
-                           type={property.secret && !showPassword ? "password" 
: "text"}
+                           type="text"
                            autoComplete="off"
                            id={id} name={id}
                            value={(textValue !== undefined ? textValue : 
property.defaultValue) || ''}
@@ -299,13 +298,6 @@ export function ComponentPropertyField(props: Props) {
                                            setCheckChanges(false);
                                        }}/>
             </InputGroupItem>}
-            {property.secret &&
-                <Tooltip position="bottom-end" content={showPassword ? "Hide" 
: "Show"}>
-                    <Button variant="control" onClick={e => 
setShowPassword(!showPassword)}>
-                        {showPassword ? <ShowIcon/> : <HideIcon/>}
-                    </Button>
-                </Tooltip>
-            }
             <InputGroupItem>
                 <PropertyPlaceholderDropdown property={property} value={value} 
onComponentPropertyChange={(parameter, v) => {
                     onParametersChange(parameter, v);
@@ -322,7 +314,7 @@ export function ComponentPropertyField(props: Props) {
                 <InputGroupItem isFill>
                     <TextInput
                         className="text-field" isRequired
-                        type={(property.secret ? "password" : "text")}
+                        type="text"
                         autoComplete="off"
                         id={id} name={id}
                         value={(textValue !== undefined ? textValue : 
property.defaultValue) || ''}
diff --git 
a/karavan-app/src/main/webui/src/designer/property/property/KameletPropertyField.tsx
 
b/karavan-app/src/main/webui/src/designer/property/property/KameletPropertyField.tsx
index 0e1e2bf0..d70582b5 100644
--- 
a/karavan-app/src/main/webui/src/designer/property/property/KameletPropertyField.tsx
+++ 
b/karavan-app/src/main/webui/src/designer/property/property/KameletPropertyField.tsx
@@ -51,7 +51,6 @@ export function KameletPropertyField(props: Props) {
 
     const [dark] = useDesignerStore((s) => [s.dark], shallow)
     const [showEditor, setShowEditor] = useState<boolean>(false);
-    const [showPassword, setShowPassword] = useState<boolean>(false);
     const [infrastructureSelector, setInfrastructureSelector] = 
useState<boolean>(false);
     const [infrastructureSelectorProperty, setInfrastructureSelectorProperty] 
= useState<string | undefined>(undefined);
     const [selectStatus, setSelectStatus] = useState<Map<string, boolean>>(new 
Map<string, boolean>());
@@ -171,7 +170,7 @@ export function KameletPropertyField(props: Props) {
                 <TextInput
                     ref={ref}
                     className="text-field" isRequired
-                    type={property.format && !showPassword ? "password" : 
"text"}
+                    type='text'
                     autoComplete="off"
                     id={id} name={id}
                     value={textValue}
@@ -220,13 +219,6 @@ export function KameletPropertyField(props: Props) {
                         setCheckChanges(true);
                     }}/>
             </InputGroupItem>
-            {property.format === "password" &&
-                <Tooltip position="bottom-end" content={showPassword ? "Hide" 
: "Show"}>
-                    <Button variant="control" onClick={e => 
setShowPassword(!showPassword)}>
-                        {showPassword ? <ShowIcon/> : <HideIcon/>}
-                    </Button>
-                </Tooltip>
-            }
         </InputGroup>
     }
 
diff --git a/karavan-app/src/main/webui/src/designer/utils/ValidatorUtils.ts 
b/karavan-app/src/main/webui/src/designer/utils/ValidatorUtils.ts
new file mode 100644
index 00000000..b9240dad
--- /dev/null
+++ b/karavan-app/src/main/webui/src/designer/utils/ValidatorUtils.ts
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export function isSensitiveFieldValid(field: string): boolean {
+    if (field === undefined || field.trim() === "") {
+        return true;
+    }
+    if (field.startsWith("{{") && field.endsWith("}}")) {
+        const content = field.slice(2, -2).trim();
+        return content !== "";
+    }
+    return false;
+}
+
+
diff --git a/karavan-app/src/main/webui/src/util/StringUtils.ts 
b/karavan-app/src/main/webui/src/util/StringUtils.ts
index e6ad8644..e1e9e56c 100644
--- a/karavan-app/src/main/webui/src/util/StringUtils.ts
+++ b/karavan-app/src/main/webui/src/util/StringUtils.ts
@@ -1,3 +1,20 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 export function isEmpty(str: string) {
     return !str?.trim();
 }
diff --git a/karavan-designer/public/example/demo.camel.yaml 
b/karavan-designer/public/example/demo.camel.yaml
index b6f75ab3..b60f1af7 100644
--- a/karavan-designer/public/example/demo.camel.yaml
+++ b/karavan-designer/public/example/demo.camel.yaml
@@ -1,7 +1,3 @@
-- rest:
-    id: rest-fe3c
-    get:
-      - id: get-8c13
 - routeTemplate:
     id: routeFileReaderTemplate
     description: File reader
@@ -9,18 +5,12 @@
       id: routeFileReader
       description: File reader
       from:
-        id: from-c667
-        description: Read file
-        uri: file
-        parameters:
-          directoryName: "{{folderName}}"
-          noop: true
+        id: from-4101
+        uri: sftp
         steps:
           - to:
               id: to-1234
-              uri: direct
-              parameters:
-                name: converter
+              uri: sql
     parameters:
       - name: folderName
 - routeTemplate:
@@ -30,12 +20,8 @@
       id: routeFileReader 2
       description: File reader 2
       from:
-        id: from-c667
-        description: Read file
-        uri: file
-        parameters:
-          directoryName: "{{folderName}}"
-          noop: true
+        id: from-4101
+        uri: sftp
         steps:
           - to:
               id: to-1234
@@ -49,6 +35,9 @@
     from:
       id: from-b6a5
       uri: kamelet:aws-kinesis-source
+      parameters:
+        secretKey: asasdasd
+        accessKey: asdasd
       steps:
         - log:
             id: log-b47b
diff --git a/karavan-designer/src/designer/property/property/BeanProperties.tsx 
b/karavan-designer/src/designer/property/property/BeanProperties.tsx
index 34c93cca..d49cd985 100644
--- a/karavan-designer/src/designer/property/property/BeanProperties.tsx
+++ b/karavan-designer/src/designer/property/property/BeanProperties.tsx
@@ -16,13 +16,18 @@
  */
 import React, {useEffect, useState} from 'react';
 import {
-    TextInput, Button, Tooltip, Popover, InputGroup, InputGroupItem, 
capitalize,
+    Button,
+    capitalize,
+    InputGroup,
+    InputGroupItem,
+    Popover,
+    TextInput,
+    Tooltip,
+    ValidatedOptions,
 } from '@patternfly/react-core';
 import '../../karavan.css';
 import "@patternfly/patternfly/patternfly.css";
-import {
-    BeanFactoryDefinition,
-} from "karavan-core/lib/model/CamelDefinition";
+import {BeanFactoryDefinition,} from "karavan-core/lib/model/CamelDefinition";
 import {CamelUtil} from "karavan-core/lib/api/CamelUtil";
 import {SensitiveKeys} from "karavan-core/lib/model/CamelMetadata";
 import {v4 as uuidv4} from "uuid";
@@ -31,13 +36,11 @@ import AddIcon from 
"@patternfly/react-icons/dist/js/icons/plus-circle-icon";
 import HelpIcon from "@patternfly/react-icons/dist/js/icons/help-icon";
 import {InfrastructureSelector} from "./InfrastructureSelector";
 import {InfrastructureAPI} from "../../utils/InfrastructureAPI";
-import ShowIcon from "@patternfly/react-icons/dist/js/icons/eye-icon";
-import HideIcon from "@patternfly/react-icons/dist/js/icons/eye-slash-icon";
 import DockerIcon from "@patternfly/react-icons/dist/js/icons/docker-icon";
 import {useDesignerStore} from "../../DesignerStore";
 import {shallow} from "zustand/shallow";
 import {KubernetesIcon} from "../../icons/ComponentIcons";
-
+import {isSensitiveFieldValid} from "../../utils/ValidatorUtils";
 
 interface Props {
     type: 'constructors' | 'properties'
@@ -51,26 +54,26 @@ export function BeanProperties (props: Props) {
     const [infrastructureSelector, setInfrastructureSelector] = 
useState<boolean>(false);
     const [infrastructureSelectorProperty, setInfrastructureSelectorProperty] 
= useState<string | undefined>(undefined);
     const [infrastructureSelectorUuid, setInfrastructureSelectorUuid] = 
useState<string | undefined>(undefined);
-    const [properties, setProperties] = useState<Map<string, [string, string, 
boolean]>>(new Map<string, [string, string, boolean]>());
-    const [constructors, setConstructors] = useState<Map<string, [number, 
string, boolean]>>(new Map<string, [number, string, boolean]>());
+    const [properties, setProperties] = useState<Map<string, [string, 
string]>>(new Map<string, [string, string]>());
+    const [constructors, setConstructors] = useState<Map<string, [number, 
string]>>(new Map<string, [number, string]>());
 
     useEffect(()=> {
         setProperties(preparePropertiesMap((selectedStep as 
BeanFactoryDefinition)?.properties))
         setConstructors(prepareConstructorsMap((selectedStep as 
BeanFactoryDefinition)?.constructors))
     }, [selectedStep?.uuid])
 
-    function preparePropertiesMap (properties: any): Map<string, [string, 
string, boolean]>  {
-        const result = new Map<string, [string, string, boolean]>();
+    function preparePropertiesMap (properties: any): Map<string, [string, 
string]>  {
+        const result = new Map<string, [string, string]>();
         if (properties) {
-            Object.keys(properties).forEach((k, i, a) => result.set(uuidv4(), 
[k, properties[k], false]));
+            Object.keys(properties).forEach((k, i, a) => result.set(uuidv4(), 
[k, properties[k]]));
         }
         return result;
     }
 
-    function prepareConstructorsMap (constructors: any): Map<string, [number, 
string, boolean]>  {
-        const result = new Map<string, [number, string, boolean]>();
+    function prepareConstructorsMap (constructors: any): Map<string, [number, 
string]>  {
+        const result = new Map<string, [number, string]>();
         if (constructors) {
-            Object.keys(constructors).forEach((k, i, a) => 
result.set(uuidv4(), [parseInt(k), constructors[k], false]));
+            Object.keys(constructors).forEach((k, i, a) => 
result.set(uuidv4(), [parseInt(k), constructors[k]]));
         }
         return result;
     }
@@ -103,17 +106,17 @@ export function BeanProperties (props: Props) {
         }
     }
 
-    function propertyChanged (uuid: string, key: string, value: string, 
showPassword: boolean)  {
+    function propertyChanged (uuid: string, key: string, value: string)  {
         setProperties(prevState => {
-            prevState.set(uuid, [key, value, showPassword]);
+            prevState.set(uuid, [key, value]);
             return prevState;
         });
         onBeanPropertyUpdate();
     }
 
-    function constructorChanged (uuid: string, key: number, value: string, 
showPassword: boolean)  {
+    function constructorChanged (uuid: string, key: number, value: string)  {
         setConstructors(prevState => {
-            prevState.set(uuid, [key, value, showPassword]);
+            prevState.set(uuid, [key, value]);
             return prevState;
         });
         onBeanConstructorsUpdate();
@@ -140,7 +143,7 @@ export function BeanProperties (props: Props) {
         const uuid = infrastructureSelectorUuid;
         if (propertyId && uuid){
             if (value.startsWith("config") || value.startsWith("secret")) 
value = "{{" + value + "}}";
-            propertyChanged(uuid, propertyId, value, false);
+            propertyChanged(uuid, propertyId, value);
             setInfrastructureSelector(false);
             setInfrastructureSelectorProperty(undefined);
         }
@@ -201,20 +204,19 @@ export function BeanProperties (props: Props) {
                     const i = v[0];
                     const key = v[1][0];
                     const value = v[1][1];
-                    const showPassword = v[1][2];
                     const isSecret = false;
                     return (
                         <div key={"key-" + i} className="bean-property">
                             <TextInput placeholder="Argument Index" 
className="text-field" isRequired type="text" id={"key-" + i}
                                        name={"key-" + i} value={key}
                                        onChange={(_, beanFieldName) => {
-                                           constructorChanged(i, 
parseInt(beanFieldName) , value, showPassword)
+                                           constructorChanged(i, 
parseInt(beanFieldName) , value)
                                        }}/>
                             <InputGroup>
                                 <InputGroupItem isFill>
                                     <TextInput
                                         placeholder="Argument Value"
-                                        type={isSecret && !showPassword ? 
"password" : "text"}
+                                        type='text'
                                         autoComplete="off"
                                         className="text-field"
                                         isRequired
@@ -222,14 +224,9 @@ export function BeanProperties (props: Props) {
                                         name={"value-" + i}
                                         value={value}
                                         onChange={(_, value) => {
-                                            constructorChanged(i, key, value, 
showPassword)
+                                            constructorChanged(i, key, value)
                                         }}/>
                                 </InputGroupItem>
-                                {isSecret && <Tooltip position="bottom-end" 
content={showPassword ? "Hide" : "Show"}>
-                                    <Button variant="control" onClick={e => 
constructorChanged(i, key, value, !showPassword)}>
-                                        {showPassword ? <ShowIcon/> : 
<HideIcon/>}
-                                    </Button>
-                                </Tooltip>}
                             </InputGroup>
                             <Button variant="link" className="delete-button" 
onClick={e => constructorDeleted(i)}>
                                 <DeleteIcon/>
@@ -237,7 +234,7 @@ export function BeanProperties (props: Props) {
                         </div>
                     )
                 })}
-                <Button variant="link" className="add-button" onClick={e => 
constructorChanged(uuidv4(), constructors.size, '', false)}>
+                <Button variant="link" className="add-button" onClick={e => 
constructorChanged(uuidv4(), constructors.size, '')}>
                     <AddIcon/>Add argument</Button>
             </>
         )
@@ -250,8 +247,8 @@ export function BeanProperties (props: Props) {
                     const i = v[0];
                     const key = v[1][0];
                     const value = v[1][1];
-                    const showPassword = v[1][2];
                     const isSecret = key !== undefined && 
SensitiveKeys.includes(key.toLowerCase());
+                    const validated = (isSecret && 
!isSensitiveFieldValid(value)) ? ValidatedOptions.error : 
ValidatedOptions.default;
                     const inInfrastructure = InfrastructureAPI.infrastructure 
!== 'local';
                     const icon = InfrastructureAPI.infrastructure === 
'kubernetes' ? KubernetesIcon("infra-button"): <DockerIcon/>
                     return (
@@ -259,11 +256,11 @@ export function BeanProperties (props: Props) {
                             <TextInput placeholder="Bean Field Name" 
className="text-field" isRequired type="text" id={"key-" + i}
                                        name={"key-" + i} value={key}
                                        onChange={(_, beanFieldName) => {
-                                           propertyChanged(i, beanFieldName, 
value, showPassword)
+                                           propertyChanged(i, beanFieldName, 
value)
                                        }}/>
                             <InputGroup>
                                 {inInfrastructure &&
-                                    <Tooltip position="bottom-end" 
content={"Select from " + capitalize(InfrastructureAPI.infrastructure)}>
+                                    <Tooltip position="bottom-end" 
content={'Select from ' + capitalize(InfrastructureAPI.infrastructure)}>
                                         <Button variant="control" onClick={e 
=> openInfrastructureSelector(i, key)}>
                                             {icon}
                                         </Button>
@@ -271,28 +268,24 @@ export function BeanProperties (props: Props) {
                                 <InputGroupItem isFill>
                                     <TextInput
                                         placeholder="Bean Field Value"
-                                        type={isSecret && !showPassword ? 
"password" : "text"}
+                                        type='text'
                                         autoComplete="off"
                                         className="text-field"
                                         isRequired
+                                        validated={validated}
                                         id={"value-" + i}
                                         name={"value-" + i}
                                         value={value}
                                         onChange={(_, value) => {
-                                            propertyChanged(i, key, value, 
showPassword)
+                                            propertyChanged(i, key, value)
                                         }}/>
                                 </InputGroupItem>
-                                {isSecret && <Tooltip position="bottom-end" 
content={showPassword ? "Hide" : "Show"}>
-                                    <Button variant="control" onClick={e => 
propertyChanged(i, key, value, !showPassword)}>
-                                        {showPassword ? <ShowIcon/> : 
<HideIcon/>}
-                                    </Button>
-                                </Tooltip>}
                             </InputGroup>
                             <Button variant="link" className="delete-button" 
onClick={e => propertyDeleted(i)}><DeleteIcon/></Button>
                         </div>
                     )
                 })}
-                <Button variant="link" className="add-button" onClick={e => 
propertyChanged(uuidv4(), '', '', false)}>
+                <Button variant="link" className="add-button" onClick={e => 
propertyChanged(uuidv4(), '', '')}>
                     <AddIcon/>Add property</Button>
             </>
         )
diff --git 
a/karavan-designer/src/designer/property/property/ComponentPropertyField.tsx 
b/karavan-designer/src/designer/property/property/ComponentPropertyField.tsx
index 27e22780..57ff7d4c 100644
--- a/karavan-designer/src/designer/property/property/ComponentPropertyField.tsx
+++ b/karavan-designer/src/designer/property/property/ComponentPropertyField.tsx
@@ -78,7 +78,6 @@ export function ComponentPropertyField(props: Props) {
 
     const [selectStatus, setSelectStatus] = useState<Map<string, boolean>>(new 
Map<string, boolean>());
     const [showEditor, setShowEditor] = useState<boolean>(false);
-    const [showPassword, setShowPassword] = useState<boolean>(false);
     const [infrastructureSelector, setInfrastructureSelector] = 
useState<boolean>(false);
     const [infrastructureSelectorProperty, setInfrastructureSelectorProperty] 
= useState<string | undefined>(undefined);
     const [id, setId] = useState<string>(prefix + "-" + props.property.name);
@@ -266,7 +265,7 @@ export function ComponentPropertyField(props: Props) {
                 </Tooltip>}
             {(!showEditor || property.secret) &&
                 <TextInput className="text-field" isRequired ref={ref}
-                           type={property.secret && !showPassword ? "password" 
: "text"}
+                           type="text"
                            autoComplete="off"
                            id={id} name={id}
                            value={(textValue !== undefined ? textValue : 
property.defaultValue) || ''}
@@ -299,13 +298,6 @@ export function ComponentPropertyField(props: Props) {
                                            setCheckChanges(false);
                                        }}/>
             </InputGroupItem>}
-            {property.secret &&
-                <Tooltip position="bottom-end" content={showPassword ? "Hide" 
: "Show"}>
-                    <Button variant="control" onClick={e => 
setShowPassword(!showPassword)}>
-                        {showPassword ? <ShowIcon/> : <HideIcon/>}
-                    </Button>
-                </Tooltip>
-            }
             <InputGroupItem>
                 <PropertyPlaceholderDropdown property={property} value={value} 
onComponentPropertyChange={(parameter, v) => {
                     onParametersChange(parameter, v);
@@ -322,7 +314,7 @@ export function ComponentPropertyField(props: Props) {
                 <InputGroupItem isFill>
                     <TextInput
                         className="text-field" isRequired
-                        type={(property.secret ? "password" : "text")}
+                        type="text"
                         autoComplete="off"
                         id={id} name={id}
                         value={(textValue !== undefined ? textValue : 
property.defaultValue) || ''}
diff --git 
a/karavan-designer/src/designer/property/property/KameletPropertyField.tsx 
b/karavan-designer/src/designer/property/property/KameletPropertyField.tsx
index 0e1e2bf0..d70582b5 100644
--- a/karavan-designer/src/designer/property/property/KameletPropertyField.tsx
+++ b/karavan-designer/src/designer/property/property/KameletPropertyField.tsx
@@ -51,7 +51,6 @@ export function KameletPropertyField(props: Props) {
 
     const [dark] = useDesignerStore((s) => [s.dark], shallow)
     const [showEditor, setShowEditor] = useState<boolean>(false);
-    const [showPassword, setShowPassword] = useState<boolean>(false);
     const [infrastructureSelector, setInfrastructureSelector] = 
useState<boolean>(false);
     const [infrastructureSelectorProperty, setInfrastructureSelectorProperty] 
= useState<string | undefined>(undefined);
     const [selectStatus, setSelectStatus] = useState<Map<string, boolean>>(new 
Map<string, boolean>());
@@ -171,7 +170,7 @@ export function KameletPropertyField(props: Props) {
                 <TextInput
                     ref={ref}
                     className="text-field" isRequired
-                    type={property.format && !showPassword ? "password" : 
"text"}
+                    type='text'
                     autoComplete="off"
                     id={id} name={id}
                     value={textValue}
@@ -220,13 +219,6 @@ export function KameletPropertyField(props: Props) {
                         setCheckChanges(true);
                     }}/>
             </InputGroupItem>
-            {property.format === "password" &&
-                <Tooltip position="bottom-end" content={showPassword ? "Hide" 
: "Show"}>
-                    <Button variant="control" onClick={e => 
setShowPassword(!showPassword)}>
-                        {showPassword ? <ShowIcon/> : <HideIcon/>}
-                    </Button>
-                </Tooltip>
-            }
         </InputGroup>
     }
 
diff --git a/karavan-designer/src/designer/utils/ValidatorUtils.ts 
b/karavan-designer/src/designer/utils/ValidatorUtils.ts
new file mode 100644
index 00000000..b9240dad
--- /dev/null
+++ b/karavan-designer/src/designer/utils/ValidatorUtils.ts
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export function isSensitiveFieldValid(field: string): boolean {
+    if (field === undefined || field.trim() === "") {
+        return true;
+    }
+    if (field.startsWith("{{") && field.endsWith("}}")) {
+        const content = field.slice(2, -2).trim();
+        return content !== "";
+    }
+    return false;
+}
+
+
diff --git a/karavan-space/src/designer/property/property/BeanProperties.tsx 
b/karavan-space/src/designer/property/property/BeanProperties.tsx
index 34c93cca..d49cd985 100644
--- a/karavan-space/src/designer/property/property/BeanProperties.tsx
+++ b/karavan-space/src/designer/property/property/BeanProperties.tsx
@@ -16,13 +16,18 @@
  */
 import React, {useEffect, useState} from 'react';
 import {
-    TextInput, Button, Tooltip, Popover, InputGroup, InputGroupItem, 
capitalize,
+    Button,
+    capitalize,
+    InputGroup,
+    InputGroupItem,
+    Popover,
+    TextInput,
+    Tooltip,
+    ValidatedOptions,
 } from '@patternfly/react-core';
 import '../../karavan.css';
 import "@patternfly/patternfly/patternfly.css";
-import {
-    BeanFactoryDefinition,
-} from "karavan-core/lib/model/CamelDefinition";
+import {BeanFactoryDefinition,} from "karavan-core/lib/model/CamelDefinition";
 import {CamelUtil} from "karavan-core/lib/api/CamelUtil";
 import {SensitiveKeys} from "karavan-core/lib/model/CamelMetadata";
 import {v4 as uuidv4} from "uuid";
@@ -31,13 +36,11 @@ import AddIcon from 
"@patternfly/react-icons/dist/js/icons/plus-circle-icon";
 import HelpIcon from "@patternfly/react-icons/dist/js/icons/help-icon";
 import {InfrastructureSelector} from "./InfrastructureSelector";
 import {InfrastructureAPI} from "../../utils/InfrastructureAPI";
-import ShowIcon from "@patternfly/react-icons/dist/js/icons/eye-icon";
-import HideIcon from "@patternfly/react-icons/dist/js/icons/eye-slash-icon";
 import DockerIcon from "@patternfly/react-icons/dist/js/icons/docker-icon";
 import {useDesignerStore} from "../../DesignerStore";
 import {shallow} from "zustand/shallow";
 import {KubernetesIcon} from "../../icons/ComponentIcons";
-
+import {isSensitiveFieldValid} from "../../utils/ValidatorUtils";
 
 interface Props {
     type: 'constructors' | 'properties'
@@ -51,26 +54,26 @@ export function BeanProperties (props: Props) {
     const [infrastructureSelector, setInfrastructureSelector] = 
useState<boolean>(false);
     const [infrastructureSelectorProperty, setInfrastructureSelectorProperty] 
= useState<string | undefined>(undefined);
     const [infrastructureSelectorUuid, setInfrastructureSelectorUuid] = 
useState<string | undefined>(undefined);
-    const [properties, setProperties] = useState<Map<string, [string, string, 
boolean]>>(new Map<string, [string, string, boolean]>());
-    const [constructors, setConstructors] = useState<Map<string, [number, 
string, boolean]>>(new Map<string, [number, string, boolean]>());
+    const [properties, setProperties] = useState<Map<string, [string, 
string]>>(new Map<string, [string, string]>());
+    const [constructors, setConstructors] = useState<Map<string, [number, 
string]>>(new Map<string, [number, string]>());
 
     useEffect(()=> {
         setProperties(preparePropertiesMap((selectedStep as 
BeanFactoryDefinition)?.properties))
         setConstructors(prepareConstructorsMap((selectedStep as 
BeanFactoryDefinition)?.constructors))
     }, [selectedStep?.uuid])
 
-    function preparePropertiesMap (properties: any): Map<string, [string, 
string, boolean]>  {
-        const result = new Map<string, [string, string, boolean]>();
+    function preparePropertiesMap (properties: any): Map<string, [string, 
string]>  {
+        const result = new Map<string, [string, string]>();
         if (properties) {
-            Object.keys(properties).forEach((k, i, a) => result.set(uuidv4(), 
[k, properties[k], false]));
+            Object.keys(properties).forEach((k, i, a) => result.set(uuidv4(), 
[k, properties[k]]));
         }
         return result;
     }
 
-    function prepareConstructorsMap (constructors: any): Map<string, [number, 
string, boolean]>  {
-        const result = new Map<string, [number, string, boolean]>();
+    function prepareConstructorsMap (constructors: any): Map<string, [number, 
string]>  {
+        const result = new Map<string, [number, string]>();
         if (constructors) {
-            Object.keys(constructors).forEach((k, i, a) => 
result.set(uuidv4(), [parseInt(k), constructors[k], false]));
+            Object.keys(constructors).forEach((k, i, a) => 
result.set(uuidv4(), [parseInt(k), constructors[k]]));
         }
         return result;
     }
@@ -103,17 +106,17 @@ export function BeanProperties (props: Props) {
         }
     }
 
-    function propertyChanged (uuid: string, key: string, value: string, 
showPassword: boolean)  {
+    function propertyChanged (uuid: string, key: string, value: string)  {
         setProperties(prevState => {
-            prevState.set(uuid, [key, value, showPassword]);
+            prevState.set(uuid, [key, value]);
             return prevState;
         });
         onBeanPropertyUpdate();
     }
 
-    function constructorChanged (uuid: string, key: number, value: string, 
showPassword: boolean)  {
+    function constructorChanged (uuid: string, key: number, value: string)  {
         setConstructors(prevState => {
-            prevState.set(uuid, [key, value, showPassword]);
+            prevState.set(uuid, [key, value]);
             return prevState;
         });
         onBeanConstructorsUpdate();
@@ -140,7 +143,7 @@ export function BeanProperties (props: Props) {
         const uuid = infrastructureSelectorUuid;
         if (propertyId && uuid){
             if (value.startsWith("config") || value.startsWith("secret")) 
value = "{{" + value + "}}";
-            propertyChanged(uuid, propertyId, value, false);
+            propertyChanged(uuid, propertyId, value);
             setInfrastructureSelector(false);
             setInfrastructureSelectorProperty(undefined);
         }
@@ -201,20 +204,19 @@ export function BeanProperties (props: Props) {
                     const i = v[0];
                     const key = v[1][0];
                     const value = v[1][1];
-                    const showPassword = v[1][2];
                     const isSecret = false;
                     return (
                         <div key={"key-" + i} className="bean-property">
                             <TextInput placeholder="Argument Index" 
className="text-field" isRequired type="text" id={"key-" + i}
                                        name={"key-" + i} value={key}
                                        onChange={(_, beanFieldName) => {
-                                           constructorChanged(i, 
parseInt(beanFieldName) , value, showPassword)
+                                           constructorChanged(i, 
parseInt(beanFieldName) , value)
                                        }}/>
                             <InputGroup>
                                 <InputGroupItem isFill>
                                     <TextInput
                                         placeholder="Argument Value"
-                                        type={isSecret && !showPassword ? 
"password" : "text"}
+                                        type='text'
                                         autoComplete="off"
                                         className="text-field"
                                         isRequired
@@ -222,14 +224,9 @@ export function BeanProperties (props: Props) {
                                         name={"value-" + i}
                                         value={value}
                                         onChange={(_, value) => {
-                                            constructorChanged(i, key, value, 
showPassword)
+                                            constructorChanged(i, key, value)
                                         }}/>
                                 </InputGroupItem>
-                                {isSecret && <Tooltip position="bottom-end" 
content={showPassword ? "Hide" : "Show"}>
-                                    <Button variant="control" onClick={e => 
constructorChanged(i, key, value, !showPassword)}>
-                                        {showPassword ? <ShowIcon/> : 
<HideIcon/>}
-                                    </Button>
-                                </Tooltip>}
                             </InputGroup>
                             <Button variant="link" className="delete-button" 
onClick={e => constructorDeleted(i)}>
                                 <DeleteIcon/>
@@ -237,7 +234,7 @@ export function BeanProperties (props: Props) {
                         </div>
                     )
                 })}
-                <Button variant="link" className="add-button" onClick={e => 
constructorChanged(uuidv4(), constructors.size, '', false)}>
+                <Button variant="link" className="add-button" onClick={e => 
constructorChanged(uuidv4(), constructors.size, '')}>
                     <AddIcon/>Add argument</Button>
             </>
         )
@@ -250,8 +247,8 @@ export function BeanProperties (props: Props) {
                     const i = v[0];
                     const key = v[1][0];
                     const value = v[1][1];
-                    const showPassword = v[1][2];
                     const isSecret = key !== undefined && 
SensitiveKeys.includes(key.toLowerCase());
+                    const validated = (isSecret && 
!isSensitiveFieldValid(value)) ? ValidatedOptions.error : 
ValidatedOptions.default;
                     const inInfrastructure = InfrastructureAPI.infrastructure 
!== 'local';
                     const icon = InfrastructureAPI.infrastructure === 
'kubernetes' ? KubernetesIcon("infra-button"): <DockerIcon/>
                     return (
@@ -259,11 +256,11 @@ export function BeanProperties (props: Props) {
                             <TextInput placeholder="Bean Field Name" 
className="text-field" isRequired type="text" id={"key-" + i}
                                        name={"key-" + i} value={key}
                                        onChange={(_, beanFieldName) => {
-                                           propertyChanged(i, beanFieldName, 
value, showPassword)
+                                           propertyChanged(i, beanFieldName, 
value)
                                        }}/>
                             <InputGroup>
                                 {inInfrastructure &&
-                                    <Tooltip position="bottom-end" 
content={"Select from " + capitalize(InfrastructureAPI.infrastructure)}>
+                                    <Tooltip position="bottom-end" 
content={'Select from ' + capitalize(InfrastructureAPI.infrastructure)}>
                                         <Button variant="control" onClick={e 
=> openInfrastructureSelector(i, key)}>
                                             {icon}
                                         </Button>
@@ -271,28 +268,24 @@ export function BeanProperties (props: Props) {
                                 <InputGroupItem isFill>
                                     <TextInput
                                         placeholder="Bean Field Value"
-                                        type={isSecret && !showPassword ? 
"password" : "text"}
+                                        type='text'
                                         autoComplete="off"
                                         className="text-field"
                                         isRequired
+                                        validated={validated}
                                         id={"value-" + i}
                                         name={"value-" + i}
                                         value={value}
                                         onChange={(_, value) => {
-                                            propertyChanged(i, key, value, 
showPassword)
+                                            propertyChanged(i, key, value)
                                         }}/>
                                 </InputGroupItem>
-                                {isSecret && <Tooltip position="bottom-end" 
content={showPassword ? "Hide" : "Show"}>
-                                    <Button variant="control" onClick={e => 
propertyChanged(i, key, value, !showPassword)}>
-                                        {showPassword ? <ShowIcon/> : 
<HideIcon/>}
-                                    </Button>
-                                </Tooltip>}
                             </InputGroup>
                             <Button variant="link" className="delete-button" 
onClick={e => propertyDeleted(i)}><DeleteIcon/></Button>
                         </div>
                     )
                 })}
-                <Button variant="link" className="add-button" onClick={e => 
propertyChanged(uuidv4(), '', '', false)}>
+                <Button variant="link" className="add-button" onClick={e => 
propertyChanged(uuidv4(), '', '')}>
                     <AddIcon/>Add property</Button>
             </>
         )
diff --git 
a/karavan-space/src/designer/property/property/ComponentPropertyField.tsx 
b/karavan-space/src/designer/property/property/ComponentPropertyField.tsx
index 27e22780..57ff7d4c 100644
--- a/karavan-space/src/designer/property/property/ComponentPropertyField.tsx
+++ b/karavan-space/src/designer/property/property/ComponentPropertyField.tsx
@@ -78,7 +78,6 @@ export function ComponentPropertyField(props: Props) {
 
     const [selectStatus, setSelectStatus] = useState<Map<string, boolean>>(new 
Map<string, boolean>());
     const [showEditor, setShowEditor] = useState<boolean>(false);
-    const [showPassword, setShowPassword] = useState<boolean>(false);
     const [infrastructureSelector, setInfrastructureSelector] = 
useState<boolean>(false);
     const [infrastructureSelectorProperty, setInfrastructureSelectorProperty] 
= useState<string | undefined>(undefined);
     const [id, setId] = useState<string>(prefix + "-" + props.property.name);
@@ -266,7 +265,7 @@ export function ComponentPropertyField(props: Props) {
                 </Tooltip>}
             {(!showEditor || property.secret) &&
                 <TextInput className="text-field" isRequired ref={ref}
-                           type={property.secret && !showPassword ? "password" 
: "text"}
+                           type="text"
                            autoComplete="off"
                            id={id} name={id}
                            value={(textValue !== undefined ? textValue : 
property.defaultValue) || ''}
@@ -299,13 +298,6 @@ export function ComponentPropertyField(props: Props) {
                                            setCheckChanges(false);
                                        }}/>
             </InputGroupItem>}
-            {property.secret &&
-                <Tooltip position="bottom-end" content={showPassword ? "Hide" 
: "Show"}>
-                    <Button variant="control" onClick={e => 
setShowPassword(!showPassword)}>
-                        {showPassword ? <ShowIcon/> : <HideIcon/>}
-                    </Button>
-                </Tooltip>
-            }
             <InputGroupItem>
                 <PropertyPlaceholderDropdown property={property} value={value} 
onComponentPropertyChange={(parameter, v) => {
                     onParametersChange(parameter, v);
@@ -322,7 +314,7 @@ export function ComponentPropertyField(props: Props) {
                 <InputGroupItem isFill>
                     <TextInput
                         className="text-field" isRequired
-                        type={(property.secret ? "password" : "text")}
+                        type="text"
                         autoComplete="off"
                         id={id} name={id}
                         value={(textValue !== undefined ? textValue : 
property.defaultValue) || ''}
diff --git 
a/karavan-space/src/designer/property/property/KameletPropertyField.tsx 
b/karavan-space/src/designer/property/property/KameletPropertyField.tsx
index 0e1e2bf0..d70582b5 100644
--- a/karavan-space/src/designer/property/property/KameletPropertyField.tsx
+++ b/karavan-space/src/designer/property/property/KameletPropertyField.tsx
@@ -51,7 +51,6 @@ export function KameletPropertyField(props: Props) {
 
     const [dark] = useDesignerStore((s) => [s.dark], shallow)
     const [showEditor, setShowEditor] = useState<boolean>(false);
-    const [showPassword, setShowPassword] = useState<boolean>(false);
     const [infrastructureSelector, setInfrastructureSelector] = 
useState<boolean>(false);
     const [infrastructureSelectorProperty, setInfrastructureSelectorProperty] 
= useState<string | undefined>(undefined);
     const [selectStatus, setSelectStatus] = useState<Map<string, boolean>>(new 
Map<string, boolean>());
@@ -171,7 +170,7 @@ export function KameletPropertyField(props: Props) {
                 <TextInput
                     ref={ref}
                     className="text-field" isRequired
-                    type={property.format && !showPassword ? "password" : 
"text"}
+                    type='text'
                     autoComplete="off"
                     id={id} name={id}
                     value={textValue}
@@ -220,13 +219,6 @@ export function KameletPropertyField(props: Props) {
                         setCheckChanges(true);
                     }}/>
             </InputGroupItem>
-            {property.format === "password" &&
-                <Tooltip position="bottom-end" content={showPassword ? "Hide" 
: "Show"}>
-                    <Button variant="control" onClick={e => 
setShowPassword(!showPassword)}>
-                        {showPassword ? <ShowIcon/> : <HideIcon/>}
-                    </Button>
-                </Tooltip>
-            }
         </InputGroup>
     }
 
diff --git a/karavan-space/src/designer/utils/ValidatorUtils.ts 
b/karavan-space/src/designer/utils/ValidatorUtils.ts
new file mode 100644
index 00000000..b9240dad
--- /dev/null
+++ b/karavan-space/src/designer/utils/ValidatorUtils.ts
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export function isSensitiveFieldValid(field: string): boolean {
+    if (field === undefined || field.trim() === "") {
+        return true;
+    }
+    if (field.startsWith("{{") && field.endsWith("}}")) {
+        const content = field.slice(2, -2).trim();
+        return content !== "";
+    }
+    return false;
+}
+
+

Reply via email to