From c00c1fbaa7d663593cc0396262f0051c31ce9e39 Mon Sep 17 00:00:00 2001 From: curo1305 Date: Fri, 5 Jun 2026 19:15:01 +0200 Subject: [PATCH] feat(07.2-02): add jti UUID claim to create_access_token MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Added "jti": str(uuid.uuid4()) to the access token payload in services/auth.py - Promoted Wave 0 xfail stub test_create_access_token_includes_jti_claim to PASS - Added test_create_access_token_jti_is_unique_per_call uniqueness guard - uuid module was already imported at module top — no new imports needed --- backend/services/auth.py | 1 + backend/tests/test_task2_auth_service.py | 17 +++++++++++++---- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/backend/services/auth.py b/backend/services/auth.py index 24ed573..a51da1b 100644 --- a/backend/services/auth.py +++ b/backend/services/auth.py @@ -95,6 +95,7 @@ def create_access_token(user_id: str, role: str) -> str: "typ": "access", "iat": now, "exp": now + timedelta(minutes=settings.access_token_expire_minutes), + "jti": str(uuid.uuid4()), } return jwt.encode(payload, settings.secret_key, algorithm="HS256") diff --git a/backend/tests/test_task2_auth_service.py b/backend/tests/test_task2_auth_service.py index d3502eb..2bb6f9e 100644 --- a/backend/tests/test_task2_auth_service.py +++ b/backend/tests/test_task2_auth_service.py @@ -194,15 +194,24 @@ async def test_rotate_revoked_token_raises(db_session): await rotate_refresh_token(db_session, raw) -@pytest.mark.xfail(strict=False, reason="Phase 7.2 Wave 1 — jti claim not yet added to create_access_token") def test_create_access_token_includes_jti_claim(): """create_access_token payload must include a 'jti' key with a UUID-format string value.""" import uuid from services.auth import create_access_token, decode_access_token t = create_access_token("test-uid", "user") - payload = decode_access_token(t) - assert "jti" in payload, "jti claim missing from access token payload" - uuid.UUID(payload["jti"]) # raises ValueError if not a valid UUID + decoded = decode_access_token(t) + assert "jti" in decoded, "jti claim missing from access token payload" + assert isinstance(decoded["jti"], str), "jti claim must be a string" + uuid.UUID(decoded["jti"]) # raises ValueError if not a valid UUID + + +def test_create_access_token_jti_is_unique_per_call(): + """Two consecutive create_access_token calls must produce different jti values.""" + import uuid + from services.auth import create_access_token, decode_access_token + t1 = decode_access_token(create_access_token("test-uid", "user")) + t2 = decode_access_token(create_access_token("test-uid", "user")) + assert t1["jti"] != t2["jti"], "jti values must differ between calls" @pytest.mark.asyncio