Skip to content

Commit 8aff707

Browse files
authored
fix(e2e): stamp the testing token on the OAuth callback when consent is skipped (#10438)
1 parent 8b80b24 commit 8aff707

4 files changed

Lines changed: 39 additions & 5 deletions

File tree

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
---
2+
---

‎integration/testUtils/setupTestingTokens.ts‎

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,21 @@ export const setupTestingTokens = async ({
2222

2323
await context.route(
2424
url =>
25-
(tokens.has(url.origin) && url.pathname.startsWith('/v1/')) || url.pathname.startsWith('/v1/me/oauth/consent/'),
25+
(tokens.has(url.origin) && url.pathname.startsWith('/v1/')) ||
26+
url.pathname.startsWith('/v1/me/oauth/consent/') ||
27+
url.pathname === '/oauth/authorize/continue',
2628
async route => {
27-
const requestUrl = new URL(route.request().url());
28-
const requestToken = tokens.get(requestUrl.origin);
29+
const request = route.request();
30+
const requestUrl = new URL(request.url());
31+
const requestToken = requestUrl.pathname.startsWith('/v1/') ? tokens.get(requestUrl.origin) : undefined;
2932
if (requestToken) {
3033
requestUrl.searchParams.set('__clerk_testing_token', requestToken);
3134
}
3235

33-
if (route.request().method() !== 'POST' || !requestUrl.pathname.startsWith('/v1/me/oauth/consent/')) {
36+
const redirectsToCallback =
37+
(request.method() === 'POST' && requestUrl.pathname.startsWith('/v1/me/oauth/consent/')) ||
38+
(request.method() === 'GET' && requestUrl.pathname === '/oauth/authorize/continue');
39+
if (!redirectsToCallback) {
3440
if (!requestToken) {
3541
return route.fallback();
3642
}

‎integration/tests/session-tasks-sign-up.test.ts‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,11 @@ testAgainstRunningApps({ withEnv: [appConfigs.envs.withSessionTasks] })(
101101
await u.po.signUp.waitForMounted();
102102
await u.po.signUp.setEmailAddress(fakeUserForOAuth.email);
103103
await u.po.signUp.continue();
104-
await u.po.signUp.enterTestOtpCode();
104+
const [callback] = await Promise.all([
105+
page.waitForRequest(request => new URL(request.url()).pathname === '/v1/oauth_callback'),
106+
u.po.signUp.enterTestOtpCode(),
107+
]);
108+
expect(new URL(callback.url()).searchParams.has('__clerk_testing_token')).toBe(true);
105109

106110
// Resolves task
107111
await u.po.signUp.waitForMounted();

‎integration/tests/testing-token.test.ts‎

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ test.describe('OAuth testing tokens @nextjs', () => {
1313
let appOrigin: string;
1414
let consentPosts: string[];
1515
let consentTokens: (string | null)[];
16+
let authorizeTokens: (string | null)[];
1617

1718
test.beforeAll(async () => {
1819
app = createServer((request, response) => {
@@ -37,6 +38,10 @@ test.describe('OAuth testing tokens @nextjs', () => {
3738
});
3839
response.end('Consent accepted');
3940
});
41+
} else if (url.pathname === '/oauth/authorize/continue') {
42+
authorizeTokens.push(url.searchParams.get('__clerk_testing_token'));
43+
response.writeHead(303, { location: url.searchParams.get('callback') || '/' });
44+
response.end('Authorized');
4045
} else {
4146
response.end(JSON.stringify({ url: request.url, method: request.method }));
4247
}
@@ -49,6 +54,7 @@ test.describe('OAuth testing tokens @nextjs', () => {
4954
test.beforeEach(async ({ context }) => {
5055
consentPosts = [];
5156
consentTokens = [];
57+
authorizeTokens = [];
5258
await setupTestingTokens({ context, frontendApiOrigin: appOrigin, token: 'app-testing-token' });
5359
});
5460

@@ -95,6 +101,22 @@ test.describe('OAuth testing tokens @nextjs', () => {
95101
expect((await context.cookies(providerOrigin)).map(cookie => cookie.name).sort()).toEqual(['consent', 'provider']);
96102
});
97103

104+
test('delivers the token on the callback when the provider skips the consent screen', async ({ page, context }) => {
105+
await setupTestingTokens({ context, frontendApiOrigin: providerOrigin, token: 'provider-testing-token' });
106+
const callback = new URL('/v1/oauth_callback?code=auth-code&state=a%2Bb%2F%3D', appOrigin);
107+
const authorize = new URL('/oauth/authorize/continue', providerOrigin);
108+
authorize.searchParams.set('callback', callback.toString());
109+
await page.goto(authorize.toString());
110+
111+
expect(authorizeTokens).toEqual([null]);
112+
const received = JSON.parse((await page.locator('body').textContent()) || '{}');
113+
expect(Object.fromEntries(new URL(received.url, appOrigin).searchParams)).toEqual({
114+
code: 'auth-code',
115+
state: 'a+b/=',
116+
__clerk_testing_token: 'app-testing-token',
117+
});
118+
});
119+
98120
for (const [name, getCallback] of [
99121
['another origin', () => new URL('/v1/oauth_callback?code=auth-code', providerOrigin)],
100122
['another path', () => new URL('/sso-callback?code=auth-code', appOrigin)],

0 commit comments

Comments
 (0)