@molecule/api-oauth-client-generic
v1.0.1
Published
Generic OAuth 2.0 client provider for molecule.dev — standard authorization code flow with PKCE support
Maintainers
Readme
@molecule/api-oauth-client-generic
Auto-generated, AI-first package reference for the molecule.dev ecosystem. It is written to be read by coding agents as much as by people, and is generated from this package's source — edit
src/index.tsJSDoc, not this file.
Generic OAuth 2.0 client provider for molecule.dev.
Implements the standard OAuth 2.0 authorization code flow with PKCE support,
using Node.js built-in fetch for HTTP requests. Compatible with any
OAuth 2.0 compliant provider (GitHub, Google, GitLab, Slack, etc.).
Quick Start
import { setProvider, getAuthorizationUrl, getToken } from '@molecule/api-oauth-client'
import { provider } from '@molecule/api-oauth-client-generic'
setProvider(provider)
const config = {
id: 'github',
clientId: process.env.GITHUB_CLIENT_ID,
clientSecret: process.env.GITHUB_CLIENT_SECRET,
authorizationUrl: 'https://github.com/login/oauth/authorize',
tokenUrl: 'https://github.com/login/oauth/access_token',
redirectUri: 'https://myapp.com/callback',
scopes: ['user', 'repo'],
}
const authUrl = getAuthorizationUrl(config, { state: 'random-csrf' })
// Redirect user to authUrl, then on callback:
const tokens = await getToken(config, code)Type
provider
Installation
npm install @molecule/api-oauth-client-generic @molecule/api-oauth-clientAPI
Interfaces
GenericOAuthConfig
Configuration options for the generic OAuth 2.0 client provider.
interface GenericOAuthConfig {
/** Default timeout for HTTP requests in milliseconds. Defaults to `10_000`. */
timeout?: number
/** Custom user-agent header sent with all requests. */
userAgent?: string
/**
* How the client credentials are sent in token requests.
* - `'body'` — client_id and client_secret in the POST body (default).
* - `'header'` — HTTP Basic auth header.
*/
clientAuthMethod?: 'body' | 'header'
}Functions
createProvider(config)
Creates a generic OAuth 2.0 client provider.
function createProvider(config?: GenericOAuthConfig): OAuthClientProviderconfig— Optional provider configuration.
Returns: An OAuthClientProvider backed by standard OAuth 2.0 flows.
Constants
provider
The provider implementation with default configuration.
const provider: OAuthClientProviderCore Interface
Implements @molecule/api-oauth-client interface.
Bond Wiring
Setup function to register this provider with the core interface:
import { setProvider } from '@molecule/api-oauth-client'
import { provider } from '@molecule/api-oauth-client-generic'
export function setupOauthClientGeneric(): void {
setProvider(provider)
}Injection Notes
Requirements
Peer dependencies:
@molecule/api-oauth-client^1.0.1
Runtime Dependencies
@molecule/api-oauth-client
E2E Tests
Integration checklist — drive the real UI (live preview, no mocks), adapt
each item to this app's actual "connect account" screens/flows, and check
every box off one by one. A box you can't check is an integration bug to
fix — not a skip. The third-party CONSENT SCREEN cannot be driven in-sandbox,
so verify the token lifecycle + API-call wiring you own (authorize →
callback → getToken → token store → refreshToken → request), stubbing
the provider bond or the token endpoint where the real grant would occur:
- [ ] Connecting a third-party account from the UI runs
authorize→callback→
getTokenand STORES the returnedOAuthTokens(accessToken+refreshToken) server-side keyed to the authenticated user; the connection then shows as "connected" in the UI. - [ ] An authenticated call to the third-party API via
request(tokens, url)using the STORED token succeeds and its result appears in the app (bond a stub/test provider if available, else assertrequestis invoked with the storedaccessToken— never a hardcoded or browser-supplied one). - [ ] Token REFRESH works: an expired
accessToken(force/simulate expiry viaexpiresAt) is transparently refreshed withrefreshTokenand the call is RETRIED — confirm exactly ONE refresh + a stored-token update, not an auth error surfaced to the user (requestdoes not auto-refresh; the caller's refresh-and-retry loop must). - [ ] Disconnecting revokes/removes the stored tokens (
revokeToken+ delete from the store) and the connection no longer works — a subsequent API call fails until the account is reconnected. - [ ] SECURITY:
accessToken/refreshToken+clientSecretlive server-side only (encrypted at rest ideally) and are NEVER sent to the browser — the client only ever receives the authorization URL and returns thecode. - [ ] Tokens are scoped per user: user A's stored connection cannot be used to act as user B (the store is keyed by user id; handlers load only the caller's own tokens).
- [ ] The callback verifies
state(CSRF): a per-session randomstatesent ongetAuthorizationUrlmust match on the callback, and a missing or mismatchedstateis rejected BEFORE any token exchange.
