Skip to content

chore(deps): bump @cloudflare/workers-oauth-provider from 0.10.4 to 1.2.1 in /cod-server - #152

Closed
dependabot[bot] wants to merge 1 commit into
mainfrom
dependabot/npm_and_yarn/cod-server/cloudflare/workers-oauth-provider-1.2.1
Closed

dependabot[bot] wants to merge 1 commit into
mainfrom
dependabot/npm_and_yarn/cod-server/cloudflare/workers-oauth-provider-1.2.1

Conversation

@dependabot

@dependabot dependabot Bot commented on behalf of github Oct 5, 2026

Copy link
Copy Markdown
Contributor

Bumps @cloudflare/workers-oauth-provider from 0.10.4 to 1.2.1.

Release notes

Sourced from @​cloudflare/workers-oauth-provider's releases.

v1.2.1

Patch Changes

  • #391 0f0b2cc Thanks @​mattzcarey! - A registration may list redirect URIs the redirect policy refuses, next to one it accepts. Some Cursor versions register cursor://anysphere.cursor-mcp/oauth/callback beside their https and loopback callbacks and sign in with the loopback one; 1.2.0 refused the whole registration because of the cursor:// entry, although 0.10 accepted it. Dynamic registration, createClient() and updateClient() now need at least one redirect URI that follows the policy, and still refuse any with a dangerous scheme, a fragment or userinfo. Every authorization request is still held to the full policy: parseAuthRequest() refuses a refused URI locally, and completeAuthorization() won't send a code to one.

v1.2.0

Minor Changes

  • #338 b61bfc0 Thanks @​mattzcarey! - Error redirects back to the client no longer need building by hand. AuthorizationError.redirectTo is the ready-made redirect (error, error_description, state, iss), set only when a redirect is safe, i.e. when redirectUri was validated. authorizationErrorRedirect(request, code, description?) builds the same for an error the application decides on, such as a decline at a third-party provider, from a request the library validated. denyConsent() uses it.

  • #339 c801878 Thanks @​mattzcarey! - OAuthHelpers.describeConsent(request) returns what a consent page must show, per the MCP authorization spec: the client's name (or ID), its verified domain for a Client ID Metadata Document client, the redirect URI's hostname, whether the redirect goes to a local app (show a warning), and the scopes. Every string may come from the client, so escape it before rendering.

  • #340 b9a0307 Thanks @​mattzcarey! - Redirect URIs must use https, or http on a loopback host (localhost, 127.0.0.0/8, ::1), as MCP and OAuth 2.1 require, with no userinfo or fragment. The rule is enforced at dynamic registration, in createClient() and updateClient() (which previously validated nothing), and on every authorization request and completeAuthorization(), so clients registered before the policy are held to it: their authorizations fail with a locally rendered invalid_request, never a redirect. A Client ID Metadata Document, which every server the client uses reads, may still list other redirect URIs next to a compliant one; only a request that uses one is refused.

    Breaking: clients registered with a remote http redirect URI or a private-use scheme stop authorizing. Native apps that rely on RFC 8252 private-use schemes (com.example.app:/cb) keep working with the new allowPrivateUseRedirectUris: true; remote http is never accepted.

  • #381 95924a3 Thanks @​mattzcarey! - A resource's required scopes have their own option, requiredScopes, on OAuthResourceServer and OAuthProvider: the scopes any access needs, published as the protected resource metadata's scopes_supported and named in the 401 challenge, so MCP clients request them first. It sits beside resourceMetadata instead of inside it, where it read like the authorization server's scopesSupported catalogue. It is advertised, not enforced: handlers check ctx.auth.scope, since only they know which scopes imply others. resourceMetadata.scopes_supported still works but is deprecated in favour of requiredScopes; setting both throws at construction.

  • #337 9bab931 Thanks @​mattzcarey! - tokenExchangeCallback receives the request's env (TokenExchangeCallbackOptions<Env>['env']), as resolveExternalToken already does. A callback that needs secrets or bindings, such as an upstream OAuth client secret, no longer forces the provider to be rebuilt on every request to close over env.

  • #383 d53af65 Thanks @​mattzcarey! - An OAuthResourceServer's validateToken can throw OAuthError to choose the response, as a tokenExchangeCallback already can. temporarily_unavailable with statusCode: 429 and Retry-After passes through; insufficient_scope becomes the MCP 403 challenge naming the new OAuthError requiredScopes option (or the resource's requiredScopes); invalid_token becomes a 401 with the Bearer challenge. Anything else thrown is still a 503. This lets one resource validate an upstream API's own credentials in validateToken before falling back to its authorization server. OAuthProvider's resolveExternalToken and ExternalTokenError are unchanged.

