Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 13 additions & 14 deletions pyicloud/hsa2_bridge.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,9 @@ class _BridgePushPayloadModel(BaseModel):
arbitrary_types_allowed=True,
)

session_uuid: StrictStr = Field(alias="sessionUUID")
# Apple's newer protocol sends flowid instead of echoing back sessionUUID
session_uuid: Optional[StrictStr] = Field(default=None, alias="sessionUUID")
flow_id: Optional[StrictStr] = Field(default=None, alias="flowid")
next_step: Optional[StrictStr | StrictInt] = Field(default=None, alias="nextStep")
rui_url_key: Optional[str] = Field(default=None, alias="ruiURLKey")
txnid: Optional[StrictStr] = None
Expand All @@ -154,12 +156,12 @@ class _BridgePushPayloadModel(BaseModel):
encrypted_code: Optional[StrictStr] = Field(default=None, alias="encryptedCode")
error_code: Optional[StrictInt] = Field(default=None, alias="ec")

@field_validator("session_uuid")
@field_validator("session_uuid", "flow_id")
@classmethod
def _validate_session_uuid(cls, value: str) -> str:
def _validate_session_uuid(cls, value: Optional[str]) -> Optional[str]:
"""Reject blank bridge session identifiers."""
if not value.strip():
raise ValueError("sessionUUID must not be blank")
if value is not None and not value.strip():
raise ValueError("sessionUUID/flowid must not be blank")
return value
Comment on lines +159 to 165
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Allow fallback when sessionUUID is present-but-blank

Right now, a blank sessionUUID raises validation even if flowid is valid. Treat blank identifiers as None so flowid fallback can still work.

Suggested patch
 `@field_validator`("session_uuid", "flow_id")
 `@classmethod`
 def _validate_session_uuid(cls, value: Optional[str]) -> Optional[str]:
     """Reject blank bridge session identifiers."""
-    if value is not None and not value.strip():
-        raise ValueError("sessionUUID/flowid must not be blank")
-    return value
+    if value is None:
+        return None
+    normalized = value.strip()
+    return normalized or None
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pyicloud/hsa2_bridge.py` around lines 159 - 165, The validator
_validate_session_uuid currently raises ValueError for blank session identifiers
which prevents flow_id fallback; change its behavior to treat blank strings as
None instead of raising: in the `@field_validator` for "session_uuid" and
"flow_id" (function _validate_session_uuid) detect if value is not None and
value.strip() is empty, and return None rather than raising an error, keeping
the return type Optional[str] so a present-but-blank session_uuid will be
treated as missing and allow flow_id fallback to proceed.


@field_validator(
Expand Down Expand Up @@ -215,14 +217,16 @@ def from_payload(cls, payload: dict[str, Any]) -> "BridgePushPayload":
"Malformed trusted-device bridge push payload."
) from exc

if not validated.session_uuid:
# Accept flowid (newer Apple protocol) as fallback for sessionUUID
resolved_session_uuid = validated.session_uuid or validated.flow_id
if not resolved_session_uuid:
raise PyiCloudTrustedDevicePromptException(
"Trusted-device bridge push payload is missing sessionUUID."
"Trusted-device bridge push payload is missing sessionUUID/flowid."
)

return cls(
payload=payload,
session_uuid=validated.session_uuid,
session_uuid=resolved_session_uuid,
next_step=(
str(validated.next_step) if validated.next_step is not None else None
),
Expand Down Expand Up @@ -1130,15 +1134,10 @@ def start(
push_payload.next_step,
push_payload.rui_url_key,
)
if push_payload.session_uuid != session_uuid:
raise PyiCloudTrustedDevicePromptException(
"Trusted-device bridge returned a mismatched session UUID."
)

bridge_state = TrustedDeviceBridgeState(
connection_path=connection_path,
push_token=push_token_hex,
session_uuid=session_uuid,
session_uuid=push_payload.session_uuid,
websocket=websocket,
topic=topic,
topics_by_hash=dict(topics_by_hash),
Expand Down
Loading