diff --git a/CHANGELOG.md b/CHANGELOG.md index cd8027b050..cae884793b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,7 @@ ### Server - Fix: プロフィール追加情報で無効なURLに入力された場合に照会エラーを出るのを修正 - Fix: ActivityPubリクエストURLチェック実装は仕様に従っていないのを修正 +- Fix: 連合無しモードでも外部から照会可能だった問題を修正 ## 2025.3.1 diff --git a/packages/backend/src/server/ActivityPubServerService.ts b/packages/backend/src/server/ActivityPubServerService.ts index 20e985aaf2..48c80e5e61 100644 --- a/packages/backend/src/server/ActivityPubServerService.ts +++ b/packages/backend/src/server/ActivityPubServerService.ts @@ -13,7 +13,7 @@ import accepts from 'accepts'; import vary from 'vary'; import secureJson from 'secure-json-parse'; import { DI } from '@/di-symbols.js'; -import type { FollowingsRepository, NotesRepository, EmojisRepository, NoteReactionsRepository, UserProfilesRepository, UserNotePiningsRepository, UsersRepository, FollowRequestsRepository } from '@/models/_.js'; +import type { FollowingsRepository, NotesRepository, EmojisRepository, NoteReactionsRepository, UserProfilesRepository, UserNotePiningsRepository, UsersRepository, FollowRequestsRepository, MiMeta } from '@/models/_.js'; import * as url from '@/misc/prelude/url.js'; import type { Config } from '@/config.js'; import { ApRendererService } from '@/core/activitypub/ApRendererService.js'; @@ -42,6 +42,9 @@ export class ActivityPubServerService { @Inject(DI.config) private config: Config, + @Inject(DI.meta) + private meta: MiMeta, + @Inject(DI.usersRepository) private usersRepository: UsersRepository, @@ -102,6 +105,11 @@ export class ActivityPubServerService { @bindThis private inbox(request: FastifyRequest, reply: FastifyReply) { + if (this.meta.federation === 'none') { + reply.code(403); + return; + } + let signature; try { @@ -173,6 +181,11 @@ export class ActivityPubServerService { request: FastifyRequest<{ Params: { user: string; }; Querystring: { cursor?: string; page?: string; }; }>, reply: FastifyReply, ) { + if (this.meta.federation === 'none') { + reply.code(403); + return; + } + const userId = request.params.user; const cursor = request.query.cursor; @@ -265,6 +278,11 @@ export class ActivityPubServerService { request: FastifyRequest<{ Params: { user: string; }; Querystring: { cursor?: string; page?: string; }; }>, reply: FastifyReply, ) { + if (this.meta.federation === 'none') { + reply.code(403); + return; + } + const userId = request.params.user; const cursor = request.query.cursor; @@ -354,6 +372,11 @@ export class ActivityPubServerService { @bindThis private async featured(request: FastifyRequest<{ Params: { user: string; }; }>, reply: FastifyReply) { + if (this.meta.federation === 'none') { + reply.code(403); + return; + } + const userId = request.params.user; const user = await this.usersRepository.findOneBy({ @@ -398,6 +421,11 @@ export class ActivityPubServerService { }>, reply: FastifyReply, ) { + if (this.meta.federation === 'none') { + reply.code(403); + return; + } + const userId = request.params.user; const sinceId = request.query.since_id; @@ -482,6 +510,11 @@ export class ActivityPubServerService { @bindThis private async userInfo(request: FastifyRequest, reply: FastifyReply, user: MiUser | null) { + if (this.meta.federation === 'none') { + reply.code(403); + return; + } + if (user == null) { reply.code(404); return; @@ -564,6 +597,11 @@ export class ActivityPubServerService { fastify.get<{ Params: { note: string; } }>('/notes/:note', { constraints: { apOrHtml: 'ap' } }, async (request, reply) => { vary(reply.raw, 'Accept'); + if (this.meta.federation === 'none') { + reply.code(403); + return; + } + const note = await this.notesRepository.findOneBy({ id: request.params.note, visibility: In(['public', 'home']), @@ -594,6 +632,11 @@ export class ActivityPubServerService { fastify.get<{ Params: { note: string; } }>('/notes/:note/activity', async (request, reply) => { vary(reply.raw, 'Accept'); + if (this.meta.federation === 'none') { + reply.code(403); + return; + } + const note = await this.notesRepository.findOneBy({ id: request.params.note, userHost: IsNull(), @@ -634,6 +677,11 @@ export class ActivityPubServerService { // publickey fastify.get<{ Params: { user: string; } }>('/users/:user/publickey', async (request, reply) => { + if (this.meta.federation === 'none') { + reply.code(403); + return; + } + const userId = request.params.user; const user = await this.usersRepository.findOneBy({ @@ -661,6 +709,11 @@ export class ActivityPubServerService { fastify.get<{ Params: { user: string; } }>('/users/:user', { constraints: { apOrHtml: 'ap' } }, async (request, reply) => { vary(reply.raw, 'Accept'); + if (this.meta.federation === 'none') { + reply.code(403); + return; + } + const userId = request.params.user; const user = await this.usersRepository.findOneBy({ @@ -674,6 +727,11 @@ export class ActivityPubServerService { fastify.get<{ Params: { acct: string; } }>('/@:acct', { constraints: { apOrHtml: 'ap' } }, async (request, reply) => { vary(reply.raw, 'Accept'); + if (this.meta.federation === 'none') { + reply.code(403); + return; + } + const acct = Acct.parse(request.params.acct); const user = await this.usersRepository.findOneBy({ @@ -688,6 +746,11 @@ export class ActivityPubServerService { // emoji fastify.get<{ Params: { emoji: string; } }>('/emojis/:emoji', async (request, reply) => { + if (this.meta.federation === 'none') { + reply.code(403); + return; + } + const emoji = await this.emojisRepository.findOneBy({ host: IsNull(), name: request.params.emoji, @@ -705,6 +768,11 @@ export class ActivityPubServerService { // like fastify.get<{ Params: { like: string; } }>('/likes/:like', async (request, reply) => { + if (this.meta.federation === 'none') { + reply.code(403); + return; + } + const reaction = await this.noteReactionsRepository.findOneBy({ id: request.params.like }); if (reaction == null) { @@ -726,6 +794,11 @@ export class ActivityPubServerService { // follow fastify.get<{ Params: { follower: string; followee: string; } }>('/follows/:follower/:followee', async (request, reply) => { + if (this.meta.federation === 'none') { + reply.code(403); + return; + } + // This may be used before the follow is completed, so we do not // check if the following exists. @@ -752,6 +825,11 @@ export class ActivityPubServerService { // follow fastify.get<{ Params: { followRequestId: string; } }>('/follows/:followRequestId', async (request, reply) => { + if (this.meta.federation === 'none') { + reply.code(403); + return; + } + // This may be used before the follow is completed, so we do not // check if the following exists and only check if the follow request exists. diff --git a/packages/backend/src/server/WellKnownServerService.ts b/packages/backend/src/server/WellKnownServerService.ts index 8e326da89a..d106be5bc8 100644 --- a/packages/backend/src/server/WellKnownServerService.ts +++ b/packages/backend/src/server/WellKnownServerService.ts @@ -8,7 +8,7 @@ import { IsNull } from 'typeorm'; import vary from 'vary'; import fastifyAccepts from '@fastify/accepts'; import { DI } from '@/di-symbols.js'; -import type { UsersRepository } from '@/models/_.js'; +import type { MiMeta, UsersRepository } from '@/models/_.js'; import type { Config } from '@/config.js'; import { escapeAttribute, escapeValue } from '@/misc/prelude/xml.js'; import type { MiUser } from '@/models/User.js'; @@ -26,6 +26,9 @@ export class WellKnownServerService { @Inject(DI.config) private config: Config, + @Inject(DI.meta) + private meta: MiMeta, + @Inject(DI.usersRepository) private usersRepository: UsersRepository, @@ -66,6 +69,11 @@ export class WellKnownServerService { }); fastify.get('/.well-known/host-meta', async (request, reply) => { + if (this.meta.federation === 'none') { + reply.code(403); + return; + } + reply.header('Content-Type', xrd); return XRD({ element: 'Link', attributes: { rel: 'lrdd', @@ -75,6 +83,11 @@ export class WellKnownServerService { }); fastify.get('/.well-known/host-meta.json', async (request, reply) => { + if (this.meta.federation === 'none') { + reply.code(403); + return; + } + reply.header('Content-Type', 'application/json'); return { links: [{ @@ -86,6 +99,11 @@ export class WellKnownServerService { }); fastify.get('/.well-known/nodeinfo', async (request, reply) => { + if (this.meta.federation === 'none') { + reply.code(403); + return; + } + return { links: this.nodeinfoServerService.getLinks() }; }); @@ -99,6 +117,11 @@ fastify.get('/.well-known/change-password', async (request, reply) => { */ fastify.get<{ Querystring: { resource: string } }>(webFingerPath, async (request, reply) => { + if (this.meta.federation === 'none') { + reply.code(403); + return; + } + const fromId = (id: MiUser['id']): FindOptionsWhere => ({ id, host: IsNull(), diff --git a/packages/frontend/src/boot/main-boot.ts b/packages/frontend/src/boot/main-boot.ts index 64e3a236e8..46668cb934 100644 --- a/packages/frontend/src/boot/main-boot.ts +++ b/packages/frontend/src/boot/main-boot.ts @@ -201,6 +201,8 @@ export async function mainBoot() { prefer.commit('sound.on.noteMy', store.s.sound_noteMy as any); prefer.commit('sound.on.notification', store.s.sound_notification as any); prefer.commit('sound.on.reaction', store.s.sound_reaction as any); + prefer.commit('defaultNoteVisibility', store.s.defaultNoteVisibility); + prefer.commit('defaultNoteLocalOnly', store.s.defaultNoteLocalOnly); window.setTimeout(() => { unisonReload();