Patch Changes

  • #385 ebb2efd Thanks @​mattzcarey! - OAuthAuthorizationServer's authorizeEndpoint and tokenEndpoint are optional and default to ${issuer}/authorize and ${issuer}/oauth/token, under the issuer's path if it has one. OAuthProvider still requires both.

    Construction also rejects any endpoint another would claim, so it could never be reached: a token, registration or authorization endpoint on the metadata path with a query (metadata is served whatever the query), an endpoint that is the token endpoint plus a query, or an authorization endpoint equal to the token or registration endpoint.

  • #388 bd97dc1 Thanks @​mattzcarey! - OAuthAuthorizationServer.fetch() no longer writes env.OAUTH_PROVIDER into the caller's env when it answers a path that isn't one of its endpoints. It answers 404 directly; a dead branch meant it fell through to a placeholder handler after setting the helpers, which only the combined OAuthProvider's defaultHandler reads. Use authorizationServer.getOAuthApi(env) for the helpers, as documented.

  • #361 36cb1b4 Thanks @​mattzcarey! - tokenExchangeCallback lifetimes no longer fail requests or silently remove expiry. refreshTokenTTL: undefined in a callback result now keeps the provider's lifetime; it used to make the grant never expire, which is what a callback passing through an upstream's missing refresh_expires_in did. refreshTokenTTL is validated (0, or an integer of at least 60 seconds) instead of failing the code exchange with a storage error. Each lifetime is ignored where it doesn't apply, rather than rejected after the callback ran: returning refreshTokenTTL on refresh, or refreshTokenIdleTTL at code exchange or token exchange, used to fail the request after the callback's side effects, such as rotating an upstream refresh token.

  • #372 78b3c80 Thanks @​mattzcarey! - createClient() and updateClient() check grant and response types against what the server implements, as dynamic registration does, so a client can no longer be stored with, say, grantTypes: ['implicit'] and then fail every authorization. updateClient() refuses a Client ID Metadata Document client while CIMD is enabled, instead of writing a stored copy that did nothing then and would have become the client if CIMD were later turned off. deleteClient() on a CIMD client revokes its grants, as before, and is now documented as doing so.

  • #363 958d792 Thanks @​mattzcarey! - deleteClient() deletes the client before revoking its grants, so the client stops working at once even if revocation fails partway; calling it again finishes the revocation. It finds the client's grants from their KV key metadata instead of reading every grant in the namespace one by one, which could exceed a Worker's subrequest limit and, because the client record was deleted last, leave the client active.

  • #366 0cecdba Thanks @​mattzcarey! - With disallowPublicClientRegistration, a dynamic registration that prefers none but also supports a secret method is registered with the secret method instead of being refused. none is simply not on offer during negotiation; a client that supports only none is still refused.

  • #371 a6d99ad Thanks @​mattzcarey! - A grant issued without a refresh token (refreshTokenTTL: 0, from the option or a tokenExchangeCallback) now expires with its access token. It used to be stored with no expiry, so every such authorization left a grant record in KV for good.

  • #365 3c940ff Thanks @​mattzcarey! - Six internal helpers are no longer exported from the package: base64UrlToBytes, parseJwtJsonPart, getJwtCryptoAlgorithms, isValidOAuthScopeToken, resourceMatches and validateResourceUri. They were exported by accident in 1.0 (the first three only so the enterprise-managed authorization modules could import them back from the package entry) and were never documented. A test now pins the package's runtime exports.

  • #342 696045a Thanks @​mattzcarey! - A bearer token in this provider's own userId:grantId:secret format that isn't found in storage (an expired or revoked access token, or a forgery of the format) is now answered invalid_token directly instead of being handed to resolveExternalToken. Resolvers that validate foreign credentials upstream were forwarding our expired tokens to third-party APIs: about 24k calls an hour in one production deployment, from MCP clients presenting a stale access token before refreshing.

  • #362 23c151e Thanks @​mattzcarey! - purgeExpiredData() is resumable. It returns a cursor whenever the sweep isn't finished, and takes it back as PurgeOptions.cursor. Previously every invocation started from the first grant, so with more than batchSize live grants a scheduled sweep re-checked the same records forever, never reached later grants, and never swept orphaned tokens at all. Persist the cursor between runs; the example in docs/advanced-configuration.md stores it in KV.

  • #368 bf61067 Thanks @​mattzcarey! - A token request whose scope names only scopes the grant doesn't hold is refused with invalid_scope (RFC 6749 §6) at code exchange, refresh and token exchange, instead of succeeding with a token that carries no scope. Requests that name at least one granted scope are still narrowed silently, as before.

  • #374 fe5e1e2 Thanks @​mattzcarey! - Dynamic client registration stops reading a request body at 1 MiB even when it has no Content-Length (a chunked body), instead of reading all of it first. When clientRegistrationCallback throws, the client gets a fixed Client registration callback failed description rather than the error's message, which may be internal; onError still receives the error.

