Merge branch 'abuse-report-resolver' of ssh://github.com/chocolate-pie/misskey into abuse-report-resolver

This commit is contained in:
Chocolate Pie 2023-08-02 14:15:20 +09:00
commit f3045d6145
12 changed files with 80 additions and 34 deletions

View File

@ -1,5 +1,5 @@
<!-- <!--
## 13.x.x (unreleased) ## 2023.x.x (unreleased)
### General ### General
- -
@ -12,11 +12,20 @@
--> -->
## 13.x.x (unreleased) ### General
=======
## 2023.8.0 (unreleased)
### General ### General
- OAuth 2.0のサポート
- 通報の即時解決機能を追加 - 通報の即時解決機能を追加
### Client
- Fix: サーバー情報画面(`/instance-info/{domain}`)でブロックができないのを修正
### Server
-
## 13.14.2 ## 13.14.2
### Client ### Client

View File

@ -147,7 +147,6 @@
"rss-parser": "3.13.0", "rss-parser": "3.13.0",
"rxjs": "7.8.1", "rxjs": "7.8.1",
"sanitize-html": "2.11.0", "sanitize-html": "2.11.0",
"semver": "7.5.4",
"sharp": "0.32.3", "sharp": "0.32.3",
"sharp-read-bmp": "github:misskey-dev/sharp-read-bmp", "sharp-read-bmp": "github:misskey-dev/sharp-read-bmp",
"slacc": "0.0.10", "slacc": "0.0.10",

View File

@ -10,7 +10,6 @@ import * as os from 'node:os';
import cluster from 'node:cluster'; import cluster from 'node:cluster';
import chalk from 'chalk'; import chalk from 'chalk';
import chalkTemplate from 'chalk-template'; import chalkTemplate from 'chalk-template';
import semver from 'semver';
import Logger from '@/logger.js'; import Logger from '@/logger.js';
import { loadConfig } from '@/config.js'; import { loadConfig } from '@/config.js';
import type { Config } from '@/config.js'; import type { Config } from '@/config.js';

View File

@ -1,3 +1,8 @@
/*
* SPDX-FileCopyrightText: syuilo and other misskey contributors
* SPDX-License-Identifier: AGPL-3.0-only
*/
import dns from 'node:dns/promises'; import dns from 'node:dns/promises';
import { fileURLToPath } from 'node:url'; import { fileURLToPath } from 'node:url';
import { Inject, Injectable } from '@nestjs/common'; import { Inject, Injectable } from '@nestjs/common';

View File

