diff --git a/backend/test/mastodon/oauth.spec.ts b/backend/test/mastodon/oauth.spec.ts index 765e47f..669da1b 100644 --- a/backend/test/mastodon/oauth.spec.ts +++ b/backend/test/mastodon/oauth.spec.ts @@ -174,6 +174,31 @@ describe('Mastodon APIs', () => { assert((await getSigningKey(userKEK, db, actor as Actor)) instanceof CryptoKey) }) + test('first login redirect relative URLs', async () => { + const db = await makeDB() + + const params = new URLSearchParams({ + redirect_uri: '/a', + }) + + const formData = new FormData() + formData.set('username', 'username') + formData.set('name', 'name') + + const req = new Request('https://example.com/first-login?' + params, { + method: 'POST', + body: formData, + headers: { + cookie: `CF_Authorization=${TEST_JWT}`, + }, + }) + const res = await first_login.handlePostRequest(req, db, userKEK, accessDomain, accessAud) + assert.equal(res.status, 302) + + const location = res.headers.get('location') + assert.equal(location, 'https://example.com/a') + }) + test('token error on unknown client', async () => { const db = await makeDB() const body = new URLSearchParams({ code: 'some-code' }) diff --git a/functions/first-login.ts b/functions/first-login.ts index 1a9c9e2..a4e95ea 100644 --- a/functions/first-login.ts +++ b/functions/first-login.ts @@ -55,6 +55,10 @@ export async function handlePostRequest( return new Response('', { status: 400 }) } - const redirect_uri = decodeURIComponent(url.searchParams.get('redirect_uri') || '') + let redirect_uri = decodeURIComponent(url.searchParams.get('redirect_uri') || '') + if (redirect_uri.startsWith('/')) { + // URL is a relative URL, prepend the domain to it. + redirect_uri = 'https://' + url.hostname + redirect_uri + } return Response.redirect(redirect_uri, 302) }