From 1c7007449d0bba443e2e260c26bf10b6cc14a65e Mon Sep 17 00:00:00 2001 From: tamaina Date: Sat, 9 Mar 2024 08:50:52 +0000 Subject: [PATCH 1/7] =?UTF-8?q?fix(federation):=20Announce=E3=81=AEobject?= =?UTF-8?q?=E3=81=8CLike=E5=87=BA=E3=81=AA=E3=81=8B=E3=81=A3=E3=81=9F?= =?UTF-8?q?=E3=82=89=E3=82=AD=E3=83=A5=E3=83=BC=E3=81=AB=E3=81=9F=E3=82=81?= =?UTF-8?q?=E3=81=AA=E3=81=84=20Fix=20https://github.com/misskey-dev/missk?= =?UTF-8?q?ey/issues/13552?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/core/activitypub/ApInboxService.ts | 56 ++++++++++--------- .../core/activitypub/models/ApNoteService.ts | 8 +-- .../queue/processors/InboxProcessorService.ts | 12 +++- 3 files changed, 45 insertions(+), 31 deletions(-) diff --git a/packages/backend/src/core/activitypub/ApInboxService.ts b/packages/backend/src/core/activitypub/ApInboxService.ts index 1621c41bcc54..783b99dbde68 100644 --- a/packages/backend/src/core/activitypub/ApInboxService.ts +++ b/packages/backend/src/core/activitypub/ApInboxService.ts @@ -90,13 +90,15 @@ export class ApInboxService { } @bindThis - public async performActivity(actor: MiRemoteUser, activity: IObject): Promise { + public async performActivity(actor: MiRemoteUser, activity: IObject): Promise { + let reason = undefined as string | void; if (isCollectionOrOrderedCollection(activity)) { + const reasons = [] as [string, string | void][]; const resolver = this.apResolverService.createResolver(); for (const item of toArray(isCollection(activity) ? activity.items : activity.orderedItems)) { const act = await resolver.resolve(item); try { - await this.performOneActivity(actor, act); + reasons.push([getApId(item), await this.performOneActivity(actor, act)]); } catch (err) { if (err instanceof Error || typeof err === 'string') { this.logger.error(err); @@ -105,52 +107,56 @@ export class ApInboxService { } } } + + const hasReason = reasons.some(([, reason]) => reason != null); + if (hasReason) { + reason = reasons.map(([id, reason]) => `${id}: ${reason}`).join('\n'); + } } else { - await this.performOneActivity(actor, activity); + reason = await this.performOneActivity(actor, activity); } // ついでにリモートユーザーの情報が古かったら更新しておく if (actor.uri) { if (actor.lastFetchedAt == null || Date.now() - actor.lastFetchedAt.getTime() > 1000 * 60 * 60 * 24) { - setImmediate(() => { - this.apPersonService.updatePerson(actor.uri); - }); + await this.apPersonService.updatePerson(actor.uri); } } + return reason; } @bindThis - public async performOneActivity(actor: MiRemoteUser, activity: IObject): Promise { + public async performOneActivity(actor: MiRemoteUser, activity: IObject): Promise { if (actor.isSuspended) return; if (isCreate(activity)) { - await this.create(actor, activity); + return await this.create(actor, activity); } else if (isDelete(activity)) { - await this.delete(actor, activity); + return await this.delete(actor, activity); } else if (isUpdate(activity)) { - await this.update(actor, activity); + return await this.update(actor, activity); } else if (isFollow(activity)) { - await this.follow(actor, activity); + return await this.follow(actor, activity); } else if (isAccept(activity)) { - await this.accept(actor, activity); + return await this.accept(actor, activity); } else if (isReject(activity)) { - await this.reject(actor, activity); + return await this.reject(actor, activity); } else if (isAdd(activity)) { - await this.add(actor, activity).catch(err => this.logger.error(err)); + return await this.add(actor, activity).catch(err => this.logger.error(err)); } else if (isRemove(activity)) { - await this.remove(actor, activity).catch(err => this.logger.error(err)); + return await this.remove(actor, activity).catch(err => this.logger.error(err)); } else if (isAnnounce(activity)) { - await this.announce(actor, activity); + return await this.announce(actor, activity); } else if (isLike(activity)) { - await this.like(actor, activity); + return await this.like(actor, activity); } else if (isUndo(activity)) { - await this.undo(actor, activity); + return await this.undo(actor, activity); } else if (isBlock(activity)) { - await this.block(actor, activity); + return await this.block(actor, activity); } else if (isFlag(activity)) { - await this.flag(actor, activity); + return await this.flag(actor, activity); } else if (isMove(activity)) { - await this.move(actor, activity); + return await this.move(actor, activity); } else { this.logger.warn(`unrecognized activity type: ${activity.type}`); } @@ -254,18 +260,18 @@ export class ApInboxService { } @bindThis - private async announce(actor: MiRemoteUser, activity: IAnnounce): Promise { + private async announce(actor: MiRemoteUser, activity: IAnnounce): Promise { const uri = getApId(activity); this.logger.info(`Announce: ${uri}`); const targetUri = getApId(activity.object); - await this.announceNote(actor, activity, targetUri); + return await this.announceNote(actor, activity, targetUri); } @bindThis - private async announceNote(actor: MiRemoteUser, activity: IAnnounce, targetUri: string): Promise { + private async announceNote(actor: MiRemoteUser, activity: IAnnounce, targetUri: string): Promise { const uri = getApId(activity); if (actor.isSuspended) { @@ -289,7 +295,7 @@ export class ApInboxService { let renote; try { renote = await this.apNoteService.resolveNote(targetUri); - if (renote == null) throw new Error('announce target is null'); + if (renote == null) return 'announce target is null'; } catch (err) { // 対象が4xxならスキップ if (err instanceof StatusError) { diff --git a/packages/backend/src/core/activitypub/models/ApNoteService.ts b/packages/backend/src/core/activitypub/models/ApNoteService.ts index 4d64b08e15c4..aea358e30b2e 100644 --- a/packages/backend/src/core/activitypub/models/ApNoteService.ts +++ b/packages/backend/src/core/activitypub/models/ApNoteService.ts @@ -82,20 +82,20 @@ export class ApNoteService { const expectHost = this.utilityService.extractDbHost(uri); if (!validPost.includes(getApType(object))) { - return new Error(`invalid Note: invalid object type ${getApType(object)}`); + return new IdentifiableError('d450b8a9-48e4-4dab-ae36-f4db763fda7c', `invalid Note: invalid object type ${getApType(object)}`); } if (object.id && this.utilityService.extractDbHost(object.id) !== expectHost) { - return new Error(`invalid Note: id has different host. expected: ${expectHost}, actual: ${this.utilityService.extractDbHost(object.id)}`); + return new IdentifiableError('d450b8a9-48e4-4dab-ae36-f4db763fda7c', `invalid Note: id has different host. expected: ${expectHost}, actual: ${this.utilityService.extractDbHost(object.id)}`); } const actualHost = object.attributedTo && this.utilityService.extractDbHost(getOneApId(object.attributedTo)); if (object.attributedTo && actualHost !== expectHost) { - return new Error(`invalid Note: attributedTo has different host. expected: ${expectHost}, actual: ${actualHost}`); + return new IdentifiableError('d450b8a9-48e4-4dab-ae36-f4db763fda7c', `invalid Note: attributedTo has different host. expected: ${expectHost}, actual: ${actualHost}`); } if (object.published && !this.idService.isSafeT(new Date(object.published).valueOf())) { - return new Error('invalid Note: published timestamp is malformed'); + return new IdentifiableError('d450b8a9-48e4-4dab-ae36-f4db763fda7c', 'invalid Note: published timestamp is malformed'); } return null; diff --git a/packages/backend/src/queue/processors/InboxProcessorService.ts b/packages/backend/src/queue/processors/InboxProcessorService.ts index 3addead0587b..4f2d13429a75 100644 --- a/packages/backend/src/queue/processors/InboxProcessorService.ts +++ b/packages/backend/src/queue/processors/InboxProcessorService.ts @@ -182,13 +182,21 @@ export class InboxProcessorService { // アクティビティを処理 try { - await this.apInboxService.performActivity(authUser.user, activity); + const reason = await this.apInboxService.performActivity(authUser.user, activity); + if (reason) { + return reason; + } } catch (e) { if (e instanceof IdentifiableError) { if (e.id === '689ee33f-f97c-479a-ac49-1b9f8140af99') { return 'blocked notes with prohibited words'; } - if (e.id === '85ab9bd7-3a41-4530-959d-f07073900109') return 'actor has been suspended'; + if (e.id === '85ab9bd7-3a41-4530-959d-f07073900109') { + return 'actor has been suspended'; + } + if (e.id === 'd450b8a9-48e4-4dab-ae36-f4db763fda7c') { // invalid Note + return e.message; + } } throw e; } From 680839afd63f875bc5e35f9de4ac5af6e9734306 Mon Sep 17 00:00:00 2001 From: tamaina Date: Sat, 9 Mar 2024 08:54:18 +0000 Subject: [PATCH 2/7] revert --- packages/backend/src/core/activitypub/ApInboxService.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/backend/src/core/activitypub/ApInboxService.ts b/packages/backend/src/core/activitypub/ApInboxService.ts index 783b99dbde68..cbe2ca58d72f 100644 --- a/packages/backend/src/core/activitypub/ApInboxService.ts +++ b/packages/backend/src/core/activitypub/ApInboxService.ts @@ -119,7 +119,9 @@ export class ApInboxService { // ついでにリモートユーザーの情報が古かったら更新しておく if (actor.uri) { if (actor.lastFetchedAt == null || Date.now() - actor.lastFetchedAt.getTime() > 1000 * 60 * 60 * 24) { - await this.apPersonService.updatePerson(actor.uri); + setImmediate(() => { + this.apPersonService.updatePerson(actor.uri); + }); } } return reason; From d76f7046fcdf34f6c9edea173d621ca1d22e89ca Mon Sep 17 00:00:00 2001 From: tamaina Date: Sat, 9 Mar 2024 09:07:29 +0000 Subject: [PATCH 3/7] better reason handlings --- .../src/core/activitypub/ApInboxService.ts | 61 +++++++++---------- .../queue/processors/InboxProcessorService.ts | 7 ++- 2 files changed, 33 insertions(+), 35 deletions(-) diff --git a/packages/backend/src/core/activitypub/ApInboxService.ts b/packages/backend/src/core/activitypub/ApInboxService.ts index cbe2ca58d72f..ae282d924da0 100644 --- a/packages/backend/src/core/activitypub/ApInboxService.ts +++ b/packages/backend/src/core/activitypub/ApInboxService.ts @@ -91,14 +91,14 @@ export class ApInboxService { @bindThis public async performActivity(actor: MiRemoteUser, activity: IObject): Promise { - let reason = undefined as string | void; + let result = undefined as string | void; if (isCollectionOrOrderedCollection(activity)) { - const reasons = [] as [string, string | void][]; + const results = [] as [string, string | void][]; const resolver = this.apResolverService.createResolver(); for (const item of toArray(isCollection(activity) ? activity.items : activity.orderedItems)) { const act = await resolver.resolve(item); try { - reasons.push([getApId(item), await this.performOneActivity(actor, act)]); + results.push([getApId(item), await this.performOneActivity(actor, act)]); } catch (err) { if (err instanceof Error || typeof err === 'string') { this.logger.error(err); @@ -108,12 +108,12 @@ export class ApInboxService { } } - const hasReason = reasons.some(([, reason]) => reason != null); + const hasReason = results.some(([, reason]) => (reason != null && !reason.startsWith('ok'))); if (hasReason) { - reason = reasons.map(([id, reason]) => `${id}: ${reason}`).join('\n'); + result = results.map(([id, reason]) => `${id}: ${reason}`).join('\n'); } } else { - reason = await this.performOneActivity(actor, activity); + result = await this.performOneActivity(actor, activity); } // ついでにリモートユーザーの情報が古かったら更新しておく @@ -124,7 +124,7 @@ export class ApInboxService { }); } } - return reason; + return result; } @bindThis @@ -144,9 +144,9 @@ export class ApInboxService { } else if (isReject(activity)) { return await this.reject(actor, activity); } else if (isAdd(activity)) { - return await this.add(actor, activity).catch(err => this.logger.error(err)); + return await this.add(actor, activity); } else if (isRemove(activity)) { - return await this.remove(actor, activity).catch(err => this.logger.error(err)); + return await this.remove(actor, activity); } else if (isAnnounce(activity)) { return await this.announce(actor, activity); } else if (isLike(activity)) { @@ -160,7 +160,7 @@ export class ApInboxService { } else if (isMove(activity)) { return await this.move(actor, activity); } else { - this.logger.warn(`unrecognized activity type: ${activity.type}`); + return `unrecognized activity type: ${activity.type}`; } } @@ -242,23 +242,23 @@ export class ApInboxService { } @bindThis - private async add(actor: MiRemoteUser, activity: IAdd): Promise { + private async add(actor: MiRemoteUser, activity: IAdd): Promise { if (actor.uri !== activity.actor) { - throw new Error('invalid actor'); + return 'invalid actor'; } if (activity.target == null) { - throw new Error('target is null'); + return 'target is null'; } if (activity.target === actor.featured) { const note = await this.apNoteService.resolveNote(activity.object); - if (note == null) throw new Error('note not found'); + if (note == null) return 'note not found'; await this.notePiningService.addPinned(actor, note.id); return; } - throw new Error(`unknown target: ${activity.target}`); + return `unknown target: ${activity.target}`; } @bindThis @@ -302,18 +302,16 @@ export class ApInboxService { // 対象が4xxならスキップ if (err instanceof StatusError) { if (!err.isRetryable) { - this.logger.warn(`Ignored announce target ${targetUri} - ${err.statusCode}`); - return; + return `Ignored announce target ${targetUri} - ${err.statusCode}`; } - this.logger.warn(`Error in announce target ${targetUri} - ${err.statusCode}`); + return `Error in announce target ${targetUri} - ${err.statusCode}`; } throw err; } if (!await this.noteEntityService.isVisibleForMe(renote, actor.id)) { - this.logger.warn('skip: invalid actor for this activity'); - return; + return 'skip: invalid actor for this activity'; } this.logger.info(`Creating the (Re)Note: ${uri}`); @@ -322,8 +320,7 @@ export class ApInboxService { const createdAt = activity.published ? new Date(activity.published) : null; if (createdAt && createdAt < this.idService.parse(renote.id).date) { - this.logger.warn('skip: malformed createdAt'); - return; + return 'skip: malformed createdAt'; } await this.noteCreateService.create(actor, { @@ -357,7 +354,7 @@ export class ApInboxService { } @bindThis - private async create(actor: MiRemoteUser, activity: ICreate): Promise { + private async create(actor: MiRemoteUser, activity: ICreate): Promise { const uri = getApId(activity); this.logger.info(`Create: ${uri}`); @@ -388,7 +385,7 @@ export class ApInboxService { if (isPost(object)) { await this.createNote(resolver, actor, object, false, activity); } else { - this.logger.warn(`Unknown type: ${getApType(object)}`); + return `Unknown type: ${getApType(object)}`; } } @@ -430,7 +427,7 @@ export class ApInboxService { @bindThis private async delete(actor: MiRemoteUser, activity: IDelete): Promise { if (actor.uri !== activity.actor) { - throw new Error('invalid actor'); + return 'invalid actor'; } // 削除対象objectのtype @@ -589,29 +586,29 @@ export class ApInboxService { } @bindThis - private async remove(actor: MiRemoteUser, activity: IRemove): Promise { + private async remove(actor: MiRemoteUser, activity: IRemove): Promise { if (actor.uri !== activity.actor) { - throw new Error('invalid actor'); + return 'invalid actor'; } if (activity.target == null) { - throw new Error('target is null'); + return 'target is null'; } if (activity.target === actor.featured) { const note = await this.apNoteService.resolveNote(activity.object); - if (note == null) throw new Error('note not found'); + if (note == null) return 'note not found'; await this.notePiningService.removePinned(actor, note.id); return; } - throw new Error(`unknown target: ${activity.target}`); + return `unknown target: ${activity.target}`; } @bindThis private async undo(actor: MiRemoteUser, activity: IUndo): Promise { if (actor.uri !== activity.actor) { - throw new Error('invalid actor'); + return 'invalid actor'; } const uri = activity.id ?? activity; @@ -622,7 +619,7 @@ export class ApInboxService { const object = await resolver.resolve(activity.object).catch(e => { this.logger.error(`Resolution failed: ${e}`); - throw e; + return e; }); // don't queue because the sender may attempt again when timeout diff --git a/packages/backend/src/queue/processors/InboxProcessorService.ts b/packages/backend/src/queue/processors/InboxProcessorService.ts index 4f2d13429a75..1ee2433070d8 100644 --- a/packages/backend/src/queue/processors/InboxProcessorService.ts +++ b/packages/backend/src/queue/processors/InboxProcessorService.ts @@ -182,9 +182,10 @@ export class InboxProcessorService { // アクティビティを処理 try { - const reason = await this.apInboxService.performActivity(authUser.user, activity); - if (reason) { - return reason; + const result = await this.apInboxService.performActivity(authUser.user, activity); + if (result && !result.startsWith('ok')) { + this.logger.warn(`inbox activity ignored (maybe): id=${activity.id} reason=${reason}`); + return result; } } catch (e) { if (e instanceof IdentifiableError) { From 8450a809950a6253aa567b990457d7050aeb60bd Mon Sep 17 00:00:00 2001 From: tamaina Date: Sat, 9 Mar 2024 09:12:46 +0000 Subject: [PATCH 4/7] result --- packages/backend/src/queue/processors/InboxProcessorService.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/backend/src/queue/processors/InboxProcessorService.ts b/packages/backend/src/queue/processors/InboxProcessorService.ts index 1ee2433070d8..6000e9c794fa 100644 --- a/packages/backend/src/queue/processors/InboxProcessorService.ts +++ b/packages/backend/src/queue/processors/InboxProcessorService.ts @@ -184,7 +184,7 @@ export class InboxProcessorService { try { const result = await this.apInboxService.performActivity(authUser.user, activity); if (result && !result.startsWith('ok')) { - this.logger.warn(`inbox activity ignored (maybe): id=${activity.id} reason=${reason}`); + this.logger.warn(`inbox activity ignored (maybe): id=${activity.id} reason=${result}`); return result; } } catch (e) { From d3e17e0c8237d3d146f6a5daf4c0998f451eae53 Mon Sep 17 00:00:00 2001 From: tamaina Date: Fri, 22 Mar 2024 01:21:34 +0900 Subject: [PATCH 5/7] improve announce handling --- .../src/core/activitypub/ApInboxService.ts | 22 ++++++++++++------- packages/backend/src/core/activitypub/type.ts | 1 + 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/packages/backend/src/core/activitypub/ApInboxService.ts b/packages/backend/src/core/activitypub/ApInboxService.ts index ae282d924da0..3aea0fad7ca5 100644 --- a/packages/backend/src/core/activitypub/ApInboxService.ts +++ b/packages/backend/src/core/activitypub/ApInboxService.ts @@ -38,7 +38,7 @@ import { ApPersonService } from './models/ApPersonService.js'; import { ApQuestionService } from './models/ApQuestionService.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'; +import type { IAccept, IAdd, IAnnounce, IBlock, ICreate, IDelete, IFlag, IFollow, ILike, IObject, IReject, IRemove, IUndo, IUpdate, IMove, IPost } from './type.js'; @Injectable() export class ApInboxService { @@ -267,13 +267,20 @@ export class ApInboxService { this.logger.info(`Announce: ${uri}`); - const targetUri = getApId(activity.object); + const resolver = this.apResolverService.createResolver(); + + const target = await resolver.resolve(activity.object).catch(e => { + this.logger.error(`Resolution failed: ${e}`); + return e; + }); - return await this.announceNote(actor, activity, targetUri); + if (isPost(target)) return await this.announceNote(actor, activity, target); + + return `skip: unknown object type ${getApType(target)}`; } @bindThis - private async announceNote(actor: MiRemoteUser, activity: IAnnounce, targetUri: string): Promise { + private async announceNote(actor: MiRemoteUser, activity: IAnnounce, target: IPost): Promise { const uri = getApId(activity); if (actor.isSuspended) { @@ -296,16 +303,15 @@ export class ApInboxService { // Announce対象をresolve let renote; try { - renote = await this.apNoteService.resolveNote(targetUri); + renote = await this.apNoteService.resolveNote(target); if (renote == null) return 'announce target is null'; } catch (err) { // 対象が4xxならスキップ if (err instanceof StatusError) { if (!err.isRetryable) { - return `Ignored announce target ${targetUri} - ${err.statusCode}`; + return `Ignored announce target ${target.id} - ${err.statusCode}`; } - - return `Error in announce target ${targetUri} - ${err.statusCode}`; + return `Error in announce target ${target.id} - ${err.statusCode}`; } throw err; } diff --git a/packages/backend/src/core/activitypub/type.ts b/packages/backend/src/core/activitypub/type.ts index b43dddad61d2..22bf2d25c69b 100644 --- a/packages/backend/src/core/activitypub/type.ts +++ b/packages/backend/src/core/activitypub/type.ts @@ -327,3 +327,4 @@ export const isAnnounce = (object: IObject): object is IAnnounce => getApType(ob export const isBlock = (object: IObject): object is IBlock => getApType(object) === 'Block'; export const isFlag = (object: IObject): object is IFlag => getApType(object) === 'Flag'; export const isMove = (object: IObject): object is IMove => getApType(object) === 'Move'; +export const isNote = (object: IObject): object is IPost => getApType(object) === 'Note'; From 822b95eebd26f40c4eb1ada1a8c6ad0b06676f11 Mon Sep 17 00:00:00 2001 From: tamaina Date: Fri, 22 Mar 2024 02:37:39 +0900 Subject: [PATCH 6/7] skip bearcaps --- packages/backend/src/core/activitypub/ApInboxService.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/backend/src/core/activitypub/ApInboxService.ts b/packages/backend/src/core/activitypub/ApInboxService.ts index 1621c41bcc54..f8f20a7f722b 100644 --- a/packages/backend/src/core/activitypub/ApInboxService.ts +++ b/packages/backend/src/core/activitypub/ApInboxService.ts @@ -28,6 +28,7 @@ import type { UsersRepository, NotesRepository, FollowingsRepository, AbuseUserR import { bindThis } from '@/decorators.js'; import type { MiRemoteUser } from '@/models/User.js'; import { isNotNull } from '@/misc/is-not-null.js'; +import { GlobalEventService } from '@/core/GlobalEventService.js'; import { getApHrefNullable, getApId, getApIds, getApType, isAccept, isActor, isAdd, isAnnounce, isBlock, isCollection, isCollectionOrOrderedCollection, isCreate, isDelete, isFlag, isFollow, isLike, isMove, isPost, isReject, isRemove, isTombstone, isUndo, isUpdate, validActor, validPost } from './type.js'; import { ApNoteService } from './models/ApNoteService.js'; import { ApLoggerService } from './ApLoggerService.js'; @@ -36,7 +37,6 @@ import { ApResolverService } from './ApResolverService.js'; import { ApAudienceService } from './ApAudienceService.js'; import { ApPersonService } from './models/ApPersonService.js'; import { ApQuestionService } from './models/ApQuestionService.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'; @@ -349,11 +349,15 @@ export class ApInboxService { } @bindThis - private async create(actor: MiRemoteUser, activity: ICreate): Promise { + private async create(actor: MiRemoteUser, activity: ICreate): Promise { const uri = getApId(activity); this.logger.info(`Create: ${uri}`); + if (!activity.object) return 'skip: activity has no object property'; + const targetUri = getApId(activity.object); + if (targetUri.startsWith('bear:')) return 'skip: bearcaps url not supported.'; + // copy audiences between activity <=> object. if (typeof activity.object === 'object') { const to = unique(concat([toArray(activity.to), toArray(activity.object.to)])); From 7f3b48705d0e7126d43a8590739f01359805b6fb Mon Sep 17 00:00:00 2001 From: tamaina Date: Fri, 22 Mar 2024 02:39:46 +0900 Subject: [PATCH 7/7] also announce --- packages/backend/src/core/activitypub/ApInboxService.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/backend/src/core/activitypub/ApInboxService.ts b/packages/backend/src/core/activitypub/ApInboxService.ts index dbb250a96edd..d0d206760cb9 100644 --- a/packages/backend/src/core/activitypub/ApInboxService.ts +++ b/packages/backend/src/core/activitypub/ApInboxService.ts @@ -269,6 +269,10 @@ export class ApInboxService { const resolver = this.apResolverService.createResolver(); + if (!activity.object) return 'skip: activity has no object property'; + const targetUri = getApId(activity.object); + if (targetUri.startsWith('bear:')) return 'skip: bearcaps url not supported.'; + const target = await resolver.resolve(activity.object).catch(e => { this.logger.error(`Resolution failed: ${e}`); return e;