@ -1,3 +1,8 @@
/*
* SPDX-FileCopyrightText: syuilo and other misskey contributors
* SPDX-License-Identifier: AGPL-3.0-only
*/
/** /**
* Basic OAuth tests to make sure the library is correctly integrated to Misskey * Basic OAuth tests to make sure the library is correctly integrated to Misskey
* and not regressed by version updates or potential migration to another library. * and not regressed by version updates or potential migration to another library.

View File

@ -751,18 +751,25 @@ async function post(ev?: MouseEvent) {
claimAchievement('notes1'); claimAchievement('notes1');
} }
const text = postData.text?.toLowerCase() ?? ''; const text = postData.text ?? '';
if ((text.includes('love') || text.includes('❤')) && text.includes('misskey')) { const lowerCase = text.toLowerCase();
if ((lowerCase.includes('love') || lowerCase.includes('❤')) && lowerCase.includes('misskey')) {
claimAchievement('iLoveMisskey'); claimAchievement('iLoveMisskey');
} }
if ( if ([
text.includes('https://youtu.be/Efrlqw8ytg4'.toLowerCase()) || 'https://youtu.be/Efrlqw8ytg4',
text.includes('https://www.youtube.com/watch?v=Efrlqw8ytg4'.toLowerCase()) || 'https://www.youtube.com/watch?v=Efrlqw8ytg4',
text.includes('https://m.youtube.com/watch?v=Efrlqw8ytg4'.toLowerCase()) || 'https://m.youtube.com/watch?v=Efrlqw8ytg4',
text.includes('https://youtu.be/XVCwzwxdHuA'.toLowerCase()) ||
text.includes('https://www.youtube.com/watch?v=XVCwzwxdHuA'.toLowerCase()) || 'https://youtu.be/XVCwzwxdHuA',
text.includes('https://m.youtube.com/watch?v=XVCwzwxdHuA'.toLowerCase()) 'https://www.youtube.com/watch?v=XVCwzwxdHuA',
) { 'https://m.youtube.com/watch?v=XVCwzwxdHuA',
'https://open.spotify.com/track/3Cuj0mZrlLoXx9nydNi7RB',
'https://open.spotify.com/track/7anfcaNPQWlWCwyCHmZqNy',
'https://open.spotify.com/track/5Odr16TvEN4my22K9nbH7l',
'https://open.spotify.com/album/5bOlxyl4igOrp2DwVQxBco',
].some(url => text.includes(url))) {
claimAchievement('brainDiver'); claimAchievement('brainDiver');
} }

View File

@ -34,8 +34,8 @@ SPDX-License-Identifier: AGPL-3.0-only
<FormSection v-if="iAmModerator"> <FormSection v-if="iAmModerator">
<template #label>Moderation</template> <template #label>Moderation</template>
<div class="_gaps_s"> <div class="_gaps_s">
<MkSwitch v-model="suspended" @update:modelValue="toggleSuspend">{{ i18n.ts.stopActivityDelivery }}</MkSwitch> <MkSwitch v-model="suspended" :disabled="!instance" @update:modelValue="toggleSuspend">{{ i18n.ts.stopActivityDelivery }}</MkSwitch>
<MkSwitch v-model="isBlocked" @update:modelValue="toggleBlock">{{ i18n.ts.blockThisInstance }}</MkSwitch> <MkSwitch v-model="isBlocked" :disabled="!meta || !instance" @update:modelValue="toggleBlock">{{ i18n.ts.blockThisInstance }}</MkSwitch>
<MkButton @click="refreshMetadata"><i class="ti ti-refresh"></i> Refresh metadata</MkButton> <MkButton @click="refreshMetadata"><i class="ti ti-refresh"></i> Refresh metadata</MkButton>
</div> </div>
</FormSection> </FormSection>
@ -129,7 +129,7 @@ import MkSelect from '@/components/MkSelect.vue';
import MkSwitch from '@/components/MkSwitch.vue'; import MkSwitch from '@/components/MkSwitch.vue';
import * as os from '@/os'; import * as os from '@/os';
import number from '@/filters/number'; import number from '@/filters/number';
import { iAmModerator } from '@/account'; import { iAmModerator, iAmAdmin } from '@/account';
import { definePageMetadata } from '@/scripts/page-metadata'; import { definePageMetadata } from '@/scripts/page-metadata';
import { i18n } from '@/i18n'; import { i18n } from '@/i18n';
import MkUserCardMini from '@/components/MkUserCardMini.vue'; import MkUserCardMini from '@/components/MkUserCardMini.vue';
@ -143,11 +143,11 @@ const props = defineProps<{
let tab = $ref('overview'); let tab = $ref('overview');
let chartSrc = $ref('instance-requests'); let chartSrc = $ref('instance-requests');
let meta = $ref<misskey.entities.DetailedInstanceMetadata | null>(null); let meta = $ref<misskey.entities.AdminInstanceMetadata | null>(null);
let instance = $ref<misskey.entities.Instance | null>(null); let instance = $ref<misskey.entities.Instance | null>(null);
let suspended = $ref(false); let suspended = $ref(false);
let isBlocked = $ref(false); let isBlocked = $ref(false);
let faviconUrl = $ref(null); let faviconUrl = $ref<string | null>(null);
const usersPagination = { const usersPagination = {
endpoint: iAmModerator ? 'admin/show-users' : 'users' as const, endpoint: iAmModerator ? 'admin/show-users' : 'users' as const,
@ -160,7 +160,10 @@ const usersPagination = {
offsetMode: true, offsetMode: true,
}; };
async function fetch() { async function fetch(): Promise<void> {
if (iAmAdmin) {
meta = await os.api('admin/meta');
}
instance = await os.api('federation/show-instance', { instance = await os.api('federation/show-instance', {
host: props.host, host: props.host,
}); });
@ -169,21 +172,25 @@ async function fetch() {
faviconUrl = getProxiedImageUrlNullable(instance.faviconUrl, 'preview') ?? getProxiedImageUrlNullable(instance.iconUrl, 'preview'); faviconUrl = getProxiedImageUrlNullable(instance.faviconUrl, 'preview') ?? getProxiedImageUrlNullable(instance.iconUrl, 'preview');
} }
async function toggleBlock(ev) { async function toggleBlock(): Promise<void> {
if (meta == null) return; if (!meta) throw new Error('No meta?');
if (!instance) throw new Error('No instance?');
const { host } = instance;
await os.api('admin/update-meta', { await os.api('admin/update-meta', {
blockedHosts: isBlocked ? meta.blockedHosts.concat([instance.host]) : meta.blockedHosts.filter(x => x !== instance.host), blockedHosts: isBlocked ? meta.blockedHosts.concat([host]) : meta.blockedHosts.filter(x => x !== host),
}); });
} }
async function toggleSuspend(v) { async function toggleSuspend(): Promise<void> {
if (!instance) throw new Error('No instance?');
await os.api('admin/federation/update-instance', { await os.api('admin/federation/update-instance', {
host: instance.host, host: instance.host,
isSuspended: suspended, isSuspended: suspended,
}); });
} }
function refreshMetadata() { function refreshMetadata(): void {
if (!instance) throw new Error('No instance?');
os.api('admin/federation/refresh-remote-instance-metadata', { os.api('admin/federation/refresh-remote-instance-metadata', {
host: instance.host, host: instance.host,
}); });

View File

@ -1,3 +1,8 @@
<!--
SPDX-FileCopyrightText: syuilo and other misskey contributors
SPDX-License-Identifier: AGPL-3.0-only
-->
<template> <template>
<MkStickyContainer> <MkStickyContainer>
<template #header><MkPageHeader/></template> <template #header><MkPageHeader/></template>

View File

@ -17,6 +17,11 @@ export type Acct = {
// @public (undocumented) // @public (undocumented)
type Ad = TODO_2; type Ad = TODO_2;
// @public (undocumented)
type AdminInstanceMetadata = DetailedInstanceMetadata & {
blockedHosts: string[];
};
// @public (undocumented) // @public (undocumented)
type Announcement = { type Announcement = {
id: ID; id: ID;
@ -329,8 +334,8 @@ export type Endpoints = {
res: TODO; res: TODO;
}; };
'admin/meta': { 'admin/meta': {
req: TODO; req: NoParams;
res: TODO; res: AdminInstanceMetadata;
}; };
'admin/reset-password': { 'admin/reset-password': {
req: TODO; req: TODO;
@ -2242,6 +2247,7 @@ declare namespace entities {
LiteInstanceMetadata, LiteInstanceMetadata,
DetailedInstanceMetadata, DetailedInstanceMetadata,
InstanceMetadata, InstanceMetadata,
AdminInstanceMetadata,
ServerInfo, ServerInfo,
Stats, Stats,
Page, Page,
@ -2333,7 +2339,7 @@ type ID = string;
// @public (undocumented) // @public (undocumented)
type Instance = { type Instance = {
id: ID; id: ID;
caughtAt: DateString; firstRetrievedAt: DateString;
host: string; host: string;
usersCount: number; usersCount: number;
notesCount: number; notesCount: number;
@ -2347,6 +2353,7 @@ type Instance = {
lastCommunicatedAt: DateString; lastCommunicatedAt: DateString;
isNotResponding: boolean; isNotResponding: boolean;
isSuspended: boolean; isSuspended: boolean;
isBlocked: boolean;
softwareName: string | null; softwareName: string | null;
softwareVersion: string | null; softwareVersion: string | null;
openRegistrations: boolean | null; openRegistrations: boolean | null;

View File

@ -2,7 +2,7 @@ import type {
Ad, Announcement, Antenna, App, AuthSession, Blocking, Channel, Clip, DateString, DetailedInstanceMetadata, DriveFile, DriveFolder, Following, FollowingFolloweePopulated, FollowingFollowerPopulated, FollowRequest, GalleryPost, Instance, Ad, Announcement, Antenna, App, AuthSession, Blocking, Channel, Clip, DateString, DetailedInstanceMetadata, DriveFile, DriveFolder, Following, FollowingFolloweePopulated, FollowingFollowerPopulated, FollowRequest, GalleryPost, Instance,
LiteInstanceMetadata, LiteInstanceMetadata,
MeDetailed, MeDetailed,
Note, NoteFavorite, OriginType, Page, ServerInfo, Stats, User, UserDetailed, MeSignup, UserGroup, UserList, UserSorting, Notification, NoteReaction, Signin, MessagingMessage, Invite, InviteLimit, Note, NoteFavorite, OriginType, Page, ServerInfo, Stats, User, UserDetailed, MeSignup, UserGroup, UserList, UserSorting, Notification, NoteReaction, Signin, MessagingMessage, Invite, InviteLimit, AdminInstanceMetadata,
} from './entities.js'; } from './entities.js';
type TODO = Record<string, any> | null; type TODO = Record<string, any> | null;
@ -20,7 +20,7 @@ export type Endpoints = {
'admin/get-table-stats': { req: TODO; res: TODO; }; 'admin/get-table-stats': { req: TODO; res: TODO; };
'admin/invite': { req: TODO; res: TODO; }; 'admin/invite': { req: TODO; res: TODO; };
'admin/logs': { req: TODO; res: TODO; }; 'admin/logs': { req: TODO; res: TODO; };
'admin/meta': { req: TODO; res: TODO; }; 'admin/meta': { req: NoParams; res: AdminInstanceMetadata; };
'admin/reset-password': { req: TODO; res: TODO; }; 'admin/reset-password': { req: TODO; res: TODO; };
'admin/resolve-abuse-user-report': { req: TODO; res: TODO; }; 'admin/resolve-abuse-user-report': { req: TODO; res: TODO; };
'admin/resync-chart': { req: TODO; res: TODO; }; 'admin/resync-chart': { req: TODO; res: TODO; };

View File

@ -346,6 +346,11 @@ export type DetailedInstanceMetadata = LiteInstanceMetadata & {
export type InstanceMetadata = LiteInstanceMetadata | DetailedInstanceMetadata; export type InstanceMetadata = LiteInstanceMetadata | DetailedInstanceMetadata;
export type AdminInstanceMetadata = DetailedInstanceMetadata & {
// TODO: There are more fields.
blockedHosts: string[];
};
export type ServerInfo = { export type ServerInfo = {
machine: string; machine: string;
cpu: { cpu: {
@ -482,7 +487,7 @@ export type Blocking = {
export type Instance = { export type Instance = {
id: ID; id: ID;
caughtAt: DateString; firstRetrievedAt: DateString;
host: string; host: string;
usersCount: number; usersCount: number;
notesCount: number; notesCount: number;
@ -496,6 +501,7 @@ export type Instance = {
lastCommunicatedAt: DateString; lastCommunicatedAt: DateString;
isNotResponding: boolean; isNotResponding: boolean;
isSuspended: boolean; isSuspended: boolean;
isBlocked: boolean;
softwareName: string | null; softwareName: string | null;
softwareVersion: string | null; softwareVersion: string | null;
openRegistrations: boolean | null; openRegistrations: boolean | null;

View File

@ -341,9 +341,6 @@ importers:
sanitize-html: sanitize-html:
specifier: 2.11.0 specifier: 2.11.0
version: 2.11.0 version: 2.11.0
semver:
specifier: 7.5.4
version: 7.5.4
sharp: sharp:
specifier: 0.32.3 specifier: 0.32.3
version: 0.32.3 version: 0.32.3