diff --git a/airflow-core/src/airflow/api_fastapi/core_api/datamodels/connections.py b/airflow-core/src/airflow/api_fastapi/core_api/datamodels/connections.py
index 2a6bd6bec8af2..f2ac1f7a9403a 100644
--- a/airflow-core/src/airflow/api_fastapi/core_api/datamodels/connections.py
+++ b/airflow-core/src/airflow/api_fastapi/core_api/datamodels/connections.py
@@ -17,15 +17,12 @@
from __future__ import annotations
-import json
from collections import abc
from typing import Annotated
-from pydantic import Field, field_validator
-from pydantic_core.core_schema import ValidationInfo
+from pydantic import Field
from airflow.api_fastapi.core_api.base import BaseModel, StrictBaseModel
-from airflow.sdk.execution_time.secrets_masker import redact
# Response Models
@@ -42,26 +39,6 @@ class ConnectionResponse(BaseModel):
password: str | None
extra: str | None
- @field_validator("password", mode="after")
- @classmethod
- def redact_password(cls, v: str | None, field_info: ValidationInfo) -> str | None:
- if v is None:
- return None
- return str(redact(v, field_info.field_name))
-
- @field_validator("extra", mode="before")
- @classmethod
- def redact_extra(cls, v: str | None) -> str | None:
- if v is None:
- return None
- try:
- extra_dict = json.loads(v)
- redacted_dict = redact(extra_dict)
- return json.dumps(redacted_dict)
- except json.JSONDecodeError:
- # we can't redact fields in an unstructured `extra`
- return v
-
class ConnectionCollectionResponse(BaseModel):
"""Connection Collection serializer for responses."""
diff --git a/airflow-core/src/airflow/ui/src/pages/Connections/ConnectionForm.tsx b/airflow-core/src/airflow/ui/src/pages/Connections/ConnectionForm.tsx
index bf921a1de3c99..9e4e38647eaf4 100644
--- a/airflow-core/src/airflow/ui/src/pages/Connections/ConnectionForm.tsx
+++ b/airflow-core/src/airflow/ui/src/pages/Connections/ConnectionForm.tsx
@@ -57,7 +57,7 @@ const ConnectionForm = ({
const { conf: extra, setConf } = useParamStore();
const {
control,
- formState: { isValid },
+ formState: { isDirty, isValid },
handleSubmit,
reset,
watch,
@@ -94,6 +94,14 @@ const ConnectionForm = ({
mutateConnection(data);
};
+ const hasChanges = () => {
+ if (isDirty) {
+ return true;
+ }
+
+ return JSON.stringify(JSON.parse(extra)) !== JSON.stringify(JSON.parse(initialConnection.extra));
+ };
+
const validateAndPrettifyJson = (value: string) => {
try {
const parsedJson = JSON.parse(value) as JSON;
@@ -234,7 +242,7 @@ const ConnectionForm = ({