/** * SMART on FHIR Backend Services authorization (server-to-server). * * Implements the [SMART Backend Services] flow: * * 1. Build a signed JWT (`client_assertion`) using the app's private key. * 2. POST to the FHIR server's token endpoint with * `grant_type=client_credentials` and the JWT. * 3. Receive an `access_token` and use it to call FHIR APIs. * * Supports `RS384` (RSA) and `ES384` (EC P-384) signing — the two * algorithms required by the spec. Uses the Web Crypto API, which is * available natively in Node.js 18+ and modern browsers. * * [SMART Backend Services]: https://hl7.org/fhir/smart-app-launch/backend-services.html * * @example * ```ts * const auth = new BackendServicesAuth({ * clientId: "my-system", * fhirBaseUrl: "https://fhir.example.com", * privateKey: process.env.PRIVATE_KEY!, // PEM, PKCS#8 * keyId: "key-1", // matches kid in your JWKS * scopes: "system/Patient.read system/Observation.read", * }); * * const fetchFn = auth.createAuthenticatedFetch(); * const res = await fetchFn("https://fhir.example.com/Patient"); * ``` */ import { type SmartToken } from "./smart-auth.js"; import { type SmartSigningAlgorithm } from "./crypto.js"; export type BackendServicesAlgorithm = SmartSigningAlgorithm; export interface BackendServicesConfig { /** OAuth2 client_id registered with the FHIR server */ clientId: string; /** FHIR server base URL — used for token endpoint discovery */ fhirBaseUrl: string; /** * Private key for signing the client assertion JWT. * Accepts a PEM-encoded PKCS#8 string (`-----BEGIN PRIVATE KEY-----...`) * or a pre-imported `CryptoKey`. */ privateKey: string | CryptoKey; /** Signing algorithm (default `RS384`). */ algorithm?: BackendServicesAlgorithm; /** Key ID — must match the `kid` of the public key in the registered JWKS. */ keyId?: string; /** Override token endpoint discovery (e.g. for offline tests). */ tokenEndpoint?: string; /** Default scopes for token requests (default `system/*.read`). */ scopes?: string; /** Token assertion lifetime in seconds (default 300, max 5 minutes). */ assertionLifetimeSeconds?: number; /** Custom fetch (e.g. for tests, proxies). */ fetchFn?: typeof globalThis.fetch; } /** * Manages SMART Backend Services tokens — discovers the token endpoint, * mints client assertions, and caches access tokens until just before * expiry. */ export declare class BackendServicesAuth { readonly config: BackendServicesConfig; private cachedToken; private cachedScopes; private expiresAtMs; private cachedTokenEndpoint; private privateKeyPromise; /** Refresh the token this many ms before its real expiry. */ private static readonly REFRESH_LEEWAY_MS; constructor(config: BackendServicesConfig); /** Get a valid access token, fetching or refreshing as needed. */ getToken(scopes?: string): Promise; /** Clear any cached token (e.g. after a 401). */ invalidate(): void; /** * Build a `fetch` function that automatically attaches a bearer token * to outgoing requests. Refreshes the token when expired and retries * once on a 401. */ createAuthenticatedFetch(baseFetch?: typeof globalThis.fetch): typeof globalThis.fetch; private resolveTokenEndpoint; private resolvePrivateKey; private buildAssertion; private requestToken; } //# sourceMappingURL=backend-services.d.ts.map