Skip to content

feat: send auth credentials on all STAC API requests#71

Open
alukach wants to merge 11 commits into
mainfrom
feature/authed-get-requests
Open

feat: send auth credentials on all STAC API requests#71
alukach wants to merge 11 commits into
mainfrom
feature/authed-get-requests

Conversation

@alukach
Copy link
Copy Markdown
Member

@alukach alukach commented Apr 24, 2026

What I'm changing

STAC APIs may return different data in response to GET requests or searches when the carries an auth token (e.g. private vs. public collections). This PR threads the current OIDC token into every STAC API request.

How it works

Two paths share one token source:

1. Hook reads (useCollections, useCollection, useItem, useStacSearch)

A new StacApiAuthBridge in main.tsx reads the token from useAuth() and passes a memoized options={{ headers: { Authorization: 'Bearer …' } }} into StacApiProvider. On every token change, useStacApi's effect sees a new options identity and rebuilds the underlying StacApi with fresh headers.

2. Direct fetches (Api.fetch, used for mutations)

The bridge also syncs the token into a module-level store via setApiAuthToken(token). Api.fetch reads from that store and injects Authorization only when the URL is under REACT_APP_STAC_API. Path-boundary normalized so /stac-admin cannot match a /stac base. Caller-provided headers always win on collision.

CollectionForm no longer hand-rolls its own Authorization header — mutations now carry exactly one, injected centrally.

useCollections.ts (the pagination workaround) calls useStacApi directly because stac-react@0.1.0-alpha.10 does not re-export useStacApiContext. It reads useAuth() itself and mirrors the bridge's options.

Relationship to stac-react

No stac-react changes are required for this PR — alpha.10 already merges options.headers into every fetch, and a new options identity triggers a rebuild of the StacApi.

developmentseed/stac-react#56 is a follow-up optimization: it widens options to accept a callable resolved per request, letting us keep a single StacApi instance across token rotations and skip the landing-page re-probe that currently fires on each token change. We can pick that up once it lands and we bump the dep.

Tests

Added packages/client/src/api/index.test.ts covering the Api.fetch injection rules:

  • Token present + URL under STAC base → header added
  • Token absent → no header
  • Token present + URL outside STAC base → no header
  • Caller-provided Authorization overrides injected one
  • REACT_APP_STAC_API unset → no header

Full suite passing (npx jest: 108/108). Lint clean (npm run lint: 0 errors).

How to test it

  1. Point .env at a protected STAC API:
    REACT_APP_STAC_API="https://eoapi.develop.eoepca.org/stac/"
    REACT_APP_OIDC_AUTHORITY="https://iam-auth.develop.eoepca.org/realms/eoepca"
    REACT_APP_OIDC_CLIENT_ID="eoapi"
    
    (contact me for credentials)
  2. Run npm run client:serve and open DevTools → Network.
  3. Logged out: requests to the STAC API carry no Authorization header.
  4. Log in: every subsequent STAC request carries Authorization: Bearer <token> — collection list, detail, items, search.
  5. Log out: the next request drops the header again.
  6. Mutations: edit a collection. The PUT succeeds with exactly one Authorization header.
  7. Scope check: non-STAC requests (OIDC discovery, static assets) never receive the token.

@alukach alukach changed the title Send auth credentials on all STAC API requests feat: send auth credentials on all STAC API requests May 15, 2026
@alukach alukach force-pushed the feature/authed-get-requests branch from c7982f1 to cbe1c46 Compare May 15, 2026 18:12
@alukach alukach force-pushed the feature/authed-get-requests branch from cbe1c46 to 84397dd Compare May 15, 2026 18:14
@alukach alukach force-pushed the feature/authed-get-requests branch from 84397dd to 88c662d Compare May 15, 2026 18:19
authority: process.env.REACT_APP_OIDC_AUTHORITY,
clientId: process.env.REACT_APP_OIDC_CLIENT_ID
}
: undefined;
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was just some simplification to remove packages/client/src/auth/resolveAuthConfig.ts which seemed unnecessary

Otherwise
useStacApi probes the landing page (and useCollections fetches) once
without auth, then again when the token arrives. App.tsx already
gates content rendering on isLoading, so no consumer hooks need the
context during this window.
@alukach
Copy link
Copy Markdown
Member Author

alukach commented May 20, 2026

/cc @pantierra

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