mirror of
https://codeberg.org/yeentown/barkey.git
synced 2025-07-07 20:44:34 +00:00
merge: Don't unfollow suspended users (!1122)
View MR for information: https://activitypub.software/TransFem-org/Sharkey/-/merge_requests/1122 Approved-by: dakkar <dakkar@thenautilus.net> Approved-by: Marie <github@yuugi.dev>
This commit is contained in:
commit
e80187b8f1
1 changed files with 64 additions and 20 deletions
|
@ -6,7 +6,7 @@
|
||||||
import { Inject, Injectable } from '@nestjs/common';
|
import { Inject, Injectable } from '@nestjs/common';
|
||||||
import { Not, IsNull } from 'typeorm';
|
import { Not, IsNull } from 'typeorm';
|
||||||
import type { FollowingsRepository, FollowRequestsRepository, UsersRepository } from '@/models/_.js';
|
import type { FollowingsRepository, FollowRequestsRepository, UsersRepository } from '@/models/_.js';
|
||||||
import type { MiUser } from '@/models/User.js';
|
import { MiUser } from '@/models/User.js';
|
||||||
import { QueueService } from '@/core/QueueService.js';
|
import { QueueService } from '@/core/QueueService.js';
|
||||||
import { GlobalEventService } from '@/core/GlobalEventService.js';
|
import { GlobalEventService } from '@/core/GlobalEventService.js';
|
||||||
import { DI } from '@/di-symbols.js';
|
import { DI } from '@/di-symbols.js';
|
||||||
|
@ -17,9 +17,15 @@ import { RelationshipJobData } from '@/queue/types.js';
|
||||||
import { ModerationLogService } from '@/core/ModerationLogService.js';
|
import { ModerationLogService } from '@/core/ModerationLogService.js';
|
||||||
import { isSystemAccount } from '@/misc/is-system-account.js';
|
import { isSystemAccount } from '@/misc/is-system-account.js';
|
||||||
import { CacheService } from '@/core/CacheService.js';
|
import { CacheService } from '@/core/CacheService.js';
|
||||||
|
import { LoggerService } from '@/core/LoggerService.js';
|
||||||
|
import type Logger from '@/logger.js';
|
||||||
|
import { renderInlineError } from '@/misc/render-inline-error.js';
|
||||||
|
import { trackPromise } from '@/misc/promise-tracker.js';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class UserSuspendService {
|
export class UserSuspendService {
|
||||||
|
private readonly logger: Logger;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@Inject(DI.usersRepository)
|
@Inject(DI.usersRepository)
|
||||||
private usersRepository: UsersRepository,
|
private usersRepository: UsersRepository,
|
||||||
|
@ -36,7 +42,10 @@ export class UserSuspendService {
|
||||||
private apRendererService: ApRendererService,
|
private apRendererService: ApRendererService,
|
||||||
private moderationLogService: ModerationLogService,
|
private moderationLogService: ModerationLogService,
|
||||||
private readonly cacheService: CacheService,
|
private readonly cacheService: CacheService,
|
||||||
|
|
||||||
|
loggerService: LoggerService,
|
||||||
) {
|
) {
|
||||||
|
this.logger = loggerService.getLogger('user-suspend');
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
|
@ -47,16 +56,16 @@ export class UserSuspendService {
|
||||||
isSuspended: true,
|
isSuspended: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
this.moderationLogService.log(moderator, 'suspend', {
|
await this.moderationLogService.log(moderator, 'suspend', {
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
userUsername: user.username,
|
userUsername: user.username,
|
||||||
userHost: user.host,
|
userHost: user.host,
|
||||||
});
|
});
|
||||||
|
|
||||||
(async () => {
|
trackPromise((async () => {
|
||||||
await this.postSuspend(user).catch(e => {});
|
await this.postSuspend(user);
|
||||||
await this.unFollowAll(user).catch(e => {});
|
await this.freezeAll(user);
|
||||||
})();
|
})().catch(e => this.logger.error(`Error suspending user ${user.id}: ${renderInlineError(e)}`)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
|
@ -65,33 +74,36 @@ export class UserSuspendService {
|
||||||
isSuspended: false,
|
isSuspended: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
this.moderationLogService.log(moderator, 'unsuspend', {
|
await this.moderationLogService.log(moderator, 'unsuspend', {
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
userUsername: user.username,
|
userUsername: user.username,
|
||||||
userHost: user.host,
|
userHost: user.host,
|
||||||
});
|
});
|
||||||
|
|
||||||
(async () => {
|
trackPromise((async () => {
|
||||||
await this.postUnsuspend(user).catch(e => {});
|
await this.postUnsuspend(user);
|
||||||
})();
|
await this.unFreezeAll(user);
|
||||||
|
})().catch(e => this.logger.error(`Error un-suspending for user ${user.id}: ${renderInlineError(e)}`)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
private async postSuspend(user: { id: MiUser['id']; host: MiUser['host'] }): Promise<void> {
|
private async postSuspend(user: { id: MiUser['id']; host: MiUser['host'] }): Promise<void> {
|
||||||
this.globalEventService.publishInternalEvent('userChangeSuspendedState', { id: user.id, isSuspended: true });
|
this.globalEventService.publishInternalEvent('userChangeSuspendedState', { id: user.id, isSuspended: true });
|
||||||
|
|
||||||
|
/*
|
||||||
this.followRequestsRepository.delete({
|
this.followRequestsRepository.delete({
|
||||||
followeeId: user.id,
|
followeeId: user.id,
|
||||||
});
|
});
|
||||||
this.followRequestsRepository.delete({
|
this.followRequestsRepository.delete({
|
||||||
followerId: user.id,
|
followerId: user.id,
|
||||||
});
|
});
|
||||||
|
*/
|
||||||
|
|
||||||
if (this.userEntityService.isLocalUser(user)) {
|
if (this.userEntityService.isLocalUser(user)) {
|
||||||
// 知り得る全SharedInboxにDelete配信
|
// 知り得る全SharedInboxにDelete配信
|
||||||
const content = this.apRendererService.addContext(this.apRendererService.renderDelete(this.userEntityService.genLocalUserUri(user.id), user));
|
const content = this.apRendererService.addContext(this.apRendererService.renderDelete(this.userEntityService.genLocalUserUri(user.id), user));
|
||||||
|
|
||||||
const queue: string[] = [];
|
const queue = new Map<string, boolean>();
|
||||||
|
|
||||||
const followings = await this.followingsRepository.find({
|
const followings = await this.followingsRepository.find({
|
||||||
where: [
|
where: [
|
||||||
|
@ -104,12 +116,12 @@ export class UserSuspendService {
|
||||||
const inboxes = followings.map(x => x.followerSharedInbox ?? x.followeeSharedInbox);
|
const inboxes = followings.map(x => x.followerSharedInbox ?? x.followeeSharedInbox);
|
||||||
|
|
||||||
for (const inbox of inboxes) {
|
for (const inbox of inboxes) {
|
||||||
if (inbox != null && !queue.includes(inbox)) queue.push(inbox);
|
if (inbox != null) {
|
||||||
|
queue.set(inbox, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const inbox of queue) {
|
await this.queueService.deliverMany(user, content, queue);
|
||||||
this.queueService.deliver(user, content, inbox, true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,7 +133,7 @@ export class UserSuspendService {
|
||||||
// 知り得る全SharedInboxにUndo Delete配信
|
// 知り得る全SharedInboxにUndo Delete配信
|
||||||
const content = this.apRendererService.addContext(this.apRendererService.renderUndo(this.apRendererService.renderDelete(this.userEntityService.genLocalUserUri(user.id), user), user));
|
const content = this.apRendererService.addContext(this.apRendererService.renderUndo(this.apRendererService.renderDelete(this.userEntityService.genLocalUserUri(user.id), user), user));
|
||||||
|
|
||||||
const queue: string[] = [];
|
const queue = new Map<string, boolean>();
|
||||||
|
|
||||||
const followings = await this.followingsRepository.find({
|
const followings = await this.followingsRepository.find({
|
||||||
where: [
|
where: [
|
||||||
|
@ -134,12 +146,12 @@ export class UserSuspendService {
|
||||||
const inboxes = followings.map(x => x.followerSharedInbox ?? x.followeeSharedInbox);
|
const inboxes = followings.map(x => x.followerSharedInbox ?? x.followeeSharedInbox);
|
||||||
|
|
||||||
for (const inbox of inboxes) {
|
for (const inbox of inboxes) {
|
||||||
if (inbox != null && !queue.includes(inbox)) queue.push(inbox);
|
if (inbox != null) {
|
||||||
|
queue.set(inbox, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const inbox of queue) {
|
await this.queueService.deliverMany(user, content, queue);
|
||||||
this.queueService.deliver(user as any, content, inbox, true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,4 +172,36 @@ export class UserSuspendService {
|
||||||
}
|
}
|
||||||
this.queueService.createUnfollowJob(jobs);
|
this.queueService.createUnfollowJob(jobs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@bindThis
|
||||||
|
private async freezeAll(user: MiUser): Promise<void> {
|
||||||
|
// Freeze follow relations with all remote users
|
||||||
|
await this.followingsRepository
|
||||||
|
.createQueryBuilder('following')
|
||||||
|
.orWhere({
|
||||||
|
followeeId: user.id,
|
||||||
|
followerHost: Not(IsNull()),
|
||||||
|
})
|
||||||
|
.update({
|
||||||
|
isFollowerHibernated: true,
|
||||||
|
})
|
||||||
|
.execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
@bindThis
|
||||||
|
private async unFreezeAll(user: MiUser): Promise<void> {
|
||||||
|
// Restore follow relations with all remote users
|
||||||
|
await this.followingsRepository
|
||||||
|
.createQueryBuilder('following')
|
||||||
|
.innerJoin(MiUser, 'follower', 'user.id = following.followerId')
|
||||||
|
.andWhere('follower.isHibernated = false') // Don't unfreeze if the follower is *actually* frozen
|
||||||
|
.andWhere({
|
||||||
|
followeeId: user.id,
|
||||||
|
followerHost: Not(IsNull()),
|
||||||
|
})
|
||||||
|
.update({
|
||||||
|
isFollowerHibernated: false,
|
||||||
|
})
|
||||||
|
.execute();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue