don't discard the target of announce activities, in case it's a private note that can't be re-fetched

This commit is contained in:
Hazelnoot 2025-03-02 21:08:39 -05:00
parent f88430aebc
commit 3958b71f4e

View file

@ -36,7 +36,7 @@ import InstanceChart from '@/core/chart/charts/instance.js';
import FederationChart from '@/core/chart/charts/federation.js'; import FederationChart from '@/core/chart/charts/federation.js';
import { FetchInstanceMetadataService } from '@/core/FetchInstanceMetadataService.js'; import { FetchInstanceMetadataService } from '@/core/FetchInstanceMetadataService.js';
import { UpdateInstanceQueue } from '@/core/UpdateInstanceQueue.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 { ApNoteService } from './models/ApNoteService.js';
import { ApLoggerService } from './ApLoggerService.js'; import { ApLoggerService } from './ApLoggerService.js';
import { ApDbResolverService } from './ApDbResolverService.js'; import { ApDbResolverService } from './ApDbResolverService.js';
@ -318,9 +318,7 @@ export class ApInboxService {
const targetUri = getApId(activityObject); const targetUri = getApId(activityObject);
if (targetUri.startsWith('bear:')) return 'skip: bearcaps url not supported.'; 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. const target = await resolver.secureResolve(activityObject, uri).catch(e => {
// We cannot just re-fetch or the resolver will throw a recursion error.
const target = await resolver.resolve(targetUri).catch(e => {
this.logger.error(`Resolution failed: ${e}`); this.logger.error(`Resolution failed: ${e}`);
throw e; throw e;
}); });
@ -332,7 +330,7 @@ export class ApInboxService {
} }
@bindThis @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); const uri = getApId(activity);
if (actor.isSuspended) { if (actor.isSuspended) {
@ -354,7 +352,9 @@ export class ApInboxService {
// Announce対象をresolve // Announce対象をresolve
let renote; let renote;
try { 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'; if (renote == null) return 'announce target is null';
} catch (err) { } catch (err) {
// 対象が4xxならスキップ // 対象が4xxならスキップ
@ -394,12 +394,7 @@ export class ApInboxService {
} }
} }
private async announceActivity(announce: IAnnounce, activity: IActivity, resolver: Resolver): Promise<string | void> { private async announceActivity(announce: IAnnounce, activity: IActivity & IObjectWithId, 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}`);
}
// Since this is a new activity, we need to get a new actor. // Since this is a new activity, we need to get a new actor.
const actorId = getApId(activity.actor); const actorId = getApId(activity.actor);
const actor = await this.apPersonService.resolvePerson(actorId, resolver); const actor = await this.apPersonService.resolvePerson(actorId, resolver);