summaryrefslogtreecommitdiff
path: root/packages/backend/src/core
diff options
context:
space:
mode:
authortamaina <tamaina@hotmail.co.jp>2024-02-23 18:04:30 +0900
committerGitHub <noreply@github.com>2024-02-23 18:04:30 +0900
commit600d91beda206fa22cfa1c1a3f94ca9e5a0cac68 (patch)
tree8dd8ec865956a71c077a7c86ea71980fc96a0e00 /packages/backend/src/core
parentfix(backend): より多くの人に使われているハッシュタグが検... (diff)
downloadsharkey-600d91beda206fa22cfa1c1a3f94ca9e5a0cac68.tar.gz
sharkey-600d91beda206fa22cfa1c1a3f94ca9e5a0cac68.tar.bz2
sharkey-600d91beda206fa22cfa1c1a3f94ca9e5a0cac68.zip
enhance: リモートのフォロワーから再度Followが来た場合、acceptを返してあげる (#13388)
* enhance: リモートのフォロワーから再度Followが来た場合、acceptを返してあげる * nanka meccha kaeta * ブロックチェックの後にフォロー関係の存在チェックをする
Diffstat (limited to 'packages/backend/src/core')
-rw-r--r--packages/backend/src/core/UserFollowingService.ts60
1 files changed, 50 insertions, 10 deletions
diff --git a/packages/backend/src/core/UserFollowingService.ts b/packages/backend/src/core/UserFollowingService.ts
index 8ad85391c6..d87cbacdcb 100644
--- a/packages/backend/src/core/UserFollowingService.ts
+++ b/packages/backend/src/core/UserFollowingService.ts
@@ -30,6 +30,7 @@ import type { Config } from '@/config.js';
import { AccountMoveService } from '@/core/AccountMoveService.js';
import { UtilityService } from '@/core/UtilityService.js';
import { FanoutTimelineService } from '@/core/FanoutTimelineService.js';
+import type { ThinUser } from '@/queue/types.js';
import Logger from '../logger.js';
const logger = new Logger('following/create');
@@ -95,19 +96,42 @@ export class UserFollowingService implements OnModuleInit {
}
@bindThis
+ public async deliverAccept(follower: MiRemoteUser, followee: MiPartialLocalUser, requestId?: string) {
+ const content = this.apRendererService.addContext(this.apRendererService.renderAccept(this.apRendererService.renderFollow(follower, followee, requestId), followee));
+ this.queueService.deliver(followee, content, follower.inbox, false);
+ }
+
+ /**
+ * ThinUserでなくともユーザーの情報が最新でない場合はこちらを使うべき
+ */
+ @bindThis
+ public async followByThinUser(
+ _follower: ThinUser,
+ _followee: ThinUser,
+ options: Parameters<typeof this.follow>[2] = {},
+ ) {
+ const [follower, followee] = await Promise.all([
+ this.usersRepository.findOneByOrFail({ id: _follower.id }),
+ this.usersRepository.findOneByOrFail({ id: _followee.id }),
+ ]) as [MiLocalUser | MiRemoteUser, MiLocalUser | MiRemoteUser];
+
+ await this.follow(follower, followee, options);
+ }
+
+ @bindThis
public async follow(
- _follower: { id: MiUser['id'] },
- _followee: { id: MiUser['id'] },
+ follower: MiLocalUser | MiRemoteUser,
+ followee: MiLocalUser | MiRemoteUser,
{ requestId, silent = false, withReplies }: {
requestId?: string,
silent?: boolean,
withReplies?: boolean,
} = {},
): Promise<void> {
- const [follower, followee] = await Promise.all([
- this.usersRepository.findOneByOrFail({ id: _follower.id }),
- this.usersRepository.findOneByOrFail({ id: _followee.id }),
- ]) as [MiLocalUser | MiRemoteUser, MiLocalUser | MiRemoteUser];
+ if (this.userEntityService.isRemoteUser(follower) && this.userEntityService.isRemoteUser(followee)) {
+ // What?
+ throw new Error('Remote user cannot follow remote user.');
+ }
// check blocking
const [blocking, blocked] = await Promise.all([
@@ -129,6 +153,24 @@ export class UserFollowingService implements OnModuleInit {
if (blocked) throw new IdentifiableError('3338392a-f764-498d-8855-db939dcf8c48', 'blocked');
}
+ if (await this.followingsRepository.exists({
+ where: {
+ followerId: follower.id,
+ followeeId: followee.id,
+ },
+ })) {
+ // すでにフォロー関係が存在している場合
+ if (this.userEntityService.isRemoteUser(follower) && this.userEntityService.isLocalUser(followee)) {
+ // リモート → ローカル: acceptを送り返しておしまい
+ this.deliverAccept(follower, followee, requestId);
+ return;
+ }
+ if (this.userEntityService.isLocalUser(follower)) {
+ // ローカル → リモート/ローカル: 例外
+ throw new IdentifiableError('ec3f65c0-a9d1-47d9-8791-b2e7b9dcdced', 'already following');
+ }
+ }
+
const followeeProfile = await this.userProfilesRepository.findOneByOrFail({ userId: followee.id });
// フォロー対象が鍵アカウントである or
// フォロワーがBotであり、フォロー対象がBotからのフォローに慎重である or
@@ -189,8 +231,7 @@ export class UserFollowingService implements OnModuleInit {
await this.insertFollowingDoc(followee, follower, silent, withReplies);
if (this.userEntityService.isRemoteUser(follower) && this.userEntityService.isLocalUser(followee)) {
- const content = this.apRendererService.addContext(this.apRendererService.renderAccept(this.apRendererService.renderFollow(follower, followee, requestId), followee));
- this.queueService.deliver(followee, content, follower.inbox, false);
+ this.deliverAccept(follower, followee, requestId);
}
}
@@ -571,8 +612,7 @@ export class UserFollowingService implements OnModuleInit {
await this.insertFollowingDoc(followee, follower, false, request.withReplies);
if (this.userEntityService.isRemoteUser(follower) && this.userEntityService.isLocalUser(followee)) {
- const content = this.apRendererService.addContext(this.apRendererService.renderAccept(this.apRendererService.renderFollow(follower, followee as MiPartialLocalUser, request.requestId!), followee));
- this.queueService.deliver(followee, content, follower.inbox, false);
+ this.deliverAccept(follower, followee as MiPartialLocalUser, request.requestId ?? undefined);
}
this.userEntityService.pack(followee.id, followee, {