From e1e3d4c9e1b3b23215dd0030dad8ae50f2ba7bab Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Wed, 22 Jul 2026 02:11:42 +0000 Subject: [PATCH] Upgrade @cloudflare/workers-oauth-provider to 0.8.2 Adopt finite OAuth KV TTLs and scheduled purge, silence default onError console warnings, and keep malformed-client token exception coverage working under stricter auth-code validation. --- package-lock.json | 14 +++++++------- packages/worker/package.json | 2 +- packages/worker/src/index.ts | 14 ++++++++++++-- packages/worker/src/mcp-auth.workers.test.ts | 10 ++++++++++ .../worker/src/oauth-handlers.workers.test.ts | 15 +++++++++++++++ 5 files changed, 45 insertions(+), 10 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6d40d55893..664390442e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1141,6 +1141,12 @@ "node": ">=16" } }, + "node_modules/@cloudflare/workers-oauth-provider": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/@cloudflare/workers-oauth-provider/-/workers-oauth-provider-0.8.2.tgz", + "integrity": "sha512-Pho5qWDl4qj1STI5QYMQfPmJBBkxyrFpXyDl9BrtYOfWHxThabEzdi9p3ezS2cUkbjA0E6L5ki/kq2pcbRUtlg==", + "license": "MIT" + }, "node_modules/@cloudflare/workers-types": { "version": "4.20260702.1", "license": "MIT OR Apache-2.0" @@ -14747,7 +14753,7 @@ "@cloudflare/codemode": "^0.4.3", "@cloudflare/shell": "^0.4.1", "@cloudflare/worker-bundler": "^0.2.1", - "@cloudflare/workers-oauth-provider": "^0.4.0", + "@cloudflare/workers-oauth-provider": "^0.8.2", "@epic-web/cachified": "^5.6.3", "@epic-web/invariant": "^1.0.0", "@epic-web/totp": "^4.0.1", @@ -14772,12 +14778,6 @@ "zod": "^4.3.6" } }, - "packages/worker/node_modules/@cloudflare/workers-oauth-provider": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@cloudflare/workers-oauth-provider/-/workers-oauth-provider-0.4.0.tgz", - "integrity": "sha512-UtbV8hjC2NloB+Ds6J6v/9HiG8rx8MbdeYGCyFwOACT5vANWzDL6SKo3W5UZymsXiameAgC7jAmtUx4cc+Qpaw==", - "license": "MIT" - }, "packages/worker/node_modules/@remix-run/data-schema": { "version": "0.3.0", "license": "MIT", diff --git a/packages/worker/package.json b/packages/worker/package.json index 8557715ed5..5f6711572f 100644 --- a/packages/worker/package.json +++ b/packages/worker/package.json @@ -10,7 +10,7 @@ "@cloudflare/codemode": "^0.4.3", "@cloudflare/shell": "^0.4.1", "@cloudflare/worker-bundler": "^0.2.1", - "@cloudflare/workers-oauth-provider": "^0.4.0", + "@cloudflare/workers-oauth-provider": "^0.8.2", "@epic-web/cachified": "^5.6.3", "@epic-web/invariant": "^1.0.0", "@epic-web/totp": "^4.0.1", diff --git a/packages/worker/src/index.ts b/packages/worker/src/index.ts index 6a99018044..e12193bc09 100644 --- a/packages/worker/src/index.ts +++ b/packages/worker/src/index.ts @@ -353,6 +353,10 @@ const oauthProvider = new OAuthProvider({ tokenEndpoint: oauthPaths.token, clientRegistrationEndpoint: oauthPaths.register, scopesSupported: oauthScopes, + // Provider default onError logs every structured OAuth error via console.warn. + // Keep those responses on the wire without duplicating them into worker logs / + // test console guards; unexpected throws still reach our fetch catch + Sentry. + onError: () => undefined, // NOTE: we intentionally do NOT set `allowPlainPKCE: false`. In this provider // version that option rejects EVERY authorize request whose // `code_challenge_method` is absent or `plain` — including confidential @@ -397,8 +401,8 @@ function isOAuthProviderOwnedPath(pathname: string) { function isMalformedOAuthClientException(error: unknown, pathname: string) { const message = error instanceof Error ? error.message : '' - // @cloudflare/workers-oauth-provider@0.4.0 throws this raw TypeError - // when a stored client is missing redirectUris during token validation. + // @cloudflare/workers-oauth-provider still throws this raw TypeError when a + // stored client is missing redirectUris during token redirect_uri checks. return ( pathname === oauthPaths.token && message.includes("Cannot read properties of undefined (reading 'some')") @@ -539,6 +543,12 @@ const workerHandler = { name: 'stripe_plan_refresh', run: () => refreshStaleStripePlans({ env, now: scheduledAt }), }, + { + // 0.5+ defaults refresh/client TTLs and exposes purgeExpiredData for + // defense-in-depth cleanup of orphaned OAUTH_KV grants/tokens. + name: 'oauth_purge_expired', + run: () => oauthProvider.purgeExpiredData(env), + }, ] if (shouldRunRetentionCron(scheduledAt)) { lanes.push({ diff --git a/packages/worker/src/mcp-auth.workers.test.ts b/packages/worker/src/mcp-auth.workers.test.ts index cc3bb7386d..9ab6d67754 100644 --- a/packages/worker/src/mcp-auth.workers.test.ts +++ b/packages/worker/src/mcp-auth.workers.test.ts @@ -48,6 +48,16 @@ function createHelpers(overrides: Partial = {}): OAuthHelpers { listUserGrants: async () => ({ items: [] }), revokeGrant: async () => undefined, unwrapToken: async () => null, + async exchangeToken() { + throw new Error('Not implemented') + }, + purgeExpiredData: async () => ({ + grantsChecked: 0, + grantsPurged: 0, + tokensChecked: 0, + tokensPurged: 0, + done: true, + }), ...overrides, } } diff --git a/packages/worker/src/oauth-handlers.workers.test.ts b/packages/worker/src/oauth-handlers.workers.test.ts index 880efda3ec..41d135a8fb 100644 --- a/packages/worker/src/oauth-handlers.workers.test.ts +++ b/packages/worker/src/oauth-handlers.workers.test.ts @@ -73,6 +73,16 @@ function createHelpers(overrides: Partial = {}): OAuthHelpers { listUserGrants: async () => ({ items: [] }), revokeGrant: async () => undefined, unwrapToken: async () => null, + async exchangeToken() { + throw new Error('Not implemented') + }, + purgeExpiredData: async () => ({ + grantsChecked: 0, + grantsPurged: 0, + tokensChecked: 0, + tokensPurged: 0, + done: true, + }), ...overrides, } } @@ -791,6 +801,11 @@ test('worker entrypoint returns OAuth errors for provider-owned route exceptions encryptedProps: '', createdAt: Math.floor(Date.now() / 1000), authCodeId: await createSha256Hex(code), + // 0.8+ treats a missing authCodeWrappedKey as an already-used code and + // returns invalid_grant before redirect_uri validation. Keep a dummy + // wrapped key so the malformed-client redirectUris TypeError still + // reaches the worker exception mapper under test. + authCodeWrappedKey: 'malformed-client-auth-code-wrapped-key', resource: 'https://heykody.dev/mcp', codeChallenge: 'verifier', codeChallengeMethod: 'plain',