From 11356acb98853e2da5dcbb7c287fac7b2529d42f Mon Sep 17 00:00:00 2001 From: Hazelnoot Date: Mon, 15 Sep 2025 12:17:40 -0400 Subject: [PATCH] suppress JSON-LD errors when signing activities for relays --- packages/backend/src/core/RelayService.ts | 19 ++++++++++++++++++- .../src/core/activitypub/ApRendererService.ts | 4 ++-- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/packages/backend/src/core/RelayService.ts b/packages/backend/src/core/RelayService.ts index afb5b425a1..e255d2ebdd 100644 --- a/packages/backend/src/core/RelayService.ts +++ b/packages/backend/src/core/RelayService.ts @@ -16,9 +16,15 @@ import { deepClone } from '@/misc/clone.js'; import { bindThis } from '@/decorators.js'; import { SystemAccountService } from '@/core/SystemAccountService.js'; import { CacheManagementService, ManagedMemorySingleCache } from '@/global/CacheManagementService.js'; +import { IActivity } from '@/core/activitypub/type.js'; +import { LoggerService } from '@/core/LoggerService.js'; +import type Logger from '@/logger.js'; +import { renderInlineError } from '@/misc/render-inline-error.js'; +import { Signed } from '@/core/activitypub/JsonLdService.js'; @Injectable() export class RelayService { + private readonly logger: Logger; private readonly relaysCache: ManagedMemorySingleCache; constructor( @@ -29,9 +35,11 @@ export class RelayService { private queueService: QueueService, private systemAccountService: SystemAccountService, private apRendererService: ApRendererService, + private readonly loggerService: LoggerService, cacheManagementService: CacheManagementService, ) { + this.logger = this.loggerService.getLogger('relay'); this.relaysCache = cacheManagementService.createMemorySingleCache('relay', 1000 * 60 * 10); // 10m } @@ -106,10 +114,19 @@ export class RelayService { const copy = deepClone(activity); if (!copy.to) copy.to = ['https://www.w3.org/ns/activitystreams#Public']; - const signed = await this.apRendererService.attachLdSignature(copy, user); + const signed = await this.signActivity(copy, user); for (const relay of relays) { this.queueService.deliver(user, signed, relay.inbox, false); } } + + private async signActivity(activity: T, user: { id: MiUser['id']; host: null; }): Promise> { + try { + return await this.apRendererService.attachLdSignature(activity, user); + } catch (err) { + this.logger.warn(`Error signing activity ${activity.id}: ${renderInlineError(err)}`); + return activity; + } + } } diff --git a/packages/backend/src/core/activitypub/ApRendererService.ts b/packages/backend/src/core/activitypub/ApRendererService.ts index 6fc6786bf3..672edf9bb7 100644 --- a/packages/backend/src/core/activitypub/ApRendererService.ts +++ b/packages/backend/src/core/activitypub/ApRendererService.ts @@ -36,7 +36,7 @@ import { CacheService } from '@/core/CacheService.js'; import { isPureRenote, isQuote, isRenote } from '@/misc/is-renote.js'; import { FederatedInstanceService } from '@/core/FederatedInstanceService.js'; import { TimeService } from '@/global/TimeService.js'; -import { JsonLdService } from './JsonLdService.js'; +import { JsonLdService, type Signed } from './JsonLdService.js'; import { ApMfmService } from './ApMfmService.js'; import { CONTEXT } from './misc/contexts.js'; import { getApId, ILink, IOrderedCollection, IOrderedCollectionPage } from './type.js'; @@ -804,7 +804,7 @@ export class ApRendererService { } @bindThis - public async attachLdSignature(activity: any, user: { id: MiUser['id']; host: null; }): Promise { + public async attachLdSignature(activity: T, user: { id: MiUser['id']; host: null; }): Promise> { // Linked Data signatures are cryptographic signatures attached to each activity to provide proof of authenticity. // When using authorized fetch, this is often undesired as any signed activity can be forwarded to a blocked instance by relays and other instances. // This setting allows admins to disable LD signatures for increased privacy, at the expense of fewer relayed activities and additional inbound fetch (GET) requests.