feat: auth/pkce - allow extra token request params - #114
Merged
odsamuels merged 3 commits intoAug 15, 2026
Conversation
The lock file had drifted out of sync with package.json (missing @emnapi optional entries, stale libc metadata), causing npm ci to fail in CI. No dependency changes were needed for this feature. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
doistbot
reviewed
Aug 15, 2026
doistbot
left a comment
Member
There was a problem hiding this comment.
This PR adds an optional tokenRequestParams resolver to PkceProviderOptions, letting providers inject extra form-encoded parameters into the PKCE token exchange request body.
I also included a few optional follow-up notes in the details below.
Optional follow-up notes (3)
src/auth/providers/pkce.test.ts:84: The test verifies extra params appear in the POST body but doesn't cover two scenarios the PR description lists: (a) a param resolving to
undefinedbeing omitted (not sent as the string"undefined"), and (b) the callback receiving the correcthandshakeandflagsfrom the in-progress exchange. Consider adding these cases.src/auth/providers/pkce.ts:153: The
Object.fromEntries(Object.entries(...).filter(...).map(...))chain hand-rolls filtering+stringifying that the standardURLSearchParams.set()API already handles — and is the pattern already used inbuildPkceAuthorizeUrl(oauth.ts:64-65) for the same purpose. Consider a simpler loop consistent with that existing code:ts const body = new URLSearchParams({ grant_type: 'authorization_code', code: input.code, redirect_uri: input.redirectUri, client_id: clientId, code_verifier: verifier, }) for (const [key, value] of Object.entries(extraTokenParams)) { if (value !== undefined) body.set(key, String(value)) }src/auth/providers/pkce.ts:140:
tokenUrlandtokenRequestParamsare independent resolvers that only readinput.handshakeandflags, but they're awaited sequentially here. Both can be async (config read / prompt), so this serializes two async steps that could run concurrently. TheauthorizeandrefreshTokenpaths already parallelize their independent lazy resolvers withPromise.all; matching that here (e.g.const [tokenUrl, extraTokenParams] = await Promise.all([resolve(options.tokenUrl, ...), options.tokenRequestParams?.({...}) ?? {}])) avoids adding latency to the exchange when both are async.
Contributor
Author
|
@scottlovegrove - I'm going to go ahead and merge this, as I'm trying to extinguish an incident, and other functionality is dependent on getting this out. The impact and risk are expected to be very low. An async review is very welcome, as it's my first time dabbling in this repo. Thanks. 🙏 |
odsamuels
deleted the
odsamuels/feat/implement-tokenRequestParams-flexibility
branch
August 15, 2026 04:25
doist-release-bot Bot
added a commit
that referenced
this pull request
Aug 15, 2026
## [1.2.0](v1.1.0...v1.2.0) (2026-08-15) ### Features * auth/pkce - allow extra token request params ([#114](#114)) ([f6922f6](f6922f6))
Contributor
|
🎉 This PR is included in version 1.2.0 🎉 The release is available on: Your semantic-release bot 📦🚀 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
createPkceProviderhard-coded the token endpoint request body to the standard PKCE fields (grant_type,code,redirect_uri,client_id,code_verifier). Providers like Zendesk require additional provider-specific parameters on the authorization_code token request (e.g.expires_in,refresh_token_expires_into control max token lifetimes), and there was no way to inject them.🚨 As a result of what is likely Zendesk's token revamping efforts, CXers/users of the Zendesk CLI were running into failures every ~30 minutes and directed to re-auth.
Solution
This PR adds an optional
tokenRequestParamsoption toPkceProviderOptions. It's a function receiving{ handshake, flags }(same context as the other lazy resolvers) and returning a record of extra form-encoded parameters, synchronously or as a promise.exchangeCoderesolves it, filters outundefinedvalues, stringifies the rest, and merges them into the token request body alongside the standard PKCE fields.This allows the internal Zendesk CLI to request tokens for the maximum expiration time, instead of the Zendesk-set default.
The module remains backward compatible with existing consumers.
Reference
Test Plan
tokenRequestParamsis optional — existing providers (Outline, Todoist) that don't set it continue to exchange tokens with just the standard PKCE body fieldstokenRequestParams: () => ({ expires_in: 172800, refresh_token_expires_in: 7776000 })and verify the token POST body includes both extra fields alongsidegrant_type,code,redirect_uri,client_id,code_verifierDevice and Browser Testing