fix(oidc): silent SSO also consumes refresh_token cookie on /authorize #90
No reviewers
Labels
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
psa-systems/bunyip!90
Loading…
Reference in a new issue
No description provided.
Delete branch "fix/oidc-silent-sso-via-access-token"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Extends the access_token-based silent SSO with a refresh_token fallback so the closing edge case from the previous commit no longer requires a credentialed re-login. Concretely: after the browser auto-expires the 15-min
access_tokencookie (Max-Age elapsed; the JWT itself may also have expired), but the 30-dayrefresh_tokencookie is still in the jar,/oauth2/authorizenow runs the same DB-tracked rotation that/v1/auth/refreshdoes, sets the rotated access + refresh cookies alongside the new bunyip_op_session cookie, and continues into the code-mint path. The browser leaves the request in the same state it would be in after a manual/v1/auth/refreshround-trip plus a successful authorize, just folded into a single request.DMARC-21 closes completely: a user who comes back to drillmark days later, with only the refresh_token cookie still alive (op_session row expired, access_token cookie auto-deleted, sessionStorage bundle on the SPA side ALSO expired) walks through
start_login -> /authorizeonce and lands on/dashboardwith no login screen.The helper now walks two paths in order:
access_tokencookie verifies viaJwtService::verify_access_token-> mint op_session, return one Set-Cookie. Cheap, no DB writes besides the op_sessions insert. Catches "user is actively in bunyip-web."access_tokenabsent or expired -> verifyrefresh_tokenJWT locally (so a forged token short-circuits with no DB write), then callAuthService::refresh_tokensfor the full rotation (family-reuse detection + audit logging + token revocation untouched). Mint op_session, emit clear_stale + new access + new refresh + new op_session cookies. Catches the DMARC-21 case.Falls through to the existing
/loginredirect when both inputs are gone, the refresh JWT is forged, or the rotation is rejected (revoked, family-reuse detected). Logout's existing posture (AuthCookies::clear removes all three cookies + revoke_op_sessions runs synchronously + auth_service.logout marks the refresh row revoked) leaves a logged-out user with no cookie input the silent path can consume.The handler grows two web::Data params (JwtService was already added by the previous commit; AuthService is new) and routes
extract_client_ip/extract_device_infofrombunyip_domain::middleware::authso the silent rotation looks identical to/v1/auth/refreshin audit logs.#DMARC-21