... (truncated)

Changelog

Sourced from @​cloudflare/workers-oauth-provider's changelog.

1.2.1

Patch Changes

  • #391 0f0b2cc Thanks @​mattzcarey! - A registration may list redirect URIs the redirect policy refuses, next to one it accepts. Some Cursor versions register cursor://anysphere.cursor-mcp/oauth/callback beside their https and loopback callbacks and sign in with the loopback one; 1.2.0 refused the whole registration because of the cursor:// entry, although 0.10 accepted it. Dynamic registration, createClient() and updateClient() now need at least one redirect URI that follows the policy, and still refuse any with a dangerous scheme, a fragment or userinfo. Every authorization request is still held to the full policy: parseAuthRequest() refuses a refused URI locally, and completeAuthorization() won't send a code to one.

1.2.0

Minor Changes

  • #338 b61bfc0 Thanks @​mattzcarey! - Error redirects back to the client no longer need building by hand. AuthorizationError.redirectTo is the ready-made redirect (error, error_description, state, iss), set only when a redirect is safe, i.e. when redirectUri was validated. authorizationErrorRedirect(request, code, description?) builds the same for an error the application decides on, such as a decline at a third-party provider, from a request the library validated. denyConsent() uses it.

  • #339 c801878 Thanks @​mattzcarey! - OAuthHelpers.describeConsent(request) returns what a consent page must show, per the MCP authorization spec: the client's name (or ID), its verified domain for a Client ID Metadata Document client, the redirect URI's hostname, whether the redirect goes to a local app (show a warning), and the scopes. Every string may come from the client, so escape it before rendering.

  • #340 b9a0307 Thanks @​mattzcarey! - Redirect URIs must use https, or http on a loopback host (localhost, 127.0.0.0/8, ::1), as MCP and OAuth 2.1 require, with no userinfo or fragment. The rule is enforced at dynamic registration, in createClient() and updateClient() (which previously validated nothing), and on every authorization request and completeAuthorization(), so clients registered before the policy are held to it: their authorizations fail with a locally rendered invalid_request, never a redirect. A Client ID Metadata Document, which every server the client uses reads, may still list other redirect URIs next to a compliant one; only a request that uses one is refused.

    Breaking: clients registered with a remote http redirect URI or a private-use scheme stop authorizing. Native apps that rely on RFC 8252 private-use schemes (com.example.app:/cb) keep working with the new allowPrivateUseRedirectUris: true; remote http is never accepted.

  • #381 95924a3 Thanks @​mattzcarey! - A resource's required scopes have their own option, requiredScopes, on OAuthResourceServer and OAuthProvider: the scopes any access needs, published as the protected resource metadata's scopes_supported and named in the 401 challenge, so MCP clients request them first. It sits beside resourceMetadata instead of inside it, where it read like the authorization server's scopesSupported catalogue. It is advertised, not enforced: handlers check ctx.auth.scope, since only they know which scopes imply others. resourceMetadata.scopes_supported still works but is deprecated in favour of requiredScopes; setting both throws at construction.

  • #337 9bab931 Thanks @​mattzcarey! - tokenExchangeCallback receives the request's env (TokenExchangeCallbackOptions<Env>['env']), as resolveExternalToken already does. A callback that needs secrets or bindings, such as an upstream OAuth client secret, no longer forces the provider to be rebuilt on every request to close over env.

  • #383 d53af65 Thanks @​mattzcarey! - An OAuthResourceServer's validateToken can throw OAuthError to choose the response, as a tokenExchangeCallback already can. temporarily_unavailable with statusCode: 429 and Retry-After passes through; insufficient_scope becomes the MCP 403 challenge naming the new OAuthError requiredScopes option (or the resource's requiredScopes); invalid_token becomes a 401 with the Bearer challenge. Anything else thrown is still a 503. This lets one resource validate an upstream API's own credentials in validateToken before falling back to its authorization server. OAuthProvider's resolveExternalToken and ExternalTokenError are unchanged.

