From 0bafdd8ce366a4ca2223ffe1fac26ee20baced75 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 18 Jan 2026 03:14:48 +0000 Subject: [PATCH 1/4] Initial plan From 88d13c3b539ff8fb1ff448d5e714f011f79a9967 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 18 Jan 2026 03:30:58 +0000 Subject: [PATCH 2/4] Fix intermittent token service test failures due to Base64 padding Co-authored-by: lstein <111189+lstein@users.noreply.github.com> --- tests/app/services/auth/test_token_service.py | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/tests/app/services/auth/test_token_service.py b/tests/app/services/auth/test_token_service.py index f5e47af5b41..f3eab24f3ca 100644 --- a/tests/app/services/auth/test_token_service.py +++ b/tests/app/services/auth/test_token_service.py @@ -151,10 +151,13 @@ def test_verify_token_with_modified_payload(self): token = create_access_token(token_data) - # Try to modify the token by changing a character + # Try to modify the token by changing a character in the middle # JWT tokens are base64 encoded, so changing any character should invalidate the signature - if len(token) > 10: - modified_token = token[:-1] + ("X" if token[-1] != "X" else "Y") + # Note: We change a character in the middle to avoid Base64 padding issues where + # the last character might not affect the decoded value + if len(token) > 50: + mid = len(token) // 2 + modified_token = token[:mid] + ("X" if token[mid] != "X" else "Y") + token[mid + 1 :] verified_data = verify_token(modified_token) assert verified_data is None @@ -291,8 +294,13 @@ def test_token_signature_verification(self): if len(token) > 50: # Change a character in the signature part (last part of JWT) parts = token.split(".") - if len(parts) == 3: - modified_signature = parts[2][:-1] + ("X" if parts[2][-1] != "X" else "Y") + if len(parts) == 3 and len(parts[2]) > 10: + # Modify a character in the middle of the signature to avoid Base64 padding issues + # where the last few characters might not affect the decoded value + mid = len(parts[2]) // 2 + modified_signature = ( + parts[2][:mid] + ("X" if parts[2][mid] != "X" else "Y") + parts[2][mid + 1 :] + ) modified_token = f"{parts[0]}.{parts[1]}.{modified_signature}" assert verify_token(modified_token) is None From 483b9b1c16ca7c09a9e9537b0c29e75fc02676be Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 18 Jan 2026 03:32:26 +0000 Subject: [PATCH 3/4] Address code review: add constants for magic numbers in tests Co-authored-by: lstein <111189+lstein@users.noreply.github.com> --- tests/app/services/auth/test_token_service.py | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/tests/app/services/auth/test_token_service.py b/tests/app/services/auth/test_token_service.py index f3eab24f3ca..e24b574af1f 100644 --- a/tests/app/services/auth/test_token_service.py +++ b/tests/app/services/auth/test_token_service.py @@ -5,6 +5,14 @@ from invokeai.app.services.auth.token_service import TokenData, create_access_token, verify_token +# Minimum token length to safely modify middle characters for testing +# JWT tokens have format header.payload.signature and are typically >180 characters +MIN_TOKEN_LENGTH_FOR_MODIFICATION = 50 + +# Minimum signature length to safely modify middle characters for testing +# JWT signatures are typically 43 characters (base64-encoded HMAC-SHA256) +MIN_SIGNATURE_LENGTH_FOR_MODIFICATION = 10 + class TestTokenCreation: """Tests for JWT token creation.""" @@ -155,7 +163,7 @@ def test_verify_token_with_modified_payload(self): # JWT tokens are base64 encoded, so changing any character should invalidate the signature # Note: We change a character in the middle to avoid Base64 padding issues where # the last character might not affect the decoded value - if len(token) > 50: + if len(token) > MIN_TOKEN_LENGTH_FOR_MODIFICATION: mid = len(token) // 2 modified_token = token[:mid] + ("X" if token[mid] != "X" else "Y") + token[mid + 1 :] verified_data = verify_token(modified_token) @@ -291,10 +299,10 @@ def test_token_signature_verification(self): assert verify_token(token) is not None # Modified token should fail verification - if len(token) > 50: + if len(token) > MIN_TOKEN_LENGTH_FOR_MODIFICATION: # Change a character in the signature part (last part of JWT) parts = token.split(".") - if len(parts) == 3 and len(parts[2]) > 10: + if len(parts) == 3 and len(parts[2]) > MIN_SIGNATURE_LENGTH_FOR_MODIFICATION: # Modify a character in the middle of the signature to avoid Base64 padding issues # where the last few characters might not affect the decoded value mid = len(parts[2]) // 2 From 4741c0102fa1fb3185935f018a81b7fd3e9a2ce8 Mon Sep 17 00:00:00 2001 From: Lincoln Stein Date: Sat, 17 Jan 2026 22:51:17 -0500 Subject: [PATCH 4/4] chore(tests): ruff --- tests/app/services/auth/test_token_service.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/app/services/auth/test_token_service.py b/tests/app/services/auth/test_token_service.py index e24b574af1f..55e7cdbe3bd 100644 --- a/tests/app/services/auth/test_token_service.py +++ b/tests/app/services/auth/test_token_service.py @@ -306,9 +306,7 @@ def test_token_signature_verification(self): # Modify a character in the middle of the signature to avoid Base64 padding issues # where the last few characters might not affect the decoded value mid = len(parts[2]) // 2 - modified_signature = ( - parts[2][:mid] + ("X" if parts[2][mid] != "X" else "Y") + parts[2][mid + 1 :] - ) + modified_signature = parts[2][:mid] + ("X" if parts[2][mid] != "X" else "Y") + parts[2][mid + 1 :] modified_token = f"{parts[0]}.{parts[1]}.{modified_signature}" assert verify_token(modified_token) is None