From 55e46c03b9945020a645653d154c173b64d476e7 Mon Sep 17 00:00:00 2001
From: naskya <m@naskya.net>
Date: Sat, 27 Jul 2024 17:02:24 +0900
Subject: [PATCH] refactor (backend): port renderFollowRelay to backend-rs

---
 packages/backend-rs/index.d.ts                | 11 ++++++++
 packages/backend-rs/index.js                  |  2 ++
 .../src/federation/activitypub/mod.rs         |  1 +
 .../src/federation/activitypub/object/mod.rs  |  9 ++++++
 .../federation/activitypub/object/relay.rs    | 28 +++++++++++++++++++
 packages/backend-rs/src/federation/mod.rs     |  1 +
 .../activitypub/renderer/follow-relay.ts      | 14 ----------
 packages/backend/src/services/relay.ts        |  7 ++---
 8 files changed, 55 insertions(+), 18 deletions(-)
 create mode 100644 packages/backend-rs/src/federation/activitypub/mod.rs
 create mode 100644 packages/backend-rs/src/federation/activitypub/object/mod.rs
 create mode 100644 packages/backend-rs/src/federation/activitypub/object/relay.rs
 delete mode 100644 packages/backend/src/remote/activitypub/renderer/follow-relay.ts

diff --git a/packages/backend-rs/index.d.ts b/packages/backend-rs/index.d.ts
index e6a1e5d0ec..b4bf0f65a9 100644
--- a/packages/backend-rs/index.d.ts
+++ b/packages/backend-rs/index.d.ts
@@ -48,6 +48,8 @@ export interface Acct {
 
 export declare function acctToString(acct: Acct): string
 
+export type Activity =  'Follow';
+
 export interface Ad {
   id: string
   createdAt: DateTimeWithTimeZone
@@ -389,6 +391,13 @@ export interface Following {
   followeeSharedInbox: string | null
 }
 
+export interface FollowRelay {
+  id: string
+  type: Activity
+  actor: string
+  object: string
+}
+
 export interface FollowRequest {
   id: string
   createdAt: DateTimeWithTimeZone
@@ -1190,6 +1199,8 @@ export type RelayStatus =  'accepted'|
 /** Delete all entries in the [attestation_challenge] table created at more than 5 minutes ago */
 export declare function removeOldAttestationChallenges(): Promise<void>
 
+export declare function renderFollowRelay(relayId: string): Promise<FollowRelay>
+
 export interface RenoteMuting {
   id: string
   createdAt: DateTimeWithTimeZone
diff --git a/packages/backend-rs/index.js b/packages/backend-rs/index.js
index d248ab3231..de95ac634c 100644
--- a/packages/backend-rs/index.js
+++ b/packages/backend-rs/index.js
@@ -362,6 +362,7 @@ if (!nativeBinding) {
 }
 
 module.exports.acctToString = nativeBinding.acctToString
+module.exports.Activity = nativeBinding.Activity
 module.exports.AntennaSrc = nativeBinding.AntennaSrc
 module.exports.ChatEvent = nativeBinding.ChatEvent
 module.exports.ChatIndexEvent = nativeBinding.ChatIndexEvent
@@ -429,6 +430,7 @@ module.exports.PushNotificationKind = nativeBinding.PushNotificationKind
 module.exports.PushSubscriptionType = nativeBinding.PushSubscriptionType
 module.exports.RelayStatus = nativeBinding.RelayStatus
 module.exports.removeOldAttestationChallenges = nativeBinding.removeOldAttestationChallenges
+module.exports.renderFollowRelay = nativeBinding.renderFollowRelay
 module.exports.safeForSql = nativeBinding.safeForSql
 module.exports.sendPushNotification = nativeBinding.sendPushNotification
 module.exports.shouldNyaify = nativeBinding.shouldNyaify
diff --git a/packages/backend-rs/src/federation/activitypub/mod.rs b/packages/backend-rs/src/federation/activitypub/mod.rs
new file mode 100644
index 0000000000..e63d53de85
--- /dev/null
+++ b/packages/backend-rs/src/federation/activitypub/mod.rs
@@ -0,0 +1 @@
+pub mod object;
diff --git a/packages/backend-rs/src/federation/activitypub/object/mod.rs b/packages/backend-rs/src/federation/activitypub/object/mod.rs
new file mode 100644
index 0000000000..b245bca98a
--- /dev/null
+++ b/packages/backend-rs/src/federation/activitypub/object/mod.rs
@@ -0,0 +1,9 @@
+pub mod relay;
+
+pub trait ActivityPubObject {}
+
+#[derive(serde::Serialize)]
+#[macros::export(string_enum)]
+pub enum Activity {
+    Follow,
+}
diff --git a/packages/backend-rs/src/federation/activitypub/object/relay.rs b/packages/backend-rs/src/federation/activitypub/object/relay.rs
new file mode 100644
index 0000000000..f3d7656564
--- /dev/null
+++ b/packages/backend-rs/src/federation/activitypub/object/relay.rs
@@ -0,0 +1,28 @@
+use super::*;
+use crate::{config::CONFIG, federation::internal_actor};
+use serde::Serialize;
+
+#[derive(Serialize)]
+#[macros::export(object)]
+pub struct FollowRelay {
+    pub id: String,
+    pub r#type: Activity,
+    pub actor: String,
+    pub object: String,
+}
+
+impl ActivityPubObject for FollowRelay {}
+
+#[macros::export(js_name = "renderFollowRelay")]
+pub async fn follow(relay_id: &str) -> Result<FollowRelay, internal_actor::relay::Error> {
+    Ok(FollowRelay {
+        id: format!("{}/activities/follow-relay/{}", CONFIG.url, relay_id),
+        r#type: Activity::Follow,
+        actor: format!(
+            "{}/users/{}",
+            CONFIG.url,
+            internal_actor::relay::get_id().await?
+        ),
+        object: "https://www.w3.org/ns/activitystreams#Public".to_owned(),
+    })
+}
diff --git a/packages/backend-rs/src/federation/mod.rs b/packages/backend-rs/src/federation/mod.rs
index 1db28b0858..c432fc9be8 100644
--- a/packages/backend-rs/src/federation/mod.rs
+++ b/packages/backend-rs/src/federation/mod.rs
@@ -1,5 +1,6 @@
 //! Services used to federate with other servers
 
 pub mod acct;
+pub mod activitypub;
 pub mod internal_actor;
 pub mod nodeinfo;
diff --git a/packages/backend/src/remote/activitypub/renderer/follow-relay.ts b/packages/backend/src/remote/activitypub/renderer/follow-relay.ts
deleted file mode 100644
index 48e73777e5..0000000000
--- a/packages/backend/src/remote/activitypub/renderer/follow-relay.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-import { config } from "@/config.js";
-import type { Relay } from "@/models/entities/relay.js";
-import type { ILocalUser } from "@/models/entities/user.js";
-
-export function renderFollowRelay(relay: Relay, relayActorId: string) {
-	const follow = {
-		id: `${config.url}/activities/follow-relay/${relay.id}`,
-		type: "Follow",
-		actor: `${config.url}/users/${relayActorId}`,
-		object: "https://www.w3.org/ns/activitystreams#Public",
-	};
-
-	return follow;
-}
diff --git a/packages/backend/src/services/relay.ts b/packages/backend/src/services/relay.ts
index e1ecc707e3..c0d5b3935a 100644
--- a/packages/backend/src/services/relay.ts
+++ b/packages/backend/src/services/relay.ts
@@ -1,4 +1,3 @@
-import { renderFollowRelay } from "@/remote/activitypub/renderer/follow-relay.js";
 import {
 	renderActivity,
 	attachLdSignature,
@@ -7,7 +6,7 @@ import { renderUndo } from "@/remote/activitypub/renderer/undo.js";
 import { deliver } from "@/queue/index.js";
 import type { User } from "@/models/entities/user.js";
 import { Relays } from "@/models/index.js";
-import { getRelayActorId, genId } from "backend-rs";
+import { getRelayActorId, genId, renderFollowRelay } from "backend-rs";
 import { Cache } from "@/misc/cache.js";
 import type { Relay } from "@/models/entities/relay.js";
 
@@ -21,7 +20,7 @@ export async function addRelay(inbox: string) {
 	}).then((x) => Relays.findOneByOrFail(x.identifiers[0]));
 
 	const relayActorId = await getRelayActorId();
-	const follow = renderFollowRelay(relay, relayActorId);
+	const follow = await renderFollowRelay(relay.id);
 	const activity = renderActivity(follow);
 	deliver(relayActorId, activity, relay.inbox);
 
@@ -38,7 +37,7 @@ export async function removeRelay(inbox: string) {
 	}
 
 	const relayActorId = await getRelayActorId();
-	const follow = renderFollowRelay(relay, relayActorId);
+	const follow = await renderFollowRelay(relay.id);
 	const undo = renderUndo(follow, relayActorId);
 	const activity = renderActivity(undo);
 	deliver(relayActorId, activity, relay.inbox);