feat(federation): 特定の連合サーバーのメディアを全てセンシティブとして設定する機能を追加 (MisskeyIO#340)

This commit is contained in:
まっちゃとーにゅ
2024-01-07 19:51:07 +09:00
committed by GitHub
parent ce58adce22
commit d4a8e9a499
15 changed files with 105 additions and 5 deletions

View File

@@ -0,0 +1,16 @@
/*
* SPDX-FileCopyrightText: syuilo and other misskey contributors
* SPDX-License-Identifier: AGPL-3.0-only
*/
export class SensitiveMediaHosts1704622962215 {
name = 'SensitiveMediaHosts1704622962215'
async up(queryRunner) {
await queryRunner.query(`ALTER TABLE "meta" ADD "sensitiveMediaHosts" character varying(1024) array NOT NULL DEFAULT '{}'`);
}
async down(queryRunner) {
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "sensitiveMediaHosts"`);
}
}

View File

@@ -42,6 +42,12 @@ export class UtilityService {
return silencedHosts.some(x => `.${host.toLowerCase()}`.endsWith(`.${x}`));
}
@bindThis
public isSensitiveMediaHost(sensitiveMediaHosts: string[] | undefined, host: string | null): boolean {
if (!sensitiveMediaHosts || host == null) return false;
return sensitiveMediaHosts.some(x => `.${host.toLowerCase()}`.endsWith(`.${x}`));
}
@bindThis
public isSensitiveWordIncluded(text: string, sensitiveWords: string[]): boolean {
if (sensitiveWords.length === 0) return false;

View File

@@ -173,6 +173,9 @@ export class ApNoteService {
const apMentions = await this.apMentionService.extractApMentions(note.tag, resolver);
const apHashtags = extractApHashtags(note.tag);
const meta = await this.metaService.fetch();
const isSensitiveMediaHost = this.utilityService.isSensitiveMediaHost(meta.blockedHosts, this.utilityService.extractDbHost(note.id ?? entryUri));
// 添付ファイル
// TODO: attachmentは必ずしもImageではない
// TODO: attachmentは必ずしも配列ではない
@@ -180,7 +183,7 @@ export class ApNoteService {
const files = (await Promise.all(toArray(note.attachment).map(attach => (
limit(() => this.apImageService.resolveImage(actor, {
...attach,
sensitive: note.sensitive, // Noteがsensitiveなら添付もsensitiveにする
sensitive: isSensitiveMediaHost || note.sensitive, // Noteがsensitiveなら添付もsensitiveにする
}))
))));

View File

@@ -43,6 +43,7 @@ export class InstanceEntityService {
maintainerName: instance.maintainerName,
maintainerEmail: instance.maintainerEmail,
isSilenced: this.utilityService.isSilencedHost(meta.silencedHosts, instance.host),
isSensitiveMedia: this.utilityService.isSensitiveMediaHost(meta.sensitiveMediaHosts, instance.host),
iconUrl: instance.iconUrl,
faviconUrl: instance.faviconUrl,
themeColor: instance.themeColor,

View File

@@ -81,6 +81,11 @@ export class MiMeta {
})
public silencedHosts: string[];
@Column('varchar', {
length: 1024, array: true, default: '{}',
})
public sensitiveMediaHosts: string[];
@Column('varchar', {
length: 1024,
nullable: true,

View File

@@ -83,6 +83,10 @@ export const packedFederationInstanceSchema = {
type: 'boolean',
optional: false, nullable: false,
},
isSensitiveMedia: {
type: 'boolean',
optional: false, nullable: false,
},
iconUrl: {
type: 'string',
optional: false, nullable: true,

View File

@@ -116,6 +116,16 @@ export const meta = {
nullable: false,
},
},
sensitiveMediaHosts: {
type: 'array',
optional: true,
nullable: false,
items: {
type: 'string',
optional: false,
nullable: false,
},
},
pinnedUsers: {
type: 'array',
optional: false, nullable: false,
@@ -491,6 +501,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
hiddenTags: instance.hiddenTags,
blockedHosts: instance.blockedHosts,
silencedHosts: instance.silencedHosts,
sensitiveMediaHosts: instance.sensitiveMediaHosts,
sensitiveWords: instance.sensitiveWords,
preservedUsernames: instance.preservedUsernames,
hcaptchaSecretKey: instance.hcaptchaSecretKey,

View File

@@ -138,6 +138,11 @@ export const paramDef = {
type: 'string',
},
},
sensitiveMediaHosts: {
type: 'array', nullable: true, items: {
type: 'string',
},
},
urlPreviewDenyList: { type: 'array', nullable: true, items: {
type: 'string',
} },
@@ -173,13 +178,23 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
if (Array.isArray(ps.sensitiveWords)) {
set.sensitiveWords = ps.sensitiveWords.filter(Boolean);
}
if (Array.isArray(ps.silencedHosts)) {
let lastValue = '';
set.silencedHosts = ps.silencedHosts.sort().filter((h) => {
const lv = lastValue;
lastValue = h;
return h !== '' && h !== lv && !set.blockedHosts?.includes(h);
});
}).map(x => x.toLowerCase());
}
if (Array.isArray(ps.sensitiveMediaHosts)) {
let lastValue = '';
set.sensitiveMediaHosts = ps.sensitiveMediaHosts.sort().filter((h) => {
const lv = lastValue;
lastValue = h;
return h !== '' && h !== lv && !set.blockedHosts?.includes(h);
}).map(x => x.toLowerCase());
}
if (Array.isArray(ps.urlPreviewDenyList)) {