diff options
| author | Hazelnoot <acomputerdog@gmail.com> | 2025-03-02 21:08:39 -0500 |
|---|---|---|
| committer | Hazelnoot <acomputerdog@gmail.com> | 2025-03-21 12:37:06 -0400 |
| commit | 3958b71f4e56f3a122ea226ce763315c82f8eef0 (patch) | |
| tree | 80088acf672abae8628cc02d737cedfb6f6c23fb /packages/backend/src | |
| parent | add IObjectWithId type for APIs that work with objects required to have an ID. (diff) | |
| download | sharkey-3958b71f4e56f3a122ea226ce763315c82f8eef0.tar.gz sharkey-3958b71f4e56f3a122ea226ce763315c82f8eef0.tar.bz2 sharkey-3958b71f4e56f3a122ea226ce763315c82f8eef0.zip | |
don't discard the target of announce activities, in case it's a private note that can't be re-fetched
Diffstat (limited to 'packages/backend/src')
| -rw-r--r-- | packages/backend/src/core/activitypub/ApInboxService.ts | 19 |
1 files changed, 7 insertions, 12 deletions
diff --git a/packages/backend/src/core/activitypub/ApInboxService.ts b/packages/backend/src/core/activitypub/ApInboxService.ts index 6e1359cbdc..402d5ab2a4 100644 --- a/packages/backend/src/core/activitypub/ApInboxService.ts +++ b/packages/backend/src/core/activitypub/ApInboxService.ts @@ -36,7 +36,7 @@ import InstanceChart from '@/core/chart/charts/instance.js'; import FederationChart from '@/core/chart/charts/federation.js'; import { FetchInstanceMetadataService } from '@/core/FetchInstanceMetadataService.js'; import { UpdateInstanceQueue } from '@/core/UpdateInstanceQueue.js'; -import { getApHrefNullable, getApId, getApIds, getApType, getNullableApId, isAccept, isActor, isAdd, isAnnounce, isApObject, isBlock, isCollection, isCollectionOrOrderedCollection, isCreate, isDelete, isFlag, isFollow, isLike, isDislike, isMove, isPost, isReject, isRemove, isTombstone, isUndo, isUpdate, validActor, validPost, isActivity } from './type.js'; +import { getApHrefNullable, getApId, getApIds, getApType, getNullableApId, isAccept, isActor, isAdd, isAnnounce, isApObject, isBlock, isCollection, isCollectionOrOrderedCollection, isCreate, isDelete, isFlag, isFollow, isLike, isDislike, isMove, isPost, isReject, isRemove, isTombstone, isUndo, isUpdate, validActor, validPost, isActivity, IObjectWithId } from './type.js'; import { ApNoteService } from './models/ApNoteService.js'; import { ApLoggerService } from './ApLoggerService.js'; import { ApDbResolverService } from './ApDbResolverService.js'; @@ -318,9 +318,7 @@ export class ApInboxService { const targetUri = getApId(activityObject); if (targetUri.startsWith('bear:')) return 'skip: bearcaps url not supported.'; - // Force a fetch by passing URL only, since the target object must be trusted for announceActivity. - // We cannot just re-fetch or the resolver will throw a recursion error. - const target = await resolver.resolve(targetUri).catch(e => { + const target = await resolver.secureResolve(activityObject, uri).catch(e => { this.logger.error(`Resolution failed: ${e}`); throw e; }); @@ -332,7 +330,7 @@ export class ApInboxService { } @bindThis - private async announceNote(actor: MiRemoteUser, activity: IAnnounce, target: IPost, resolver?: Resolver): Promise<string | void> { + private async announceNote(actor: MiRemoteUser, activity: IAnnounce, target: IPost & IObjectWithId, resolver?: Resolver): Promise<string | void> { const uri = getApId(activity); if (actor.isSuspended) { @@ -354,7 +352,9 @@ export class ApInboxService { // Announce対象をresolve let renote; try { - renote = await this.apNoteService.resolveNote(target, { resolver }); + // The target ID is verified by secureResolve, so we know it shares host authority with the actor who sent it. + // This means we can pass that ID to resolveNote and avoid an extra fetch, which will fail if the note is private. + renote = await this.apNoteService.resolveNote(target, { resolver, sentFrom: new URL(getApId(target)) }); if (renote == null) return 'announce target is null'; } catch (err) { // 対象が4xxならスキップ @@ -394,12 +394,7 @@ export class ApInboxService { } } - private async announceActivity(announce: IAnnounce, activity: IActivity, resolver: Resolver): Promise<string | void> { - // Shouldn't happen, but just in case - if (!activity.id) { - throw new Bull.UnrecoverableError(`Cannot announce an activity with no ID: ${announce.id}`); - } - + private async announceActivity(announce: IAnnounce, activity: IActivity & IObjectWithId, resolver: Resolver): Promise<string | void> { // Since this is a new activity, we need to get a new actor. const actorId = getApId(activity.actor); const actor = await this.apPersonService.resolvePerson(actorId, resolver); |