diff --git a/digital-avatar-app/backend/services/boxim_client.py b/digital-avatar-app/backend/services/boxim_client.py index ce3071b..726da2a 100644 --- a/digital-avatar-app/backend/services/boxim_client.py +++ b/digital-avatar-app/backend/services/boxim_client.py @@ -32,6 +32,8 @@ class BoxIMClient: keys = sorted(params.keys()) sign_parts = [] for k in keys: + if k in ("signature", "accessSecret"): + continue v = params.get(k) if v and v != "" and v != []: sign_parts.append(f"{k}={v}") diff --git a/digital-avatar-app/backend/tests/test_boxim_client.py b/digital-avatar-app/backend/tests/test_boxim_client.py index 230bde2..5bd4d0c 100644 --- a/digital-avatar-app/backend/tests/test_boxim_client.py +++ b/digital-avatar-app/backend/tests/test_boxim_client.py @@ -98,6 +98,28 @@ def test_build_sign_params_contains_required_fields(mock_config): assert len(params["nonce"]) == 12 +def test_build_sign_params_excludes_signature_and_accessSecret_from_signing_string(mock_config): + """signature and accessSecret must be excluded from the signing string to match news_service.py.""" + from services.boxim_client import BoxIMClient + + client = BoxIMClient(mock_config) + + # Pass params that already contain a stale "signature" value + params_with_stale_sig = client._build_sign_params({ + "userId": "u1", + "signature": "OLD_STALE_SIG", + }) + + # The returned signature must be freshly computed (32-char MD5 uppercase), + # NOT the stale value we passed in. + assert params_with_stale_sig["signature"] != "OLD_STALE_SIG" + assert len(params_with_stale_sig["signature"]) == 32 + + # Calling with the same extra params but no stale signature should also work. + params_clean = client._build_sign_params({"userId": "u1"}) + assert len(params_clean["signature"]) == 32 + + def test_build_sign_params_signature_is_deterministic(mock_config): """Same inputs should produce valid MD5 signatures.""" from services.boxim_client import BoxIMClient