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