Skip to content

Commit

Permalink
Merge branch 'develop' into fix-popup-dispose-1
Browse files Browse the repository at this point in the history
  • Loading branch information
kakkokari-gtyih committed Aug 17, 2024
2 parents 059eb6d + c0de57c commit ed38be5
Show file tree
Hide file tree
Showing 23 changed files with 417 additions and 60 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@
### General
- Enhance: モデレーターはすべてのユーザーのフォロー・フォロワーの一覧を見られるように
- Enhance: アカウントの削除のモデレーションログを残すように
- Enhance: 不適切なページ、ギャラリー、Playを管理者権限で削除できるように
- Fix: リモートユーザのフォロー・フォロワーの一覧が非公開設定の場合も表示できてしまう問題を修正

### Client
- Enhance: 「自分のPlay」ページにおいてPlayが非公開かどうかが一目でわかるように
- Enhance: 不適切なページ、ギャラリー、Playを通報できるように
- Fix: Play編集時に公開範囲が「パブリック」にリセットされる問題を修正
- Fix: ページ遷移に失敗することがある問題を修正
- Fix: iOSでユーザー名などがリンクとして誤検知される現象を抑制
Expand All @@ -15,6 +17,7 @@
- Fix: 特定の条件下でノートの削除ボタンが出ないのを修正

