fix: remove dead auth_refresh code, fix logout storage, align bootstrap TTL, add hash rehash, tighten CSP

- Remove duplicate dead code in daemon/handlers/auth.py (auth_refresh)
- Fix logout reading refresh token from localStorage instead of sessionStorage
- Align bootstrap auth config access_token_ttl (900 -> 300) with hardened default
- Add password hash rehash check on successful login (needs_rehash was unused)
- Remove 'unsafe-inline' from CSP style-src (all styles are applied via JS DOM API)
This commit is contained in:
2026-07-24 03:06:31 +00:00
parent a365059976
commit edaf16a433
5 changed files with 9 additions and 29 deletions
-25
View File
@@ -195,31 +195,6 @@ def auth_refresh(_request: Any, body: Any) -> dict[str, Any]:
}, },
"permissions": permissions, "permissions": permissions,
} }
if payload is None:
raise ValueError("Invalid or expired refresh token")
username = payload["sub"]
user = get_user(username)
if user is None:
raise ValueError("User not found")
jti = payload.get("jti")
if jti:
blacklist_token(jti, token_type="refresh")
if username:
_clear_refresh_token_after_rotation(username)
permissions = user["permissions"]
tokens = generate_tokens(username, permissions)
return {
"tokens": tokens,
"access_ttl": get_access_ttl(),
"user": {
"id": user["id"],
"username": user["username"],
},
"permissions": permissions,
}
@registry.register(GET_AUTH_SESSION) @registry.register(GET_AUTH_SESSION)
+6 -1
View File
@@ -27,7 +27,7 @@ from lib.db import (
Q_UPSERT_PERMISSION, Q_UPSERT_PERMISSION,
get_db, get_db,
) )
from lib.password import hash_password, verify_password from lib.password import hash_password, needs_rehash, verify_password
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@@ -116,6 +116,11 @@ def verify_user_password(username: str, password: str) -> dict[str, Any] | None:
return None return None
if not verify_password(password, user["password_hash"]): if not verify_password(password, user["password_hash"]):
return None return None
if needs_rehash(user["password_hash"]):
new_hash = hash_password(password)
db = get_db()
db.run(Q_UPDATE_PASSWORD, (new_hash, username))
logger.info("Password hash rehashed for %r (param upgrade)", username)
return { return {
"id": user["id"], "id": user["id"],
"username": user["username"], "username": user["username"],
+1 -1
View File
@@ -45,7 +45,7 @@ def main() -> None:
config = { config = {
"jwt": { "jwt": {
"access_token_ttl": 900, "access_token_ttl": 300,
"refresh_token_ttl": 604800, "refresh_token_ttl": 604800,
"algorithm": "HS256", "algorithm": "HS256",
}, },
+1 -1
View File
@@ -238,7 +238,7 @@ def _log_request_finish(response):
response.headers["Content-Security-Policy"] = ( response.headers["Content-Security-Policy"] = (
"default-src 'self'; " "default-src 'self'; "
"script-src 'self'; " "script-src 'self'; "
"style-src 'self' 'unsafe-inline'; " "style-src 'self'; "
"img-src 'self' data:; " "img-src 'self' data:; "
"font-src 'self'; " "font-src 'self'; "
"connect-src 'self'; " "connect-src 'self'; "
+1 -1
View File
@@ -69,7 +69,7 @@ export async function logout() {
'Accept': 'application/json', 'Accept': 'application/json',
'Authorization': 'Bearer ' + token, 'Authorization': 'Bearer ' + token,
}; };
const refresh = localStorage.getItem('vw:refresh'); const refresh = sessionStorage.getItem('vw:refresh');
await fetch('/api/auth/logout', { await fetch('/api/auth/logout', {
method: 'POST', method: 'POST',
headers, headers,