Patch Changes

  • #385 ebb2efd Thanks @​mattzcarey! - OAuthAuthorizationServer's authorizeEndpoint and tokenEndpoint are optional and default to ${issuer}/authorize and ${issuer}/oauth/token, under the issuer's path if it has one. OAuthProvider still requires both.

    Construction also rejects any endpoint another would claim, so it could never be reached: a token, registration or authorization endpoint on the metadata path with a query (metadata is served whatever the query), an endpoint that is the token endpoint plus a query, or an authorization endpoint equal to the token or registration endpoint.

  • #388 bd97dc1 Thanks @​mattzcarey! - OAuthAuthorizationServer.fetch() no longer writes env.OAUTH_PROVIDER into the caller's env when it answers a path that isn't one of its endpoints. It answers 404 directly; a dead branch meant it fell through to a placeholder handler after setting the helpers, which only the combined OAuthProvider's defaultHandler reads. Use authorizationServer.getOAuthApi(env) for the helpers, as documented.

  • #361 36cb1b4 Thanks @​mattzcarey! - tokenExchangeCallback lifetimes no longer fail requests or silently remove expiry. refreshTokenTTL: undefined in a callback result now keeps the provider's lifetime; it used to make the grant never expire, which is what a callback passing through an upstream's missing refresh_expires_in did. refreshTokenTTL is validated (0, or an integer of at least 60 seconds) instead of failing the code exchange with a storage error. Each lifetime is ignored where it doesn't apply, rather than rejected after the callback ran: returning refreshTokenTTL on refresh, or refreshTokenIdleTTL at code exchange or token exchange, used to fail the request after the callback's side effects, such as rotating an upstream refresh token.

  • #372 78b3c80 Thanks @​mattzcarey! - createClient() and updateClient() check grant and response types against what the server implements, as dynamic registration does, so a client can no longer be stored with, say, grantTypes: ['implicit'] and then fail every authorization. updateClient() refuses a Client ID Metadata Document client while CIMD is enabled, instead of writing a stored copy that did nothing then and would have become the client if CIMD were later turned off. deleteClient() on a CIMD client revokes its grants, as before, and is now documented as doing so.

  • #363 958d792 Thanks @​mattzcarey! - deleteClient() deletes the client before revoking its grants, so the client stops working at once even if revocation fails partway; calling it again finishes the revocation. It finds the client's grants from their KV key metadata instead of reading every grant in the namespace one by one, which could exceed a Worker's subrequest limit and, because the client record was deleted last, leave the client active.

  • #366 0cecdba Thanks @​mattzcarey! - With disallowPublicClientRegistration, a dynamic registration that prefers none but also supports a secret method is registered with the secret method instead of being refused. none is simply not on offer during negotiation; a client that supports only none is still refused.

  • #371 a6d99ad Thanks @​mattzcarey! - A grant issued without a refresh token (refreshTokenTTL: 0, from the option or a tokenExchangeCallback) now expires with its access token. It used to be stored with no expiry, so every such authorization left a grant record in KV for good.

  • #365 3c940ff Thanks @​mattzcarey! - Six internal helpers are no longer exported from the package: base64UrlToBytes, parseJwtJsonPart, getJwtCryptoAlgorithms, isValidOAuthScopeToken, resourceMatches and validateResourceUri. They were exported by accident in 1.0 (the first three only so the enterprise-managed authorization modules could import them back from the package entry) and were never documented. A test now pins the package's runtime exports.

  • #342 696045a Thanks @​mattzcarey! - A bearer token in this provider's own userId:grantId:secret format that isn't found in storage (an expired or revoked access token, or a forgery of the format) is now answered invalid_token directly instead of being handed to resolveExternalToken. Resolvers that validate foreign credentials upstream were forwarding our expired tokens to third-party APIs: about 24k calls an hour in one production deployment, from MCP clients presenting a stale access token before refreshing.

  • #362 23c151e Thanks @​mattzcarey! - purgeExpiredData() is resumable. It returns a cursor whenever the sweep isn't finished, and takes it back as PurgeOptions.cursor. Previously every invocation started from the first grant, so with more than batchSize live grants a scheduled sweep re-checked the same records forever, never reached later grants, and never swept orphaned tokens at all. Persist the cursor between runs; the example in docs/advanced-configuration.md stores it in KV.

  • #368 bf61067 Thanks @​mattzcarey! - A token request whose scope names only scopes the grant doesn't hold is refused with invalid_scope (RFC 6749 §6) at code exchange, refresh and token exchange, instead of succeeding with a token that carries no scope. Requests that name at least one granted scope are still narrowed silently, as before.

