Skip to content

Show dedicated sign-in blocked page for linked-primary account HTTP 409#253

Open
Gerry-Cern wants to merge 5 commits into
cernboxfrom
4348-sign-in-409-temp-branch
Open

Show dedicated sign-in blocked page for linked-primary account HTTP 409#253
Gerry-Cern wants to merge 5 commits into
cernboxfrom
4348-sign-in-409-temp-branch

Conversation

@Gerry-Cern

Copy link
Copy Markdown

Summary

When a user signs in with an identity that CERNBox blocks as a linked primary account, the backend returns HTTP 409 with a machine-readable linked-primary contract (Reva http.interceptors.auth, documented as identity-auth-http-errors). Previously, Web treated that like a generic auth failure and sent users to Access denied.

This PR detects that contract on Graph, OCS, and authenticated HTTP responses, routes auth errors to a new linkedAccountBlocked page, and surfaces configurable links to documentation and the user portal where the account can be unlinked.

Companion change (separate repo): cs3org/reva branch feat/4348-linked-primary-http-contract adds the HTTP response shape (409, X-Oc-Linked-Primary-Account: true, JSON error.code: linkedPrimaryAccount). Detection in production also depends on cernbox/reva-plugins (v0.0.37+, “block linked accounts”) via the REST user provider.


Problem

  • Users signing in with a blocked linked-primary identity saw a generic Access denied screen with no guidance.
  • 409 Conflict is used elsewhere in Web (for example WebDAV autosave), so detection must not rely on status code alone.
  • CERNBox uses useRevaToken and multiple HTTP stacks (Graph, OCS, authenticated HTTP); handling must be centralized.

Solution

Backend contract (consumer)

Web treats a response as linked-primary when:

Signal Value
Status 409 Conflict
Header X-Oc-Linked-Primary-Account: true
Body error.code in linkedPrimaryAccount (and documented aliases)
Fallback On identity bootstrap URLs only: error.message contains “linked primary account”

Bootstrap paths include Graph /me, OCS user/capabilities, and settings URLs (see isIdentityBootstrapRequestUrl).

Web changes

  1. linkedPrimaryAccountError.ts — Shared detection, createLinkedPrimaryRejectionHandler, Axios interceptor helper, and a marker to avoid duplicate handleAuthError / removeUser calls.
  2. ClientService.attachLinkedPrimaryAccountHandling — Registers handlers on Graph, OCS, and authenticated HTTP clients at bootstrap.
  3. AuthService — Sets authBlockRouteName to linkedAccountBlocked when the error cause matches; auth guard keeps users on that route instead of login.
  4. linkedAccountBlocked.vue — Dedicated page (same layout pattern as access denied) with:
    • Clear explanation copy
    • Read documentation (default: https://auth.docs.cern.ch/user-documentation/verified-guest/)
    • Open user portal to unlink (default: https://account.cern.ch/account/, or options.accountEditLink.href)
    • Log in again CTA
  5. Config — Optional options.linkedAccount.docUrl and options.linkedAccount.userPortalUrl in OptionsConfigSchema.

What we intentionally do not match

  • Bare 409 without header/code/message contract (for example WebDAV file conflicts).
  • Message-only matching on non-bootstrap URLs (avoids false positives on arbitrary APIs).

Files changed

Area Files
Detection / interceptors packages/web-pkg/src/helpers/auth/linkedPrimaryAccountError.ts, client.ts, http/client.ts
Runtime / auth authService.ts, bootstrap.ts, setupAuthGuard.ts, useAuthService.ts
UI linkedAccountBlocked.vue, router/index.ts
Config config/types.ts
Tests linkedPrimaryAccountError.spec.ts, linkedAccountBlocked.spec.ts, authService.spec.ts, snapshot

Test plan

Automated

  • npx vitest run linkedPrimaryAccountError linkedAccountBlocked authService.spec (33 tests)

Manual (requires backend with full stack)

Deploy or point Web at a backend with:

  • Reva HTTP contract branch (or equivalent 409 + header + JSON)
  • reva-plugins ≥ v0.0.37 (linked-account block on @cern.ch username lookup)
  • CERN-style OIDC (useRevaToken if applicable)
Step Action Expected
1 Sign in as a linked-primary / blocked test user
2 Open Network tab; inspect bootstrap call (e.g. GET .../graph/v1.0/me or OCS user) 409, header X-Oc-Linked-Primary-Account: true, body error.code: linkedPrimaryAccount
3 Observe UI /linked-account-blocked (not access denied): title “Sign-in blocked”, doc + portal links, “Log in again”
4 Sign in as a normal user 200 on bootstrap; normal app load
5 Optional: set options.linkedAccount in config.json Custom doc and portal URLs on blocked page

Regression

  • File edit / autosave 409 still shows “file changed elsewhere”, not linked-account page.
  • Generic auth failure still routes to access denied.

Deployment notes

  1. Merge and ship Reva HTTP contract (feat/4348-linked-primary-http-contract) in revad before or with this Web change; otherwise Web cannot detect the contract reliably.
  2. reva-plugins is already required in CERN revad builds; no Web change needed there.
  3. Optional puppet/config: add options.linkedAccount to web.json if defaults should differ per environment (defaults are CERN URLs in the Vue component).

Related

  • Ticket: 4348 — Show messages in web when getting 409 on user call (linked primary account)
  • Reva: feat/4348-linked-primary-http-contract
  • reva-plugins: PR R1: fixes #67 — block linked accounts (v0.0.37+)

- Updated AuthService to manage linked primary account errors, redirecting to a new 'linkedAccountBlocked' page.
- Introduced a new helper for linked primary account error detection and handling.
- Enhanced error handling in the HttpClient and ClientService to support linked account scenarios.
- Added a new Vue component for the linked account blocked page with appropriate routing.
- Updated tests to cover new functionality and ensure proper error handling.
…ount blocked page

- Updated linked primary account error detection to include trusted signals for protected endpoints.
- Improved error handling logic in `isLinkedPrimaryAccountError` function.
- Added default documentation and portal URLs in the linked account blocked page component.
- Enhanced unit tests to cover new scenarios for linked primary account errors and default link rendering.
- Introduced a new `createLinkedPrimaryRejectionHandler` function to streamline error handling for linked-primary account errors.
- Updated `attachLinkedPrimaryAccountResponseInterceptor` to utilize the new handler, improving code clarity and maintainability.
- Enhanced unit tests to validate the new rejection handler functionality and ensure proper error handling behavior.
- Replaced the "Log in again" button with a "Log out" button that triggers the logout process.
- Updated the component to remove unused imports and streamline the code.
- Enhanced unit tests to verify the logout functionality and ensure proper interaction with the auth service.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant