From e917dc6be368078055960e29750a97263ff0c39d Mon Sep 17 00:00:00 2001 From: syuilo Date: Sat, 4 Feb 2023 09:10:01 +0900 Subject: [PATCH 01/35] fix(client): validate urls to improve security --- packages/client/src/components/MkUrlPreview.vue | 1 + packages/client/src/components/global/MkUrl.vue | 1 + packages/client/src/pages/miauth.vue | 2 ++ 3 files changed, 4 insertions(+) diff --git a/packages/client/src/components/MkUrlPreview.vue b/packages/client/src/components/MkUrlPreview.vue index ef65cb796..865d4bcbe 100644 --- a/packages/client/src/components/MkUrlPreview.vue +++ b/packages/client/src/components/MkUrlPreview.vue @@ -67,6 +67,7 @@ const embedId = `embed${Math.random().toString().replace(/\D/,'')}`; let tweetHeight = $ref(150); const requestUrl = new URL(props.url); +if (!['http:', 'https:'].includes(requestUrl.protocol)) throw new Error('invalid url'); if (requestUrl.hostname === 'twitter.com' || requestUrl.hostname === 'mobile.twitter.com') { const m = requestUrl.pathname.match(/^\/.+\/status(?:es)?\/(\d+)/); diff --git a/packages/client/src/components/global/MkUrl.vue b/packages/client/src/components/global/MkUrl.vue index 2d328211d..d22c0b299 100644 --- a/packages/client/src/components/global/MkUrl.vue +++ b/packages/client/src/components/global/MkUrl.vue @@ -33,6 +33,7 @@ const props = defineProps<{ const self = props.url.startsWith(local); const url = new URL(props.url); +if (!['http:', 'https:'].includes(url.protocol)) throw new Error('invalid url'); const el = ref(); useTooltip(el, (showing) => { diff --git a/packages/client/src/pages/miauth.vue b/packages/client/src/pages/miauth.vue index 6352dc329..eaf96d60f 100644 --- a/packages/client/src/pages/miauth.vue +++ b/packages/client/src/pages/miauth.vue @@ -70,6 +70,8 @@ async function accept(): Promise { state = 'accepted'; if (props.callback) { + const cbUrl = new URL(props.callback); + if (!['http:', 'https:'].includes(cbUrl.protocol)) throw new Error('invalid url'); location.href = appendQuery(props.callback, query({ session: props.session, })); From 76011a3f28e38d0561efcc4ca1d3997554717950 Mon Sep 17 00:00:00 2001 From: ThatOneCalculator Date: Fri, 10 Feb 2023 11:14:33 -0800 Subject: [PATCH 02/35] fix: :lock: prevent issues --- .../src/remote/activitypub/models/note.ts | 12 +++++++++++- .../src/remote/activitypub/models/person.ts | 16 ++++++++++++++-- packages/backend/src/server/web/url-preview.ts | 8 ++++++++ packages/client/src/pages/auth.vue | 2 ++ packages/client/src/pages/miauth.vue | 3 +-- packages/client/src/scripts/aiscript/api.ts | 6 +++++- 6 files changed, 41 insertions(+), 6 deletions(-) diff --git a/packages/backend/src/remote/activitypub/models/note.ts b/packages/backend/src/remote/activitypub/models/note.ts index afb3af6cb..34d8d0ba1 100644 --- a/packages/backend/src/remote/activitypub/models/note.ts +++ b/packages/backend/src/remote/activitypub/models/note.ts @@ -111,6 +111,16 @@ export async function createNote( const note: IPost = object; + if (note.id && !note.id.startsWith('https://')) { + throw new Error(`unexpected shcema of note.id: ${note.id}`); + } + + const url = getOneApHrefNullable(note.url); + + if (url && !url.startsWith('https://')) { + throw new Error(`unexpected shcema of note url: ${url}`); + } + logger.debug(`Note fetched: ${JSON.stringify(note, null, 2)}`); logger.info(`Creating the Note: ${note.id}`); @@ -345,7 +355,7 @@ export async function createNote( apEmojis, poll, uri: note.id, - url: getOneApHrefNullable(note.url), + url: url, }, silent, ); diff --git a/packages/backend/src/remote/activitypub/models/person.ts b/packages/backend/src/remote/activitypub/models/person.ts index 0ec671f0a..88bbca5c4 100644 --- a/packages/backend/src/remote/activitypub/models/person.ts +++ b/packages/backend/src/remote/activitypub/models/person.ts @@ -195,6 +195,12 @@ export async function createPerson( const bday = person["vcard:bday"]?.match(/^\d{4}-\d{2}-\d{2}/); + const url = getOneApHrefNullable(person.url); + + if (url && !url.startsWith('https://')) { + throw new Error(`unexpected shcema of person url: ${url}`); + } + // Create user let user: IRemoteUser; try { @@ -237,7 +243,7 @@ export async function createPerson( description: person.summary ? htmlToMfm(truncate(person.summary, summaryLength), person.tag) : null, - url: getOneApHrefNullable(person.url), + url: url, fields, birthday: bday ? bday[0] : null, location: person["vcard:Address"] || null, @@ -387,6 +393,12 @@ export async function updatePerson( const bday = person["vcard:bday"]?.match(/^\d{4}-\d{2}-\d{2}/); + const url = getOneApHrefNullable(person.url); + + if (url && !url.startsWith('https://')) { + throw new Error(`unexpected shcema of person url: ${url}`); + } + const updates = { lastFetchedAt: new Date(), inbox: person.inbox, @@ -430,7 +442,7 @@ export async function updatePerson( await UserProfiles.update( { userId: exist.id }, { - url: getOneApHrefNullable(person.url), + url: url, fields, description: person.summary ? htmlToMfm(truncate(person.summary, summaryLength), person.tag) diff --git a/packages/backend/src/server/web/url-preview.ts b/packages/backend/src/server/web/url-preview.ts index d7da4e72c..cb58efa81 100644 --- a/packages/backend/src/server/web/url-preview.ts +++ b/packages/backend/src/server/web/url-preview.ts @@ -44,6 +44,14 @@ export const urlPreviewHandler = async (ctx: Koa.Context) => { logger.succ(`Got preview of ${url}: ${summary.title}`); + if (summary.url && !(summary.url.startsWith('http://') || summary.url.startsWith('https://'))) { + throw new Error('unsupported schema included'); + } + + if (summary.player?.url && !(summary.player.url.startsWith('http://') || summary.player.url.startsWith('https://'))) { + throw new Error('unsupported schema included'); + } + summary.icon = wrap(summary.icon); summary.thumbnail = wrap(summary.thumbnail); diff --git a/packages/client/src/pages/auth.vue b/packages/client/src/pages/auth.vue index bb3c54bd3..9fc04d4f4 100644 --- a/packages/client/src/pages/auth.vue +++ b/packages/client/src/pages/auth.vue @@ -80,6 +80,8 @@ export default defineComponent({ this.state = 'accepted'; const getUrlParams = () => window.location.search.substring(1).split('&').reduce((result, query) => { const [k, v] = query.split('='); result[k] = decodeURI(v); return result; }, {}); if (this.session.app.callbackUrl) { + const url = new URL(this.session.app.callbackUrl); + if (['javascript:', 'file:', 'data:', 'mailto:', 'tel:'].includes(url.protocol)) throw new Error('invalid url'); location.href = `${this.session.app.callbackUrl}?token=${this.session.token}&code=${this.session.token}&state=${getUrlParams().state || ''}`; } }, onLogin(res) { diff --git a/packages/client/src/pages/miauth.vue b/packages/client/src/pages/miauth.vue index eaf96d60f..292b47338 100644 --- a/packages/client/src/pages/miauth.vue +++ b/packages/client/src/pages/miauth.vue @@ -71,14 +71,13 @@ async function accept(): Promise { state = 'accepted'; if (props.callback) { const cbUrl = new URL(props.callback); - if (!['http:', 'https:'].includes(cbUrl.protocol)) throw new Error('invalid url'); + if (['javascript:', 'file:', 'data:', 'mailto:', 'tel:'].includes(cbUrl.protocol)) throw new Error('invalid url'); location.href = appendQuery(props.callback, query({ session: props.session, })); } } -function deny(): void { state = 'denied'; } diff --git a/packages/client/src/scripts/aiscript/api.ts b/packages/client/src/scripts/aiscript/api.ts index b37eca8ab..32560b4ab 100644 --- a/packages/client/src/scripts/aiscript/api.ts +++ b/packages/client/src/scripts/aiscript/api.ts @@ -24,7 +24,11 @@ export function createAiScriptEnv(opts) { return confirm.canceled ? values.FALSE : values.TRUE; }), "Mk:api": values.FN_NATIVE(async ([ep, param, token]) => { - if (token) utils.assertString(token); + if (token) { + utils.assertString(token); + // バグがあればundefinedもあり得るため念のため + if (typeof token.value !== 'string') throw new Error('invalid token'); + } apiRequests++; if (apiRequests > 16) return values.NULL; const res = await os.api( From 8ddfd9630c1b1f194acebf563ee659567a42ef13 Mon Sep 17 00:00:00 2001 From: cutestnekoaqua Date: Fri, 10 Feb 2023 20:40:54 +0100 Subject: [PATCH 03/35] Revert "yeet koabody" This reverts commit d5eb131f582ad1900392eafbf3e1f6d3e55f1d5f. --- .../src/server/api/mastodon/endpoints/account.ts | 4 ++-- .../backend/src/server/api/mastodon/endpoints/auth.ts | 2 +- .../src/server/api/mastodon/endpoints/filter.ts | 10 +++++----- .../src/server/api/mastodon/endpoints/notifications.ts | 8 ++++---- .../src/server/api/mastodon/endpoints/search.ts | 2 +- .../src/server/api/mastodon/endpoints/status.ts | 6 +++--- packages/backend/src/server/index.ts | 2 +- 7 files changed, 17 insertions(+), 17 deletions(-) diff --git a/packages/backend/src/server/api/mastodon/endpoints/account.ts b/packages/backend/src/server/api/mastodon/endpoints/account.ts index 61d4da8a8..1b55a5fbd 100644 --- a/packages/backend/src/server/api/mastodon/endpoints/account.ts +++ b/packages/backend/src/server/api/mastodon/endpoints/account.ts @@ -33,7 +33,7 @@ export function apiAccountMastodon(router: Router): void { ctx.body = e.response.data; } }); - router.patch('/v1/accounts/update_credentials', async (ctx) => { + router.patch('/v1/accounts/update_credentials', koaBody(), async (ctx) => { const BASE_URL = `${ctx.protocol}://${ctx.hostname}`; const accessTokens = ctx.headers.authorization; const client = getClient(BASE_URL, accessTokens); @@ -177,7 +177,7 @@ export function apiAccountMastodon(router: Router): void { ctx.body = e.response.data; } }); - router.post<{ Params: { id: string } }>('/v1/accounts/:id/mute', async (ctx) => { + router.post<{ Params: { id: string } }>('/v1/accounts/:id/mute', koaBody(), async (ctx) => { const BASE_URL = `${ctx.protocol}://${ctx.hostname}`; const accessTokens = ctx.headers.authorization; const client = getClient(BASE_URL, accessTokens); diff --git a/packages/backend/src/server/api/mastodon/endpoints/auth.ts b/packages/backend/src/server/api/mastodon/endpoints/auth.ts index ff8b8a518..5f5756077 100644 --- a/packages/backend/src/server/api/mastodon/endpoints/auth.ts +++ b/packages/backend/src/server/api/mastodon/endpoints/auth.ts @@ -42,7 +42,7 @@ const writeScope = [ export function apiAuthMastodon(router: Router): void { - router.post('/v1/apps', async (ctx) => { + router.post('/v1/apps', koaBody(), async (ctx) => { const BASE_URL = `${ctx.request.protocol}://${ctx.request.hostname}`; const accessTokens = ctx.request.headers.authorization; const client = getClient(BASE_URL, accessTokens); diff --git a/packages/backend/src/server/api/mastodon/endpoints/filter.ts b/packages/backend/src/server/api/mastodon/endpoints/filter.ts index 810b8be11..3c66362dd 100644 --- a/packages/backend/src/server/api/mastodon/endpoints/filter.ts +++ b/packages/backend/src/server/api/mastodon/endpoints/filter.ts @@ -5,7 +5,7 @@ import { getClient } from '../ApiMastodonCompatibleService.js'; export function apiFilterMastodon(router: Router): void { - router.get('/v1/filters', async (ctx) => { + router.get('/v1/filters', koaBody(), async (ctx) => { const BASE_URL = `${ctx.request.protocol}://${ctx.request.hostname}`; const accessTokens = ctx.request.headers.authorization; const client = getClient(BASE_URL, accessTokens); @@ -20,7 +20,7 @@ export function apiFilterMastodon(router: Router): void { } }); - router.get('/v1/filters/:id', async (ctx) => { + router.get('/v1/filters/:id', koaBody(), async (ctx) => { const BASE_URL = `${ctx.request.protocol}://${ctx.request.hostname}`; const accessTokens = ctx.request.headers.authorization; const client = getClient(BASE_URL, accessTokens); @@ -35,7 +35,7 @@ export function apiFilterMastodon(router: Router): void { } }); - router.post('/v1/filters', async (ctx) => { + router.post('/v1/filters', koaBody(), async (ctx) => { const BASE_URL = `${ctx.request.protocol}://${ctx.request.hostname}`; const accessTokens = ctx.request.headers.authorization; const client = getClient(BASE_URL, accessTokens); @@ -50,7 +50,7 @@ export function apiFilterMastodon(router: Router): void { } }); - router.post('/v1/filters/:id', async (ctx) => { + router.post('/v1/filters/:id', koaBody(), async (ctx) => { const BASE_URL = `${ctx.request.protocol}://${ctx.request.hostname}`; const accessTokens = ctx.request.headers.authorization; const client = getClient(BASE_URL, accessTokens); @@ -65,7 +65,7 @@ export function apiFilterMastodon(router: Router): void { } }); - router.delete('/v1/filters/:id', async (ctx) => { + router.delete('/v1/filters/:id', koaBody(), async (ctx) => { const BASE_URL = `${ctx.request.protocol}://${ctx.request.hostname}`; const accessTokens = ctx.request.headers.authorization; const client = getClient(BASE_URL, accessTokens); diff --git a/packages/backend/src/server/api/mastodon/endpoints/notifications.ts b/packages/backend/src/server/api/mastodon/endpoints/notifications.ts index 625ff386c..59869da06 100644 --- a/packages/backend/src/server/api/mastodon/endpoints/notifications.ts +++ b/packages/backend/src/server/api/mastodon/endpoints/notifications.ts @@ -10,7 +10,7 @@ function toLimitToInt(q: any) { export function apiNotificationsMastodon(router: Router): void { - router.get('/v1/notifications', async (ctx) => { + router.get('/v1/notifications', koaBody(), async (ctx) => { const BASE_URL = `${ctx.request.protocol}://${ctx.request.hostname}`; const accessTokens = ctx.request.headers.authorization; const client = getClient(BASE_URL, accessTokens); @@ -35,7 +35,7 @@ export function apiNotificationsMastodon(router: Router): void { } }); - router.get('/v1/notification/:id', async (ctx) => { + router.get('/v1/notification/:id', koaBody(), async (ctx) => { const BASE_URL = `${ctx.request.protocol}://${ctx.request.hostname}`; const accessTokens = ctx.request.headers.authorization; const client = getClient(BASE_URL, accessTokens); @@ -56,7 +56,7 @@ export function apiNotificationsMastodon(router: Router): void { } }); - router.post('/v1/notifications/clear', async (ctx) => { + router.post('/v1/notifications/clear', koaBody(), async (ctx) => { const BASE_URL = `${ctx.request.protocol}://${ctx.request.hostname}`; const accessTokens = ctx.request.headers.authorization; const client = getClient(BASE_URL, accessTokens); @@ -71,7 +71,7 @@ export function apiNotificationsMastodon(router: Router): void { } }); - router.post('/v1/notification/:id/dismiss', async (ctx) => { + router.post('/v1/notification/:id/dismiss', koaBody(), async (ctx) => { const BASE_URL = `${ctx.request.protocol}://${ctx.request.hostname}`; const accessTokens = ctx.request.headers.authorization; const client = getClient(BASE_URL, accessTokens); diff --git a/packages/backend/src/server/api/mastodon/endpoints/search.ts b/packages/backend/src/server/api/mastodon/endpoints/search.ts index dce3ff57c..f87e199f5 100644 --- a/packages/backend/src/server/api/mastodon/endpoints/search.ts +++ b/packages/backend/src/server/api/mastodon/endpoints/search.ts @@ -5,7 +5,7 @@ import { getClient } from '../ApiMastodonCompatibleService.js'; export function apiSearchMastodon(router: Router): void { - router.get('/v1/search', async (ctx) => { + router.get('/v1/search', koaBody(), async (ctx) => { const BASE_URL = `${ctx.request.protocol}://${ctx.request.hostname}`; const accessTokens = ctx.request.headers.authorization; const client = getClient(BASE_URL, accessTokens); diff --git a/packages/backend/src/server/api/mastodon/endpoints/status.ts b/packages/backend/src/server/api/mastodon/endpoints/status.ts index 8dc4ba5f7..593be10f9 100644 --- a/packages/backend/src/server/api/mastodon/endpoints/status.ts +++ b/packages/backend/src/server/api/mastodon/endpoints/status.ts @@ -11,7 +11,7 @@ import axios from 'axios'; const pump = promisify(pipeline); export function apiStatusMastodon(router: Router): void { - router.post('/v1/statuses', async (ctx, reply) => { + router.post('/v1/statuses', koaBody(), async (ctx, reply) => { const BASE_URL = `${ctx.protocol}://${ctx.hostname}`; const accessTokens = ctx.headers.authorization; const client = getClient(BASE_URL, accessTokens); @@ -284,7 +284,7 @@ export function apiStatusMastodon(router: Router): void { ctx.body = e.response.data; } }); - router.put<{ Params: { id: string } }>('/v1/media/:id', async (ctx, reply) => { + router.put<{ Params: { id: string } }>('/v1/media/:id', koaBody(), async (ctx, reply) => { const BASE_URL = `${ctx.protocol}://${ctx.hostname}`; const accessTokens = ctx.headers.authorization; const client = getClient(BASE_URL, accessTokens); @@ -310,7 +310,7 @@ export function apiStatusMastodon(router: Router): void { ctx.body = e.response.data; } }); - router.post<{ Params: { id: string } }>('/v1/polls/:id/votes', async (ctx, reply) => { + router.post<{ Params: { id: string } }>('/v1/polls/:id/votes', koaBody(), async (ctx, reply) => { const BASE_URL = `${ctx.protocol}://${ctx.hostname}`; const accessTokens = ctx.headers.authorization; const client = getClient(BASE_URL, accessTokens); diff --git a/packages/backend/src/server/index.ts b/packages/backend/src/server/index.ts index 6ade50d18..ea4740cba 100644 --- a/packages/backend/src/server/index.ts +++ b/packages/backend/src/server/index.ts @@ -141,7 +141,7 @@ router.get("/oauth/authorize", async (ctx) => { ctx.redirect(Buffer.from(client_id?.toString() || '', 'base64').toString()); }); -router.post("/oauth/token", async (ctx) => { +router.get("/oauth/token", koaBody(), async (ctx) => { const body: any = ctx.request.body; const BASE_URL = `${ctx.request.protocol}://${ctx.request.hostname}`; const generator = (megalodon as any).default; From 3f73e2ff849d626768a997220dadad4b21ab1ba0 Mon Sep 17 00:00:00 2001 From: cutestnekoaqua Date: Fri, 10 Feb 2023 20:45:29 +0100 Subject: [PATCH 04/35] Merge Masto Api changes Co-authored-by Natty --- .../src/server/api/endpoints/i/registry/get-unsecure.ts | 2 +- .../server/api/mastodon/ApiMastodonCompatibleService.ts | 4 ++-- packages/backend/src/server/api/mastodon/endpoints/auth.ts | 6 +++++- packages/backend/src/server/index.ts | 7 +++++-- 4 files changed, 13 insertions(+), 6 deletions(-) diff --git a/packages/backend/src/server/api/endpoints/i/registry/get-unsecure.ts b/packages/backend/src/server/api/endpoints/i/registry/get-unsecure.ts index 40065c83e..a8169aa95 100644 --- a/packages/backend/src/server/api/endpoints/i/registry/get-unsecure.ts +++ b/packages/backend/src/server/api/endpoints/i/registry/get-unsecure.ts @@ -1,6 +1,6 @@ import { ApiError } from "../../../error.js"; import define from "../../../define.js"; -import { RegistryItems } from "../../../../../models/index.js"; +import {RegistryItems} from "@/models/index.js"; export const meta = { requireCredential: true, diff --git a/packages/backend/src/server/api/mastodon/ApiMastodonCompatibleService.ts b/packages/backend/src/server/api/mastodon/ApiMastodonCompatibleService.ts index 57a86c96d..cb00f9f38 100644 --- a/packages/backend/src/server/api/mastodon/ApiMastodonCompatibleService.ts +++ b/packages/backend/src/server/api/mastodon/ApiMastodonCompatibleService.ts @@ -5,7 +5,7 @@ import { apiAccountMastodon } from './endpoints/account.js'; import { apiStatusMastodon } from './endpoints/status.js'; import { apiFilterMastodon } from './endpoints/filter.js'; import { apiTimelineMastodon } from './endpoints/timeline.js'; -import { apiNotificationsMastodon } from './endpoints/notifications.js'; +import { apiNotificationMastodon } from './endpoints/notifications.js'; import { apiSearchMastodon } from './endpoints/search.js'; import { getInstance } from './endpoints/meta.js'; @@ -23,7 +23,7 @@ export function apiMastodonCompatible(router: Router): void { apiStatusMastodon(router) apiFilterMastodon(router) apiTimelineMastodon(router) - apiNotificationsMastodon(router) + apiNotificationMastodon(router) apiSearchMastodon(router) router.get('/v1/custom_emojis', async (ctx) => { diff --git a/packages/backend/src/server/api/mastodon/endpoints/auth.ts b/packages/backend/src/server/api/mastodon/endpoints/auth.ts index 5f5756077..63dbcc364 100644 --- a/packages/backend/src/server/api/mastodon/endpoints/auth.ts +++ b/packages/backend/src/server/api/mastodon/endpoints/auth.ts @@ -2,6 +2,7 @@ import megalodon, { MegalodonInterface } from '@cutls/megalodon'; import Router from "@koa/router"; import { koaBody } from 'koa-body'; import { getClient } from '../ApiMastodonCompatibleService.js'; +import bodyParser from "koa-bodyparser"; const readScope = [ 'read:account', @@ -42,7 +43,10 @@ const writeScope = [ export function apiAuthMastodon(router: Router): void { - router.post('/v1/apps', koaBody(), async (ctx) => { + router.post('/v1/apps', koaBody({ + json: false, + multipart: true + }), async (ctx) => { const BASE_URL = `${ctx.request.protocol}://${ctx.request.hostname}`; const accessTokens = ctx.request.headers.authorization; const client = getClient(BASE_URL, accessTokens); diff --git a/packages/backend/src/server/index.ts b/packages/backend/src/server/index.ts index ea4740cba..14c127e8b 100644 --- a/packages/backend/src/server/index.ts +++ b/packages/backend/src/server/index.ts @@ -20,7 +20,7 @@ import { createTemp } from "@/misc/create-temp.js"; import { publishMainStream } from "@/services/stream.js"; import * as Acct from "@/misc/acct.js"; import { envOption } from "@/env.js"; -import { koaBody } from 'koa-body'; +import {koaBody} from "koa-body"; import megalodon, { MegalodonInterface } from '@cutls/megalodon'; import activityPub from "./activitypub.js"; import nodeinfo from "./nodeinfo.js"; @@ -141,7 +141,10 @@ router.get("/oauth/authorize", async (ctx) => { ctx.redirect(Buffer.from(client_id?.toString() || '', 'base64').toString()); }); -router.get("/oauth/token", koaBody(), async (ctx) => { +router.post("/oauth/token", koaBody({ + json: false, + multipart: true +}), async (ctx) => { const body: any = ctx.request.body; const BASE_URL = `${ctx.request.protocol}://${ctx.request.hostname}`; const generator = (megalodon as any).default; From c19b0758456fe2c788a5c965a63292012cfcbc02 Mon Sep 17 00:00:00 2001 From: cutestnekoaqua Date: Fri, 10 Feb 2023 20:50:42 +0100 Subject: [PATCH 05/35] make build work after calcks merge --- packages/client/src/pages/miauth.vue | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/client/src/pages/miauth.vue b/packages/client/src/pages/miauth.vue index 292b47338..a71c7b9a5 100644 --- a/packages/client/src/pages/miauth.vue +++ b/packages/client/src/pages/miauth.vue @@ -78,6 +78,7 @@ async function accept(): Promise { } } +function deny(): void { state = 'denied'; } From ebd53e1f90613efad3d4d46ade806eda6c51bb69 Mon Sep 17 00:00:00 2001 From: cutestnekoaqua Date: Fri, 10 Feb 2023 20:52:58 +0100 Subject: [PATCH 06/35] weird merge error --- .../src/server/api/mastodon/ApiMastodonCompatibleService.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/backend/src/server/api/mastodon/ApiMastodonCompatibleService.ts b/packages/backend/src/server/api/mastodon/ApiMastodonCompatibleService.ts index cb00f9f38..65f8130a6 100644 --- a/packages/backend/src/server/api/mastodon/ApiMastodonCompatibleService.ts +++ b/packages/backend/src/server/api/mastodon/ApiMastodonCompatibleService.ts @@ -5,7 +5,7 @@ import { apiAccountMastodon } from './endpoints/account.js'; import { apiStatusMastodon } from './endpoints/status.js'; import { apiFilterMastodon } from './endpoints/filter.js'; import { apiTimelineMastodon } from './endpoints/timeline.js'; -import { apiNotificationMastodon } from './endpoints/notifications.js'; +import { apiNotificationsMastodon } from './endpoints/notifications.js'; import { apiSearchMastodon } from './endpoints/search.js'; import { getInstance } from './endpoints/meta.js'; From 78463f5f36f4de6d0b1f191246d14287134fd773 Mon Sep 17 00:00:00 2001 From: cutestnekoaqua Date: Fri, 10 Feb 2023 20:53:27 +0100 Subject: [PATCH 07/35] ree --- .../src/server/api/mastodon/ApiMastodonCompatibleService.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/backend/src/server/api/mastodon/ApiMastodonCompatibleService.ts b/packages/backend/src/server/api/mastodon/ApiMastodonCompatibleService.ts index 65f8130a6..57a86c96d 100644 --- a/packages/backend/src/server/api/mastodon/ApiMastodonCompatibleService.ts +++ b/packages/backend/src/server/api/mastodon/ApiMastodonCompatibleService.ts @@ -23,7 +23,7 @@ export function apiMastodonCompatible(router: Router): void { apiStatusMastodon(router) apiFilterMastodon(router) apiTimelineMastodon(router) - apiNotificationMastodon(router) + apiNotificationsMastodon(router) apiSearchMastodon(router) router.get('/v1/custom_emojis', async (ctx) => { From 1024e4d02707a090ae300339c6b86610e970eac6 Mon Sep 17 00:00:00 2001 From: cutestnekoaqua Date: Fri, 10 Feb 2023 21:16:55 +0100 Subject: [PATCH 08/35] merge more multipart stuff --- .../src/server/api/mastodon/endpoints/account.ts | 4 ++-- .../src/server/api/mastodon/endpoints/filter.ts | 10 +++++----- .../src/server/api/mastodon/endpoints/notifications.ts | 8 ++++---- .../src/server/api/mastodon/endpoints/search.ts | 3 +-- .../src/server/api/mastodon/endpoints/status.ts | 6 +++--- 5 files changed, 15 insertions(+), 16 deletions(-) diff --git a/packages/backend/src/server/api/mastodon/endpoints/account.ts b/packages/backend/src/server/api/mastodon/endpoints/account.ts index 1b55a5fbd..65caf7168 100644 --- a/packages/backend/src/server/api/mastodon/endpoints/account.ts +++ b/packages/backend/src/server/api/mastodon/endpoints/account.ts @@ -33,7 +33,7 @@ export function apiAccountMastodon(router: Router): void { ctx.body = e.response.data; } }); - router.patch('/v1/accounts/update_credentials', koaBody(), async (ctx) => { + router.patch('/v1/accounts/update_credentials', koaBody({ multipart: true }), async (ctx) => { const BASE_URL = `${ctx.protocol}://${ctx.hostname}`; const accessTokens = ctx.headers.authorization; const client = getClient(BASE_URL, accessTokens); @@ -177,7 +177,7 @@ export function apiAccountMastodon(router: Router): void { ctx.body = e.response.data; } }); - router.post<{ Params: { id: string } }>('/v1/accounts/:id/mute', koaBody(), async (ctx) => { + router.post<{ Params: { id: string } }>('/v1/accounts/:id/mute', koaBody({ multipart: true }), async (ctx) => { const BASE_URL = `${ctx.protocol}://${ctx.hostname}`; const accessTokens = ctx.headers.authorization; const client = getClient(BASE_URL, accessTokens); diff --git a/packages/backend/src/server/api/mastodon/endpoints/filter.ts b/packages/backend/src/server/api/mastodon/endpoints/filter.ts index 3c66362dd..b4f67cf1e 100644 --- a/packages/backend/src/server/api/mastodon/endpoints/filter.ts +++ b/packages/backend/src/server/api/mastodon/endpoints/filter.ts @@ -5,7 +5,7 @@ import { getClient } from '../ApiMastodonCompatibleService.js'; export function apiFilterMastodon(router: Router): void { - router.get('/v1/filters', koaBody(), async (ctx) => { + router.get('/v1/filters', koaBody({ multipart: true }), async (ctx) => { const BASE_URL = `${ctx.request.protocol}://${ctx.request.hostname}`; const accessTokens = ctx.request.headers.authorization; const client = getClient(BASE_URL, accessTokens); @@ -20,7 +20,7 @@ export function apiFilterMastodon(router: Router): void { } }); - router.get('/v1/filters/:id', koaBody(), async (ctx) => { + router.get('/v1/filters/:id', koaBody({ multipart: true }), async (ctx) => { const BASE_URL = `${ctx.request.protocol}://${ctx.request.hostname}`; const accessTokens = ctx.request.headers.authorization; const client = getClient(BASE_URL, accessTokens); @@ -35,7 +35,7 @@ export function apiFilterMastodon(router: Router): void { } }); - router.post('/v1/filters', koaBody(), async (ctx) => { + router.post('/v1/filters', koaBody({ multipart: true }), async (ctx) => { const BASE_URL = `${ctx.request.protocol}://${ctx.request.hostname}`; const accessTokens = ctx.request.headers.authorization; const client = getClient(BASE_URL, accessTokens); @@ -50,7 +50,7 @@ export function apiFilterMastodon(router: Router): void { } }); - router.post('/v1/filters/:id', koaBody(), async (ctx) => { + router.post('/v1/filters/:id', koaBody({ multipart: true }), async (ctx) => { const BASE_URL = `${ctx.request.protocol}://${ctx.request.hostname}`; const accessTokens = ctx.request.headers.authorization; const client = getClient(BASE_URL, accessTokens); @@ -65,7 +65,7 @@ export function apiFilterMastodon(router: Router): void { } }); - router.delete('/v1/filters/:id', koaBody(), async (ctx) => { + router.delete('/v1/filters/:id', koaBody({ multipart: true }), async (ctx) => { const BASE_URL = `${ctx.request.protocol}://${ctx.request.hostname}`; const accessTokens = ctx.request.headers.authorization; const client = getClient(BASE_URL, accessTokens); diff --git a/packages/backend/src/server/api/mastodon/endpoints/notifications.ts b/packages/backend/src/server/api/mastodon/endpoints/notifications.ts index 59869da06..b4599de80 100644 --- a/packages/backend/src/server/api/mastodon/endpoints/notifications.ts +++ b/packages/backend/src/server/api/mastodon/endpoints/notifications.ts @@ -10,7 +10,7 @@ function toLimitToInt(q: any) { export function apiNotificationsMastodon(router: Router): void { - router.get('/v1/notifications', koaBody(), async (ctx) => { + router.get('/v1/notifications', async (ctx) => { const BASE_URL = `${ctx.request.protocol}://${ctx.request.hostname}`; const accessTokens = ctx.request.headers.authorization; const client = getClient(BASE_URL, accessTokens); @@ -35,7 +35,7 @@ export function apiNotificationsMastodon(router: Router): void { } }); - router.get('/v1/notification/:id', koaBody(), async (ctx) => { + router.get('/v1/notification/:id', async (ctx) => { const BASE_URL = `${ctx.request.protocol}://${ctx.request.hostname}`; const accessTokens = ctx.request.headers.authorization; const client = getClient(BASE_URL, accessTokens); @@ -56,7 +56,7 @@ export function apiNotificationsMastodon(router: Router): void { } }); - router.post('/v1/notifications/clear', koaBody(), async (ctx) => { + router.post('/v1/notifications/clear', async (ctx) => { const BASE_URL = `${ctx.request.protocol}://${ctx.request.hostname}`; const accessTokens = ctx.request.headers.authorization; const client = getClient(BASE_URL, accessTokens); @@ -71,7 +71,7 @@ export function apiNotificationsMastodon(router: Router): void { } }); - router.post('/v1/notification/:id/dismiss', koaBody(), async (ctx) => { + router.post('/v1/notification/:id/dismiss', koaBody({ multipart: true }), async (ctx) => { const BASE_URL = `${ctx.request.protocol}://${ctx.request.hostname}`; const accessTokens = ctx.request.headers.authorization; const client = getClient(BASE_URL, accessTokens); diff --git a/packages/backend/src/server/api/mastodon/endpoints/search.ts b/packages/backend/src/server/api/mastodon/endpoints/search.ts index f87e199f5..dcd5be461 100644 --- a/packages/backend/src/server/api/mastodon/endpoints/search.ts +++ b/packages/backend/src/server/api/mastodon/endpoints/search.ts @@ -1,11 +1,10 @@ import megalodon, { MegalodonInterface } from '@cutls/megalodon'; import Router from "@koa/router"; -import { koaBody } from 'koa-body'; import { getClient } from '../ApiMastodonCompatibleService.js'; export function apiSearchMastodon(router: Router): void { - router.get('/v1/search', koaBody(), async (ctx) => { + router.get('/v1/search', async (ctx) => { const BASE_URL = `${ctx.request.protocol}://${ctx.request.hostname}`; const accessTokens = ctx.request.headers.authorization; const client = getClient(BASE_URL, accessTokens); diff --git a/packages/backend/src/server/api/mastodon/endpoints/status.ts b/packages/backend/src/server/api/mastodon/endpoints/status.ts index 593be10f9..cef966e47 100644 --- a/packages/backend/src/server/api/mastodon/endpoints/status.ts +++ b/packages/backend/src/server/api/mastodon/endpoints/status.ts @@ -11,7 +11,7 @@ import axios from 'axios'; const pump = promisify(pipeline); export function apiStatusMastodon(router: Router): void { - router.post('/v1/statuses', koaBody(), async (ctx, reply) => { + router.post('/v1/statuses', koaBody({ multipart: true }), async (ctx, reply) => { const BASE_URL = `${ctx.protocol}://${ctx.hostname}`; const accessTokens = ctx.headers.authorization; const client = getClient(BASE_URL, accessTokens); @@ -284,7 +284,7 @@ export function apiStatusMastodon(router: Router): void { ctx.body = e.response.data; } }); - router.put<{ Params: { id: string } }>('/v1/media/:id', koaBody(), async (ctx, reply) => { + router.put<{ Params: { id: string } }>('/v1/media/:id', koaBody({ multipart: true }), async (ctx, reply) => { const BASE_URL = `${ctx.protocol}://${ctx.hostname}`; const accessTokens = ctx.headers.authorization; const client = getClient(BASE_URL, accessTokens); @@ -310,7 +310,7 @@ export function apiStatusMastodon(router: Router): void { ctx.body = e.response.data; } }); - router.post<{ Params: { id: string } }>('/v1/polls/:id/votes', koaBody(), async (ctx, reply) => { + router.post<{ Params: { id: string } }>('/v1/polls/:id/votes', koaBody({ multipart: true }), async (ctx, reply) => { const BASE_URL = `${ctx.protocol}://${ctx.hostname}`; const accessTokens = ctx.headers.authorization; const client = getClient(BASE_URL, accessTokens); From 9703b2496f6a4f79dbbd1c90979de680a0186ff7 Mon Sep 17 00:00:00 2001 From: cutestnekoaqua Date: Fri, 10 Feb 2023 22:30:19 +0100 Subject: [PATCH 09/35] temp test --- packages/backend/src/server/index.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/backend/src/server/index.ts b/packages/backend/src/server/index.ts index 14c127e8b..34ffa3c0e 100644 --- a/packages/backend/src/server/index.ts +++ b/packages/backend/src/server/index.ts @@ -146,7 +146,8 @@ router.post("/oauth/token", koaBody({ multipart: true }), async (ctx) => { const body: any = ctx.request.body; - const BASE_URL = `${ctx.request.protocol}://${ctx.request.hostname}`; + //const BASE_URL = `${ctx.request.protocol}://${ctx.request.hostname}`; + const BASE_URL = "http://localhost:3000"; const generator = (megalodon as any).default; const client = generator('misskey', BASE_URL, null) as MegalodonInterface; const m = body.code.match(/^[a-zA-Z0-9-]+/); From 9b2cd8f2e842ef11acbea3352c3c28edab3243c4 Mon Sep 17 00:00:00 2001 From: cutestnekoaqua Date: Fri, 10 Feb 2023 23:00:15 +0100 Subject: [PATCH 10/35] this is super cursed --- packages/backend/src/server/api/index.ts | 8 ++++++++ packages/backend/src/server/index.ts | 3 +-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/packages/backend/src/server/api/index.ts b/packages/backend/src/server/api/index.ts index da98a9df1..40ecd10ec 100644 --- a/packages/backend/src/server/api/index.ts +++ b/packages/backend/src/server/api/index.ts @@ -12,6 +12,7 @@ import { Instances, AccessTokens, Users } from "@/models/index.js"; import config from "@/config/index.js"; import endpoints from "./endpoints.js"; import compatibility from "./compatibility.js"; +import {koaBody} from "koa-body"; import handler from "./api-handler.js"; import signup from "./private/signup.js"; import signin from "./private/signin.js"; @@ -35,6 +36,13 @@ app.use(async (ctx, next) => { await next(); }); +app.use( + koaBody({ + json: false, + multipart: true + }) +); + app.use( bodyParser({ // リクエストが multipart/form-data でない限りはJSONだと見なす diff --git a/packages/backend/src/server/index.ts b/packages/backend/src/server/index.ts index 34ffa3c0e..14c127e8b 100644 --- a/packages/backend/src/server/index.ts +++ b/packages/backend/src/server/index.ts @@ -146,8 +146,7 @@ router.post("/oauth/token", koaBody({ multipart: true }), async (ctx) => { const body: any = ctx.request.body; - //const BASE_URL = `${ctx.request.protocol}://${ctx.request.hostname}`; - const BASE_URL = "http://localhost:3000"; + const BASE_URL = `${ctx.request.protocol}://${ctx.request.hostname}`; const generator = (megalodon as any).default; const client = generator('misskey', BASE_URL, null) as MegalodonInterface; const m = body.code.match(/^[a-zA-Z0-9-]+/); From 23aa51102bb65a3d0ff1f6d5135b918effc19e92 Mon Sep 17 00:00:00 2001 From: cutestnekoaqua Date: Fri, 10 Feb 2023 23:15:34 +0100 Subject: [PATCH 11/35] migrate middleware usage Co-authored-by Natty --- .../src/server/api/mastodon/endpoints/account.ts | 4 ++-- .../src/server/api/mastodon/endpoints/filter.ts | 11 +++++------ .../server/api/mastodon/endpoints/notifications.ts | 2 +- .../src/server/api/mastodon/endpoints/status.ts | 7 +++---- .../src/server/api/mastodon/endpoints/timeline.ts | 1 - packages/backend/src/server/index.ts | 11 +++++------ 6 files changed, 16 insertions(+), 20 deletions(-) diff --git a/packages/backend/src/server/api/mastodon/endpoints/account.ts b/packages/backend/src/server/api/mastodon/endpoints/account.ts index 65caf7168..4fda37a48 100644 --- a/packages/backend/src/server/api/mastodon/endpoints/account.ts +++ b/packages/backend/src/server/api/mastodon/endpoints/account.ts @@ -33,7 +33,7 @@ export function apiAccountMastodon(router: Router): void { ctx.body = e.response.data; } }); - router.patch('/v1/accounts/update_credentials', koaBody({ multipart: true }), async (ctx) => { + router.patch('/v1/accounts/update_credentials', async (ctx) => { const BASE_URL = `${ctx.protocol}://${ctx.hostname}`; const accessTokens = ctx.headers.authorization; const client = getClient(BASE_URL, accessTokens); @@ -177,7 +177,7 @@ export function apiAccountMastodon(router: Router): void { ctx.body = e.response.data; } }); - router.post<{ Params: { id: string } }>('/v1/accounts/:id/mute', koaBody({ multipart: true }), async (ctx) => { + router.post<{ Params: { id: string } }>('/v1/accounts/:id/mute', async (ctx) => { const BASE_URL = `${ctx.protocol}://${ctx.hostname}`; const accessTokens = ctx.headers.authorization; const client = getClient(BASE_URL, accessTokens); diff --git a/packages/backend/src/server/api/mastodon/endpoints/filter.ts b/packages/backend/src/server/api/mastodon/endpoints/filter.ts index b4f67cf1e..f665f8d23 100644 --- a/packages/backend/src/server/api/mastodon/endpoints/filter.ts +++ b/packages/backend/src/server/api/mastodon/endpoints/filter.ts @@ -1,11 +1,10 @@ import megalodon, { MegalodonInterface } from '@cutls/megalodon'; import Router from "@koa/router"; -import { koaBody } from 'koa-body'; import { getClient } from '../ApiMastodonCompatibleService.js'; export function apiFilterMastodon(router: Router): void { - router.get('/v1/filters', koaBody({ multipart: true }), async (ctx) => { + router.get('/v1/filters', async (ctx) => { const BASE_URL = `${ctx.request.protocol}://${ctx.request.hostname}`; const accessTokens = ctx.request.headers.authorization; const client = getClient(BASE_URL, accessTokens); @@ -20,7 +19,7 @@ export function apiFilterMastodon(router: Router): void { } }); - router.get('/v1/filters/:id', koaBody({ multipart: true }), async (ctx) => { + router.get('/v1/filters/:id', async (ctx) => { const BASE_URL = `${ctx.request.protocol}://${ctx.request.hostname}`; const accessTokens = ctx.request.headers.authorization; const client = getClient(BASE_URL, accessTokens); @@ -35,7 +34,7 @@ export function apiFilterMastodon(router: Router): void { } }); - router.post('/v1/filters', koaBody({ multipart: true }), async (ctx) => { + router.post('/v1/filters', async (ctx) => { const BASE_URL = `${ctx.request.protocol}://${ctx.request.hostname}`; const accessTokens = ctx.request.headers.authorization; const client = getClient(BASE_URL, accessTokens); @@ -50,7 +49,7 @@ export function apiFilterMastodon(router: Router): void { } }); - router.post('/v1/filters/:id', koaBody({ multipart: true }), async (ctx) => { + router.post('/v1/filters/:id', async (ctx) => { const BASE_URL = `${ctx.request.protocol}://${ctx.request.hostname}`; const accessTokens = ctx.request.headers.authorization; const client = getClient(BASE_URL, accessTokens); @@ -65,7 +64,7 @@ export function apiFilterMastodon(router: Router): void { } }); - router.delete('/v1/filters/:id', koaBody({ multipart: true }), async (ctx) => { + router.delete('/v1/filters/:id', async (ctx) => { const BASE_URL = `${ctx.request.protocol}://${ctx.request.hostname}`; const accessTokens = ctx.request.headers.authorization; const client = getClient(BASE_URL, accessTokens); diff --git a/packages/backend/src/server/api/mastodon/endpoints/notifications.ts b/packages/backend/src/server/api/mastodon/endpoints/notifications.ts index b4599de80..e65b47f02 100644 --- a/packages/backend/src/server/api/mastodon/endpoints/notifications.ts +++ b/packages/backend/src/server/api/mastodon/endpoints/notifications.ts @@ -71,7 +71,7 @@ export function apiNotificationsMastodon(router: Router): void { } }); - router.post('/v1/notification/:id/dismiss', koaBody({ multipart: true }), async (ctx) => { + router.post('/v1/notification/:id/dismiss', async (ctx) => { const BASE_URL = `${ctx.request.protocol}://${ctx.request.hostname}`; const accessTokens = ctx.request.headers.authorization; const client = getClient(BASE_URL, accessTokens); diff --git a/packages/backend/src/server/api/mastodon/endpoints/status.ts b/packages/backend/src/server/api/mastodon/endpoints/status.ts index cef966e47..f01665537 100644 --- a/packages/backend/src/server/api/mastodon/endpoints/status.ts +++ b/packages/backend/src/server/api/mastodon/endpoints/status.ts @@ -1,5 +1,4 @@ import Router from "@koa/router"; -import { koaBody } from 'koa-body'; import megalodon, { MegalodonInterface } from '@cutls/megalodon'; import { getClient } from '../ApiMastodonCompatibleService.js'; import fs from 'fs' @@ -11,7 +10,7 @@ import axios from 'axios'; const pump = promisify(pipeline); export function apiStatusMastodon(router: Router): void { - router.post('/v1/statuses', koaBody({ multipart: true }), async (ctx, reply) => { + router.post('/v1/statuses', async (ctx, reply) => { const BASE_URL = `${ctx.protocol}://${ctx.hostname}`; const accessTokens = ctx.headers.authorization; const client = getClient(BASE_URL, accessTokens); @@ -284,7 +283,7 @@ export function apiStatusMastodon(router: Router): void { ctx.body = e.response.data; } }); - router.put<{ Params: { id: string } }>('/v1/media/:id', koaBody({ multipart: true }), async (ctx, reply) => { + router.put<{ Params: { id: string } }>('/v1/media/:id',async (ctx, reply) => { const BASE_URL = `${ctx.protocol}://${ctx.hostname}`; const accessTokens = ctx.headers.authorization; const client = getClient(BASE_URL, accessTokens); @@ -310,7 +309,7 @@ export function apiStatusMastodon(router: Router): void { ctx.body = e.response.data; } }); - router.post<{ Params: { id: string } }>('/v1/polls/:id/votes', koaBody({ multipart: true }), async (ctx, reply) => { + router.post<{ Params: { id: string } }>('/v1/polls/:id/votes', async (ctx, reply) => { const BASE_URL = `${ctx.protocol}://${ctx.hostname}`; const accessTokens = ctx.headers.authorization; const client = getClient(BASE_URL, accessTokens); diff --git a/packages/backend/src/server/api/mastodon/endpoints/timeline.ts b/packages/backend/src/server/api/mastodon/endpoints/timeline.ts index 3fdb6ce88..2cbdf5a0e 100644 --- a/packages/backend/src/server/api/mastodon/endpoints/timeline.ts +++ b/packages/backend/src/server/api/mastodon/endpoints/timeline.ts @@ -1,5 +1,4 @@ import Router from "@koa/router"; -import { koaBody } from 'koa-body'; import megalodon, { Entity, MegalodonInterface } from '@cutls/megalodon'; import { getClient } from '../ApiMastodonCompatibleService.js' import { statusModel } from './status.js'; diff --git a/packages/backend/src/server/index.ts b/packages/backend/src/server/index.ts index 14c127e8b..6609627fe 100644 --- a/packages/backend/src/server/index.ts +++ b/packages/backend/src/server/index.ts @@ -20,7 +20,6 @@ import { createTemp } from "@/misc/create-temp.js"; import { publishMainStream } from "@/services/stream.js"; import * as Acct from "@/misc/acct.js"; import { envOption } from "@/env.js"; -import {koaBody} from "koa-body"; import megalodon, { MegalodonInterface } from '@cutls/megalodon'; import activityPub from "./activitypub.js"; import nodeinfo from "./nodeinfo.js"; @@ -141,16 +140,16 @@ router.get("/oauth/authorize", async (ctx) => { ctx.redirect(Buffer.from(client_id?.toString() || '', 'base64').toString()); }); -router.post("/oauth/token", koaBody({ - json: false, - multipart: true -}), async (ctx) => { +router.post("/oauth/token", async (ctx) => { const body: any = ctx.request.body; const BASE_URL = `${ctx.request.protocol}://${ctx.request.hostname}`; const generator = (megalodon as any).default; const client = generator('misskey', BASE_URL, null) as MegalodonInterface; const m = body.code.match(/^[a-zA-Z0-9-]+/); - if (!m.length) return { error: 'Invalid code' } + if (!m.length) { + ctx.body = {error: 'Invalid code'} + return + } try { const atData = await client.fetchAccessToken(null, body.client_secret, m[0]); ctx.body = { From 2ff3e68d9463a88a4b13d8d8c67af8a49287648e Mon Sep 17 00:00:00 2001 From: cutestnekoaqua Date: Fri, 10 Feb 2023 23:17:29 +0100 Subject: [PATCH 12/35] me forgorr --- packages/backend/src/server/api/mastodon/endpoints/auth.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/packages/backend/src/server/api/mastodon/endpoints/auth.ts b/packages/backend/src/server/api/mastodon/endpoints/auth.ts index 63dbcc364..6425aac09 100644 --- a/packages/backend/src/server/api/mastodon/endpoints/auth.ts +++ b/packages/backend/src/server/api/mastodon/endpoints/auth.ts @@ -43,10 +43,7 @@ const writeScope = [ export function apiAuthMastodon(router: Router): void { - router.post('/v1/apps', koaBody({ - json: false, - multipart: true - }), async (ctx) => { + router.post('/v1/apps', async (ctx) => { const BASE_URL = `${ctx.request.protocol}://${ctx.request.hostname}`; const accessTokens = ctx.request.headers.authorization; const client = getClient(BASE_URL, accessTokens); From 465cb5a5702375c024595f0cf02fca70b5f40699 Mon Sep 17 00:00:00 2001 From: cutestnekoaqua Date: Fri, 10 Feb 2023 23:29:29 +0100 Subject: [PATCH 13/35] use multer instead --- packages/backend/src/server/api/index.ts | 29 ++++++++++-------------- pnpm-lock.yaml | 12 ++++++---- 2 files changed, 19 insertions(+), 22 deletions(-) diff --git a/packages/backend/src/server/api/index.ts b/packages/backend/src/server/api/index.ts index 40ecd10ec..593c7a284 100644 --- a/packages/backend/src/server/api/index.ts +++ b/packages/backend/src/server/api/index.ts @@ -12,7 +12,6 @@ import { Instances, AccessTokens, Users } from "@/models/index.js"; import config from "@/config/index.js"; import endpoints from "./endpoints.js"; import compatibility from "./compatibility.js"; -import {koaBody} from "koa-body"; import handler from "./api-handler.js"; import signup from "./private/signup.js"; import signin from "./private/signin.js"; @@ -24,6 +23,15 @@ import twitter from "./service/twitter.js"; // Init app const app = new Koa(); +// Init multer instance +const upload = multer({ + storage: multer.diskStorage({}), + limits: { + fileSize: config.maxFileSize || 262144000, + files: 1, + }, +}); + app.use( cors({ origin: "*", @@ -36,13 +44,6 @@ app.use(async (ctx, next) => { await next(); }); -app.use( - koaBody({ - json: false, - multipart: true - }) -); - app.use( bodyParser({ // リクエストが multipart/form-data でない限りはJSONだと見なす @@ -54,14 +55,9 @@ app.use( }), ); -// Init multer instance -const upload = multer({ - storage: multer.diskStorage({}), - limits: { - fileSize: config.maxFileSize || 262144000, - files: 1, - }, -}); +app.use( + upload.any() +); // Init router const router = new Router(); @@ -75,7 +71,6 @@ for (const endpoint of [...endpoints, ...compatibility]) { if (endpoint.meta.requireFile) { router.post( `/${endpoint.name}`, - upload.single("file"), handler.bind(null, endpoint), ); } else { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 476fd2fbb..54880d9c9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -3335,7 +3335,7 @@ packages: /axios/0.24.0: resolution: {integrity: sha512-Q6cWsys88HoPgAaFAVUb0WpPk0O8iTeisR9IMqy9G8AbO4NlpVknrnQS03zzF9PGAWgO3cgletO3VjV/P7VztA==} dependencies: - follow-redirects: 1.15.2 + follow-redirects: 1.15.2_debug@4.3.4 transitivePeerDependencies: - debug dev: false @@ -3343,7 +3343,7 @@ packages: /axios/0.25.0_debug@4.3.4: resolution: {integrity: sha512-cD8FOb0tRH3uuEe6+evtAbgJtfxr7ly3fQjYcMcuPlgkwVS9xboaVIpcDV+cYQe+yGykgwZCs1pzjntcGa6l5g==} dependencies: - follow-redirects: 1.15.2 + follow-redirects: 1.15.2_debug@4.3.4 transitivePeerDependencies: - debug dev: true @@ -3351,7 +3351,7 @@ packages: /axios/1.2.2: resolution: {integrity: sha512-bz/J4gS2S3I7mpN/YZfGFTqhXTYzRho8Ay38w2otuuDR322KzFIWm/4W2K6gIwvWaws5n+mnb7D1lN9uD+QH6Q==} dependencies: - follow-redirects: 1.15.2 + follow-redirects: 1.15.2_debug@4.3.4 form-data: 4.0.0 proxy-from-env: 1.1.0 transitivePeerDependencies: @@ -3361,7 +3361,7 @@ packages: /axios/1.3.2: resolution: {integrity: sha512-1M3O703bYqYuPhbHeya5bnhpYVsDDRyQSabNja04mZtboLNSuZ4YrltestrLXfHgmzua4TpUqRiVKbiQuo2epw==} dependencies: - follow-redirects: 1.15.2 + follow-redirects: 1.15.2_debug@4.3.4 form-data: 4.0.0 proxy-from-env: 1.1.0 transitivePeerDependencies: @@ -6301,7 +6301,7 @@ packages: readable-stream: 2.3.7 dev: true - /follow-redirects/1.15.2: + /follow-redirects/1.15.2_debug@4.3.4: resolution: {integrity: sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==} engines: {node: '>=4.0'} peerDependencies: @@ -6309,6 +6309,8 @@ packages: peerDependenciesMeta: debug: optional: true + dependencies: + debug: 4.3.4 /for-each/0.3.3: resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} From 2ca1717f2a4019e934af56f090e2940d8c37e56f Mon Sep 17 00:00:00 2001 From: Cleo Date: Fri, 10 Feb 2023 22:46:08 +0000 Subject: [PATCH 14/35] fix(client): use proxied image for instance icon --- packages/client/assets/dummy.png | 3 +++ packages/client/src/ui/_common_/statusbar-federation.vue | 7 ++++++- packages/client/src/widgets/federation.vue | 7 ++++++- packages/client/src/widgets/instance-cloud.vue | 7 ++++++- 4 files changed, 21 insertions(+), 3 deletions(-) create mode 100644 packages/client/assets/dummy.png diff --git a/packages/client/assets/dummy.png b/packages/client/assets/dummy.png new file mode 100644 index 000000000..1703badd7 --- /dev/null +++ b/packages/client/assets/dummy.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fe0f4c44a5e63ac228fafc6fa3aba1fbe88188dea73ca39d2f8c950f17f74d47 +size 6285 diff --git a/packages/client/src/ui/_common_/statusbar-federation.vue b/packages/client/src/ui/_common_/statusbar-federation.vue index f29c6a9ff..2896cc09c 100644 --- a/packages/client/src/ui/_common_/statusbar-federation.vue +++ b/packages/client/src/ui/_common_/statusbar-federation.vue @@ -4,7 +4,7 @@ - + {{ instance.host }} @@ -27,6 +27,7 @@ import * as os from '@/os'; import { useInterval } from '@/scripts/use-interval'; import { getNoteSummary } from '@/scripts/get-note-summary'; import { notePage } from '@/filters/note'; +import { getProxiedImageUrlNullable } from '@/scripts/media-proxy'; const props = defineProps<{ display?: 'marquee' | 'oneByOne'; @@ -56,6 +57,10 @@ useInterval(tick, Math.max(5000, props.refreshIntervalSec * 1000), { immediate: true, afterMounted: true, }); + +function getInstanceIcon(instance): string { + return getProxiedImageUrlNullable(instance.iconUrl, 'preview') ?? getProxiedImageUrlNullable(instance.faviconUrl, 'preview') ?? '/client-assets/dummy.png'; +}