Second commit in the session-expiration-policy series. Lands the error-detail taxonomy from §4.10 of the plan; no UI-visible change yet because the frontend interceptor (commit 7) doesn't read the new detail strings, but the wire is now ready for it. Today every /auth/refresh failure returns 401 "Invalid refresh token" regardless of cause, so the frontend has no way to distinguish "your session ended for security" from "we don't recognize this token at all." This commit introduces: - decode_refresh_token_strict(): wraps jose.jwt.decode and raises a new IdleTokenExpired exception (from ExpiredSignatureError) so callers can branch on idle expiry. All other jose failures still propagate as JWTError. The legacy decode_token() is preserved for access-token, password-reset, and email-verification paths that don't need the distinction. - get_refresh_token_payload(): now maps IdleTokenExpired -> "session_expired_idle", JWTError and wrong-type tokens -> "invalid_refresh_token". - test_session_policy.py: new test file (will accumulate cases across the series). Three tests for the taxonomy: idle-expired returns session_expired_idle; wrong type returns invalid_refresh_token; bad signature returns invalid_refresh_token. 20/20 across test_session_policy + test_auth + test_oauth_callbacks. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
13 KiB
13 KiB