summaryrefslogtreecommitdiff
path: root/packages/backend/src
diff options
context:
space:
mode:
authorHazelnoot <acomputerdog@gmail.com>2025-03-02 21:08:39 -0500
committerHazelnoot <acomputerdog@gmail.com>2025-03-21 12:37:06 -0400
commit3958b71f4e56f3a122ea226ce763315c82f8eef0 (patch)
tree80088acf672abae8628cc02d737cedfb6f6c23fb /packages/backend/src
parentadd IObjectWithId type for APIs that work with objects required to have an ID. (diff)
downloadsharkey-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.ts19
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);