enhance(backend): フォローしているユーザーならフォロワー限定投稿のノートでもアンテナで検知できるように (#15264)
* フォローしているユーザーなら鍵ノートでもアンテナにひっかかるように Co-authored-by: kozakura913 <98575220+kozakura913@users.noreply.github.com> Co-authored-by: mai <74494945+chan-mai@users.noreply.github.com> * Eliminate build errors by resolving conflicts * 低コストな判定文を前にもってきて重い判定文に入る可能性を少しでも下げる * fix CHANGELOG.md * fix CHANGELOG.md * fix diff * removed comment * fix CHANGELOG.md --------- Co-authored-by: kozakura913 <98575220+kozakura913@users.noreply.github.com> Co-authored-by: mai <74494945+chan-mai@users.noreply.github.com> Co-authored-by: syuilo <4439005+syuilo@users.noreply.github.com>
This commit is contained in:
parent
1f0621b085
commit
0d4feed6d3
|
@ -8,6 +8,8 @@
|
|||
- Fix: 自動バックアップが設定されている環境でログアウト直前に設定をバックアップするように
|
||||
|
||||
### Server
|
||||
- Enhance: フォローしているユーザーならフォロワー限定投稿のノートでもアンテナで検知できるように
|
||||
(Cherry-picked from https://github.com/yojo-art/cherrypick/pull/568 and https://github.com/team-shahu/misskey/pull/38)
|
||||
- Fix: システムアカウントの名前がサーバー名と同期されない問題を修正
|
||||
- Fix: 大文字を含むユーザの URL で紹介された場合に 404 エラーを返す問題 #15813
|
||||
- Fix: リードレプリカ設定時にレコードの追加・更新・削除を伴うクエリを発行した際はmasterノードで実行されるように調整( #10897 )
|
||||
|
|
|
@ -5,18 +5,19 @@
|
|||
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import * as Redis from 'ioredis';
|
||||
import { FanoutTimelineService } from '@/core/FanoutTimelineService.js';
|
||||
import type { GlobalEvents } from '@/core/GlobalEventService.js';
|
||||
import { GlobalEventService } from '@/core/GlobalEventService.js';
|
||||
import { UtilityService } from '@/core/UtilityService.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import * as Acct from '@/misc/acct.js';
|
||||
import type { Packed } from '@/misc/json-schema.js';
|
||||
import type { AntennasRepository, UserListMembershipsRepository } from '@/models/_.js';
|
||||
import type { MiAntenna } from '@/models/Antenna.js';
|
||||
import type { MiNote } from '@/models/Note.js';
|
||||
import type { MiUser } from '@/models/User.js';
|
||||
import { GlobalEventService } from '@/core/GlobalEventService.js';
|
||||
import * as Acct from '@/misc/acct.js';
|
||||
import type { Packed } from '@/misc/json-schema.js';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import type { AntennasRepository, UserListMembershipsRepository } from '@/models/_.js';
|
||||
import { UtilityService } from '@/core/UtilityService.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import type { GlobalEvents } from '@/core/GlobalEventService.js';
|
||||
import { FanoutTimelineService } from '@/core/FanoutTimelineService.js';
|
||||
import { CacheService } from './CacheService.js';
|
||||
import type { OnApplicationShutdown } from '@nestjs/common';
|
||||
|
||||
@Injectable()
|
||||
|
@ -37,6 +38,7 @@ export class AntennaService implements OnApplicationShutdown {
|
|||
@Inject(DI.userListMembershipsRepository)
|
||||
private userListMembershipsRepository: UserListMembershipsRepository,
|
||||
|
||||
private cacheService: CacheService,
|
||||
private utilityService: UtilityService,
|
||||
private globalEventService: GlobalEventService,
|
||||
private fanoutTimelineService: FanoutTimelineService,
|
||||
|
@ -111,9 +113,6 @@ export class AntennaService implements OnApplicationShutdown {
|
|||
|
||||
@bindThis
|
||||
public async checkHitAntenna(antenna: MiAntenna, note: (MiNote | Packed<'Note'>), noteUser: { id: MiUser['id']; username: string; host: string | null; isBot: boolean; }): Promise<boolean> {
|
||||
if (note.visibility === 'specified') return false;
|
||||
if (note.visibility === 'followers') return false;
|
||||
|
||||
if (antenna.excludeNotesInSensitiveChannel && note.channel?.isSensitive) return false;
|
||||
|
||||
if (antenna.excludeBots && noteUser.isBot) return false;
|
||||
|
@ -122,6 +121,18 @@ export class AntennaService implements OnApplicationShutdown {
|
|||
|
||||
if (!antenna.withReplies && note.replyId != null) return false;
|
||||
|
||||
if (note.visibility === 'specified') {
|
||||
if (note.userId !== antenna.userId) {
|
||||
if (note.visibleUserIds == null) return false;
|
||||
if (!note.visibleUserIds.includes(antenna.userId)) return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (note.visibility === 'followers') {
|
||||
const isFollowing = Object.hasOwn(await this.cacheService.userFollowingsCache.fetch(antenna.userId), note.userId);
|
||||
if (!isFollowing && antenna.userId !== note.userId) return false;
|
||||
}
|
||||
|
||||
if (antenna.src === 'home') {
|
||||
// TODO
|
||||
} else if (antenna.src === 'list') {
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
process.env.NODE_ENV = 'test';
|
||||
|
||||
import * as assert from 'assert';
|
||||
import { DEFAULT_POLICIES } from '@/core/RoleService.js';
|
||||
import {
|
||||
api,
|
||||
failedApiCall,
|
||||
|
@ -19,6 +18,7 @@ import {
|
|||
userList,
|
||||
} from '../utils.js';
|
||||
import type * as misskey from 'misskey-js';
|
||||
import { DEFAULT_POLICIES } from '@/core/RoleService.js';
|
||||
|
||||
const compareBy = <T extends { id: string }>(selector: (s: T) => string = (s: T): string => s.id) => (a: T, b: T): number => {
|
||||
return selector(a).localeCompare(selector(b));
|
||||
|
@ -235,12 +235,12 @@ describe('アンテナ', () => {
|
|||
await failedApiCall({
|
||||
endpoint: 'antennas/create',
|
||||
parameters: { ...defaultParam, keywords: [[]], excludeKeywords: [[]] },
|
||||
user: alice
|
||||
user: alice,
|
||||
}, {
|
||||
status: 400,
|
||||
code: 'EMPTY_KEYWORD',
|
||||
id: '53ee222e-1ddd-4f9a-92e5-9fb82ddb463a'
|
||||
})
|
||||
id: '53ee222e-1ddd-4f9a-92e5-9fb82ddb463a',
|
||||
});
|
||||
});
|
||||
//#endregion
|
||||
//#region 更新(antennas/update)
|
||||
|
@ -274,12 +274,12 @@ describe('アンテナ', () => {
|
|||
await failedApiCall({
|
||||
endpoint: 'antennas/update',
|
||||
parameters: { ...defaultParam, antennaId: antenna.id, keywords: [[]], excludeKeywords: [[]] },
|
||||
user: alice
|
||||
user: alice,
|
||||
}, {
|
||||
status: 400,
|
||||
code: 'EMPTY_KEYWORD',
|
||||
id: '721aaff6-4e1b-4d88-8de6-877fae9f68c4'
|
||||
})
|
||||
id: '721aaff6-4e1b-4d88-8de6-877fae9f68c4',
|
||||
});
|
||||
});
|
||||
|
||||
//#endregion
|
||||
|
@ -375,14 +375,23 @@ describe('アンテナ', () => {
|
|||
],
|
||||
},
|
||||
{
|
||||
// https://github.com/misskey-dev/misskey/issues/9025
|
||||
label: 'ただし、フォロワー限定投稿とDM投稿を含まない。フォロワーであっても。',
|
||||
label: 'フォロワー限定投稿とDM投稿を含む',
|
||||
parameters: () => ({}),
|
||||
posts: [
|
||||
{ note: (): Promise<Note> => post(userFollowedByAlice, { text: `${keyword}`, visibility: 'public' }), included: true },
|
||||
{ note: (): Promise<Note> => post(userFollowedByAlice, { text: `${keyword}`, visibility: 'home' }), included: true },
|
||||
{ note: (): Promise<Note> => post(userFollowedByAlice, { text: `${keyword}`, visibility: 'followers' }) },
|
||||
{ note: (): Promise<Note> => post(userFollowedByAlice, { text: `${keyword}`, visibility: 'specified', visibleUserIds: [alice.id] }) },
|
||||
{ note: (): Promise<Note> => post(userFollowedByAlice, { text: `${keyword}`, visibility: 'followers' }), included: true },
|
||||
{ note: (): Promise<Note> => post(bob, { text: `${keyword}`, visibility: 'specified', visibleUserIds: [alice.id] }), included: true },
|
||||
],
|
||||
},
|
||||
{
|
||||
label: 'フォロワー限定投稿とDM投稿を含まない',
|
||||
parameters: () => ({}),
|
||||
posts: [
|
||||
{ note: (): Promise<Note> => post(bob, { text: `${keyword}`, visibility: 'public' }), included: true },
|
||||
{ note: (): Promise<Note> => post(bob, { text: `${keyword}`, visibility: 'home' }), included: true },
|
||||
{ note: (): Promise<Note> => post(bob, { text: `${keyword}`, visibility: 'followers' }) },
|
||||
{ note: (): Promise<Note> => post(bob, { text: `${keyword}`, visibility: 'specified', visibleUserIds: [carol.id] }) },
|
||||
],
|
||||
},
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue