From cfa573a3a1cffa9d24aa790d551d13e6a40bd958 Mon Sep 17 00:00:00 2001
From: MeiMei <30769358+mei23@users.noreply.github.com>
Date: Fri, 16 Feb 2024 14:30:53 +0900
Subject: [PATCH] =?UTF-8?q?=E3=83=AA=E3=83=A2=E3=83=BC=E3=83=88=E3=83=A6?=
 =?UTF-8?q?=E3=83=BC=E3=82=B6=E3=83=BC=E3=81=8C=E5=BE=A9=E6=B4=BB=E3=81=97?=
 =?UTF-8?q?=E3=81=A6=E3=82=82=E3=82=AD=E3=83=A3=E3=83=83=E3=82=B7=E3=83=A5?=
 =?UTF-8?q?=E3=81=AB=E3=82=88=E3=82=8A=E8=A9=B2=E5=BD=93=E3=83=A6=E3=83=BC?=
 =?UTF-8?q?=E3=82=B6=E3=83=BC=E3=81=AEActivity=E3=81=8C=E5=8F=97=E3=81=91?=
 =?UTF-8?q?=E5=85=A5=E3=82=8C=E3=82=89=E3=82=8C=E3=81=AA=E3=81=84=E3=81=AE?=
 =?UTF-8?q?=E3=82=92=E4=BF=AE=E6=AD=A3=20Fix=20#13273=20(#13275)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* リモートユーザーが復活してもキャッシュにより該当ユーザーのActivityが受け入れられないのを修正 Fix #13273

* CHAGELOG

* Use Redis event

---------

Co-authored-by: tamaina <tamaina@hotmail.co.jp>
---
 CHANGELOG.md                                  |  1 +
 packages/backend/src/core/CacheService.ts     | 28 +++++++++++++------
 .../core/activitypub/ApDbResolverService.ts   | 11 ++++++--
 .../src/core/activitypub/ApInboxService.ts    |  6 ++++
 4 files changed, 34 insertions(+), 12 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index f41188a4da..8da8d3faca 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -92,6 +92,7 @@
 - Fix: ジョブに関する設定の名前を修正 relashionshipJobPerSec -> relationshipJobPerSec
 - Fix: コントロールパネル->モデレーション->「誰でも新規登録できるようにする」の初期値をONからOFFに変更 #13122
 - Enhance: 連合向けのノート配信を軽量化 #13192
+- Fix: リモートユーザーが復活してもキャッシュにより該当ユーザーのActivityが受け入れられないのを修正 #13273
 
 ### Service Worker
 - Enhance: オフライン表示のデザインを改善・多言語対応
diff --git a/packages/backend/src/core/CacheService.ts b/packages/backend/src/core/CacheService.ts
index ef3abec191..78bb4f70e9 100644
--- a/packages/backend/src/core/CacheService.ts
+++ b/packages/backend/src/core/CacheService.ts
@@ -85,6 +85,7 @@ export class CacheService implements OnApplicationShutdown {
 		this.uriPersonCache = new MemoryKVCache<MiUser | null, string | null>(Infinity, {
 			toMapConverter: user => {
 				if (user === null) return null;
+				if (user.isDeleted) return null;
 
 				userByIdCache.set(user.id, user);
 				return user.id;
@@ -160,16 +161,25 @@ export class CacheService implements OnApplicationShutdown {
 			switch (type) {
 				case 'userChangeSuspendedState':
 				case 'remoteUserUpdated': {
-					const user = await this.usersRepository.findOneByOrFail({ id: body.id });
-					this.userByIdCache.set(user.id, user);
-					for (const [k, v] of this.uriPersonCache.cache.entries()) {
-						if (v.value === user.id) {
-							this.uriPersonCache.set(k, user);
+					const user = await this.usersRepository.findOneBy({ id: body.id });
+					if (user == null) {
+						this.userByIdCache.delete(body.id);
+						for (const [k, v] of this.uriPersonCache.cache.entries()) {
+							if (v.value === body.id) {
+								this.uriPersonCache.delete(k);
+							}
+						}
+					} else {
+						this.userByIdCache.set(user.id, user);
+						for (const [k, v] of this.uriPersonCache.cache.entries()) {
+							if (v.value === user.id) {
+								this.uriPersonCache.set(k, user);
+							}
+						}
+						if (this.userEntityService.isLocalUser(user)) {
+							this.localUserByNativeTokenCache.set(user.token!, user);
+							this.localUserByIdCache.set(user.id, user);
 						}
-					}
-					if (this.userEntityService.isLocalUser(user)) {
-						this.localUserByNativeTokenCache.set(user.token!, user);
-						this.localUserByIdCache.set(user.id, user);
 					}
 					break;
 				}
diff --git a/packages/backend/src/core/activitypub/ApDbResolverService.ts b/packages/backend/src/core/activitypub/ApDbResolverService.ts
index 143f89c368..f6b70ead44 100644
--- a/packages/backend/src/core/activitypub/ApDbResolverService.ts
+++ b/packages/backend/src/core/activitypub/ApDbResolverService.ts
@@ -106,12 +106,12 @@ export class ApDbResolverService implements OnApplicationShutdown {
 
 			return await this.cacheService.userByIdCache.fetchMaybe(
 				parsed.id,
-				() => this.usersRepository.findOneBy({ id: parsed.id }).then(x => x ?? undefined),
+				() => this.usersRepository.findOneBy({ id: parsed.id, isDeleted: false }).then(x => x ?? undefined),
 			) as MiLocalUser | undefined ?? null;
 		} else {
 			return await this.cacheService.uriPersonCache.fetch(
 				parsed.uri,
-				() => this.usersRepository.findOneBy({ uri: parsed.uri }),
+				() => this.usersRepository.findOneBy({ uri: parsed.uri, isDeleted: false }),
 			) as MiRemoteUser | null;
 		}
 	}
@@ -136,8 +136,12 @@ export class ApDbResolverService implements OnApplicationShutdown {
 
 		if (key == null) return null;
 
+		const user = await this.cacheService.findUserById(key.userId).catch(() => null) as MiRemoteUser | null;
+		if (user == null) return null;
+		if (user.isDeleted) return null;
+
 		return {
-			user: await this.cacheService.findUserById(key.userId) as MiRemoteUser,
+			user,
 			key,
 		};
 	}
@@ -151,6 +155,7 @@ export class ApDbResolverService implements OnApplicationShutdown {
 		key: MiUserPublickey | null;
 	} | null> {
 		const user = await this.apPersonService.resolvePerson(uri) as MiRemoteUser;
+		if (user.isDeleted) return null;
 
 		const key = await this.publicKeyByUserIdCache.fetch(
 			user.id,
diff --git a/packages/backend/src/core/activitypub/ApInboxService.ts b/packages/backend/src/core/activitypub/ApInboxService.ts
index 526b04b292..1cc54b6ff6 100644
--- a/packages/backend/src/core/activitypub/ApInboxService.ts
+++ b/packages/backend/src/core/activitypub/ApInboxService.ts
@@ -35,6 +35,8 @@ import { ApResolverService } from './ApResolverService.js';
 import { ApAudienceService } from './ApAudienceService.js';
 import { ApPersonService } from './models/ApPersonService.js';
 import { ApQuestionService } from './models/ApQuestionService.js';
+import { CacheService } from '@/core/CacheService.js';
+import { GlobalEventService } from '@/core/GlobalEventService.js';
 import type { Resolver } from './ApResolverService.js';
 import type { IAccept, IAdd, IAnnounce, IBlock, ICreate, IDelete, IFlag, IFollow, ILike, IObject, IReject, IRemove, IUndo, IUpdate, IMove } from './type.js';
 
@@ -82,6 +84,8 @@ export class ApInboxService {
 		private apPersonService: ApPersonService,
 		private apQuestionService: ApQuestionService,
 		private queueService: QueueService,
+		private cacheService: CacheService,
+		private globalEventService: GlobalEventService,
 	) {
 		this.logger = this.apLoggerService.logger;
 	}
@@ -479,6 +483,8 @@ export class ApInboxService {
 			isDeleted: true,
 		});
 
+		this.globalEventService.publishInternalEvent('remoteUserUpdated', { id: actor.id });
+
 		return `ok: queued ${job.name} ${job.id}`;
 	}
 
-- 
GitLab