feat(07.2-02): add jti UUID claim to create_access_token
- 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
This commit is contained in:
@@ -95,6 +95,7 @@ def create_access_token(user_id: str, role: str) -> str:
|
|||||||
"typ": "access",
|
"typ": "access",
|
||||||
"iat": now,
|
"iat": now,
|
||||||
"exp": now + timedelta(minutes=settings.access_token_expire_minutes),
|
"exp": now + timedelta(minutes=settings.access_token_expire_minutes),
|
||||||
|
"jti": str(uuid.uuid4()),
|
||||||
}
|
}
|
||||||
return jwt.encode(payload, settings.secret_key, algorithm="HS256")
|
return jwt.encode(payload, settings.secret_key, algorithm="HS256")
|
||||||
|
|
||||||
|
|||||||
@@ -194,15 +194,24 @@ async def test_rotate_revoked_token_raises(db_session):
|
|||||||
await rotate_refresh_token(db_session, raw)
|
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():
|
def test_create_access_token_includes_jti_claim():
|
||||||
"""create_access_token payload must include a 'jti' key with a UUID-format string value."""
|
"""create_access_token payload must include a 'jti' key with a UUID-format string value."""
|
||||||
import uuid
|
import uuid
|
||||||
from services.auth import create_access_token, decode_access_token
|
from services.auth import create_access_token, decode_access_token
|
||||||
t = create_access_token("test-uid", "user")
|
t = create_access_token("test-uid", "user")
|
||||||
payload = decode_access_token(t)
|
decoded = decode_access_token(t)
|
||||||
assert "jti" in payload, "jti claim missing from access token payload"
|
assert "jti" in decoded, "jti claim missing from access token payload"
|
||||||
uuid.UUID(payload["jti"]) # raises ValueError if not a valid UUID
|
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
|
@pytest.mark.asyncio
|
||||||
|
|||||||
Reference in New Issue
Block a user