Mod: UserReactionBlockingServiceとUserBlockingServiceを統合

This commit is contained in:
鴇峰 朔華 2024-11-18 21:46:28 +09:00
parent 0301e86aff
commit da94dbee00
7 changed files with 81 additions and 139 deletions

View File

@ -58,7 +58,6 @@ import { S3Service } from './S3Service.js';
import { SignupService } from './SignupService.js';
import { WebAuthnService } from './WebAuthnService.js';
import { UserBlockingService } from './UserBlockingService.js';
import { UserReactionBlockingService } from './UserReactionBlockingService.js';
import { CacheService } from './CacheService.js';
import { UserService } from './UserService.js';
import { UserFollowingService } from './UserFollowingService.js';
@ -203,7 +202,6 @@ const $S3Service: Provider = { provide: 'S3Service', useExisting: S3Service };
const $SignupService: Provider = { provide: 'SignupService', useExisting: SignupService };
const $WebAuthnService: Provider = { provide: 'WebAuthnService', useExisting: WebAuthnService };
const $UserBlockingService: Provider = { provide: 'UserBlockingService', useExisting: UserBlockingService };
const $UserReactionBlockingService: Provider = { provide: 'UserReactionBlockingService', useExisting: UserReactionBlockingService };
const $CacheService: Provider = { provide: 'CacheService', useExisting: CacheService };
const $UserService: Provider = { provide: 'UserService', useExisting: UserService };
const $UserFollowingService: Provider = { provide: 'UserFollowingService', useExisting: UserFollowingService };
@ -355,7 +353,6 @@ const $ApQuestionService: Provider = { provide: 'ApQuestionService', useExisting
SignupService,
WebAuthnService,
UserBlockingService,
UserReactionBlockingService,
CacheService,
UserService,
UserFollowingService,
@ -503,7 +500,6 @@ const $ApQuestionService: Provider = { provide: 'ApQuestionService', useExisting
$SignupService,
$WebAuthnService,
$UserBlockingService,
$UserReactionBlockingService,
$CacheService,
$UserService,
$UserFollowingService,
@ -652,7 +648,6 @@ const $ApQuestionService: Provider = { provide: 'ApQuestionService', useExisting
SignupService,
WebAuthnService,
UserBlockingService,
UserReactionBlockingService,
CacheService,
UserService,
UserFollowingService,
@ -799,7 +794,6 @@ const $ApQuestionService: Provider = { provide: 'ApQuestionService', useExisting
$SignupService,
$WebAuthnService,
$UserBlockingService,
$UserReactionBlockingService,
$CacheService,
$UserService,
$UserFollowingService,

View File

@ -30,7 +30,6 @@ import { trackPromise } from '@/misc/promise-tracker.js';
import { isQuote, isRenote } from '@/misc/is-renote.js';
import { ReactionsBufferingService } from '@/core/ReactionsBufferingService.js';
import { PER_NOTE_REACTION_USER_PAIR_CACHE_MAX } from '@/const.js';
import { BlockingReactionUserService } from '@/core/BlockingReactionUserService.js';
const FALLBACK = '\u2764';
@ -92,7 +91,7 @@ export class ReactionService {
private userEntityService: UserEntityService,
private noteEntityService: NoteEntityService,
private userBlockingService: UserBlockingService,
private blockingReactionUserService: BlockingReactionUserService,
private userReactionBlockingService: UserBlockingService,
private reactionsBufferingService: ReactionsBufferingService,
private idService: IdService,
private featuredService: FeaturedService,
@ -109,7 +108,7 @@ export class ReactionService {
// Check blocking
if (note.userId !== user.id) {
const blocked = await this.userBlockingService.checkBlocked(note.userId, user.id);
const reactionBlocked = await this.blockingReactionUserService.checkBlocked(note.userId, user.id);
const reactionBlocked = await this.userReactionBlockingService.checkBlocked(note.userId, user.id);
if (blocked || reactionBlocked) {
throw new IdentifiableError('e70412a4-7197-4726-8e74-f3e0deb92aa7');
}

View File

@ -26,7 +26,6 @@ import { UserWebhookService } from '@/core/UserWebhookService.js';
import { bindThis } from '@/decorators.js';
import { CacheService } from '@/core/CacheService.js';
import { UserFollowingService } from '@/core/UserFollowingService.js';
import { UserReactionBlockingService } from '@/core/UserReactionBlockingService.js';
@Injectable()
export class UserBlockingService implements OnModuleInit {
@ -50,7 +49,6 @@ export class UserBlockingService implements OnModuleInit {
private cacheService: CacheService,
private userEntityService: UserEntityService,
private userReactionBlockingService: UserReactionBlockingService,
private idService: IdService,
private queueService: QueueService,
private globalEventService: GlobalEventService,
@ -93,7 +91,7 @@ export class UserBlockingService implements OnModuleInit {
});
if (blocking.blockType === MiBlockingType.Reaction) {
await this.userReactionBlockingService.unblock(blocker, blockee);
await this.reactionUnblock(blocker, blockee);
}
blocking.blockType = MiBlockingType.User;
await this.blockingsRepository.insert(blocking);
@ -216,4 +214,74 @@ export class UserBlockingService implements OnModuleInit {
public async checkBlocked(blockerId: MiUser['id'], blockeeId: MiUser['id']): Promise<boolean> {
return (await this.cacheService.userBlockingCache.fetch(blockerId)).has(blockeeId);
}
@bindThis
public async reactionBlock(blocker: MiUser, blockee: MiUser, silent = false) {
const blocking = await this.blockingsRepository.findOneBy({
blockerId: blocker.id,
blockeeId: blockee.id,
}).then(blocking => {
if (blocking) {
return blocking;
}
return {
id: this.idService.gen(),
blocker,
blockerId: blocker.id,
blockee,
blockeeId: blockee.id,
blockType: MiBlockingType.Reaction,
} as MiBlocking;
});
if (blocking.blockType === MiBlockingType.User) {
await this.unblock(blocker, blockee);
}
blocking.blockType = MiBlockingType.Reaction;
await this.blockingsRepository.insert(blocking);
this.cacheService.userReactionBlockingCache.refresh(blocker.id);
this.cacheService.userReactionBlockedCache.refresh(blockee.id);
this.globalEventService.publishInternalEvent('blockingReactionCreated', {
blockerId: blocker.id,
blockeeId: blockee.id,
});
}
@bindThis
public async reactionUnblock(blocker: MiUser, blockee: MiUser) {
const blocking = await this.blockingsRepository.findOneBy({
blockerId: blocker.id,
blockeeId: blockee.id,
blockType: MiBlockingType.Reaction,
});
if (blocking == null) {
this.logger.warn('Unblock requested, but the target was not blocked.');
return;
}
// Since we already have the blocker and blockee, we do not need to fetch
// them in the query above and can just manually insert them here.
blocking.blocker = blocker;
blocking.blockee = blockee;
await this.blockingsRepository.delete(blocking.id);
this.cacheService.userReactionBlockingCache.refresh(blocker.id);
this.cacheService.userReactionBlockedCache.refresh(blockee.id);
this.globalEventService.publishInternalEvent('blockingReactionDeleted', {
blockerId: blocker.id,
blockeeId: blockee.id,
});
}
@bindThis
public async checkReactionBlocked(blockerId: MiUser['id'], blockeeId: MiUser['id']): Promise<boolean> {
return (await this.cacheService.userReactionBlockingCache.fetch(blockerId)).has(blockeeId);
}
}

View File

@ -1,120 +0,0 @@
/*
* SPDX-FileCopyrightText: syuilo and misskey-project
* SPDX-License-Identifier: AGPL-3.0-only
*/
import { Inject, Injectable } from '@nestjs/common';
import { ModuleRef } from '@nestjs/core';
import { IdService } from '@/core/IdService.js';
import type { MiUser } from '@/models/User.js';
import type { MiBlocking } from '@/models/Blocking.js';
import { QueueService } from '@/core/QueueService.js';
import { GlobalEventService } from '@/core/GlobalEventService.js';
import { DI } from '@/di-symbols.js';
import type { BlockingsRepository, UserListsRepository } from '@/models/_.js';
import Logger from '@/logger.js';
import { UserEntityService } from '@/core/entities/UserEntityService.js';
import { ApRendererService } from '@/core/activitypub/ApRendererService.js';
import { LoggerService } from '@/core/LoggerService.js';
import { UserWebhookService } from '@/core/UserWebhookService.js';
import { bindThis } from '@/decorators.js';
import { CacheService } from '@/core/CacheService.js';
import { UserFollowingService } from '@/core/UserFollowingService.js';
import { MiBlockingType } from '@/models/Blocking.js';
import { UserBlockingService } from '@/core/UserBlockingService.js';
@Injectable()
export class UserReactionBlockingService {
private logger: Logger;
private userFollowingService: UserFollowingService;
constructor(
private moduleRef: ModuleRef,
@Inject(DI.blockingsRepository)
private blockingsRepository: BlockingsRepository,
@Inject(DI.userListsRepository)
private userListsRepository: UserListsRepository,
private cacheService: CacheService,
private userEntityService: UserEntityService,
private userBlockingService: UserBlockingService,
private idService: IdService,
private queueService: QueueService,
private globalEventService: GlobalEventService,
private webhookService: UserWebhookService,
private apRendererService: ApRendererService,
private loggerService: LoggerService,
) {
this.logger = this.loggerService.getLogger('user-block');
}
@bindThis
public async block(blocker: MiUser, blockee: MiUser, silent = false) {
const blocking = await this.blockingsRepository.findOneBy({
blockerId: blocker.id,
blockeeId: blockee.id,
}).then(blocking => {
if (blocking) {
return blocking;
}
return {
id: this.idService.gen(),
blocker,
blockerId: blocker.id,
blockee,
blockeeId: blockee.id,
blockType: MiBlockingType.Reaction,
} as MiBlocking;
});
if (blocking.blockType === MiBlockingType.User) {
await this.userBlockingService.unblock(blocker, blockee);
}
blocking.blockType = MiBlockingType.Reaction;
await this.blockingsRepository.insert(blocking);
this.cacheService.userReactionBlockingCache.refresh(blocker.id);
this.cacheService.userReactionBlockedCache.refresh(blockee.id);
this.globalEventService.publishInternalEvent('blockingReactionCreated', {
blockerId: blocker.id,
blockeeId: blockee.id,
});
}
@bindThis
public async unblock(blocker: MiUser, blockee: MiUser) {
const blocking = await this.blockingsRepository.findOneBy({
blockerId: blocker.id,
blockeeId: blockee.id,
blockType: MiBlockingType.Reaction,
});
if (blocking == null) {
this.logger.warn('Unblock requested, but the target was not blocked.');
return;
}
// Since we already have the blocker and blockee, we do not need to fetch
// them in the query above and can just manually insert them here.
blocking.blocker = blocker;
blocking.blockee = blockee;
await this.blockingsRepository.delete(blocking.id);
this.cacheService.userReactionBlockingCache.refresh(blocker.id);
this.cacheService.userReactionBlockedCache.refresh(blockee.id);
this.globalEventService.publishInternalEvent('blockingReactionDeleted', {
blockerId: blocker.id,
blockeeId: blockee.id,
});
}
@bindThis
public async checkBlocked(blockerId: MiUser['id'], blockeeId: MiUser['id']): Promise<boolean> {
return (await this.cacheService.userReactionBlockingCache.fetch(blockerId)).has(blockeeId);
}
}

View File

@ -11,7 +11,7 @@ import { MiBlockingType } from '@/models/_.js';
import { UserEntityService } from '@/core/entities/UserEntityService.js';
import { DI } from '@/di-symbols.js';
import { GetterService } from '@/server/api/GetterService.js';
import { UserReactionBlockingService } from '@/core/UserReactionBlockingService.js';
import { UserBlockingService } from '@/core/UserBlockingService.js';
import { ApiError } from '../../error.js';
export const meta = {
@ -72,7 +72,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
private userEntityService: UserEntityService,
private getterService: GetterService,
private userReactionBlockingService: UserReactionBlockingService,
private userBlockingService: UserBlockingService,
) {
super(meta, paramDef, async (ps, me) => {
const blocker = await this.usersRepository.findOneByOrFail({ id: me.id });
@ -101,7 +101,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
throw new ApiError(meta.errors.alreadyBlocking);
}
await this.userReactionBlockingService.block(blocker, blockee);
await this.userBlockingService.reactionBlock(blocker, blockee);
return await this.userEntityService.pack(blockee.id, blocker, {
schema: 'UserDetailedNotMe',

View File

@ -8,9 +8,9 @@ import { Inject, Injectable } from '@nestjs/common';
import { Endpoint } from '@/server/api/endpoint-base.js';
import type { UsersRepository, BlockingsRepository, MiBlockingType } from '@/models/_.js';
import { UserEntityService } from '@/core/entities/UserEntityService.js';
import { UserReactionBlockingService } from '@/core/UserReactionBlockingService.js';
import { DI } from '@/di-symbols.js';
import { GetterService } from '@/server/api/GetterService.js';
import { UserBlockingService } from '@/core/UserBlockingService.js';
import { ApiError } from '../../error.js';
export const meta = {
@ -71,7 +71,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
private userEntityService: UserEntityService,
private getterService: GetterService,
private userReactionBlockingService: UserReactionBlockingService,
private userBlockingService: UserBlockingService,
) {
super(meta, paramDef, async (ps, me) => {
const blocker = await this.usersRepository.findOneByOrFail({ id: me.id });
@ -101,7 +101,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
}
// Delete blocking
await this.userReactionBlockingService.unblock(blocker, blockee);
await this.userBlockingService.reactionUnblock(blocker, blockee);
return await this.userEntityService.pack(blockee.id, blocker, {
schema: 'UserDetailedNotMe',

View File

@ -4515,7 +4515,8 @@ export type components = {
/** Format: id */
blockeeId: string;
blockee: components['schemas']['UserDetailedNotMe'];
isReactionBlock: boolean;
/** @enum {string} */
blockType: 'user' | 'reaction';
};
Hashtag: {
/** @example misskey */