Skip to content

Commit

Permalink
fix(backend): Fix unhandled handshake error (#2541)
Browse files Browse the repository at this point in the history
* fix(backend): Fix unhandled handshake error

* fix(backend): Handle development verification failure
  • Loading branch information
BRKalow committed Jan 10, 2024
1 parent 59f9a72 commit e6ecbaa
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 8 deletions.
5 changes: 5 additions & 0 deletions .changeset/few-rings-push.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@clerk/backend': patch
---

Fix an error in the handshake flow where the request would throw an unhandled error when verification of the handshake payload fails.
11 changes: 6 additions & 5 deletions integration/tests/handshake.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -827,26 +827,27 @@ test.describe('Client handshake @generic', () => {
}),
redirect: 'manual',
});
expect(res.status).toBe(500);
expect(res.status).toBe(200);
});

test('Handshake result - prod - skew - clock ahead', async () => {
test('Handshake result - prod - session token expired and handshake stale', async () => {
const config = generateConfig({
mode: 'live',
});
const { token: currentSessionToken, claims } = config.generateToken({ state: 'expired' });
const { token } = config.generateToken({ state: 'expired' });
const cookiesToSet = [`__session=${token};path=/`, 'foo=bar;path=/;domain=example.com'];
const handshake = await config.generateHandshakeToken(cookiesToSet);
const res = await fetch(app.serverUrl + '/', {
headers: new Headers({
'X-Publishable-Key': config.pk,
'X-Secret-Key': config.sk,
Cookie: `__clerk_handshake=${handshake}`,
Cookie: `__clerk_handshake=${handshake};__session=${currentSessionToken};__client_uat=${claims.iat}`,
'Sec-Fetch-Dest': 'document',
}),
redirect: 'manual',
});
expect(res.status).toBe(500);
expect(res.status).toBe(307);
});

test('Handshake result - prod - mismatched keys', async () => {
Expand All @@ -866,6 +867,6 @@ test.describe('Client handshake @generic', () => {
}),
redirect: 'manual',
});
expect(res.status).toBe(500);
expect(res.status).toBe(200);
});
});
20 changes: 17 additions & 3 deletions packages/backend/src/tokens/request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,8 @@ export async function authenticateRequest(

if (
instanceType === 'development' &&
(error.reason === TokenVerificationErrorReason.TokenExpired ||
error.reason === TokenVerificationErrorReason.TokenNotActiveYet)
(error?.reason === TokenVerificationErrorReason.TokenExpired ||
error?.reason === TokenVerificationErrorReason.TokenNotActiveYet)
) {
error.tokenCarrier = 'cookie';
// This probably means we're dealing with clock skew
Expand Down Expand Up @@ -204,7 +204,21 @@ ${error.getFullMessage()}`,
* If we have a handshakeToken, resolve the handshake and attempt to return a definitive signed in or signed out state.
*/
if (authenticateContext.handshakeToken) {
return resolveHandshake();
try {
return await resolveHandshake();
} catch (error) {
// If for some reason the handshake token is invalid or stale, we ignore it and continue trying to authenticate the request.
// Worst case, the handshake will trigger again and return a refreshed token.
if (error instanceof TokenVerificationError && instanceType === 'development') {
if (error.reason === TokenVerificationErrorReason.TokenInvalidSignature) {
throw new Error(
`Clerk: Handshake token verification failed due to an invalid signature. If you have switched Clerk keys locally, clear your cookies and try again.`,
);
}

throw new Error(`Clerk: Handshake token verification failed: ${error.getFullMessage()}.`);
}
}
}

/**
Expand Down

0 comments on commit e6ecbaa

Please sign in to comment.