nanka meccha kaeta

This commit is contained in:
tamaina 2024-02-21 16:52:20 +00:00
parent aefcc40a35
commit 9c3647731b
4 changed files with 39 additions and 34 deletions

View File

@ -30,6 +30,7 @@ import type { Config } from '@/config.js';
import { AccountMoveService } from '@/core/AccountMoveService.js'; import { AccountMoveService } from '@/core/AccountMoveService.js';
import { UtilityService } from '@/core/UtilityService.js'; import { UtilityService } from '@/core/UtilityService.js';
import { FanoutTimelineService } from '@/core/FanoutTimelineService.js'; import { FanoutTimelineService } from '@/core/FanoutTimelineService.js';
import type { ThinUser } from '@/queue/types.js';
import Logger from '../logger.js'; import Logger from '../logger.js';
const logger = new Logger('following/create'); const logger = new Logger('following/create');
@ -100,40 +101,55 @@ export class UserFollowingService implements OnModuleInit {
this.queueService.deliver(followee, content, follower.inbox, false); this.queueService.deliver(followee, content, follower.inbox, false);
} }
/**
* ThinUserでなくともユーザーの情報が最新でない場合はこちらを使うべき
*/
@bindThis @bindThis
public async followFromRemote( public async followByThinUser(
follower: MiRemoteUser, _follower: ThinUser,
followee: MiLocalUser, _followee: ThinUser,
options: { requestId?: string } = {}, options: Parameters<typeof this.follow>[2] = {},
) { ) {
if (await this.followingsRepository.exists({ const [follower, followee] = await Promise.all([
where: { this.usersRepository.findOneByOrFail({ id: _follower.id }),
followerId: follower.id, this.usersRepository.findOneByOrFail({ id: _followee.id }),
followeeId: followee.id, ]) as [MiLocalUser | MiRemoteUser, MiLocalUser | MiRemoteUser];
},
})) {
// すでにフォロー関係が存在している場合、acceptを送り返しておしまい
this.deliverAccept(follower, followee, options.requestId);
return;
}
await this.follow(follower, followee, options); await this.follow(follower, followee, options);
} }
@bindThis @bindThis
public async follow( public async follow(
_follower: { id: MiUser['id'] }, follower: MiLocalUser | MiRemoteUser,
_followee: { id: MiUser['id'] }, followee: MiLocalUser | MiRemoteUser,
{ requestId, silent = false, withReplies }: { { requestId, silent = false, withReplies }: {
requestId?: string, requestId?: string,
silent?: boolean, silent?: boolean,
withReplies?: boolean, withReplies?: boolean,
} = {}, } = {},
): Promise<void> { ): Promise<void> {
const [follower, followee] = await Promise.all([ if (this.userEntityService.isRemoteUser(follower) && this.userEntityService.isRemoteUser(followee)) {
this.usersRepository.findOneByOrFail({ id: _follower.id }), // What?
this.usersRepository.findOneByOrFail({ id: _followee.id }), throw new Error('Remote user cannot follow remote user.');
]) as [MiLocalUser | MiRemoteUser, MiLocalUser | MiRemoteUser]; }
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');
}
}
// check blocking // check blocking
const [blocking, blocked] = await Promise.all([ const [blocking, blocked] = await Promise.all([

View File

@ -170,7 +170,7 @@ export class ApInboxService {
} }
// don't queue because the sender may attempt again when timeout // don't queue because the sender may attempt again when timeout
await this.userFollowingService.followFromRemote(actor, followee, { requestId: activity.id }); await this.userFollowingService.follow(actor, followee, { requestId: activity.id });
return 'ok'; return 'ok';
} }

View File

@ -35,7 +35,7 @@ export class RelationshipProcessorService {
@bindThis @bindThis
public async processFollow(job: Bull.Job<RelationshipJobData>): Promise<string> { public async processFollow(job: Bull.Job<RelationshipJobData>): Promise<string> {
this.logger.info(`${job.data.from.id} is trying to follow ${job.data.to.id} ${job.data.withReplies ? "with replies" : "without replies"}`); this.logger.info(`${job.data.from.id} is trying to follow ${job.data.to.id} ${job.data.withReplies ? "with replies" : "without replies"}`);
await this.userFollowingService.follow(job.data.from, job.data.to, { await this.userFollowingService.followByThinUser(job.data.from, job.data.to, {
requestId: job.data.requestId, requestId: job.data.requestId,
silent: job.data.silent, silent: job.data.silent,
withReplies: job.data.withReplies, withReplies: job.data.withReplies,

View File

@ -100,22 +100,11 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
throw err; throw err;
}); });
// Check if already following
const exist = await this.followingsRepository.exists({
where: {
followerId: follower.id,
followeeId: followee.id,
},
});
if (exist) {
throw new ApiError(meta.errors.alreadyFollowing);
}
try { try {
await this.userFollowingService.follow(follower, followee, { withReplies: ps.withReplies }); await this.userFollowingService.follow(follower, followee, { withReplies: ps.withReplies });
} catch (e) { } catch (e) {
if (e instanceof IdentifiableError) { if (e instanceof IdentifiableError) {
if (e.id === 'ec3f65c0-a9d1-47d9-8791-b2e7b9dcdced') throw new ApiError(meta.errors.alreadyFollowing);
if (e.id === '710e8fb0-b8c3-4922-be49-d5d93d8e6a6e') throw new ApiError(meta.errors.blocking); if (e.id === '710e8fb0-b8c3-4922-be49-d5d93d8e6a6e') throw new ApiError(meta.errors.blocking);
if (e.id === '3338392a-f764-498d-8855-db939dcf8c48') throw new ApiError(meta.errors.blocked); if (e.id === '3338392a-f764-498d-8855-db939dcf8c48') throw new ApiError(meta.errors.blocked);
} }