diff --git a/packages/backend/src/core/activitypub/ApRendererService.ts b/packages/backend/src/core/activitypub/ApRendererService.ts index 89e5217285..ff909778e8 100644 --- a/packages/backend/src/core/activitypub/ApRendererService.ts +++ b/packages/backend/src/core/activitypub/ApRendererService.ts @@ -528,6 +528,7 @@ export class ApRendererService { discoverable: user.isExplorable, publicKey: this.renderKey(user, keypair, '#main-key'), isCat: user.isCat, + hideOnlineStatus: user.hideOnlineStatus, noindex: user.noindex, indexable: !user.noindex, speakAsCat: user.speakAsCat, diff --git a/packages/backend/src/core/activitypub/misc/contexts.ts b/packages/backend/src/core/activitypub/misc/contexts.ts index da75fc1d42..1c4239502e 100644 --- a/packages/backend/src/core/activitypub/misc/contexts.ts +++ b/packages/backend/src/core/activitypub/misc/contexts.ts @@ -564,6 +564,7 @@ const extension_context_definition = { speakAsCat: 'firefish:speakAsCat', // Sharkey sharkey: 'https://joinsharkey.org/ns#', + hideOnlineStatus: 'sharkey:hideOnlineStatus', backgroundUrl: 'sharkey:backgroundUrl', listenbrainz: 'sharkey:listenbrainz', // vcard diff --git a/packages/backend/src/core/activitypub/models/ApPersonService.ts b/packages/backend/src/core/activitypub/models/ApPersonService.ts index 598486cd84..2cb31b1f09 100644 --- a/packages/backend/src/core/activitypub/models/ApPersonService.ts +++ b/packages/backend/src/core/activitypub/models/ApPersonService.ts @@ -389,6 +389,8 @@ export class ApPersonService implements OnModuleInit { movedToUri: person.movedTo, movedAt: person.movedTo ? new Date() : null, alsoKnownAs: person.alsoKnownAs, + // We use "!== false" to handle incorrect types, missing / null values, and "default to true" logic. + hideOnlineStatus: person.hideOnlineStatus !== false, isExplorable: person.discoverable, username: person.preferredUsername, approved: true, @@ -585,6 +587,8 @@ export class ApPersonService implements OnModuleInit { isLocked: person.manuallyApprovesFollowers, movedToUri: person.movedTo ?? null, alsoKnownAs: person.alsoKnownAs ?? null, + // We use "!== false" to handle incorrect types, missing / null values, and "default to true" logic. + hideOnlineStatus: person.hideOnlineStatus !== false, isExplorable: person.discoverable, ...(await this.resolveAvatarAndBanner(exist, person.icon, person.image, person.backgroundUrl).catch(() => ({}))), } as Partial & Pick; diff --git a/packages/backend/src/core/activitypub/type.ts b/packages/backend/src/core/activitypub/type.ts index c9e20e0168..a0a5ae00dc 100644 --- a/packages/backend/src/core/activitypub/type.ts +++ b/packages/backend/src/core/activitypub/type.ts @@ -215,6 +215,7 @@ export interface IActor extends IObject { }; 'vcard:bday'?: string; 'vcard:Address'?: string; + hideOnlineStatus?: boolean; noindex?: boolean; listenbrainz?: string; backgroundUrl?: string;