### Server
- enhance: 照会時にURLがhtmlかつheadタグ内に`rel="alternate"`, `type="application/activity+json"``link`タグがある場合に追ってリンク先を照会できるように
- Enhance: 凍結されたアカウントのフォローリクエストを表示しないように
- Fix: WSの`readAllNotifications` メッセージが `body` を持たない場合に動作しない問題 #14374
- 通知ページや通知カラム(デッキ)を開いている状態において、新たに発生した通知が既読されない問題が修正されます。
Expand All @@ -28,6 +31,8 @@
- キュー処理のつまりが改善される可能性があります
- Fix: リバーシの対局設定の変更が反映されないのを修正
- Fix: 無制限にストリーミングのチャンネルに接続できる問題を修正
- Fix: ベースロールのポリシーを変更した際にモデログに記録されないのを修正
(Cherry-picked from https://github.com/MisskeyIO/misskey/pull/700)

## 2024.7.0

Expand Down
14 changes: 13 additions & 1 deletion locales/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2829,7 +2829,7 @@ export interface Locale extends ILocale {
*/
"reportAbuseOf": ParameterizedString<"name">;
/**
* 通報理由の詳細を記入してください。対象のノートがある場合はそのURLも記入してください
* 通報理由の詳細を記入してください。対象のノートやページなどがある場合はそのURLも記入してください
*/
"fillAbuseReportDescription": string;
/**
Expand Down Expand Up @@ -9687,6 +9687,18 @@ export interface Locale extends ILocale {
* アカウントを削除
*/
"deleteAccount": string;
/**
* ページを削除
*/
"deletePage": string;
/**
* Playを削除
*/
"deleteFlash": string;
/**
* ギャラリーの投稿を削除
*/
"deleteGalleryPost": string;
};
"_fileViewer": {
/**
Expand Down
5 changes: 4 additions & 1 deletion locales/ja-JP.yml
Original file line number Diff line number Diff line change
Expand Up @@ -703,7 +703,7 @@ abuseReports: "通報"
reportAbuse: "通報"
reportAbuseRenote: "リノートを通報"
reportAbuseOf: "{name}を通報する"
fillAbuseReportDescription: "通報理由の詳細を記入してください。対象のノートがある場合はそのURLも記入してください"
fillAbuseReportDescription: "通報理由の詳細を記入してください。対象のノートやページなどがある場合はそのURLも記入してください"
abuseReported: "内容が送信されました。ご報告ありがとうございました。"
reporter: "通報者"
reporteeOrigin: "通報先"
Expand Down Expand Up @@ -2569,6 +2569,9 @@ _moderationLogTypes:
updateAbuseReportNotificationRecipient: "通報の通知先を更新"
deleteAbuseReportNotificationRecipient: "通報の通知先を削除"
deleteAccount: "アカウントを削除"
deletePage: "ページを削除"
deleteFlash: "Playを削除"
deleteGalleryPost: "ギャラリーの投稿を削除"

_fileViewer:
title: "ファイルの詳細"
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "misskey",
"version": "2024.8.0-alpha.1",
"version": "2024.8.0-rc.3",
"codename": "nasubi",
"repository": {
"type": "git",
Expand Down
24 changes: 22 additions & 2 deletions packages/backend/src/core/activitypub/ApRequestService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import * as crypto from 'node:crypto';
import { URL } from 'node:url';
import { Inject, Injectable } from '@nestjs/common';
import { Window } from 'happy-dom';
import { DI } from '@/di-symbols.js';
import type { Config } from '@/config.js';
import type { MiUser } from '@/models/User.js';
Expand Down Expand Up @@ -180,7 +181,8 @@ export class ApRequestService {
* @param url URL to fetch
*/
@bindThis
public async signedGet(url: string, user: { id: MiUser['id'] }): Promise<unknown> {
public async signedGet(url: string, user: { id: MiUser['id'] }, followAlternate?: boolean): Promise<unknown> {
const _followAlternate = followAlternate ?? true;
const keypair = await this.userKeypairService.getUserKeypair(user.id);

const req = ApRequestCreator.createSignedGet({
Expand All @@ -198,9 +200,27 @@ export class ApRequestService {
headers: req.request.headers,
}, {
throwErrorWhenResponseNotOk: true,
validators: [validateContentTypeSetAsActivityPub],
});

//#region リクエスト先がhtmlかつactivity+jsonへのalternate linkタグがあるとき
if (res.headers.get('Content-type')?.startsWith('text/html;') && _followAlternate === true) {
const html = await res.text();
const window = new Window();
const document = window.document;
document.documentElement.innerHTML = html;

const alternate = document.querySelector('head > link[rel="alternate"][type="application/activity+json"]');
if (alternate) {
const href = alternate.getAttribute('href');
if (href) {
return await this.signedGet(href, user, false);
}
}
}
//#endregion

validateContentTypeSetAsActivityPub(res);

return await res.json();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { Injectable } from '@nestjs/common';
import { Endpoint } from '@/server/api/endpoint-base.js';
import { GlobalEventService } from '@/core/GlobalEventService.js';
import { MetaService } from '@/core/MetaService.js';
import { ModerationLogService } from '@/core/ModerationLogService.js';

export const meta = {
tags: ['admin', 'role'],
Expand All @@ -33,12 +34,22 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
constructor(
private metaService: MetaService,
private globalEventService: GlobalEventService,
private moderationLogService: ModerationLogService,
) {
super(meta, paramDef, async (ps) => {
super(meta, paramDef, async (ps, me) => {
const before = await this.metaService.fetch(true);

await this.metaService.update({
policies: ps.policies,
});
this.globalEventService.publishInternalEvent('policiesUpdated', ps.policies);

const after = await this.metaService.fetch(true);

this.globalEventService.publishInternalEvent('policiesUpdated', after.policies);
this.moderationLogService.log(me, 'updateServerSettings', {
before: before.policies,
after: after.policies,
});
});
}
}
24 changes: 22 additions & 2 deletions packages/backend/src/server/api/endpoints/flash/delete.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@
*/

import { Inject, Injectable } from '@nestjs/common';
import type { FlashsRepository } from '@/models/_.js';
import type { FlashsRepository, UsersRepository } from '@/models/_.js';
import { Endpoint } from '@/server/api/endpoint-base.js';
import { DI } from '@/di-symbols.js';
import { ModerationLogService } from '@/core/ModerationLogService.js';
import { RoleService } from '@/core/RoleService.js';
import { ApiError } from '../../error.js';

export const meta = {
Expand Down Expand Up @@ -44,17 +46,35 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
constructor(
@Inject(DI.flashsRepository)
private flashsRepository: FlashsRepository,

@Inject(DI.usersRepository)
private usersRepository: UsersRepository,

private moderationLogService: ModerationLogService,
private roleService: RoleService,
) {
super(meta, paramDef, async (ps, me) => {
const flash = await this.flashsRepository.findOneBy({ id: ps.flashId });

if (flash == null) {
throw new ApiError(meta.errors.noSuchFlash);
}
if (flash.userId !== me.id) {

if (!await this.roleService.isModerator(me) && flash.userId !== me.id) {
throw new ApiError(meta.errors.accessDenied);
}

await this.flashsRepository.delete(flash.id);

if (flash.userId !== me.id) {
const user = await this.usersRepository.findOneByOrFail({ id: flash.userId });
this.moderationLogService.log(me, 'deleteFlash', {
flashId: flash.id,
flashUserId: flash.userId,
flashUserUsername: user.username,
flash,
});
}
});
}
}
35 changes: 30 additions & 5 deletions packages/backend/src/server/api/endpoints/gallery/posts/delete.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@

import { Inject, Injectable } from '@nestjs/common';
import { Endpoint } from '@/server/api/endpoint-base.js';
import type { GalleryPostsRepository } from '@/models/_.js';
import type { GalleryPostsRepository, UsersRepository } from '@/models/_.js';
import { DI } from '@/di-symbols.js';
import { ModerationLogService } from '@/core/ModerationLogService.js';
import { RoleService } from '@/core/RoleService.js';
import { ApiError } from '../../../error.js';

export const meta = {
Expand All @@ -22,6 +24,12 @@ export const meta = {
code: 'NO_SUCH_POST',
id: 'ae52f367-4bd7-4ecd-afc6-5672fff427f5',
},

accessDenied: {
message: 'Access denied.',
code: 'ACCESS_DENIED',
id: 'c86e09de-1c48-43ac-a435-1c7e42ed4496',
},
},
} as const;

Expand All @@ -38,18 +46,35 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
constructor(
@Inject(DI.galleryPostsRepository)
private galleryPostsRepository: GalleryPostsRepository,

@Inject(DI.usersRepository)
private usersRepository: UsersRepository,

private moderationLogService: ModerationLogService,
private roleService: RoleService,
) {
super(meta, paramDef, async (ps, me) => {
const post = await this.galleryPostsRepository.findOneBy({
id: ps.postId,
userId: me.id,
});
const post = await this.galleryPostsRepository.findOneBy({ id: ps.postId });

if (post == null) {
throw new ApiError(meta.errors.noSuchPost);
}

if (!await this.roleService.isModerator(me) && post.userId !== me.id) {
throw new ApiError(meta.errors.accessDenied);
}

await this.galleryPostsRepository.delete(post.id);

if (post.userId !== me.id) {
const user = await this.usersRepository.findOneByOrFail({ id: post.userId });
this.moderationLogService.log(me, 'deleteGalleryPost', {
postId: post.id,
postUserId: post.userId,
postUserUsername: user.username,
post,
});
}
});
}
}
24 changes: 22 additions & 2 deletions packages/backend/src/server/api/endpoints/pages/delete.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@
*/

import { Inject, Injectable } from '@nestjs/common';
import type { PagesRepository } from '@/models/_.js';
import type { PagesRepository, UsersRepository } from '@/models/_.js';
import { Endpoint } from '@/server/api/endpoint-base.js';
import { DI } from '@/di-symbols.js';
import { ModerationLogService } from '@/core/ModerationLogService.js';
import { RoleService } from '@/core/RoleService.js';
import { ApiError } from '../../error.js';

export const meta = {
Expand Down Expand Up @@ -44,17 +46,35 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
constructor(
@Inject(DI.pagesRepository)
private pagesRepository: PagesRepository,

@Inject(DI.usersRepository)
private usersRepository: UsersRepository,

private moderationLogService: ModerationLogService,
private roleService: RoleService,
) {
super(meta, paramDef, async (ps, me) => {
const page = await this.pagesRepository.findOneBy({ id: ps.pageId });

if (page == null) {
throw new ApiError(meta.errors.noSuchPage);
}
if (page.userId !== me.id) {

if (!await this.roleService.isModerator(me) && page.userId !== me.id) {
throw new ApiError(meta.errors.accessDenied);
}

await this.pagesRepository.delete(page.id);

if (page.userId !== me.id) {
const user = await this.usersRepository.findOneByOrFail({ id: page.userId });
this.moderationLogService.log(me, 'deletePage', {
pageId: page.id,
pageUserId: page.userId,
pageUserUsername: user.username,
page,
});
}
});
}
}
21 changes: 21 additions & 0 deletions packages/backend/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,9 @@ export const moderationLogTypes = [
'updateAbuseReportNotificationRecipient',
'deleteAbuseReportNotificationRecipient',
'deleteAccount',
'deletePage',
'deleteFlash',
'deleteGalleryPost',
] as const;

export type ModerationLogPayloads = {
Expand Down Expand Up @@ -320,6 +323,24 @@ export type ModerationLogPayloads = {
userUsername: string;
userHost: string | null;
};
deletePage: {
pageId: string;
pageUserId: string;
pageUserUsername: string;
page: any;
};
deleteFlash: {
flashId: string;
flashUserId: string;
flashUserUsername: string;
flash: any;
};
deleteGalleryPost: {
postId: string;
postUserId: string;
postUserUsername: string;
post: any;
};
};

export type Serialized<T> = {
Expand Down
2 changes: 1 addition & 1 deletion packages/frontend/src/components/MkAbuseReportWindow.vue
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ import * as os from '@/os.js';
import { i18n } from '@/i18n.js';

const props = defineProps<{
user: Misskey.entities.UserDetailed;
user: Misskey.entities.UserLite;
initialComment?: string;
}>();

Expand Down
Loading

0 comments on commit ed38be5

Please sign in to comment.