diff --git a/packages/backend-rs/index.d.ts b/packages/backend-rs/index.d.ts index 7be4b269e6..30e59f5353 100644 --- a/packages/backend-rs/index.d.ts +++ b/packages/backend-rs/index.d.ts @@ -207,6 +207,106 @@ export interface Acct { } export function stringToAcct(acct: string): Acct export function acctToString(acct: Acct): string +export function fetchNodeinfo(host: string): Promise<Nodeinfo> +export function nodeinfo_2_1(): Promise<any> +export function nodeinfo_2_0(): Promise<any> +/** NodeInfo schema version 2.0. <https://nodeinfo.diaspora.software/docson/index.html#/ns/schema/2.0> */ +export interface Nodeinfo { + /** The schema version, must be 2.0. */ + version: string + /** Metadata about server software in use. */ + software: Software20 + /** The protocols supported on this server. */ + protocols: Array<Protocol> + /** The third party sites this server can connect to via their application API. */ + services: Services + /** Whether this server allows open self-registration. */ + openRegistrations: boolean + /** Usage statistics for this server. */ + usage: Usage + /** Free form key value pairs for software specific values. Clients should not rely on any specific key present. */ + metadata: Record<string, any> +} +/** Metadata about server software in use (version 2.0). */ +export interface Software20 { + /** The canonical name of this server software. */ + name: string + /** The version of this server software. */ + version: string +} +export enum Protocol { + Activitypub = 'activitypub', + Buddycloud = 'buddycloud', + Dfrn = 'dfrn', + Diaspora = 'diaspora', + Libertree = 'libertree', + Ostatus = 'ostatus', + Pumpio = 'pumpio', + Tent = 'tent', + Xmpp = 'xmpp', + Zot = 'zot' +} +/** The third party sites this server can connect to via their application API. */ +export interface Services { + /** The third party sites this server can retrieve messages from for combined display with regular traffic. */ + inbound: Array<Inbound> + /** The third party sites this server can publish messages to on the behalf of a user. */ + outbound: Array<Outbound> +} +/** The third party sites this server can retrieve messages from for combined display with regular traffic. */ +export enum Inbound { + Atom1 = 'atom1', + Gnusocial = 'gnusocial', + Imap = 'imap', + Pnut = 'pnut', + Pop3 = 'pop3', + Pumpio = 'pumpio', + Rss2 = 'rss2', + Twitter = 'twitter' +} +/** The third party sites this server can publish messages to on the behalf of a user. */ +export enum Outbound { + Atom1 = 'atom1', + Blogger = 'blogger', + Buddycloud = 'buddycloud', + Diaspora = 'diaspora', + Dreamwidth = 'dreamwidth', + Drupal = 'drupal', + Facebook = 'facebook', + Friendica = 'friendica', + Gnusocial = 'gnusocial', + Google = 'google', + Insanejournal = 'insanejournal', + Libertree = 'libertree', + Linkedin = 'linkedin', + Livejournal = 'livejournal', + Mediagoblin = 'mediagoblin', + Myspace = 'myspace', + Pinterest = 'pinterest', + Pnut = 'pnut', + Posterous = 'posterous', + Pumpio = 'pumpio', + Redmatrix = 'redmatrix', + Rss2 = 'rss2', + Smtp = 'smtp', + Tent = 'tent', + Tumblr = 'tumblr', + Twitter = 'twitter', + Wordpress = 'wordpress', + Xmpp = 'xmpp' +} +/** Usage statistics for this server. */ +export interface Usage { + users: Users + localPosts: number | null + localComments: number | null +} +/** statistics about the users of this server. */ +export interface Users { + total: number | null + activeHalfyear: number | null + activeMonth: number | null +} export function greet(): void export function initializeRustLogger(): void export function showServerInfo(): void @@ -1179,106 +1279,6 @@ export interface Webhook { latestStatus: number | null } export function updateAntennasOnNewNote(note: Note, noteAuthor: Acct, noteMutedUsers: Array<string>): Promise<void> -export function fetchNodeinfo(host: string): Promise<Nodeinfo> -export function nodeinfo_2_1(): Promise<any> -export function nodeinfo_2_0(): Promise<any> -/** NodeInfo schema version 2.0. <https://nodeinfo.diaspora.software/docson/index.html#/ns/schema/2.0> */ -export interface Nodeinfo { - /** The schema version, must be 2.0. */ - version: string - /** Metadata about server software in use. */ - software: Software20 - /** The protocols supported on this server. */ - protocols: Array<Protocol> - /** The third party sites this server can connect to via their application API. */ - services: Services - /** Whether this server allows open self-registration. */ - openRegistrations: boolean - /** Usage statistics for this server. */ - usage: Usage - /** Free form key value pairs for software specific values. Clients should not rely on any specific key present. */ - metadata: Record<string, any> -} -/** Metadata about server software in use (version 2.0). */ -export interface Software20 { - /** The canonical name of this server software. */ - name: string - /** The version of this server software. */ - version: string -} -export enum Protocol { - Activitypub = 'activitypub', - Buddycloud = 'buddycloud', - Dfrn = 'dfrn', - Diaspora = 'diaspora', - Libertree = 'libertree', - Ostatus = 'ostatus', - Pumpio = 'pumpio', - Tent = 'tent', - Xmpp = 'xmpp', - Zot = 'zot' -} -/** The third party sites this server can connect to via their application API. */ -export interface Services { - /** The third party sites this server can retrieve messages from for combined display with regular traffic. */ - inbound: Array<Inbound> - /** The third party sites this server can publish messages to on the behalf of a user. */ - outbound: Array<Outbound> -} -/** The third party sites this server can retrieve messages from for combined display with regular traffic. */ -export enum Inbound { - Atom1 = 'atom1', - Gnusocial = 'gnusocial', - Imap = 'imap', - Pnut = 'pnut', - Pop3 = 'pop3', - Pumpio = 'pumpio', - Rss2 = 'rss2', - Twitter = 'twitter' -} -/** The third party sites this server can publish messages to on the behalf of a user. */ -export enum Outbound { - Atom1 = 'atom1', - Blogger = 'blogger', - Buddycloud = 'buddycloud', - Diaspora = 'diaspora', - Dreamwidth = 'dreamwidth', - Drupal = 'drupal', - Facebook = 'facebook', - Friendica = 'friendica', - Gnusocial = 'gnusocial', - Google = 'google', - Insanejournal = 'insanejournal', - Libertree = 'libertree', - Linkedin = 'linkedin', - Livejournal = 'livejournal', - Mediagoblin = 'mediagoblin', - Myspace = 'myspace', - Pinterest = 'pinterest', - Pnut = 'pnut', - Posterous = 'posterous', - Pumpio = 'pumpio', - Redmatrix = 'redmatrix', - Rss2 = 'rss2', - Smtp = 'smtp', - Tent = 'tent', - Tumblr = 'tumblr', - Twitter = 'twitter', - Wordpress = 'wordpress', - Xmpp = 'xmpp' -} -/** Usage statistics for this server. */ -export interface Usage { - users: Users - localPosts: number | null - localComments: number | null -} -/** statistics about the users of this server. */ -export interface Users { - total: number | null - activeHalfyear: number | null - activeMonth: number | null -} export function watchNote(watcherId: string, noteAuthorId: string, noteId: string): Promise<void> export function unwatchNote(watcherId: string, noteId: string): Promise<void> export enum PushNotificationKind { diff --git a/packages/backend-rs/index.js b/packages/backend-rs/index.js index 3fd0fc95eb..1da5b752d7 100644 --- a/packages/backend-rs/index.js +++ b/packages/backend-rs/index.js @@ -310,7 +310,7 @@ if (!nativeBinding) { throw new Error(`Failed to load native binding`) } -const { SECOND, MINUTE, HOUR, DAY, USER_ONLINE_THRESHOLD, USER_ACTIVE_THRESHOLD, FILE_TYPE_BROWSERSAFE, loadEnv, loadConfig, stringToAcct, acctToString, greet, initializeRustLogger, showServerInfo, isBlockedServer, isSilencedServer, isAllowedServer, checkWordMute, getFullApAccount, isSelfHost, isSameOrigin, extractHost, toPuny, isUnicodeEmoji, sqlLikeEscape, safeForSql, formatMilliseconds, getImageSizeFromUrl, getNoteSummary, isQuote, isSafeUrl, latestVersion, toMastodonId, fromMastodonId, fetchMeta, metaToPugArgs, nyaify, hashPassword, verifyPassword, isOldPasswordAlgorithm, decodeReaction, countReactions, toDbReaction, removeOldAttestationChallenges, cpuInfo, cpuUsage, memoryUsage, storageUsage, AntennaSrc, DriveFileUsageHint, MutedNoteReason, NoteVisibility, NotificationType, PageVisibility, PollNoteVisibility, RelayStatus, UserEmojiModPerm, UserProfileFfvisibility, UserProfileMutingNotificationTypes, updateAntennasOnNewNote, fetchNodeinfo, nodeinfo_2_1, nodeinfo_2_0, Protocol, Inbound, Outbound, watchNote, unwatchNote, PushNotificationKind, sendPushNotification, publishToChannelStream, ChatEvent, publishToChatStream, ChatIndexEvent, publishToChatIndexStream, publishToBroadcastStream, publishToGroupChatStream, publishToModerationStream, getTimestamp, genId, genIdAt, generateSecureRandomString, generateUserToken } = nativeBinding +const { SECOND, MINUTE, HOUR, DAY, USER_ONLINE_THRESHOLD, USER_ACTIVE_THRESHOLD, FILE_TYPE_BROWSERSAFE, loadEnv, loadConfig, stringToAcct, acctToString, fetchNodeinfo, nodeinfo_2_1, nodeinfo_2_0, Protocol, Inbound, Outbound, greet, initializeRustLogger, showServerInfo, isBlockedServer, isSilencedServer, isAllowedServer, checkWordMute, getFullApAccount, isSelfHost, isSameOrigin, extractHost, toPuny, isUnicodeEmoji, sqlLikeEscape, safeForSql, formatMilliseconds, getImageSizeFromUrl, getNoteSummary, isQuote, isSafeUrl, latestVersion, toMastodonId, fromMastodonId, fetchMeta, metaToPugArgs, nyaify, hashPassword, verifyPassword, isOldPasswordAlgorithm, decodeReaction, countReactions, toDbReaction, removeOldAttestationChallenges, cpuInfo, cpuUsage, memoryUsage, storageUsage, AntennaSrc, DriveFileUsageHint, MutedNoteReason, NoteVisibility, NotificationType, PageVisibility, PollNoteVisibility, RelayStatus, UserEmojiModPerm, UserProfileFfvisibility, UserProfileMutingNotificationTypes, updateAntennasOnNewNote, watchNote, unwatchNote, PushNotificationKind, sendPushNotification, publishToChannelStream, ChatEvent, publishToChatStream, ChatIndexEvent, publishToChatIndexStream, publishToBroadcastStream, publishToGroupChatStream, publishToModerationStream, getTimestamp, genId, genIdAt, generateSecureRandomString, generateUserToken } = nativeBinding module.exports.SECOND = SECOND module.exports.MINUTE = MINUTE @@ -323,6 +323,12 @@ module.exports.loadEnv = loadEnv module.exports.loadConfig = loadConfig module.exports.stringToAcct = stringToAcct module.exports.acctToString = acctToString +module.exports.fetchNodeinfo = fetchNodeinfo +module.exports.nodeinfo_2_1 = nodeinfo_2_1 +module.exports.nodeinfo_2_0 = nodeinfo_2_0 +module.exports.Protocol = Protocol +module.exports.Inbound = Inbound +module.exports.Outbound = Outbound module.exports.greet = greet module.exports.initializeRustLogger = initializeRustLogger module.exports.showServerInfo = showServerInfo @@ -372,12 +378,6 @@ module.exports.UserEmojiModPerm = UserEmojiModPerm module.exports.UserProfileFfvisibility = UserProfileFfvisibility module.exports.UserProfileMutingNotificationTypes = UserProfileMutingNotificationTypes module.exports.updateAntennasOnNewNote = updateAntennasOnNewNote -module.exports.fetchNodeinfo = fetchNodeinfo -module.exports.nodeinfo_2_1 = nodeinfo_2_1 -module.exports.nodeinfo_2_0 = nodeinfo_2_0 -module.exports.Protocol = Protocol -module.exports.Inbound = Inbound -module.exports.Outbound = Outbound module.exports.watchNote = watchNote module.exports.unwatchNote = unwatchNote module.exports.PushNotificationKind = PushNotificationKind diff --git a/packages/backend-rs/src/database/cache.rs b/packages/backend-rs/src/database/cache.rs index abc90ef2d1..29b02f2335 100644 --- a/packages/backend-rs/src/database/cache.rs +++ b/packages/backend-rs/src/database/cache.rs @@ -46,13 +46,13 @@ fn wildcard(category: Category) -> String { /// /// This overwrites the exsisting cache with the same key. /// -/// ## Arguments +/// # Arguments /// -/// * `key` - key (will be prefixed automatically) -/// * `value` - (de)serializable value -/// * `expire_seconds` - TTL +/// - `key` : key (prefixed automatically) +/// - `value` : (de)serializable value +/// - `expire_seconds` : TTL /// -/// ## Example +/// # Example /// /// ``` /// # use backend_rs::database::cache; @@ -89,11 +89,11 @@ pub async fn set<V: for<'a> Deserialize<'a> + Serialize>( /// If the Redis connection is fine, this returns `Ok(data)` where `data` /// is the cached value. Returns `Ok(None)` if there is no value corresponding to `key`. /// -/// ## Arguments +/// # Argument /// -/// * `key` - key (will be prefixed automatically) +/// - `key` : key (will be prefixed automatically) /// -/// ## Example +/// # Example /// /// ``` /// # use backend_rs::database::cache; @@ -126,9 +126,9 @@ pub async fn get<V: for<'a> Deserialize<'a> + Serialize>(key: &str) -> Result<Op /// If the Redis connection is fine, this returns `Ok(())` /// regardless of whether the cache exists. /// -/// ## Arguments +/// # Argument /// -/// * `key` - key (will be prefixed automatically) +/// - `key` : key (prefixed automatically) /// /// ## Example /// @@ -159,12 +159,12 @@ pub async fn delete(key: &str) -> Result<(), Error> { /// The usage is the same as [set], except that you need to /// use [get_one] and [delete_one] to get/delete the cache. /// -/// ## Arguments +/// # Arguments /// -/// * `category` - one of [Category] -/// * `key` - key (will be prefixed automatically) -/// * `value` - (de)serializable value -/// * `expire_seconds` - TTL +/// - `category` : one of [Category] +/// - `key` : key (prefixed automatically) +/// - `value` : (de)serializable value +/// - `expire_seconds` : TTL pub async fn set_one<V: for<'a> Deserialize<'a> + Serialize>( category: Category, key: &str, @@ -178,10 +178,10 @@ pub async fn set_one<V: for<'a> Deserialize<'a> + Serialize>( /// /// The usage is basically the same as [get]. /// -/// ## Arguments +/// # Arguments /// -/// * `category` - one of [Category] -/// * `key` - key (will be prefixed automatically) +/// - `category` : one of [Category] +/// - `key` : key (prefixed automatically) pub async fn get_one<V: for<'a> Deserialize<'a> + Serialize>( category: Category, key: &str, @@ -193,19 +193,19 @@ pub async fn get_one<V: for<'a> Deserialize<'a> + Serialize>( /// /// The usage is basically the same as [delete]. /// -/// ## Arguments +/// # Arguments /// -/// * `category` - one of [Category] -/// * `key` - key (will be prefixed automatically) +/// - `category` : one of [Category] +/// - `key` : key (prefixed automatically) pub async fn delete_one(category: Category, key: &str) -> Result<(), Error> { delete(&categorize(category, key)).await } /// Deletes all Redis caches under a `category`. /// -/// ## Arguments +/// # Argument /// -/// * `category` - one of [Category] +/// - `category` : one of [Category] pub async fn delete_all(category: Category) -> Result<(), Error> { let mut redis = redis_conn().await?; let keys: Vec<Vec<u8>> = redis.keys(wildcard(category)).await?; diff --git a/packages/backend-rs/src/database/mod.rs b/packages/backend-rs/src/database/mod.rs index 428bc17435..e80c3c74a2 100644 --- a/packages/backend-rs/src/database/mod.rs +++ b/packages/backend-rs/src/database/mod.rs @@ -3,6 +3,9 @@ pub use redis::key as redis_key; pub use redis::redis_conn; pub use redis::RedisConnError; +/// Utilities for using Redis cache pub mod cache; +/// PostgreSQL interface pub mod postgresql; +/// Redis interface pub mod redis; diff --git a/packages/backend-rs/src/federation/mod.rs b/packages/backend-rs/src/federation/mod.rs index 93a92c008b..4251d784bf 100644 --- a/packages/backend-rs/src/federation/mod.rs +++ b/packages/backend-rs/src/federation/mod.rs @@ -1 +1,2 @@ pub mod acct; +pub mod nodeinfo; diff --git a/packages/backend-rs/src/service/nodeinfo/fetch.rs b/packages/backend-rs/src/federation/nodeinfo/fetch.rs similarity index 99% rename from packages/backend-rs/src/service/nodeinfo/fetch.rs rename to packages/backend-rs/src/federation/nodeinfo/fetch.rs index 7c781cd73d..b68b222626 100644 --- a/packages/backend-rs/src/service/nodeinfo/fetch.rs +++ b/packages/backend-rs/src/federation/nodeinfo/fetch.rs @@ -1,4 +1,4 @@ -use crate::service::nodeinfo::schema::*; +use crate::federation::nodeinfo::schema::*; use crate::util::http_client; use isahc::AsyncReadResponseExt; use serde::{Deserialize, Serialize}; diff --git a/packages/backend-rs/src/service/nodeinfo/generate.rs b/packages/backend-rs/src/federation/nodeinfo/generate.rs similarity index 99% rename from packages/backend-rs/src/service/nodeinfo/generate.rs rename to packages/backend-rs/src/federation/nodeinfo/generate.rs index 8976dc6a13..804dd3213c 100644 --- a/packages/backend-rs/src/service/nodeinfo/generate.rs +++ b/packages/backend-rs/src/federation/nodeinfo/generate.rs @@ -1,8 +1,8 @@ use crate::config::CONFIG; use crate::database::{cache, db_conn}; +use crate::federation::nodeinfo::schema::*; use crate::misc::meta::fetch_meta; use crate::model::entity::{note, user}; -use crate::service::nodeinfo::schema::*; use sea_orm::{ColumnTrait, DbErr, EntityTrait, PaginatorTrait, QueryFilter}; use serde_json::json; use std::collections::HashMap; diff --git a/packages/backend-rs/src/service/nodeinfo/mod.rs b/packages/backend-rs/src/federation/nodeinfo/mod.rs similarity index 100% rename from packages/backend-rs/src/service/nodeinfo/mod.rs rename to packages/backend-rs/src/federation/nodeinfo/mod.rs diff --git a/packages/backend-rs/src/service/nodeinfo/schema.rs b/packages/backend-rs/src/federation/nodeinfo/schema.rs similarity index 100% rename from packages/backend-rs/src/service/nodeinfo/schema.rs rename to packages/backend-rs/src/federation/nodeinfo/schema.rs diff --git a/packages/backend-rs/src/lib.rs b/packages/backend-rs/src/lib.rs index 9152a81543..ed601b9f51 100644 --- a/packages/backend-rs/src/lib.rs +++ b/packages/backend-rs/src/lib.rs @@ -1,10 +1,18 @@ -pub use macro_rs::{export, ts_export}; +use macro_rs::{export, ts_export}; +/// Server configurations and environment variables pub mod config; +/// Interfaces for accessing PostgreSQL and Redis pub mod database; +/// Services used to federate with other servers pub mod federation; +/// Initializers pub mod init; +/// Miscellaneous utilities pub mod misc; +/// Database structure, auto-generated by [sea_orm] pub mod model; +/// Services provided for local users pub mod service; +/// Basic utilities such as ID generator and HTTP client pub mod util; diff --git a/packages/backend-rs/src/service/mod.rs b/packages/backend-rs/src/service/mod.rs index 4a5a0a7311..abbd7fd7c4 100644 --- a/packages/backend-rs/src/service/mod.rs +++ b/packages/backend-rs/src/service/mod.rs @@ -1,5 +1,4 @@ pub mod antenna; -pub mod nodeinfo; pub mod note; pub mod push_notification; pub mod stream; diff --git a/packages/backend-rs/src/service/push_notification.rs b/packages/backend-rs/src/service/push_notification.rs index 797b4cf5c1..09edb4fff9 100644 --- a/packages/backend-rs/src/service/push_notification.rs +++ b/packages/backend-rs/src/service/push_notification.rs @@ -4,7 +4,7 @@ use crate::misc::meta::fetch_meta; use crate::model::entity::sw_subscription; use crate::util::http_client; use once_cell::sync::OnceCell; -use sea_orm::{prelude::*, DbErr}; +use sea_orm::prelude::*; use web_push::{ ContentEncoding, IsahcWebPushClient, SubscriptionInfo, SubscriptionKeys, VapidSignatureBuilder, WebPushClient, WebPushError, WebPushMessageBuilder, @@ -102,7 +102,7 @@ fn compact_content( } async fn handle_web_push_failure( - db: &DatabaseConnection, + db: &DbConn, err: WebPushError, subscription_id: &str, error_message: &str, diff --git a/packages/backend-rs/src/util/http_client.rs b/packages/backend-rs/src/util/http_client.rs index bc5976c283..c2c917964d 100644 --- a/packages/backend-rs/src/util/http_client.rs +++ b/packages/backend-rs/src/util/http_client.rs @@ -13,6 +13,22 @@ pub enum Error { static CLIENT: OnceCell<HttpClient> = OnceCell::new(); +/// Returns an [HttpClient] that takes the proxy configuration into account. +/// +/// # Example +/// ```no_run +/// # use backend_rs::util::http_client::client; +/// use isahc::ReadResponseExt; +/// +/// # fn f() -> Result<(), Box<dyn std::error::Error>> { +/// let mut response = client()?.get("https://example.com/")?; +/// +/// if response.status().is_success() { +/// println!("{}", response.text()?); +/// } +/// # Ok(()) +/// # } +/// ``` pub fn client() -> Result<HttpClient, Error> { CLIENT .get_or_try_init(|| { diff --git a/packages/backend-rs/src/util/id.rs b/packages/backend-rs/src/util/id.rs index 39e4c34045..fb0c25b7d3 100644 --- a/packages/backend-rs/src/util/id.rs +++ b/packages/backend-rs/src/util/id.rs @@ -1,5 +1,3 @@ -//! ID generation utility based on [cuid2] - use crate::config::CONFIG; use basen::BASE36; use chrono::{DateTime, NaiveDateTime, Utc}; diff --git a/packages/backend-rs/src/util/mod.rs b/packages/backend-rs/src/util/mod.rs index 93a5fc5ce7..21e9b157a4 100644 --- a/packages/backend-rs/src/util/mod.rs +++ b/packages/backend-rs/src/util/mod.rs @@ -1,3 +1,6 @@ +/// Shared [isahc] HTTP client pub mod http_client; +/// ID generation utility based on [cuid2] pub mod id; +/// Secure random string generator pub mod random;