summaryrefslogtreecommitdiff
path: root/packages/backend/src/core/UserFollowingService.ts
diff options
context:
space:
mode:
authorsyuilo <4439005+syuilo@users.noreply.github.com>2024-03-01 21:17:01 +0900
committerGitHub <noreply@github.com>2024-03-01 21:17:01 +0900
commit7e706ea6693781fb8973800bb3d0c91b5ab91cdf (patch)
tree8abd91edd288284cf3cc47949e749f881cfaff8e /packages/backend/src/core/UserFollowingService.ts
parentMerge pull request #13045 from misskey-dev/develop (diff)
parentNew translations ja-jp.yml (Chinese Traditional) (#13480) (diff)
downloadsharkey-7e706ea6693781fb8973800bb3d0c91b5ab91cdf.tar.gz
sharkey-7e706ea6693781fb8973800bb3d0c91b5ab91cdf.tar.bz2
sharkey-7e706ea6693781fb8973800bb3d0c91b5ab91cdf.zip
Merge pull request #13447 from misskey-dev/develop
Release: 2024.3.0
Diffstat (limited to 'packages/backend/src/core/UserFollowingService.ts')
-rw-r--r--packages/backend/src/core/UserFollowingService.ts43
1 files changed, 37 insertions, 6 deletions
diff --git a/packages/backend/src/core/UserFollowingService.ts b/packages/backend/src/core/UserFollowingService.ts
index 8ad85391c6..0a492c06e4 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,20 +96,34 @@ 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);
+ }
+
+ @bindThis
public async follow(
- _follower: { id: MiUser['id'] },
- _followee: { id: MiUser['id'] },
+ _follower: ThinUser,
+ _followee: ThinUser,
{ 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([
this.userBlockingService.checkBlocked(follower.id, followee.id),
@@ -129,6 +144,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 +222,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 +603,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, {