- Parse JWT 'exp' claim to track token expiry (token_expires_at) - Proactively refresh Bearer tokens 1 hour before expiry in ensure_authenticated() - Refresh response without expires_in now falls back to JWT exp for expiry derivation - Support custom refresh_path via bearer auth_config whitelist - Unify 401 fallback: all bearer types (including Sub2API) now go through _refresh_bearer_token() instead of separate old path - Remove dead _is_sub2api_bearer() / _refresh_sub2api_bearer_token() - Add 2 new tests: refresh_path override + JWT exp backfill Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
35 lines
1.2 KiB
Python
35 lines
1.2 KiB
Python
from __future__ import annotations
|
|
|
|
MASK = "***"
|
|
SECRET_KEYS = {"password", "token", "refresh_token", "access_token", "auth_token", "key", "secret"}
|
|
|
|
AUTH_CONFIG_ALLOWED_KEYS = {
|
|
"none": set(),
|
|
"bearer": {"token", "refresh_token", "expires_in", "token_expires_at", "refresh_path"},
|
|
"new_api_token": {"token", "user_id", "new_api_user", "provider"},
|
|
"nox_token": {"token", "user_id", "new_api_user", "provider"},
|
|
"api_key": {"key", "header"},
|
|
"cookie": {"cookie_string", "new_api_user", "user_id", "provider"},
|
|
"login_password": {
|
|
"email", "password", "login_path", "username_field", "new_api_user", "user_id", "provider",
|
|
"token", "refresh_token", "expires_in", "token_expires_at", "refresh_path",
|
|
},
|
|
}
|
|
|
|
|
|
def mask_auth_config(auth_type: str, cfg: dict) -> dict:
|
|
masked = {}
|
|
for k, v in cfg.items():
|
|
if k.lower() in SECRET_KEYS and v:
|
|
masked[k] = MASK
|
|
else:
|
|
masked[k] = v
|
|
return masked
|
|
|
|
|
|
def normalize_auth_config(auth_type: str, cfg: dict) -> dict:
|
|
allowed = AUTH_CONFIG_ALLOWED_KEYS.get(auth_type)
|
|
if allowed is None:
|
|
return cfg
|
|
return {k: v for k, v in cfg.items() if k in allowed}
|