diff --git a/packages/backend-rs/index.d.ts b/packages/backend-rs/index.d.ts index f2fdb66bd0..1c97dc2980 100644 --- a/packages/backend-rs/index.d.ts +++ b/packages/backend-rs/index.d.ts @@ -111,6 +111,13 @@ export interface ApAccept { object: ApFollow } +export interface ApAdd { + type: ApObject + actor: string + target: string + object: string +} + export interface ApEmoji { id: string type: ApObject @@ -146,6 +153,7 @@ export interface ApMention { } export type ApObject = 'Accept'| +'Add'| 'Emoji'| 'Flag'| 'Follow'| @@ -153,6 +161,7 @@ export type ApObject = 'Accept'| 'Mention'| 'Image'| 'Read'| +'Remove'| 'Tombstone'; export interface App { @@ -172,6 +181,13 @@ export interface ApRead { object: string } +export interface ApRemove { + type: ApObject + actor: string + target: string + object: string +} + export interface ApTombstone { id: string type: ApObject @@ -1328,6 +1344,8 @@ export declare function removeOldAttestationChallenges(): Promise<void> export declare function renderAccept(userId: string, followObject: ApFollow): ApAccept +export declare function renderAdd(userId: string, noteId: string): ApAdd + export declare function renderEmoji(emoji: Emoji): ApEmoji export declare function renderFlag(targetUserUri: string, comment: string): Promise<ApFlag> @@ -1342,6 +1360,8 @@ export declare function renderMention(user: UserLike): ApMention export declare function renderRead(userId: string, messageUri: string): ApRead +export declare function renderRemove(userId: string, noteId: string): ApRemove + export declare function renderTombstone(noteId: string): ApTombstone export interface RenoteMuting { diff --git a/packages/backend-rs/index.js b/packages/backend-rs/index.js index 0ef803af9e..bd87db3932 100644 --- a/packages/backend-rs/index.js +++ b/packages/backend-rs/index.js @@ -439,6 +439,7 @@ module.exports.PushSubscriptionType = nativeBinding.PushSubscriptionType module.exports.RelayStatus = nativeBinding.RelayStatus module.exports.removeOldAttestationChallenges = nativeBinding.removeOldAttestationChallenges module.exports.renderAccept = nativeBinding.renderAccept +module.exports.renderAdd = nativeBinding.renderAdd module.exports.renderEmoji = nativeBinding.renderEmoji module.exports.renderFlag = nativeBinding.renderFlag module.exports.renderFollow = nativeBinding.renderFollow @@ -446,6 +447,7 @@ module.exports.renderFollowRelay = nativeBinding.renderFollowRelay module.exports.renderHashtag = nativeBinding.renderHashtag module.exports.renderMention = nativeBinding.renderMention module.exports.renderRead = nativeBinding.renderRead +module.exports.renderRemove = nativeBinding.renderRemove module.exports.renderTombstone = nativeBinding.renderTombstone module.exports.safeForSql = nativeBinding.safeForSql module.exports.sendPushNotification = nativeBinding.sendPushNotification diff --git a/packages/backend-rs/src/federation/activitypub/object/add.rs b/packages/backend-rs/src/federation/activitypub/object/add.rs new file mode 100644 index 0000000000..4d34ae3b1f --- /dev/null +++ b/packages/backend-rs/src/federation/activitypub/object/add.rs @@ -0,0 +1,34 @@ +//! Add note to featured collection (pinned posts) + +use super::*; +use crate::misc::{note, user}; + +#[macros::export(object)] +pub struct ApAdd { + pub r#type: ApObject, + pub actor: String, + pub target: String, + pub object: String, +} + +impl ActivityPubObject for ApAdd {} + +impl ApAdd { + #[allow(dead_code)] // TODO: remove this line + fn new(user_id: String, note_id: String) -> Self { + let actor_uri = user::local_uri(user_id); + let collection_uri = format!("{}/collections/featured", actor_uri); + + Self { + r#type: ApObject::Add, + actor: actor_uri, + target: collection_uri, + object: note::local_uri(note_id), + } + } +} + +#[macros::ts_export] +pub fn render_add(user_id: String, note_id: String) -> ApAdd { + ApAdd::new(user_id, note_id) +} diff --git a/packages/backend-rs/src/federation/activitypub/object/mod.rs b/packages/backend-rs/src/federation/activitypub/object/mod.rs index 7745031907..179674da0b 100644 --- a/packages/backend-rs/src/federation/activitypub/object/mod.rs +++ b/packages/backend-rs/src/federation/activitypub/object/mod.rs @@ -1,10 +1,12 @@ pub mod accept; +pub mod add; pub mod emoji; pub mod flag; pub mod follow; pub mod hashtag; pub mod mention; pub mod read; +pub mod remove; pub mod tombstone; pub trait ActivityPubObject {} @@ -12,6 +14,7 @@ pub trait ActivityPubObject {} #[macros::export(string_enum)] pub enum ApObject { Accept, + Add, Emoji, Flag, Follow, @@ -19,6 +22,7 @@ pub enum ApObject { Mention, Image, Read, + Remove, Tombstone, } diff --git a/packages/backend-rs/src/federation/activitypub/object/remove.rs b/packages/backend-rs/src/federation/activitypub/object/remove.rs new file mode 100644 index 0000000000..42af021fca --- /dev/null +++ b/packages/backend-rs/src/federation/activitypub/object/remove.rs @@ -0,0 +1,34 @@ +//! Remove note from featured collection (pinned posts) + +use super::*; +use crate::misc::{note, user}; + +#[macros::export(object)] +pub struct ApRemove { + pub r#type: ApObject, + pub actor: String, + pub target: String, + pub object: String, +} + +impl ActivityPubObject for ApRemove {} + +impl ApRemove { + #[allow(dead_code)] // TODO: remove this line + fn new(user_id: String, note_id: String) -> Self { + let actor_uri = user::local_uri(user_id); + let collection_uri = format!("{}/collections/featured", actor_uri); + + Self { + r#type: ApObject::Remove, + actor: actor_uri, + target: collection_uri, + object: note::local_uri(note_id), + } + } +} + +#[macros::ts_export] +pub fn render_remove(user_id: String, note_id: String) -> ApRemove { + ApRemove::new(user_id, note_id) +} diff --git a/packages/backend/src/remote/activitypub/renderer/add.ts b/packages/backend/src/remote/activitypub/renderer/add.ts deleted file mode 100644 index 14c71694e1..0000000000 --- a/packages/backend/src/remote/activitypub/renderer/add.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { config } from "@/config.js"; -import type { ILocalUser } from "@/models/entities/user.js"; - -export default (user: ILocalUser, target: any, object: any) => ({ - type: "Add", - actor: `${config.url}/users/${user.id}`, - target, - object, -}); diff --git a/packages/backend/src/remote/activitypub/renderer/remove.ts b/packages/backend/src/remote/activitypub/renderer/remove.ts deleted file mode 100644 index 270744dd30..0000000000 --- a/packages/backend/src/remote/activitypub/renderer/remove.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { config } from "@/config.js"; -import type { User } from "@/models/entities/user.js"; - -export default (user: { id: User["id"] }, target: any, object: any) => ({ - type: "Remove", - actor: `${config.url}/users/${user.id}`, - target, - object, -}); diff --git a/packages/backend/src/services/i/pin.ts b/packages/backend/src/services/i/pin.ts index 42fc09b406..574e036fe1 100644 --- a/packages/backend/src/services/i/pin.ts +++ b/packages/backend/src/services/i/pin.ts @@ -1,13 +1,10 @@ -import { config } from "@/config.js"; -import renderAdd from "@/remote/activitypub/renderer/add.js"; -import renderRemove from "@/remote/activitypub/renderer/remove.js"; import { renderActivity } from "@/remote/activitypub/renderer/index.js"; import { IdentifiableError } from "@/misc/identifiable-error.js"; import type { User } from "@/models/entities/user.js"; import type { Note } from "@/models/entities/note.js"; import { Notes, UserNotePinings, Users } from "@/models/index.js"; import type { UserNotePining } from "@/models/entities/user-note-pining.js"; -import { genIdAt } from "backend-rs"; +import { genIdAt, renderAdd, renderRemove } from "backend-rs"; import { deliverToFollowers } from "@/remote/activitypub/deliver-manager.js"; import { deliverToRelays } from "@/services/relay.js"; @@ -115,12 +112,8 @@ export async function deliverPinnedChange( if (!Users.isLocalUser(user)) return; - const target = `${config.url}/users/${user.id}/collections/featured`; - const item = `${config.url}/notes/${noteId}`; const content = renderActivity( - isAddition - ? renderAdd(user, target, item) - : renderRemove(user, target, item), + isAddition ? renderAdd(user.id, noteId) : renderRemove(user.id, noteId), ); deliverToFollowers(user, content);