... (truncated)

Commits
  • 1fafae2 Version Packages (#392)
  • 0f0b2cc fix: a registration may list redirect URIs the policy refuses next to one it ...
  • c5e98a0 Rename tests directory to tests (#390)
  • f28ea84 Version Packages (#343)
  • bd97dc1 chore: remove the split server's dead dispatch branch; unexport internal-only...
  • 9750167 fix: a Client ID Metadata Document may list redirect URIs the policy refuses;...
  • 69f694c docs: the migration guide and skill cover every change from 0.10 to 1.2 (#386)
  • ebb2efd feat: OAuthAuthorizationServer endpoints default under the issuer; reject end...
  • e5249e1 test: run the official MCP conformance runner against the Worker in CI (#384)
  • d53af65 feat: validateToken can throw OAuthError to choose the response (#383)
  • Additional commits viewable in compare view

Dependabot compatibility score

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


Dependabot commands and options

You can trigger Dependabot actions by commenting on this PR:

  • @dependabot rebase will rebase this PR
  • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
  • @dependabot show <dependency name> ignore conditions will show all of the ignore conditions of the specified dependency
  • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
  • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
  • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)

Bumps [@cloudflare/workers-oauth-provider](https://github.com/cloudflare/workers-oauth-provider) from 0.10.4 to 1.2.1.
- [Release notes](https://github.com/cloudflare/workers-oauth-provider/releases)
- [Changelog](https://github.com/cloudflare/workers-oauth-provider/blob/main/CHANGELOG.md)
- [Commits](cloudflare/workers-oauth-provider@v0.10.4...v1.2.1)

---
updated-dependencies:
- dependency-name: "@cloudflare/workers-oauth-provider"
  dependency-version: 1.2.1
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
@dependabot dependabot Bot added the dependencies Pull requests that update a dependency file label Oct 5, 2026
@vercel

vercel Bot commented Oct 5, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated
codflow-theme01 Skipped Skipped Oct 5, 2026 9:38am UTC

@bighadj22

Copy link
Copy Markdown
Owner

✅ Applied manually in commit d377234 on branch feature/phase0-storefront-sdk. All tests passing.

@bighadj22 bighadj22 closed this Oct 6, 2026
@dependabot @github

dependabot Bot commented on behalf of github Oct 6, 2026

Copy link
Copy Markdown
Contributor Author

OK, I won't notify you again about this release, but will get in touch when a new version is available. If you'd rather skip all updates until the next major or minor version, let me know by commenting @dependabot ignore this major version or @dependabot ignore this minor version. You can also ignore all major, minor, or patch releases for a dependency by adding an ignore condition with the desired update_types to your config file.

If you change your mind, just re-open this PR and I'll resolve any conflicts on it.

@dependabot
dependabot Bot deleted the dependabot/npm_and_yarn/cod-server/cloudflare/workers-oauth-provider-1.2.1 branch October 6, 2026 02:12

This branch was previously deployed

1 inactive deployment
Preview — 79d22f1c Deployed Oct 5, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Pull requests that update a dependency file

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant