Fixes review finding P2: require_admin compared the Bearer credential
against config.panel_token with Python ==, which short-circuits and is
not constant-time. Compare with secrets.compare_digest on UTF-8 bytes
instead — the same pattern require_panel_token already uses for this
exact secret — keeping the truthiness guard on config.panel_token and
the same 403 rejection detail and behaviour.
WHY: the admin plane was authenticated (any valid JWT passed) but not
authorized, and the panel service token would have been run through
JWT verification like any other credential. require_admin is now the
ONE dependency every admin route uses: it refuses the panel service
token outright with 403 BEFORE any JWT parsing (a refused credential
type, not an invalid one — a 401 challenge would imply a retry could
ever succeed), then verifies the JWT via the existing require_admin_jwt
path (uniform 401 unchanged) and requires the groups claim to name
nestquest-admins (403 for a missing/empty/non-list claim or one
without the group).