diff --git a/backend/test/mastodon.spec.ts b/backend/test/mastodon.spec.ts index c9ea318..b0e9437 100644 --- a/backend/test/mastodon.spec.ts +++ b/backend/test/mastodon.spec.ts @@ -5,7 +5,7 @@ import * as v2_instance from 'wildebeest/functions/api/v2/instance' import * as custom_emojis from 'wildebeest/functions/api/v1/custom_emojis' import * as mutes from 'wildebeest/functions/api/v1/mutes' import * as blocks from 'wildebeest/functions/api/v1/blocks' -import { makeDB, assertCORS, assertJSON, assertCache, generateVAPIDKeys } from './utils' +import { makeDB, assertCORS, assertJSON, assertCache } from './utils' import { enrichStatus } from 'wildebeest/backend/src/mastodon/microformats' import { moveFollowers } from 'wildebeest/backend/src/mastodon/follow' import { createPerson } from 'wildebeest/backend/src/activitypub/actors' @@ -88,52 +88,6 @@ describe('Mastodon APIs', () => { }) }) - describe('apps', () => { - test('return the app infos', async () => { - const db = await makeDB() - const vapidKeys = await generateVAPIDKeys() - const request = new Request('https://example.com', { - method: 'POST', - body: '{"redirect_uris":"mastodon://joinmastodon.org/oauth","website":"https://app.joinmastodon.org/ios","client_name":"Mastodon for iOS","scopes":"read write follow push"}', - headers: { - 'content-type': 'application/json', - }, - }) - - const res = await apps.handleRequest(db, request, vapidKeys) - assert.equal(res.status, 200) - assertCORS(res) - assertJSON(res) - - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const { name, website, redirect_uri, client_id, client_secret, vapid_key, id, ...rest } = await res.json< - Record - >() - - assert.equal(name, 'Mastodon for iOS') - assert.equal(website, 'https://app.joinmastodon.org/ios') - assert.equal(redirect_uri, 'mastodon://joinmastodon.org/oauth') - assert.equal(id, '20') - assert.deepEqual(rest, {}) - }) - - test('returns 404 for GET request', async () => { - const vapidKeys = await generateVAPIDKeys() - const request = new Request('https://example.com') - const ctx: any = { - next: () => new Response(), - data: null, - env: { - VAPID_JWK: JSON.stringify(vapidKeys), - }, - request, - } - - const res = await apps.onRequest(ctx) - assert.equal(res.status, 400) - }) - }) - describe('custom emojis', () => { test('returns an empty array', async () => { const res = await custom_emojis.onRequest() @@ -284,4 +238,4 @@ describe('Mastodon APIs', () => { assert.equal(results[2].target_actor_acct, 'sven@cloudflare.com') }) }) -}) +}) \ No newline at end of file diff --git a/backend/test/mastodon/apps.spec.ts b/backend/test/mastodon/apps.spec.ts index d1dd4eb..9455fb9 100644 --- a/backend/test/mastodon/apps.spec.ts +++ b/backend/test/mastodon/apps.spec.ts @@ -1,11 +1,10 @@ -import { makeDB, assertCORS, assertJSON, createTestClient } from '../utils' +import { makeDB, assertCORS, assertJSON, createTestClient, generateVAPIDKeys } from '../utils' import { TEST_JWT } from '../test-data' import { strict as assert } from 'node:assert/strict' import * as apps from 'wildebeest/functions/api/v1/apps' import * as verify_app from 'wildebeest/functions/api/v1/apps/verify_credentials' import { CredentialApp } from 'wildebeest/functions/api/v1/apps/verify_credentials' import { VAPIDPublicKey } from 'wildebeest/backend/src/mastodon/subscription' -import { generateVAPIDKeys } from 'wildebeest/backend/test/mastodon.spec' describe('Mastodon APIs', () => { describe('/apps', () => { @@ -26,13 +25,14 @@ describe('Mastodon APIs', () => { assertJSON(res) // eslint-disable-next-line @typescript-eslint/no-unused-vars - const { name, website, redirect_uri, client_id, client_secret, vapid_key, ...rest } = await res.json< + const { name, website, redirect_uri, client_id, client_secret, vapid_key, id, ...rest } = await res.json< Record >() assert.equal(name, 'Mastodon for iOS') assert.equal(website, 'https://app.joinmastodon.org/ios') assert.equal(redirect_uri, 'mastodon://joinmastodon.org/oauth') + assert.equal(id, '20') assert.deepEqual(rest, {}) }) @@ -75,7 +75,7 @@ describe('Mastodon APIs', () => { assert.equal(res.status, 422) }) - test('GET /apps is bad request', async () => { + test('GET /apps is bad request', async () => { const vapidKeys = await generateVAPIDKeys() const request = new Request('https://example.com') const ctx: any = { @@ -88,7 +88,7 @@ describe('Mastodon APIs', () => { } const res = await apps.onRequest(ctx) - assert.equal(res.status, 400) + assert.equal(res.status, 405) }) test('GET /verify_credentials returns public VAPID key for known clients', async () => { @@ -125,4 +125,4 @@ describe('Mastodon APIs', () => { assert.equal(res.status, 403) }) }) -}) +}) \ No newline at end of file diff --git a/functions/api/v1/apps.ts b/functions/api/v1/apps.ts index 9364823..3ef273c 100644 --- a/functions/api/v1/apps.ts +++ b/functions/api/v1/apps.ts @@ -21,25 +21,25 @@ export const onRequest: PagesFunction = async ({ request, export async function handleRequest(db: D1Database, request: Request, vapidKeys: JWK) { if (request.method !== 'POST') { - return errors.methodNotAllowed() + return errors.methodNotAllowed() } const body: AppsPost = await readBody(request) // Parameter validation according to https://github.com/mastodon/mastodon/blob/main/app/lib/application_extension.rb if (body.client_name === undefined || body.client_name?.trim() === '') { - return errors.unprocessableEntity('client_name cannot be an empty string') + return errors.unprocessableEntity('client_name cannot be an empty string') } else if (body.client_name?.length > 60) { - return errors.unprocessableEntity('client_name cannot exceed 60 characters') + return errors.unprocessableEntity('client_name cannot exceed 60 characters') } else if (body.redirect_uris === undefined || body.redirect_uris?.trim() === '') { - return errors.unprocessableEntity('redirect_uris cannot be an empty string') + return errors.unprocessableEntity('redirect_uris cannot be an empty string') } else if (body.redirect_uris?.length > 2000) { - return errors.unprocessableEntity('redirect_uris cannot exceed 2000 characters') + return errors.unprocessableEntity('redirect_uris cannot exceed 2000 characters') } else if (body.redirect_uris !== 'urn:ietf:wg:oauth:2.0:oob') { try { new URL('', body.redirect_uris) } catch { - return errors.unprocessableEntity('redirect_uris must be a valid URI') + return errors.unprocessableEntity('redirect_uris must be a valid URI') } } @@ -64,4 +64,4 @@ export async function handleRequest(db: D1Database, request: Request, vapidKeys: 'content-type': 'application/json; charset=utf-8', } return new Response(JSON.stringify(res), { headers }) -} +} \ No newline at end of file