From 5bf45d695673a6a97ecd65fd97f429e56146d591 Mon Sep 17 00:00:00 2001 From: Vaggelis Yfantis Date: Mon, 3 Jun 2024 09:39:42 +0300 Subject: [PATCH 1/8] fix: Request#duplex now is required in unidici if body is provided in RequestInit --- packages/backend/src/tokens/clerkRequest.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/backend/src/tokens/clerkRequest.ts b/packages/backend/src/tokens/clerkRequest.ts index 3ea16842ea4..2bb7eb9d07b 100644 --- a/packages/backend/src/tokens/clerkRequest.ts +++ b/packages/backend/src/tokens/clerkRequest.ts @@ -21,6 +21,10 @@ class ClerkRequest extends Request { // https://github.com/nodejs/undici/issues/2155 // https://github.com/nodejs/undici/blob/7153a1c78d51840bbe16576ce353e481c3934701/lib/fetch/request.js#L854 const url = typeof input !== 'string' && 'url' in input ? input.url : String(input); + // duplex now required if body is provided in RequestInit + if (init?.body instanceof ReadableStream) { + (init as { duplex: 'half' }).duplex = 'half'; + } super(url, init || typeof input === 'string' ? undefined : input); this.clerkUrl = this.deriveUrlFromHeaders(this); this.cookies = this.parseCookies(this); From 3df2be51d8e12d0da39924d68804ee321570dea6 Mon Sep 17 00:00:00 2001 From: Vaggelis Yfantis Date: Mon, 3 Jun 2024 09:40:09 +0300 Subject: [PATCH 2/8] chore: update comment --- packages/backend/src/tokens/clerkRequest.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/backend/src/tokens/clerkRequest.ts b/packages/backend/src/tokens/clerkRequest.ts index 2bb7eb9d07b..a805f4c7d7a 100644 --- a/packages/backend/src/tokens/clerkRequest.ts +++ b/packages/backend/src/tokens/clerkRequest.ts @@ -21,7 +21,7 @@ class ClerkRequest extends Request { // https://github.com/nodejs/undici/issues/2155 // https://github.com/nodejs/undici/blob/7153a1c78d51840bbe16576ce353e481c3934701/lib/fetch/request.js#L854 const url = typeof input !== 'string' && 'url' in input ? input.url : String(input); - // duplex now required if body is provided in RequestInit + // Request#duplex now is required if body is provided in RequestInit if (init?.body instanceof ReadableStream) { (init as { duplex: 'half' }).duplex = 'half'; } From 6732d3a443bb6ac266a088c9a0bc3c3083390a27 Mon Sep 17 00:00:00 2001 From: Vaggelis Yfantis Date: Mon, 3 Jun 2024 09:41:38 +0300 Subject: [PATCH 3/8] chore: update comment --- packages/backend/src/tokens/clerkRequest.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/backend/src/tokens/clerkRequest.ts b/packages/backend/src/tokens/clerkRequest.ts index a805f4c7d7a..1fd29981349 100644 --- a/packages/backend/src/tokens/clerkRequest.ts +++ b/packages/backend/src/tokens/clerkRequest.ts @@ -21,7 +21,7 @@ class ClerkRequest extends Request { // https://github.com/nodejs/undici/issues/2155 // https://github.com/nodejs/undici/blob/7153a1c78d51840bbe16576ce353e481c3934701/lib/fetch/request.js#L854 const url = typeof input !== 'string' && 'url' in input ? input.url : String(input); - // Request#duplex now is required if body is provided in RequestInit + // RequestInit.duplex now is required if body is provided in RequestInit if (init?.body instanceof ReadableStream) { (init as { duplex: 'half' }).duplex = 'half'; } From ef2fabc81ecb71ebc6a8b55c9e13c05d381ddb41 Mon Sep 17 00:00:00 2001 From: Vaggelis Yfantis Date: Mon, 3 Jun 2024 09:46:43 +0300 Subject: [PATCH 4/8] chore(repo): Add Changeset --- .changeset/fifty-parents-juggle.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/fifty-parents-juggle.md diff --git a/.changeset/fifty-parents-juggle.md b/.changeset/fifty-parents-juggle.md new file mode 100644 index 00000000000..6c3e1182aa4 --- /dev/null +++ b/.changeset/fifty-parents-juggle.md @@ -0,0 +1,5 @@ +--- +'@clerk/backend': patch +--- + +Fix RequestInit.duplex which now is required if body is provided in undici From e6cd78b7ebc5d6288718ff744c9d1f6d1e6e1ef1 Mon Sep 17 00:00:00 2001 From: Vaggelis Yfantis Date: Mon, 3 Jun 2024 10:13:19 +0300 Subject: [PATCH 5/8] fix(remix): Add duplex when body is readable stream --- packages/backend/src/tokens/clerkRequest.ts | 4 ---- packages/remix/src/ssr/authenticateRequest.ts | 5 +++++ 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/packages/backend/src/tokens/clerkRequest.ts b/packages/backend/src/tokens/clerkRequest.ts index 1fd29981349..3ea16842ea4 100644 --- a/packages/backend/src/tokens/clerkRequest.ts +++ b/packages/backend/src/tokens/clerkRequest.ts @@ -21,10 +21,6 @@ class ClerkRequest extends Request { // https://github.com/nodejs/undici/issues/2155 // https://github.com/nodejs/undici/blob/7153a1c78d51840bbe16576ce353e481c3934701/lib/fetch/request.js#L854 const url = typeof input !== 'string' && 'url' in input ? input.url : String(input); - // RequestInit.duplex now is required if body is provided in RequestInit - if (init?.body instanceof ReadableStream) { - (init as { duplex: 'half' }).duplex = 'half'; - } super(url, init || typeof input === 'string' ? undefined : input); this.clerkUrl = this.deriveUrlFromHeaders(this); this.cookies = this.parseCookies(this); diff --git a/packages/remix/src/ssr/authenticateRequest.ts b/packages/remix/src/ssr/authenticateRequest.ts index 18457746852..964ae4f0324 100644 --- a/packages/remix/src/ssr/authenticateRequest.ts +++ b/packages/remix/src/ssr/authenticateRequest.ts @@ -14,6 +14,11 @@ export async function authenticateRequest( const { apiUrl, secretKey, jwtKey, proxyUrl, isSatellite, domain, publishableKey } = opts; const { signInUrl, signUpUrl, afterSignInUrl, afterSignUpUrl } = opts; + // RequestInit#duplex option is required when sending a body. + if (request?.body instanceof ReadableStream) { + (request as unknown as { duplex: 'half' }).duplex = 'half'; + } + const requestState = await createClerkClient({ apiUrl, secretKey, From 3d7068e3f6947f435f29fad2618e526c8e0837b1 Mon Sep 17 00:00:00 2001 From: Vaggelis Yfantis Date: Mon, 3 Jun 2024 11:15:26 +0300 Subject: [PATCH 6/8] fix(remix): Add duplex when sending a body --- packages/remix/src/ssr/authenticateRequest.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/remix/src/ssr/authenticateRequest.ts b/packages/remix/src/ssr/authenticateRequest.ts index 964ae4f0324..7705212847e 100644 --- a/packages/remix/src/ssr/authenticateRequest.ts +++ b/packages/remix/src/ssr/authenticateRequest.ts @@ -15,7 +15,7 @@ export async function authenticateRequest( const { signInUrl, signUpUrl, afterSignInUrl, afterSignUpUrl } = opts; // RequestInit#duplex option is required when sending a body. - if (request?.body instanceof ReadableStream) { + if (request?.body) { (request as unknown as { duplex: 'half' }).duplex = 'half'; } From 308d735a58a6bc1a6c326f4fac42ec8ba4f5d4a3 Mon Sep 17 00:00:00 2001 From: Vaggelis Yfantis Date: Wed, 12 Jun 2024 14:22:05 +0300 Subject: [PATCH 7/8] fix(remix): Patch request to have duplex='half' property --- packages/remix/src/ssr/authenticateRequest.ts | 8 ++------ packages/remix/src/ssr/loadOptions.ts | 3 ++- packages/remix/src/ssr/utils.ts | 15 +++++++++++++++ 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/packages/remix/src/ssr/authenticateRequest.ts b/packages/remix/src/ssr/authenticateRequest.ts index 7705212847e..27c23da94e2 100644 --- a/packages/remix/src/ssr/authenticateRequest.ts +++ b/packages/remix/src/ssr/authenticateRequest.ts @@ -3,6 +3,7 @@ import type { AuthenticateRequestOptions, SignedInState, SignedOutState } from ' import { AuthStatus } from '@clerk/backend/internal'; import type { LoaderFunctionArgs } from './types'; +import { patchRequest } from './utils'; export async function authenticateRequest( args: LoaderFunctionArgs, @@ -14,11 +15,6 @@ export async function authenticateRequest( const { apiUrl, secretKey, jwtKey, proxyUrl, isSatellite, domain, publishableKey } = opts; const { signInUrl, signUpUrl, afterSignInUrl, afterSignUpUrl } = opts; - // RequestInit#duplex option is required when sending a body. - if (request?.body) { - (request as unknown as { duplex: 'half' }).duplex = 'half'; - } - const requestState = await createClerkClient({ apiUrl, secretKey, @@ -28,7 +24,7 @@ export async function authenticateRequest( domain, publishableKey, userAgent: `${PACKAGE_NAME}@${PACKAGE_VERSION}`, - }).authenticateRequest(request, { + }).authenticateRequest(patchRequest(request), { audience, authorizedParties, signInUrl, diff --git a/packages/remix/src/ssr/loadOptions.ts b/packages/remix/src/ssr/loadOptions.ts index 4753006d7d4..ea582305ebd 100644 --- a/packages/remix/src/ssr/loadOptions.ts +++ b/packages/remix/src/ssr/loadOptions.ts @@ -8,10 +8,11 @@ import { isTruthy } from '@clerk/shared/underscore'; import { noSecretKeyError, satelliteAndMissingProxyUrlAndDomain, satelliteAndMissingSignInUrl } from '../utils/errors'; import { getEnvVariable } from '../utils/utils'; import type { LoaderFunctionArgs, RootAuthLoaderOptions } from './types'; +import { patchRequest } from './utils'; export const loadOptions = (args: LoaderFunctionArgs, overrides: RootAuthLoaderOptions = {}) => { const { request, context } = args; - const clerkRequest = createClerkRequest(request); + const clerkRequest = createClerkRequest(patchRequest(request)); // Fetch environment variables across Remix runtime. // 1. First check if the user passed the key in the getAuth function or the rootAuthLoader. diff --git a/packages/remix/src/ssr/utils.ts b/packages/remix/src/ssr/utils.ts index 5ac35891801..8ee504b4133 100644 --- a/packages/remix/src/ssr/utils.ts +++ b/packages/remix/src/ssr/utils.ts @@ -116,3 +116,18 @@ export function getResponseClerkState(requestState: RequestStateWithRedirectUrls export const wrapWithClerkState = (data: any) => { return { clerkState: { __internal_clerk_state: { ...data } } }; }; + +/** + * Patches request to avoid duplex issues with unidici + * For more information, see: + * https://github.com/nodejs/node/issues/46221 + * https://github.com/whatwg/fetch/pull/1457 + * @internal + */ +export const patchRequest = (request: Request) => { + const clonedRequest = request.clone(); + if (clonedRequest.method !== 'GET' && clonedRequest.body !== null) { + (clonedRequest as unknown as { duplex: 'half' }).duplex = 'half'; + } + return clonedRequest; +}; From 4d7a407bbd674f4e703e422cf658b1f55189d738 Mon Sep 17 00:00:00 2001 From: Vaggelis Yfantis Date: Wed, 12 Jun 2024 19:34:03 +0300 Subject: [PATCH 8/8] Update .changeset/fifty-parents-juggle.md Co-authored-by: Stefanos Anagnostou --- .changeset/fifty-parents-juggle.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/fifty-parents-juggle.md b/.changeset/fifty-parents-juggle.md index 6c3e1182aa4..8087d52e1a3 100644 --- a/.changeset/fifty-parents-juggle.md +++ b/.changeset/fifty-parents-juggle.md @@ -1,5 +1,5 @@ --- -'@clerk/backend': patch +'@clerk/remix': patch --- Fix RequestInit.duplex which now is required if body is provided in undici