2.1 KiB
/token endpoint
Purpose
handleToken implements the OAuth 2.0 token endpoint (RFC-6749 §4.1.3
and §6) for the mock IdP. It supports two grant types:
authorization_code (exchanging a freshly issued code for an
access+refresh-token pair) and refresh_token (rotating an existing
refresh-token).
PKCE verification (RFC-7636) is enforced when the matching auth-code
record carries a code_challenge; both plain and S256 challenge
methods are supported, and mismatches produce
{ error: "invalid_grant" } responses with HTTP 400 per spec.
Features
authorization_codegrant with single-use code semantics.refresh_tokengrant with rotation — the previous refresh token is revoked on each successful refresh.- PKCE S256 verification using a real
node:cryptosha256hash. - Configurable
expires_inviaaccessTokenTtlSeconds. - RFC-6749 error envelopes:
invalid_request,invalid_grant,unsupported_grant_type.
Usage: Basic
const tokenResponse = handleToken(state, {
grant_type: "authorization_code",
code: "abc",
code_verifier: "verifier-43-chars-min",
});
Usage: Advanced
Rotate a refresh token (the original is revoked):
const refreshed = handleToken(state, {
grant_type: "refresh_token",
refresh_token: previous.refresh_token,
});
API Reference
handleToken(state, form): TokenResultinterface TokenSuccess—{ status: 200, body: { access_token, token_type: "Bearer", expires_in, refresh_token, scope? } }.interface TokenError—{ status: 400|401, body: { error, error_description? } }.
Implementation Notes
PKCE S256 base64url encoding is performed with Buffer.toString('base64')
followed by manual = stripping and +// substitution — this matches
RFC-4648 §5 and is what every conforming client SDK produces. Auth codes
are marked used = true on first successful exchange, and reuse is
rejected as invalid_grant. Refresh tokens carry forward the original
userPayload so subsequent /userinfo calls keep returning the same
identity, modelling production IdP behaviour faithfully.