fix(auth): resolve JWT InvalidSignatureError and improve frontend UX
Some checks failed
CI / lint-and-test (push) Has been cancelled
Some checks failed
CI / lint-and-test (push) Has been cancelled
- Fix auth by using idToken fallback when accessToken audience mismatches - Add PyJWT verification with audience-aware token selection in frontend - Source health: track last_attempt_time and error status per source - Frontend: fix modal outside x-data scope, add circular-safe JSON stringify - Frontend: support multi-select service filter with All/None toggles - Frontend: improve filter layout into organized rows - Frontend: fix text overflow and result pill colors (success/succeeded) - Intune: normalize application actors (auditActorType=Application) - Add cache-control middleware for HTML/API responses - Update tests for multi-service filtering and source health
This commit is contained in:
@@ -34,6 +34,7 @@ def _decode_cursor(cursor: str) -> tuple[str, str]:
|
||||
@router.get("/events", response_model=PaginatedEventResponse)
|
||||
def list_events(
|
||||
service: str | None = None,
|
||||
services: list[str] | None = Query(default=None),
|
||||
actor: str | None = None,
|
||||
operation: str | None = None,
|
||||
result: str | None = None,
|
||||
@@ -48,6 +49,8 @@ def list_events(
|
||||
|
||||
if service:
|
||||
filters.append({"service": service})
|
||||
if services:
|
||||
filters.append({"service": {"$in": services}})
|
||||
if actor:
|
||||
actor_safe = re.escape(actor)
|
||||
filters.append(
|
||||
|
||||
@@ -31,12 +31,13 @@ def run_fetch(hours: int = 168):
|
||||
try:
|
||||
since = get_watermark(source_key)
|
||||
result = fn(since=since) if since else fn(hours=window)
|
||||
set_watermark(source_key, now)
|
||||
set_watermark(source_key, now, status="healthy")
|
||||
track_fetch(source_key, len(result))
|
||||
return result
|
||||
except Exception as exc:
|
||||
errors.append(f"{label}: {exc}")
|
||||
track_fetch_error(source_key)
|
||||
set_watermark(source_key, now, status="error")
|
||||
return []
|
||||
finally:
|
||||
track_fetch_duration(source_key, time.time() - start_time)
|
||||
|
||||
@@ -15,16 +15,21 @@ def source_health():
|
||||
results = []
|
||||
for source in SOURCES:
|
||||
doc = watermarks_collection.find_one({"source": source})
|
||||
if doc and doc.get("last_fetch_time"):
|
||||
if doc:
|
||||
status = doc.get("status")
|
||||
if not status:
|
||||
status = "healthy" if doc.get("last_fetch_time") else "unknown"
|
||||
results.append({
|
||||
"source": source,
|
||||
"last_fetch_time": doc["last_fetch_time"],
|
||||
"status": "healthy",
|
||||
"last_fetch_time": doc.get("last_fetch_time"),
|
||||
"last_attempt_time": doc.get("last_attempt_time"),
|
||||
"status": status,
|
||||
})
|
||||
else:
|
||||
results.append({
|
||||
"source": source,
|
||||
"last_fetch_time": None,
|
||||
"last_attempt_time": None,
|
||||
"status": "unknown",
|
||||
})
|
||||
return results
|
||||
|
||||
Reference in New Issue
Block a user