Skip to content

Plumb me.external_data through session enrichment to useUser#21

Draft
drewda wants to merge 1 commit into
mainfrom
gatekeeper-data
Draft

Plumb me.external_data through session enrichment to useUser#21
drewda wants to merge 1 commit into
mainfrom
gatekeeper-data

Conversation

@drewda
Copy link
Copy Markdown
Member

@drewda drewda commented May 5, 2026

Summary

Adds an opaque external_data passthrough from the GraphQL me query to the client-side useUser() composable so consumers can read fields the backend places on the user context. Generic plumbing only — no deployment-specific schema is encoded here.

The motivating consumer is the Interline Web App Gatekeeper integration: tlserver's gatekeeper middleware (internal/meters/gatekeeper) calls IWA on every authenticated request, stores the response on the request user via WithExternalData(), and transitland-lib's me resolver returns it as external_data["gatekeeper"] (a JSON-stringified GatekeeperResponse). Today that data is dropped on the floor by tlv2-auth; this PR plumbs it through verbatim. Parsing/typing of external_data.gatekeeper (or any other deployment-flavored sub-key) lives in the consumer (e.g. a useGatekeeper() composable in www-transit-land-v2).

Session endpoint

  • src/runtime/server/api/auth/session.get.ts — extends the GraphQL query from me { id name email roles } to me { id name email roles external_data }.

Enrichment

  • src/runtime/util/enrich.tsenrichUserClaims accepts an optional external_data field on MeData and writes it to tlv2_external_data on the returned claims (defaults to {} when absent).

Composable

  • src/runtime/composables/useUser.tsTlUser interface gains an externalData: Record<string, unknown> property, populated from the tlv2_external_data session claim.

Tests

  • src/runtime/util/enrich.spec.ts — adds cases for verbatim passthrough and the empty-default behavior.

Test plan

  • A consumer registers tlv2-auth as a Nuxt module, configures its backend's me resolver to return external_data (e.g. tlserver --auth=gatekeeper), logs in.
  • useUser().externalData returns the same shape the backend put on the user (e.g. { gatekeeper: "<json>", amberflo: { customer_id: "..." } }).
  • When the backend returns an empty external_data, useUser().externalData is {}.
  • When the GraphQL backend is unreachable, the session response still flows through (tlv2_external_data falls through to the default).

Adds an opaque `external_data` passthrough so consumers can read fields the
backend places on the user context (e.g. tlserver's gatekeeper middleware,
which sets `user.ExternalData["gatekeeper"]` to a JSON-stringified
GatekeeperResponse).

- Session endpoint requests `external_data` alongside id/name/email/roles
  from the GraphQL `me` query.
- `enrichUserClaims` includes a new `tlv2_external_data` claim on the
  enriched session response (defaults to `{}` when absent).
- `useUser()` exposes `externalData: Record<string, unknown>`.

The map is passed through verbatim — schema is deployment-specific, and
parsing of any deployment-flavored sub-keys (e.g. JSON-stringified
gatekeeper data) lives in the consumer.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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