From cbbdc7713533eeedbbb27aca06de62b7aaa9257c Mon Sep 17 00:00:00 2001 From: GitLab CI Date: Mon, 29 Jul 2024 04:08:06 +0000 Subject: [PATCH 001/117] chore(deps): update rust crate serde_json to 1.0.121 --- Cargo.lock | 5 +++-- Cargo.toml | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 974715ab54..8dd4e47cad 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3022,11 +3022,12 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.120" +version = "1.0.121" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e0d21c9a8cae1235ad58a00c11cb40d4b1e5c784f1ef2c537876ed6ffd8b7c5" +checksum = "4ab380d7d9f22ef3f21ad3e6c1ebe8e4fc7a2000ccba2e4d71fc96f15b2cb609" dependencies = [ "itoa", + "memchr", "ryu", "serde", ] diff --git a/Cargo.toml b/Cargo.toml index 421ae8b674..21967968b8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -38,7 +38,7 @@ regex = { version = "1.10.5", default-features = false } rmp-serde = { version = "1.3.0", default-features = false } sea-orm = { version = "0.12.15", default-features = false } serde = { version = "1.0.204", default-features = false } -serde_json = { version = "1.0.120", default-features = false } +serde_json = { version = "1.0.121", default-features = false } serde_yaml = { version = "0.9.34", default-features = false } syn = { version = "2.0.72", default-features = false } sysinfo = { version = "0.30.13", default-features = false } From 846cd892a81f40eca9fa792a73b61b9cd60ed577 Mon Sep 17 00:00:00 2001 From: GitLab CI Date: Mon, 29 Jul 2024 04:09:01 +0000 Subject: [PATCH 002/117] fix(deps): update dependency cbor-x to v1.6.0 --- packages/backend/package.json | 2 +- pnpm-lock.yaml | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/backend/package.json b/packages/backend/package.json index d0f89a4f2b..c7550dd742 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -39,7 +39,7 @@ "blurhash": "2.0.5", "bull": "4.15.1", "cacheable-lookup": "git+https://github.com/TheEssem/cacheable-lookup.git#dd2fb616366a3c68dcf321a57a67295967b204bf", - "cbor-x": "1.5.9", + "cbor-x": "1.6.0", "chalk": "5.3.0", "cli-highlight": "2.1.11", "color-convert": "2.0.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e6eabaca8f..addea19990 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -106,8 +106,8 @@ importers: specifier: git+https://github.com/TheEssem/cacheable-lookup.git#dd2fb616366a3c68dcf321a57a67295967b204bf version: https://codeload.github.com/TheEssem/cacheable-lookup/tar.gz/dd2fb616366a3c68dcf321a57a67295967b204bf cbor-x: - specifier: 1.5.9 - version: 1.5.9 + specifier: 1.6.0 + version: 1.6.0 chalk: specifier: 5.3.0 version: 5.3.0 @@ -3077,8 +3077,8 @@ packages: resolution: {integrity: sha512-Ig1zM66BjLfTXpNgKpvBePq271BPOvu8MR0Jl080yG7Jsl+wAZunfrwiwA+9ruzm/WEdIV5QF/bjDZTqyAIVHA==} hasBin: true - cbor-x@1.5.9: - resolution: {integrity: sha512-OEI5rEu3MeR0WWNUXuIGkxmbXVhABP+VtgAXzm48c9ulkrsvxshjjk94XSOGphyAKeNGLPfAxxzEtgQ6rEVpYQ==} + cbor-x@1.6.0: + resolution: {integrity: sha512-0kareyRwHSkL6ws5VXHEf8uY1liitysCVJjlmhaLG+IXLqhSaOO+t63coaso7yjwEzWZzLy8fJo06gZDVQM9Qg==} chalk@2.4.2: resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} @@ -9305,7 +9305,7 @@ snapshots: '@cbor-extract/cbor-extract-win32-x64': 2.2.0 optional: true - cbor-x@1.5.9: + cbor-x@1.6.0: optionalDependencies: cbor-extract: 2.2.0 From 41d65c800bea059adfe9f8adf1a1f45602847e82 Mon Sep 17 00:00:00 2001 From: jolupa Date: Sun, 28 Jul 2024 08:07:25 +0000 Subject: [PATCH 003/117] locale: update translations (Catalan) Currently translated at 100.0% (1952 of 1952 strings) Translation: Firefish/locales Translate-URL: https://hosted.weblate.org/projects/firefish/locales/ca/ --- locales/ca-ES.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/locales/ca-ES.yml b/locales/ca-ES.yml index 89aede8cdd..048fda1d05 100644 --- a/locales/ca-ES.yml +++ b/locales/ca-ES.yml @@ -1934,6 +1934,12 @@ _permissions: "read:reactions": Consulta les teves reaccions "read:pages": Consulta la teva pàgina "read:page-likes": Veure les pàgines que t'agraden + push: Enviar notificacions emergents + follow: Seguir i deixar de seguir comptes + read: Llegir (llegir línies de temps, notificacions, reaccions, silenciats, informació + dels comptes, etc.) + write: Escriure (escriure publicacions, reaccionar a publicacions, silenciar usuaris, + editar informació dels comptes, etc.) _poll: noOnlyOneChoice: Calen almenys dues opcions canMultipleVote: Permet seleccionar diverses opcions From 27e6469f8c4e32dc481a707e52d244e277d8d25a Mon Sep 17 00:00:00 2001 From: naskya Date: Mon, 29 Jul 2024 17:52:19 +0900 Subject: [PATCH 004/117] refactor (backend): port renderFollow to backend-rs --- packages/backend-rs/index.d.ts | 24 ++++--- packages/backend-rs/index.js | 1 + .../federation/activitypub/object/follow.rs | 65 +++++++++++++++++++ .../src/federation/activitypub/object/mod.rs | 4 +- .../federation/activitypub/object/relay.rs | 28 -------- packages/backend-rs/src/misc/user/mod.rs | 22 +++++++ .../src/remote/activitypub/models/person.ts | 8 +-- .../src/remote/activitypub/renderer/follow.ts | 22 ------- .../src/remote/activitypub/resolver.ts | 2 +- packages/backend/src/server/activitypub.ts | 8 ++- .../backend/src/services/blocking/create.ts | 2 +- .../src/services/fetch-instance-metadata.ts | 2 +- .../backend/src/services/following/create.ts | 2 +- .../backend/src/services/following/delete.ts | 2 +- .../backend/src/services/following/reject.ts | 2 +- .../src/services/following/requests/accept.ts | 3 +- .../src/services/following/requests/cancel.ts | 3 +- .../src/services/following/requests/create.ts | 3 +- 18 files changed, 126 insertions(+), 77 deletions(-) create mode 100644 packages/backend-rs/src/federation/activitypub/object/follow.rs delete mode 100644 packages/backend-rs/src/federation/activitypub/object/relay.rs delete mode 100644 packages/backend/src/remote/activitypub/renderer/follow.ts diff --git a/packages/backend-rs/index.d.ts b/packages/backend-rs/index.d.ts index d939266207..720249ef53 100644 --- a/packages/backend-rs/index.d.ts +++ b/packages/backend-rs/index.d.ts @@ -412,6 +412,13 @@ export declare function fetchMeta(): Promise /** Fetches and returns the NodeInfo (version 2.0) of a remote server. */ export declare function fetchNodeinfo(host: string): Promise +export interface Follow { + id: string + type: Activity + actor: string + object: string +} + export interface Following { id: string createdAt: DateTimeWithTimeZone @@ -425,13 +432,6 @@ export interface Following { followeeSharedInbox: string | null } -export interface FollowRelay { - id: string - type: Activity - actor: string - object: string -} - export interface FollowRequest { id: string createdAt: DateTimeWithTimeZone @@ -1265,7 +1265,9 @@ export type RelayStatus = 'accepted'| /** Delete all entries in the [attestation_challenge] table created at more than 5 minutes ago */ export declare function removeOldAttestationChallenges(): Promise -export declare function renderFollowRelay(relayId: string): Promise +export declare function renderFollow(follower: UserLike, followee: UserLike, requestId?: string | undefined | null): Follow + +export declare function renderFollowRelay(relayId: string): Promise export interface RenoteMuting { id: string @@ -1537,6 +1539,12 @@ export interface UserKeypair { privateKey: string } +export interface UserLike { + id: string + host: string | null + uri: string +} + export interface UserList { id: string createdAt: DateTimeWithTimeZone diff --git a/packages/backend-rs/index.js b/packages/backend-rs/index.js index 9ca4963455..2955ef672d 100644 --- a/packages/backend-rs/index.js +++ b/packages/backend-rs/index.js @@ -437,6 +437,7 @@ module.exports.PushNotificationKind = nativeBinding.PushNotificationKind module.exports.PushSubscriptionType = nativeBinding.PushSubscriptionType module.exports.RelayStatus = nativeBinding.RelayStatus module.exports.removeOldAttestationChallenges = nativeBinding.removeOldAttestationChallenges +module.exports.renderFollow = nativeBinding.renderFollow module.exports.renderFollowRelay = nativeBinding.renderFollowRelay module.exports.safeForSql = nativeBinding.safeForSql module.exports.sendPushNotification = nativeBinding.sendPushNotification diff --git a/packages/backend-rs/src/federation/activitypub/object/follow.rs b/packages/backend-rs/src/federation/activitypub/object/follow.rs new file mode 100644 index 0000000000..10ccbcd600 --- /dev/null +++ b/packages/backend-rs/src/federation/activitypub/object/follow.rs @@ -0,0 +1,65 @@ +use super::*; +use crate::{config::CONFIG, federation::internal_actor, misc::user}; +use serde::Serialize; + +#[macros::export(object)] +pub struct UserLike { + pub id: String, + pub host: Option, + pub uri: String, +} + +#[derive(Serialize)] +#[macros::export(object)] +pub struct Follow { + pub id: String, + pub r#type: Activity, + pub actor: String, + pub object: String, +} + +impl ActivityPubObject for Follow {} + +impl Follow { + #[allow(dead_code)] // TODO: remove this line + fn new(follower: UserLike, followee: UserLike, request_id: Option) -> Self { + Self { + id: request_id.unwrap_or_else(|| { + format!("{}/follows/{}/{}", CONFIG.url, follower.id, followee.id) + }), + r#type: Activity::Follow, + actor: match user::is_local!(follower) { + true => format!("{}/users/{}", CONFIG.url, follower.id), + false => follower.uri, + }, + object: match user::is_local!(followee) { + true => format!("{}/users/{}", CONFIG.url, followee.id), + false => followee.uri, + }, + } + } + + #[allow(dead_code)] // TODO: remove this line + async fn new_relay(relay_id: String) -> Result { + Ok(Self { + 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: AS_PUBLIC_URL.to_owned(), + }) + } +} + +#[macros::ts_export] +pub fn render_follow(follower: UserLike, followee: UserLike, request_id: Option) -> Follow { + Follow::new(follower, followee, request_id) +} + +#[macros::ts_export] +pub async fn render_follow_relay(relay_id: String) -> Result { + Follow::new_relay(relay_id).await +} diff --git a/packages/backend-rs/src/federation/activitypub/object/mod.rs b/packages/backend-rs/src/federation/activitypub/object/mod.rs index b245bca98a..7fbd1eebda 100644 --- a/packages/backend-rs/src/federation/activitypub/object/mod.rs +++ b/packages/backend-rs/src/federation/activitypub/object/mod.rs @@ -1,4 +1,4 @@ -pub mod relay; +pub mod follow; pub trait ActivityPubObject {} @@ -7,3 +7,5 @@ pub trait ActivityPubObject {} pub enum Activity { Follow, } + +const AS_PUBLIC_URL: &str = "https://www.w3.org/ns/activitystreams#Public"; diff --git a/packages/backend-rs/src/federation/activitypub/object/relay.rs b/packages/backend-rs/src/federation/activitypub/object/relay.rs deleted file mode 100644 index f3d7656564..0000000000 --- a/packages/backend-rs/src/federation/activitypub/object/relay.rs +++ /dev/null @@ -1,28 +0,0 @@ -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 { - 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/misc/user/mod.rs b/packages/backend-rs/src/misc/user/mod.rs index 16ee43aeca..059f3072c5 100644 --- a/packages/backend-rs/src/misc/user/mod.rs +++ b/packages/backend-rs/src/misc/user/mod.rs @@ -1 +1,23 @@ pub mod count; + +#[doc(hidden)] // hide the macro in the top doc page +#[macro_export] +macro_rules! is_local { + ($user_like:expr) => { + $user_like.host.is_none() + }; +} + +#[doc(inline)] // show the macro in the module doc page +pub use is_local; + +#[doc(hidden)] // hide the macro in the top doc page +#[macro_export] +macro_rules! is_remote { + ($user_like:expr) => { + $user_like.host.is_some() + }; +} + +#[doc(inline)] // show the macro in the module doc page +pub use is_remote; diff --git a/packages/backend/src/remote/activitypub/models/person.ts b/packages/backend/src/remote/activitypub/models/person.ts index e9c1b5bd1b..663f9be299 100644 --- a/packages/backend/src/remote/activitypub/models/person.ts +++ b/packages/backend/src/remote/activitypub/models/person.ts @@ -207,7 +207,7 @@ export async function createPerson( try { const data = await fetch(person.followers, { headers: { Accept: "application/json" }, - size: 1024 * 1024 + size: 1024 * 1024, }); const json_data = JSON.parse(await data.text()); @@ -223,7 +223,7 @@ export async function createPerson( try { const data = await fetch(person.following, { headers: { Accept: "application/json" }, - size: 1024 * 1024 + size: 1024 * 1024, }); const json_data = JSON.parse(await data.text()); @@ -492,7 +492,7 @@ export async function updatePerson( try { const data = await fetch(person.followers, { headers: { Accept: "application/json" }, - size: 1024 * 1024 + size: 1024 * 1024, }); const json_data = JSON.parse(await data.text()); @@ -508,7 +508,7 @@ export async function updatePerson( try { const data = await fetch(person.following, { headers: { Accept: "application/json" }, - size: 1024 * 1024 + size: 1024 * 1024, }); const json_data = JSON.parse(await data.text()); diff --git a/packages/backend/src/remote/activitypub/renderer/follow.ts b/packages/backend/src/remote/activitypub/renderer/follow.ts deleted file mode 100644 index 30ad799507..0000000000 --- a/packages/backend/src/remote/activitypub/renderer/follow.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { config } from "@/config.js"; -import type { User } from "@/models/entities/user.js"; -import { Users } from "@/models/index.js"; - -export default ( - follower: { id: User["id"]; host: User["host"]; uri: User["host"] }, - followee: { id: User["id"]; host: User["host"]; uri: User["host"] }, - requestId?: string, -) => { - const follow = { - id: requestId ?? `${config.url}/follows/${follower.id}/${followee.id}`, - type: "Follow", - actor: Users.isLocalUser(follower) - ? `${config.url}/users/${follower.id}` - : follower.uri, - object: Users.isLocalUser(followee) - ? `${config.url}/users/${followee.id}` - : followee.uri, - } as any; - - return follow; -}; diff --git a/packages/backend/src/remote/activitypub/resolver.ts b/packages/backend/src/remote/activitypub/resolver.ts index c9d94e9fd6..48ca3e6244 100644 --- a/packages/backend/src/remote/activitypub/resolver.ts +++ b/packages/backend/src/remote/activitypub/resolver.ts @@ -6,6 +6,7 @@ import { isAllowedServer, isBlockedServer, isSelfHost, + renderFollow, } from "backend-rs"; import { apGet } from "./request.js"; import type { IObject, ICollection, IOrderedCollection } from "./type.js"; @@ -24,7 +25,6 @@ import { renderPerson } from "@/remote/activitypub/renderer/person.js"; import renderQuestion from "@/remote/activitypub/renderer/question.js"; import renderCreate from "@/remote/activitypub/renderer/create.js"; import { renderActivity } from "@/remote/activitypub/renderer/index.js"; -import renderFollow from "@/remote/activitypub/renderer/follow.js"; import { apLogger } from "@/remote/activitypub/logger.js"; import { IsNull, Not } from "typeorm"; diff --git a/packages/backend/src/server/activitypub.ts b/packages/backend/src/server/activitypub.ts index 81513f5d89..bc0442d381 100644 --- a/packages/backend/src/server/activitypub.ts +++ b/packages/backend/src/server/activitypub.ts @@ -9,7 +9,12 @@ import renderKey from "@/remote/activitypub/renderer/key.js"; import { renderPerson } from "@/remote/activitypub/renderer/person.js"; import renderEmoji from "@/remote/activitypub/renderer/emoji.js"; import { inbox as processInbox } from "@/queue/index.js"; -import { fetchMeta, getInstanceActor, isSelfHost } from "backend-rs"; +import { + fetchMeta, + getInstanceActor, + isSelfHost, + renderFollow, +} from "backend-rs"; import { Notes, Users, @@ -24,7 +29,6 @@ import { checkFetch, getSignatureUser, } from "@/remote/activitypub/check-fetch.js"; -import renderFollow from "@/remote/activitypub/renderer/follow.js"; import Featured from "./activitypub/featured.js"; import Following from "./activitypub/following.js"; import Followers from "./activitypub/followers.js"; diff --git a/packages/backend/src/services/blocking/create.ts b/packages/backend/src/services/blocking/create.ts index 1d7b80ffbf..9bc59e70e9 100644 --- a/packages/backend/src/services/blocking/create.ts +++ b/packages/backend/src/services/blocking/create.ts @@ -1,5 +1,4 @@ import { renderActivity } from "@/remote/activitypub/renderer/index.js"; -import renderFollow from "@/remote/activitypub/renderer/follow.js"; import { renderUndo } from "@/remote/activitypub/renderer/undo.js"; import { renderBlock } from "@/remote/activitypub/renderer/block.js"; import { deliver } from "@/queue/index.js"; @@ -20,6 +19,7 @@ import { publishToMainStream, publishToUserStream, UserEvent, + renderFollow, } from "backend-rs"; import { getActiveWebhooks } from "@/misc/webhook-cache.js"; import { webhookDeliver } from "@/queue/index.js"; diff --git a/packages/backend/src/services/fetch-instance-metadata.ts b/packages/backend/src/services/fetch-instance-metadata.ts index 494027a37c..d0bcdd33a4 100644 --- a/packages/backend/src/services/fetch-instance-metadata.ts +++ b/packages/backend/src/services/fetch-instance-metadata.ts @@ -156,7 +156,7 @@ async function fetchFaviconUrl( // TODO //timeout: 10000, agent: getAgentByUrl, - size: 1024 * 1024 + size: 1024 * 1024, }); if (favicon.ok) { diff --git a/packages/backend/src/services/following/create.ts b/packages/backend/src/services/following/create.ts index aea5bd48a5..c3dc91ff9e 100644 --- a/packages/backend/src/services/following/create.ts +++ b/packages/backend/src/services/following/create.ts @@ -1,5 +1,4 @@ import { renderActivity } from "@/remote/activitypub/renderer/index.js"; -import renderFollow from "@/remote/activitypub/renderer/follow.js"; import renderAccept from "@/remote/activitypub/renderer/accept.js"; import renderReject from "@/remote/activitypub/renderer/reject.js"; import { deliver } from "@/queue/index.js"; @@ -23,6 +22,7 @@ import { publishToMainStream, publishToUserStream, UserEvent, + renderFollow, } from "backend-rs"; import { createNotification } from "@/services/create-notification.js"; import { isDuplicateKeyValueError } from "@/misc/is-duplicate-key-value-error.js"; diff --git a/packages/backend/src/services/following/delete.ts b/packages/backend/src/services/following/delete.ts index 9d0135b81f..e46d8422db 100644 --- a/packages/backend/src/services/following/delete.ts +++ b/packages/backend/src/services/following/delete.ts @@ -3,9 +3,9 @@ import { publishToMainStream, publishToUserStream, UserEvent, + renderFollow, } from "backend-rs"; import { renderActivity } from "@/remote/activitypub/renderer/index.js"; -import renderFollow from "@/remote/activitypub/renderer/follow.js"; import { renderUndo } from "@/remote/activitypub/renderer/undo.js"; import renderReject from "@/remote/activitypub/renderer/reject.js"; import { deliver, webhookDeliver } from "@/queue/index.js"; diff --git a/packages/backend/src/services/following/reject.ts b/packages/backend/src/services/following/reject.ts index 1523573bf9..aaed1df3a8 100644 --- a/packages/backend/src/services/following/reject.ts +++ b/packages/backend/src/services/following/reject.ts @@ -1,5 +1,4 @@ import { renderActivity } from "@/remote/activitypub/renderer/index.js"; -import renderFollow from "@/remote/activitypub/renderer/follow.js"; import renderReject from "@/remote/activitypub/renderer/reject.js"; import { deliver, webhookDeliver } from "@/queue/index.js"; import { @@ -7,6 +6,7 @@ import { publishToMainStream, publishToUserStream, UserEvent, + renderFollow, } from "backend-rs"; import type { ILocalUser, IRemoteUser } from "@/models/entities/user.js"; import { Users, FollowRequests, Followings } from "@/models/index.js"; diff --git a/packages/backend/src/services/following/requests/accept.ts b/packages/backend/src/services/following/requests/accept.ts index bcd7d2cf4c..81484d6fba 100644 --- a/packages/backend/src/services/following/requests/accept.ts +++ b/packages/backend/src/services/following/requests/accept.ts @@ -1,8 +1,7 @@ import { renderActivity } from "@/remote/activitypub/renderer/index.js"; -import renderFollow from "@/remote/activitypub/renderer/follow.js"; import renderAccept from "@/remote/activitypub/renderer/accept.js"; import { deliver } from "@/queue/index.js"; -import { Event, publishToMainStream } from "backend-rs"; +import { Event, publishToMainStream, renderFollow } from "backend-rs"; import { insertFollowingDoc } from "../create.js"; import type { User, CacheableUser } from "@/models/entities/user.js"; import { FollowRequests, Users } from "@/models/index.js"; diff --git a/packages/backend/src/services/following/requests/cancel.ts b/packages/backend/src/services/following/requests/cancel.ts index eb1b2dcb49..435c86f19b 100644 --- a/packages/backend/src/services/following/requests/cancel.ts +++ b/packages/backend/src/services/following/requests/cancel.ts @@ -1,8 +1,7 @@ import { renderActivity } from "@/remote/activitypub/renderer/index.js"; -import renderFollow from "@/remote/activitypub/renderer/follow.js"; import { renderUndo } from "@/remote/activitypub/renderer/undo.js"; import { deliver } from "@/queue/index.js"; -import { Event, publishToMainStream } from "backend-rs"; +import { Event, publishToMainStream, renderFollow } from "backend-rs"; import { IdentifiableError } from "@/misc/identifiable-error.js"; import type { User } from "@/models/entities/user.js"; import { Users, FollowRequests } from "@/models/index.js"; diff --git a/packages/backend/src/services/following/requests/create.ts b/packages/backend/src/services/following/requests/create.ts index 40f383cfd3..cc6b4261eb 100644 --- a/packages/backend/src/services/following/requests/create.ts +++ b/packages/backend/src/services/following/requests/create.ts @@ -1,9 +1,8 @@ import { renderActivity } from "@/remote/activitypub/renderer/index.js"; -import renderFollow from "@/remote/activitypub/renderer/follow.js"; import { deliver } from "@/queue/index.js"; import type { User } from "@/models/entities/user.js"; import { Blockings, FollowRequests, Users } from "@/models/index.js"; -import { Event, genIdAt, publishToMainStream } from "backend-rs"; +import { Event, genIdAt, publishToMainStream, renderFollow } from "backend-rs"; import { createNotification } from "@/services/create-notification.js"; import { config } from "@/config.js"; From 107ac93dddd36fba53b94d9b06199320b88801ce Mon Sep 17 00:00:00 2001 From: naskya Date: Mon, 29 Jul 2024 18:11:33 +0900 Subject: [PATCH 005/117] refactor (backend): port renderAccept to backend-rs --- Cargo.lock | 3 ++ Cargo.toml | 1 + packages/backend-rs/Cargo.toml | 1 + packages/backend-rs/index.d.ts | 12 ++++++- packages/backend-rs/index.js | 1 + .../federation/activitypub/object/accept.rs | 33 +++++++++++++++++++ .../federation/activitypub/object/follow.rs | 2 -- .../src/federation/activitypub/object/mod.rs | 3 +- .../src/remote/activitypub/renderer/accept.ts | 8 ----- .../backend/src/services/following/create.ts | 4 +-- .../src/services/following/requests/accept.ts | 10 ++++-- 11 files changed, 61 insertions(+), 17 deletions(-) create mode 100644 packages/backend-rs/src/federation/activitypub/object/accept.rs delete mode 100644 packages/backend/src/remote/activitypub/renderer/accept.ts diff --git a/Cargo.lock b/Cargo.lock index 8dd4e47cad..0d2f4d05f6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -241,6 +241,7 @@ dependencies = [ "tracing-subscriber", "url", "urlencoding", + "uuid", "web-push", "zhconv", ] @@ -3948,6 +3949,8 @@ version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81dfa00651efa65069b0b6b651f4aaa31ba9e3c3ce0137aaad053604ee7e0314" dependencies = [ + "getrandom", + "rand", "serde", ] diff --git a/Cargo.toml b/Cargo.toml index 21967968b8..be41de93f0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -49,6 +49,7 @@ tracing = { version = "0.1.40", default-features = false } tracing-subscriber = { version = "0.3.18", default-features = false } url = { version = "2.5.2", default-features = false } urlencoding = { version = "2.1.3", default-features = false } +uuid = { version = "1.10.0" } web-push = { git = "https://github.com/pimeys/rust-web-push.git", rev = "40febe4085e3cef9cdfd539c315e3e945aba0656", default-features = false } zhconv = "0.3.1" diff --git a/packages/backend-rs/Cargo.toml b/packages/backend-rs/Cargo.toml index 54efddecbe..a33e5f34c0 100644 --- a/packages/backend-rs/Cargo.toml +++ b/packages/backend-rs/Cargo.toml @@ -49,6 +49,7 @@ tracing = { workspace = true } tracing-subscriber = { workspace = true, features = ["ansi"] } url = { workspace = true } urlencoding = { workspace = true } +uuid = { workspace = true, features = ["v4", "fast-rng"] } web-push = { workspace = true, features = ["isahc-client"] } zhconv = { workspace = true } diff --git a/packages/backend-rs/index.d.ts b/packages/backend-rs/index.d.ts index 720249ef53..6aa9fed388 100644 --- a/packages/backend-rs/index.d.ts +++ b/packages/backend-rs/index.d.ts @@ -25,6 +25,13 @@ export interface AbuseUserReportLike { comment: string } +export interface Accept { + id: string + type: Activity + actor: string + object: Follow +} + export interface AccessToken { id: string createdAt: DateTimeWithTimeZone @@ -48,7 +55,8 @@ export interface Acct { export declare function acctToString(acct: Acct): string -export type Activity = 'Follow'; +export type Activity = 'Accept'| +'Follow'; export interface Ad { id: string @@ -1265,6 +1273,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 +export declare function renderAccept(userId: string, followObject: Follow): Accept + export declare function renderFollow(follower: UserLike, followee: UserLike, requestId?: string | undefined | null): Follow export declare function renderFollowRelay(relayId: string): Promise diff --git a/packages/backend-rs/index.js b/packages/backend-rs/index.js index 2955ef672d..55790c7928 100644 --- a/packages/backend-rs/index.js +++ b/packages/backend-rs/index.js @@ -437,6 +437,7 @@ module.exports.PushNotificationKind = nativeBinding.PushNotificationKind module.exports.PushSubscriptionType = nativeBinding.PushSubscriptionType module.exports.RelayStatus = nativeBinding.RelayStatus module.exports.removeOldAttestationChallenges = nativeBinding.removeOldAttestationChallenges +module.exports.renderAccept = nativeBinding.renderAccept module.exports.renderFollow = nativeBinding.renderFollow module.exports.renderFollowRelay = nativeBinding.renderFollowRelay module.exports.safeForSql = nativeBinding.safeForSql diff --git a/packages/backend-rs/src/federation/activitypub/object/accept.rs b/packages/backend-rs/src/federation/activitypub/object/accept.rs new file mode 100644 index 0000000000..a156b84c5d --- /dev/null +++ b/packages/backend-rs/src/federation/activitypub/object/accept.rs @@ -0,0 +1,33 @@ +use super::*; +use crate::config::CONFIG; +use uuid::Uuid; + +#[macros::export(object)] +pub struct Accept { + pub id: String, + pub r#type: Activity, + pub actor: String, + pub object: follow::Follow, +} + +impl ActivityPubObject for Accept {} + +impl Accept { + #[allow(dead_code)] // TODO: remove this line + fn new(user_id: String, follow_object: follow::Follow) -> Self { + Self { + id: format!("{}/{}", CONFIG.url, Uuid::new_v4()), + r#type: Activity::Accept, + actor: format!("{}/users/{}", CONFIG.url, user_id), + object: follow_object, + } + } +} + +#[cfg(any(test, doctest, feature = "napi"))] +type Follow = follow::Follow; + +#[macros::ts_export] +pub fn render_accept(user_id: String, follow_object: Follow) -> Accept { + Accept::new(user_id, follow_object) +} diff --git a/packages/backend-rs/src/federation/activitypub/object/follow.rs b/packages/backend-rs/src/federation/activitypub/object/follow.rs index 10ccbcd600..d90ba70d7e 100644 --- a/packages/backend-rs/src/federation/activitypub/object/follow.rs +++ b/packages/backend-rs/src/federation/activitypub/object/follow.rs @@ -1,6 +1,5 @@ use super::*; use crate::{config::CONFIG, federation::internal_actor, misc::user}; -use serde::Serialize; #[macros::export(object)] pub struct UserLike { @@ -9,7 +8,6 @@ pub struct UserLike { pub uri: String, } -#[derive(Serialize)] #[macros::export(object)] pub struct Follow { pub id: String, diff --git a/packages/backend-rs/src/federation/activitypub/object/mod.rs b/packages/backend-rs/src/federation/activitypub/object/mod.rs index 7fbd1eebda..ebb83035b0 100644 --- a/packages/backend-rs/src/federation/activitypub/object/mod.rs +++ b/packages/backend-rs/src/federation/activitypub/object/mod.rs @@ -1,10 +1,11 @@ +pub mod accept; pub mod follow; pub trait ActivityPubObject {} -#[derive(serde::Serialize)] #[macros::export(string_enum)] pub enum Activity { + Accept, Follow, } diff --git a/packages/backend/src/remote/activitypub/renderer/accept.ts b/packages/backend/src/remote/activitypub/renderer/accept.ts deleted file mode 100644 index 2d27a1b29d..0000000000 --- a/packages/backend/src/remote/activitypub/renderer/accept.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { config } from "@/config.js"; -import type { User } from "@/models/entities/user.js"; - -export default (object: any, user: { id: User["id"]; host: null }) => ({ - type: "Accept", - actor: `${config.url}/users/${user.id}`, - object, -}); diff --git a/packages/backend/src/services/following/create.ts b/packages/backend/src/services/following/create.ts index c3dc91ff9e..c5821786c8 100644 --- a/packages/backend/src/services/following/create.ts +++ b/packages/backend/src/services/following/create.ts @@ -1,5 +1,4 @@ import { renderActivity } from "@/remote/activitypub/renderer/index.js"; -import renderAccept from "@/remote/activitypub/renderer/accept.js"; import renderReject from "@/remote/activitypub/renderer/reject.js"; import { deliver } from "@/queue/index.js"; import createFollowRequest from "./requests/create.js"; @@ -22,6 +21,7 @@ import { publishToMainStream, publishToUserStream, UserEvent, + renderAccept, renderFollow, } from "backend-rs"; import { createNotification } from "@/services/create-notification.js"; @@ -275,7 +275,7 @@ export default async function ( if (Users.isRemoteUser(follower) && Users.isLocalUser(followee)) { const content = renderActivity( - renderAccept(renderFollow(follower, followee, requestId), followee), + renderAccept(followee.id, renderFollow(follower, followee, requestId)), ); deliver(followee.id, content, follower.inbox); } diff --git a/packages/backend/src/services/following/requests/accept.ts b/packages/backend/src/services/following/requests/accept.ts index 81484d6fba..ba1d40159d 100644 --- a/packages/backend/src/services/following/requests/accept.ts +++ b/packages/backend/src/services/following/requests/accept.ts @@ -1,7 +1,11 @@ import { renderActivity } from "@/remote/activitypub/renderer/index.js"; -import renderAccept from "@/remote/activitypub/renderer/accept.js"; import { deliver } from "@/queue/index.js"; -import { Event, publishToMainStream, renderFollow } from "backend-rs"; +import { + Event, + publishToMainStream, + renderAccept, + renderFollow, +} from "backend-rs"; import { insertFollowingDoc } from "../create.js"; import type { User, CacheableUser } from "@/models/entities/user.js"; import { FollowRequests, Users } from "@/models/index.js"; @@ -34,8 +38,8 @@ export default async function ( if (Users.isRemoteUser(follower) && Users.isLocalUser(followee)) { const content = renderActivity( renderAccept( + followee.id, renderFollow(follower, followee, request.requestId!), - followee, ), ); deliver(followee.id, content, follower.inbox); From 512fb466f8c3716a44cb012e21ac3bb093e2c03a Mon Sep 17 00:00:00 2001 From: naskya Date: Mon, 29 Jul 2024 18:31:18 +0900 Subject: [PATCH 006/117] chore (backend-rs): pass --frozen flag in production build --- packages/backend-rs/package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/backend-rs/package.json b/packages/backend-rs/package.json index a33effccb0..dbc6aa9770 100644 --- a/packages/backend-rs/package.json +++ b/packages/backend-rs/package.json @@ -11,7 +11,8 @@ "@napi-rs/cli": "3.0.0-alpha.62" }, "scripts": { - "build": "napi build --features napi --no-const-enum --platform --release --output-dir ./built/", + "fetch": "cargo fetch --locked --manifest-path ../../Cargo.toml", + "build": "pnpm run fetch && napi build --features napi --no-const-enum --platform --release --output-dir ./built/ -- --frozen", "build:debug": "napi build --features napi --no-const-enum --platform --output-dir ./built/ --dts-header '/* auto-generated by NAPI-RS */\n/* Do NOT edit this file manually */\n\ntype DateTimeWithTimeZone = Date;\n\ntype Json = any;\n\n'" } } From c97d8f8ab52e4f7fe5ba127685c1a23b70ba2b05 Mon Sep 17 00:00:00 2001 From: GitLab CI Date: Mon, 29 Jul 2024 12:05:44 +0000 Subject: [PATCH 007/117] chore(deps): update dependency @types/ws to v8.5.12 --- packages/backend/package.json | 2 +- pnpm-lock.yaml | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/backend/package.json b/packages/backend/package.json index c7550dd742..df94aa14f2 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -157,7 +157,7 @@ "@types/tmp": "0.2.6", "@types/uuid": "10.0.0", "@types/websocket": "1.0.10", - "@types/ws": "8.5.11", + "@types/ws": "8.5.12", "cross-env": "7.0.3", "pug": "3.0.3", "strict-event-emitter-types": "2.0.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index addea19990..886d0d19c1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -455,8 +455,8 @@ importers: specifier: 1.0.10 version: 1.0.10 '@types/ws': - specifier: 8.5.11 - version: 8.5.11 + specifier: 8.5.12 + version: 8.5.12 cross-env: specifier: 7.0.3 version: 7.0.3 @@ -2599,8 +2599,8 @@ packages: '@types/wrap-ansi@3.0.0': resolution: {integrity: sha512-ltIpx+kM7g/MLRZfkbL7EsCEjfzCcScLpkg37eXEtx5kmrAKBkTJwd1GIAjDSL8wTpM6Hzn5YO4pSb91BEwu1g==} - '@types/ws@8.5.11': - resolution: {integrity: sha512-4+q7P5h3SpJxaBft0Dzpbr6lmMaqh0Jr2tbhJZ/luAwvD7ohSCniYkwz/pLxuT2h0EOa6QADgJj1Ko+TzRfZ+w==} + '@types/ws@8.5.12': + resolution: {integrity: sha512-3tPRkv1EtkDpzlgyKyI8pGsGZAGPEaXeu0DOj5DI25Ja91bdAYddYHbADRYVrZMRbfW+1l5YwXVDKohDJNQxkQ==} '@types/yargs-parser@21.0.3': resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==} @@ -8704,7 +8704,7 @@ snapshots: '@types/wrap-ansi@3.0.0': {} - '@types/ws@8.5.11': + '@types/ws@8.5.12': dependencies: '@types/node': 20.14.13 From 7246c8675cdc7d1f4bb1a0dcfbb6ed2424095452 Mon Sep 17 00:00:00 2001 From: naskya Date: Mon, 29 Jul 2024 22:26:25 +0900 Subject: [PATCH 008/117] chore (backend-rs): cleanup --- Cargo.toml | 2 +- packages/backend-rs/src/misc/get_image_size.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index be41de93f0..ee6e68e86b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -49,7 +49,7 @@ tracing = { version = "0.1.40", default-features = false } tracing-subscriber = { version = "0.3.18", default-features = false } url = { version = "2.5.2", default-features = false } urlencoding = { version = "2.1.3", default-features = false } -uuid = { version = "1.10.0" } +uuid = "1.10.0" web-push = { git = "https://github.com/pimeys/rust-web-push.git", rev = "40febe4085e3cef9cdfd539c315e3e945aba0656", default-features = false } zhconv = "0.3.1" diff --git a/packages/backend-rs/src/misc/get_image_size.rs b/packages/backend-rs/src/misc/get_image_size.rs index d10151483a..7bf9beb982 100644 --- a/packages/backend-rs/src/misc/get_image_size.rs +++ b/packages/backend-rs/src/misc/get_image_size.rs @@ -1,7 +1,7 @@ use crate::{database::cache, util::http_client}; use futures_util::AsyncReadExt; use image::{ImageError, ImageFormat, ImageReader}; -use isahc::prelude::*; +use isahc::AsyncReadResponseExt; use nom_exif::{parse_jpeg_exif, EntryValue, ExifTag}; use std::io::Cursor; use tokio::sync::Mutex; From b85f459cfef472925443332960fd5dac8e727b59 Mon Sep 17 00:00:00 2001 From: naskya Date: Mon, 29 Jul 2024 23:10:28 +0900 Subject: [PATCH 009/117] refactor (backend): port genIdenticon to backend-rs --- Cargo.lock | 77 +++++++++++++ Cargo.toml | 1 + packages/backend-rs/Cargo.toml | 1 + packages/backend-rs/index.d.ts | 2 + packages/backend-rs/index.js | 1 + packages/backend-rs/src/misc/mod.rs | 1 + packages/backend-rs/src/misc/random_icon.rs | 17 +++ packages/backend/package.json | 2 - packages/backend/src/misc/gen-identicon.ts | 114 -------------------- packages/backend/src/server/index.ts | 6 +- pnpm-lock.yaml | 50 --------- 11 files changed, 103 insertions(+), 169 deletions(-) create mode 100644 packages/backend-rs/src/misc/random_icon.rs delete mode 100644 packages/backend/src/misc/gen-identicon.ts diff --git a/Cargo.lock b/Cargo.lock index 0d2f4d05f6..a171bb4715 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -214,6 +214,7 @@ dependencies = [ "cuid2", "emojis", "futures-util", + "identicon-rs", "idna 1.0.2", "image", "isahc", @@ -326,6 +327,12 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7e0d60973d9320722cb1206f412740e162a33b8547ea8d6be75d7cff237c7a85" +[[package]] +name = "bit_field" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc827186963e592360843fb5ba4b973e145841266c1357f7180c43526f2e5b61" + [[package]] name = "bitflags" version = "1.3.2" @@ -612,6 +619,12 @@ version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + [[package]] name = "crypto-bigint" version = "0.5.5" @@ -928,6 +941,22 @@ version = "2.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" +[[package]] +name = "exr" +version = "1.72.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "887d93f60543e9a9362ef8a21beedd0a833c5d9610e18c67abe15a5963dcb1a4" +dependencies = [ + "bit_field", + "flume", + "half", + "lebe", + "miniz_oxide", + "rayon-core", + "smallvec", + "zune-inflate", +] + [[package]] name = "fastrand" version = "1.9.0" @@ -1166,6 +1195,16 @@ dependencies = [ "subtle", ] +[[package]] +name = "half" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888" +dependencies = [ + "cfg-if", + "crunchy", +] + [[package]] name = "hashbrown" version = "0.14.5" @@ -1421,6 +1460,17 @@ dependencies = [ "syn 2.0.72", ] +[[package]] +name = "identicon-rs" +version = "5.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05c4fdcf9f82fef33187cc52ad515de24786ec837837e69f641d1cb8157f4f02" +dependencies = [ + "image", + "sha3", + "thiserror", +] + [[package]] name = "idna" version = "0.5.0" @@ -1452,11 +1502,14 @@ dependencies = [ "bytemuck", "byteorder-lite", "color_quant", + "exr", "gif", "image-webp", "num-traits", "png", + "qoi", "ravif", + "rayon", "rgb", "tiff", "zune-core", @@ -1664,6 +1717,12 @@ dependencies = [ "spin", ] +[[package]] +name = "lebe" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8" + [[package]] name = "libc" version = "0.2.155" @@ -2515,6 +2574,15 @@ dependencies = [ "syn 2.0.72", ] +[[package]] +name = "qoi" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f6d64c71eb498fe9eae14ce4ec935c555749aef511cca85b5568910d6e48001" +dependencies = [ + "bytemuck", +] + [[package]] name = "quick-error" version = "2.0.1" @@ -4475,6 +4543,15 @@ version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f423a2c17029964870cfaabb1f13dfab7d092a62a29a89264f4d36990ca414a" +[[package]] +name = "zune-inflate" +version = "0.2.54" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73ab332fe2f6680068f3582b16a24f90ad7096d5d39b974d1c0aff0125116f02" +dependencies = [ + "simd-adler32", +] + [[package]] name = "zune-jpeg" version = "0.4.13" diff --git a/Cargo.toml b/Cargo.toml index ee6e68e86b..e1a3e0dc25 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,6 +24,7 @@ convert_case = { version = "0.6.0", default-features = false } cuid2 = { version = "0.1.2", default-features = false } emojis = { version = "0.6.3", default-features = false } futures-util = { version = "0.3.30", default-features = false } +identicon-rs = "5.0.1" idna = { version = "1.0.2", default-features = false } image = { version = "0.25.2", default-features = false } isahc = { version = "1.7.2", default-features = false } diff --git a/packages/backend-rs/Cargo.toml b/packages/backend-rs/Cargo.toml index a33e5f34c0..88f271c2b3 100644 --- a/packages/backend-rs/Cargo.toml +++ b/packages/backend-rs/Cargo.toml @@ -28,6 +28,7 @@ chrono = { workspace = true } cuid2 = { workspace = true } emojis = { workspace = true } futures-util = { workspace = true, features = ["io"] } +identicon-rs = { workspace = true } idna = { workspace = true, features = ["std", "compiled_data"] } image = { workspace = true, features = ["avif", "bmp", "gif", "ico", "jpeg", "png", "tiff", "webp"] } isahc = { workspace = true, features = ["http2", "text-decoding", "json"] } diff --git a/packages/backend-rs/index.d.ts b/packages/backend-rs/index.d.ts index 6aa9fed388..d7051191c4 100644 --- a/packages/backend-rs/index.d.ts +++ b/packages/backend-rs/index.d.ts @@ -495,6 +495,8 @@ export declare function genId(): string /** Generate an ID using a specific datetime */ export declare function genIdAt(date: Date): string +export declare function genIdenticon(id: string): Buffer + export declare function getFullApAccount(username: string, host?: string | undefined | null): string export declare function getImageSizeFromUrl(url: string): Promise diff --git a/packages/backend-rs/index.js b/packages/backend-rs/index.js index 55790c7928..1ffacb1e3c 100644 --- a/packages/backend-rs/index.js +++ b/packages/backend-rs/index.js @@ -384,6 +384,7 @@ module.exports.generateSecureRandomString = nativeBinding.generateSecureRandomSt module.exports.generateUserToken = nativeBinding.generateUserToken module.exports.genId = nativeBinding.genId module.exports.genIdAt = nativeBinding.genIdAt +module.exports.genIdenticon = nativeBinding.genIdenticon module.exports.getFullApAccount = nativeBinding.getFullApAccount module.exports.getImageSizeFromUrl = nativeBinding.getImageSizeFromUrl module.exports.getInstanceActor = nativeBinding.getInstanceActor diff --git a/packages/backend-rs/src/misc/mod.rs b/packages/backend-rs/src/misc/mod.rs index 4c715f965c..f47b5078b3 100644 --- a/packages/backend-rs/src/misc/mod.rs +++ b/packages/backend-rs/src/misc/mod.rs @@ -13,6 +13,7 @@ pub mod latest_version; pub mod note; pub mod nyaify; pub mod password; +pub mod random_icon; pub mod reaction; pub mod remove_old_attestation_challenges; pub mod should_nyaify; diff --git a/packages/backend-rs/src/misc/random_icon.rs b/packages/backend-rs/src/misc/random_icon.rs new file mode 100644 index 0000000000..b712063279 --- /dev/null +++ b/packages/backend-rs/src/misc/random_icon.rs @@ -0,0 +1,17 @@ +use identicon_rs::{error::IdenticonError, Identicon}; + +pub fn generate(id: &str) -> Result, IdenticonError> { + Identicon::new(id).set_border(35).export_png_data() +} + +#[cfg(feature = "napi")] +#[napi_derive::napi(js_name = "genIdenticon")] +pub fn generate_js(id: String) -> napi::Result { + match generate(&id) { + Ok(icon) => Ok(icon.into()), + Err(err) => Err(napi::Error::from_reason(format!( + "\n{}\n", + crate::util::error_chain::format_error(&err) + ))), + } +} diff --git a/packages/backend/package.json b/packages/backend/package.json index df94aa14f2..e8fbbe7919 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -87,10 +87,8 @@ "probe-image-size": "7.2.3", "promise-limit": "2.7.0", "punycode": "2.3.1", - "pureimage": "0.4.13", "qrcode": "1.5.3", "qs": "6.12.3", - "random-seed": "0.3.0", "ratelimiter": "3.4.1", "redis-semaphore": "5.6.0", "reflect-metadata": "0.2.2", diff --git a/packages/backend/src/misc/gen-identicon.ts b/packages/backend/src/misc/gen-identicon.ts deleted file mode 100644 index 1e51dfe2ac..0000000000 --- a/packages/backend/src/misc/gen-identicon.ts +++ /dev/null @@ -1,114 +0,0 @@ -/** - * Identicon generator - * https://en.wikipedia.org/wiki/Identicon - */ - -import type { WriteStream } from "node:fs"; -import * as p from "pureimage"; -import gen from "random-seed"; - -const size = 128; // px -const n = 5; // resolution -const margin = size / 4; -const colors = [ - ["#eb6f92", "#b4637a"], - ["#f6c177", "#ea9d34"], - ["#ebbcba", "#d7827e"], - ["#9ccfd8", "#56949f"], - ["#c4a7e7", "#907aa9"], - ["#eb6f92", "#f6c177"], - ["#eb6f92", "#ebbcba"], - ["#eb6f92", "#31748f"], - ["#eb6f92", "#9ccfd8"], - ["#eb6f92", "#c4a7e7"], - ["#f6c177", "#eb6f92"], - ["#f6c177", "#ebbcba"], - ["#f6c177", "#31748f"], - ["#f6c177", "#9ccfd8"], - ["#f6c177", "#c4a7e7"], - ["#ebbcba", "#eb6f92"], - ["#ebbcba", "#f6c177"], - ["#ebbcba", "#31748f"], - ["#ebbcba", "#9ccfd8"], - ["#ebbcba", "#c4a7e7"], - ["#31748f", "#eb6f92"], - ["#31748f", "#f6c177"], - ["#31748f", "#ebbcba"], - ["#31748f", "#9ccfd8"], - ["#31748f", "#c4a7e7"], - ["#9ccfd8", "#eb6f92"], - ["#9ccfd8", "#f6c177"], - ["#9ccfd8", "#ebbcba"], - ["#9ccfd8", "#31748f"], - ["#9ccfd8", "#c4a7e7"], - ["#c4a7e7", "#eb6f92"], - ["#c4a7e7", "#f6c177"], - ["#c4a7e7", "#ebbcba"], - ["#c4a7e7", "#31748f"], - ["#c4a7e7", "#9ccfd8"], -]; - -const actualSize = size - margin * 2; -const cellSize = actualSize / n; -const sideN = Math.floor(n / 2); - -/** - * Generate buffer of an identicon by seed - */ -export function genIdenticon(seed: string, stream: WriteStream): Promise { - const rand = gen.create(seed); - const canvas = p.make(size, size, undefined); - const ctx = canvas.getContext("2d"); - - const bgColors = colors[rand(colors.length)]; - - const bg = ctx.createLinearGradient(0, 0, size, size); - bg.addColorStop(0, bgColors[0]); - bg.addColorStop(1, bgColors[1]); - - ctx.fillStyle = bg; - ctx.beginPath(); - ctx.fillRect(0, 0, size, size); - - ctx.fillStyle = "#ffffff"; - - // side bitmap (filled by false) - const side: boolean[][] = new Array(sideN); - for (let i = 0; i < side.length; i++) { - side[i] = new Array(n).fill(false); - } - - // 1*n (filled by false) - const center: boolean[] = new Array(n).fill(false); - - for (let x = 0; x < side.length; x++) { - for (let y = 0; y < side[x].length; y++) { - side[x][y] = rand(3) === 0; - } - } - - for (let i = 0; i < center.length; i++) { - center[i] = rand(3) === 0; - } - - // Draw - for (let x = 0; x < n; x++) { - for (let y = 0; y < n; y++) { - const isXCenter = x === (n - 1) / 2; - if (isXCenter && !center[y]) continue; - - const isLeftSide = x < (n - 1) / 2; - if (isLeftSide && !side[x][y]) continue; - - const isRightSide = x > (n - 1) / 2; - if (isRightSide && !side[sideN - (x - sideN)][y]) continue; - - const actualX = margin + cellSize * x; - const actualY = margin + cellSize * y; - ctx.beginPath(); - ctx.fillRect(actualX, actualY, cellSize, cellSize); - } - } - - return p.encodePNGToStream(canvas, stream); -} diff --git a/packages/backend/src/server/index.ts b/packages/backend/src/server/index.ts index 6db3c37a15..3baae0f344 100644 --- a/packages/backend/src/server/index.ts +++ b/packages/backend/src/server/index.ts @@ -15,8 +15,7 @@ import { IsNull } from "typeorm"; import { config } from "@/config.js"; import Logger from "@/services/logger.js"; import { Users } from "@/models/index.js"; -import { fetchMeta, stringToAcct } from "backend-rs"; -import { genIdenticon } from "@/misc/gen-identicon.js"; +import { fetchMeta, genIdenticon, stringToAcct } from "backend-rs"; import { createTemp } from "@/misc/create-temp.js"; import activityPub from "./activitypub.js"; import nodeinfo from "./nodeinfo.js"; @@ -119,8 +118,9 @@ router.get("/avatar/@:acct", async (ctx) => { router.get("/identicon/:x", async (ctx) => { const instanceMeta = await fetchMeta(); if (instanceMeta.enableIdenticonGeneration) { + const identicon = genIdenticon(ctx.params.x); const [temp, cleanup] = await createTemp(); - await genIdenticon(ctx.params.x, fs.createWriteStream(temp)); + fs.createWriteStream(temp).write(identicon); ctx.set("Content-Type", "image/png"); ctx.body = fs.createReadStream(temp).on("close", () => cleanup()); } else { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 886d0d19c1..5cb93c485d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -249,18 +249,12 @@ importers: punycode: specifier: 2.3.1 version: 2.3.1 - pureimage: - specifier: 0.4.13 - version: 0.4.13 qrcode: specifier: 1.5.3 version: 1.5.3 qs: specifier: 6.12.3 version: 6.12.3 - random-seed: - specifier: 0.3.0 - version: 0.3.0 ratelimiter: specifier: 3.4.1 version: 3.4.1 @@ -973,13 +967,11 @@ packages: '@biomejs/cli-darwin-arm64@1.8.3': resolution: {integrity: sha512-9DYOjclFpKrH/m1Oz75SSExR8VKvNSSsLnVIqdnKexj6NwmiMlKk94Wa1kZEdv6MCOHGHgyyoV57Cw8WzL5n3A==} engines: {node: '>=14.21.3'} - cpu: [arm64] os: [darwin] '@biomejs/cli-darwin-x64@1.8.3': resolution: {integrity: sha512-UeW44L/AtbmOF7KXLCoM+9PSgPo0IDcyEUfIoOXYeANaNXXf9mLUwV1GeF2OWjyic5zj6CnAJ9uzk2LT3v/wAw==} engines: {node: '>=14.21.3'} - cpu: [x64] os: [darwin] '@biomejs/cli-linux-arm64-musl@1.8.3': @@ -991,7 +983,6 @@ packages: '@biomejs/cli-linux-arm64@1.8.3': resolution: {integrity: sha512-fed2ji8s+I/m8upWpTJGanqiJ0rnlHOK3DdxsyVLZQ8ClY6qLuPc9uehCREBifRJLl/iJyQpHIRufLDeotsPtw==} engines: {node: '>=14.21.3'} - cpu: [arm64] os: [linux] '@biomejs/cli-linux-x64-musl@1.8.3': @@ -1003,7 +994,6 @@ packages: '@biomejs/cli-linux-x64@1.8.3': resolution: {integrity: sha512-I8G2QmuE1teISyT8ie1HXsjFRz9L1m5n83U1O6m30Kw+kPMPSKjag6QGUn+sXT8V+XWIZxFFBoTDEDZW2KPDDw==} engines: {node: '>=14.21.3'} - cpu: [x64] os: [linux] '@biomejs/cli-win32-arm64@1.8.3': @@ -4683,9 +4673,6 @@ packages: resolution: {integrity: sha512-9FzQjJ7MATs1tSpnco1K6ayiYE3figslrXA72G2HQ/n76RzvYlofyi5QM+iX4YRs/pu3yzxlVQSST23+dMDknw==} engines: {node: '>= 0.6.0'} - jpeg-js@0.4.4: - resolution: {integrity: sha512-WZzeDOEtTOBK4Mdsar0IqEU5sMr3vSV2RqkAIzUEV2BHnUfKGyswWFPFwK5EeDo93K3FohSHbLAjj0s1Wzd+dg==} - js-beautify@1.15.1: resolution: {integrity: sha512-ESjNzSlt/sWE8sciZH8kBF8BPlwXPwhR6pWKAw8bw4Bwj+iZcnKW6ONWUutJ7eObuBZQpiIb8S7OYspWrKt7rA==} engines: {node: '>=14'} @@ -4752,9 +4739,6 @@ packages: json-schema@0.4.0: resolution: {integrity: sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==} - json-stringify-safe@5.0.1: - resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} - json5@2.2.3: resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} engines: {node: '>=6'} @@ -5289,10 +5273,6 @@ packages: resolution: {integrity: sha512-8AV/sCtuzUeTo8gQK5qDZzARrulB3egtLzFgteqB2tcT4Mw7B8Kt7JcDHmltjz6FOAHsvTevk70gZEbhM4ZS9Q==} hasBin: true - opentype.js@0.4.11: - resolution: {integrity: sha512-GthxucX/6aftfLdeU5Ho7o7zmQcC8uVtqdcelVq12X++ndxwBZG8Xb5rFEKT7nEcWDD2P1x+TNuJ70jtj1Mbpw==} - hasBin: true - os-tmpdir@1.0.2: resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==} engines: {node: '>=0.10.0'} @@ -5516,10 +5496,6 @@ packages: resolution: {integrity: sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==} engines: {node: '>=10.13.0'} - pngjs@7.0.0: - resolution: {integrity: sha512-LKWqWJRhstyYo9pGvgor/ivk2w94eSjE3RGVuzLGlr3NmD8bf7RcYGze1mNdEHRP6TRP6rMuDHk5t44hnTRyow==} - engines: {node: '>=14.19.0'} - pnpm@9.6.0: resolution: {integrity: sha512-ONxvuo26NbOTQLlwARLC/h4S8QsXE0cVpKqYzPe7A152/Zgc8Ls4TfqY+NavVIHCvvL0Jmokv6IMNOtxR84LXg==} engines: {node: '>=18.12'} @@ -5683,10 +5659,6 @@ packages: pure-rand@6.1.0: resolution: {integrity: sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==} - pureimage@0.4.13: - resolution: {integrity: sha512-P8aonTNAnXWJn2pBIqyeWw0I/D4YDOfEavCVvbDG+wx3dCujQX0ENZiW5OcHfbd8HKLfVhCf4F/3Xivf1yWDiA==} - engines: {node: '>=14.19.0'} - qrcode-generator@1.4.4: resolution: {integrity: sha512-HM7yY8O2ilqhmULxGMpcHSF1EhJJ9yBj8gvDEuZ6M+KGJ0YY2hKpnXvRD+hZPLrDVck3ExIGhmPtSdcjC+guuw==} @@ -5728,10 +5700,6 @@ packages: resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==} engines: {node: '>=10'} - random-seed@0.3.0: - resolution: {integrity: sha512-y13xtn3kcTlLub3HKWXxJNeC2qK4mB59evwZ5EkeRlolx+Bp2ztF7LbcZmyCnOqlHQrLnfuNbi1sVmm9lPDlDA==} - engines: {node: '>= 0.6.0'} - randombytes@2.1.0: resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} @@ -11001,8 +10969,6 @@ snapshots: jmespath@0.16.0: {} - jpeg-js@0.4.4: {} - js-beautify@1.15.1: dependencies: config-chain: 1.1.13 @@ -11074,8 +11040,6 @@ snapshots: json-schema@0.4.0: {} - json-stringify-safe@5.0.1: {} - json5@2.2.3: {} jsonfile@4.0.0: @@ -11684,8 +11648,6 @@ snapshots: opencollective-postinstall@2.0.3: {} - opentype.js@0.4.11: {} - os-tmpdir@1.0.2: {} otpauth@9.3.1: @@ -11874,8 +11836,6 @@ snapshots: pngjs@5.0.0: {} - pngjs@7.0.0: {} - pnpm@9.6.0: {} possible-typed-array-names@1.0.0: {} @@ -12063,12 +12023,6 @@ snapshots: pure-rand@6.1.0: {} - pureimage@0.4.13: - dependencies: - jpeg-js: 0.4.4 - opentype.js: 0.4.11 - pngjs: 7.0.0 - qrcode-generator@1.4.4: {} qrcode-vue3@1.6.8: @@ -12100,10 +12054,6 @@ snapshots: quick-lru@5.1.1: {} - random-seed@0.3.0: - dependencies: - json-stringify-safe: 5.0.1 - randombytes@2.1.0: dependencies: safe-buffer: 5.2.1 From 07c5bfa6002ad96bc09e9f2229da673173441e79 Mon Sep 17 00:00:00 2001 From: naskya Date: Mon, 29 Jul 2024 23:29:40 +0900 Subject: [PATCH 010/117] fix (backend-rs): followee/follower uri may be null --- packages/backend-rs/index.d.ts | 2 +- .../federation/activitypub/object/follow.rs | 22 +++++++++++++------ 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/packages/backend-rs/index.d.ts b/packages/backend-rs/index.d.ts index d7051191c4..5c99b4d437 100644 --- a/packages/backend-rs/index.d.ts +++ b/packages/backend-rs/index.d.ts @@ -1554,7 +1554,7 @@ export interface UserKeypair { export interface UserLike { id: string host: string | null - uri: string + uri: string | null } export interface UserList { diff --git a/packages/backend-rs/src/federation/activitypub/object/follow.rs b/packages/backend-rs/src/federation/activitypub/object/follow.rs index d90ba70d7e..d2db5afdaa 100644 --- a/packages/backend-rs/src/federation/activitypub/object/follow.rs +++ b/packages/backend-rs/src/federation/activitypub/object/follow.rs @@ -5,7 +5,7 @@ use crate::{config::CONFIG, federation::internal_actor, misc::user}; pub struct UserLike { pub id: String, pub host: Option, - pub uri: String, + pub uri: Option, } #[macros::export(object)] @@ -18,23 +18,31 @@ pub struct Follow { impl ActivityPubObject for Follow {} +#[macros::errors] +pub enum Error { + #[error("follower uri is missing")] + MissingFollowerUri, + #[error("followee uri is missing")] + MissingFolloweeUri, +} + impl Follow { #[allow(dead_code)] // TODO: remove this line - fn new(follower: UserLike, followee: UserLike, request_id: Option) -> Self { - Self { + fn new(follower: UserLike, followee: UserLike, request_id: Option) -> Result { + Ok(Self { id: request_id.unwrap_or_else(|| { format!("{}/follows/{}/{}", CONFIG.url, follower.id, followee.id) }), r#type: Activity::Follow, actor: match user::is_local!(follower) { true => format!("{}/users/{}", CONFIG.url, follower.id), - false => follower.uri, + false => follower.uri.ok_or(Error::MissingFollowerUri)?, }, object: match user::is_local!(followee) { true => format!("{}/users/{}", CONFIG.url, followee.id), - false => followee.uri, + false => followee.uri.ok_or(Error::MissingFolloweeUri)?, }, - } + }) } #[allow(dead_code)] // TODO: remove this line @@ -53,7 +61,7 @@ impl Follow { } #[macros::ts_export] -pub fn render_follow(follower: UserLike, followee: UserLike, request_id: Option) -> Follow { +pub fn render_follow(follower: UserLike, followee: UserLike, request_id: Option) -> Result { Follow::new(follower, followee, request_id) } From 2c35a3885cffca9822c719460f1b07bd8b92f76a Mon Sep 17 00:00:00 2001 From: naskya Date: Mon, 29 Jul 2024 23:48:55 +0900 Subject: [PATCH 011/117] chore (backend-rs): cache generated icons --- packages/backend-rs/index.d.ts | 2 +- packages/backend-rs/src/database/cache.rs | 2 ++ packages/backend-rs/src/misc/random_icon.rs | 24 +++++++++++++++++---- packages/backend/src/server/index.ts | 2 +- 4 files changed, 24 insertions(+), 6 deletions(-) diff --git a/packages/backend-rs/index.d.ts b/packages/backend-rs/index.d.ts index 5c99b4d437..ab4fc04bc5 100644 --- a/packages/backend-rs/index.d.ts +++ b/packages/backend-rs/index.d.ts @@ -495,7 +495,7 @@ export declare function genId(): string /** Generate an ID using a specific datetime */ export declare function genIdAt(date: Date): string -export declare function genIdenticon(id: string): Buffer +export declare function genIdenticon(id: string): Promise export declare function getFullApAccount(username: string, host?: string | undefined | null): string diff --git a/packages/backend-rs/src/database/cache.rs b/packages/backend-rs/src/database/cache.rs index d56da7f680..2c5b88025a 100644 --- a/packages/backend-rs/src/database/cache.rs +++ b/packages/backend-rs/src/database/cache.rs @@ -10,6 +10,7 @@ pub enum Category { Block, Follow, CatLang, + RandomIcon, #[cfg(test)] Test, } @@ -35,6 +36,7 @@ fn categorize(category: Category, key: &str) -> String { Category::Block => "blocking", Category::Follow => "following", Category::CatLang => "catlang", + Category::RandomIcon => "randomIcon", #[cfg(test)] Category::Test => "usedOnlyForTesting", }; diff --git a/packages/backend-rs/src/misc/random_icon.rs b/packages/backend-rs/src/misc/random_icon.rs index b712063279..3cff7fcc10 100644 --- a/packages/backend-rs/src/misc/random_icon.rs +++ b/packages/backend-rs/src/misc/random_icon.rs @@ -1,13 +1,29 @@ use identicon_rs::{error::IdenticonError, Identicon}; +use crate::database::cache; -pub fn generate(id: &str) -> Result, IdenticonError> { - Identicon::new(id).set_border(35).export_png_data() +#[macros::errors] +pub enum Error { + #[doc = "failed to generate identicon"] + #[error(transparent)] + Identicon(#[from] IdenticonError), + #[error("Redis cache operation has failed")] + Cache(#[from] cache::Error), +} + +pub async fn generate(id: &str) -> Result, Error> { + if let Some(icon) = cache::get_one::>(cache::Category::RandomIcon, id).await? { + Ok(icon) + } else { + let icon = Identicon::new(id).set_border(35).export_png_data()?; + cache::set_one(cache::Category::RandomIcon, id, &icon, 10 * 60).await?; + Ok(icon) + } } #[cfg(feature = "napi")] #[napi_derive::napi(js_name = "genIdenticon")] -pub fn generate_js(id: String) -> napi::Result { - match generate(&id) { +pub async fn generate_js(id: String) -> napi::Result { + match generate(&id).await { Ok(icon) => Ok(icon.into()), Err(err) => Err(napi::Error::from_reason(format!( "\n{}\n", diff --git a/packages/backend/src/server/index.ts b/packages/backend/src/server/index.ts index 3baae0f344..58a6e33456 100644 --- a/packages/backend/src/server/index.ts +++ b/packages/backend/src/server/index.ts @@ -118,7 +118,7 @@ router.get("/avatar/@:acct", async (ctx) => { router.get("/identicon/:x", async (ctx) => { const instanceMeta = await fetchMeta(); if (instanceMeta.enableIdenticonGeneration) { - const identicon = genIdenticon(ctx.params.x); + const identicon = await genIdenticon(ctx.params.x); const [temp, cleanup] = await createTemp(); fs.createWriteStream(temp).write(identicon); ctx.set("Content-Type", "image/png"); From a5f950b4686a4e983749309d0e6c83452492bc77 Mon Sep 17 00:00:00 2001 From: naskya Date: Tue, 30 Jul 2024 00:05:30 +0900 Subject: [PATCH 012/117] chore (backend-rs): reduce identicon size --- .../src/federation/activitypub/object/follow.rs | 12 ++++++++++-- packages/backend-rs/src/misc/random_icon.rs | 7 +++++-- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/packages/backend-rs/src/federation/activitypub/object/follow.rs b/packages/backend-rs/src/federation/activitypub/object/follow.rs index d2db5afdaa..a609704af9 100644 --- a/packages/backend-rs/src/federation/activitypub/object/follow.rs +++ b/packages/backend-rs/src/federation/activitypub/object/follow.rs @@ -28,7 +28,11 @@ pub enum Error { impl Follow { #[allow(dead_code)] // TODO: remove this line - fn new(follower: UserLike, followee: UserLike, request_id: Option) -> Result { + fn new( + follower: UserLike, + followee: UserLike, + request_id: Option, + ) -> Result { Ok(Self { id: request_id.unwrap_or_else(|| { format!("{}/follows/{}/{}", CONFIG.url, follower.id, followee.id) @@ -61,7 +65,11 @@ impl Follow { } #[macros::ts_export] -pub fn render_follow(follower: UserLike, followee: UserLike, request_id: Option) -> Result { +pub fn render_follow( + follower: UserLike, + followee: UserLike, + request_id: Option, +) -> Result { Follow::new(follower, followee, request_id) } diff --git a/packages/backend-rs/src/misc/random_icon.rs b/packages/backend-rs/src/misc/random_icon.rs index 3cff7fcc10..4960581cdb 100644 --- a/packages/backend-rs/src/misc/random_icon.rs +++ b/packages/backend-rs/src/misc/random_icon.rs @@ -1,5 +1,5 @@ -use identicon_rs::{error::IdenticonError, Identicon}; use crate::database::cache; +use identicon_rs::{error::IdenticonError, Identicon}; #[macros::errors] pub enum Error { @@ -14,7 +14,10 @@ pub async fn generate(id: &str) -> Result, Error> { if let Some(icon) = cache::get_one::>(cache::Category::RandomIcon, id).await? { Ok(icon) } else { - let icon = Identicon::new(id).set_border(35).export_png_data()?; + let icon = Identicon::new(id) + .set_border(16) + .set_scale(96)? + .export_png_data()?; cache::set_one(cache::Category::RandomIcon, id, &icon, 10 * 60).await?; Ok(icon) } From 1109fd62487ace5c47c7f2d00af63066ae5c323c Mon Sep 17 00:00:00 2001 From: naskya Date: Tue, 30 Jul 2024 00:29:27 +0900 Subject: [PATCH 013/117] fix (backend): generated icons sometimes not showing --- packages/backend/src/server/index.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/backend/src/server/index.ts b/packages/backend/src/server/index.ts index 58a6e33456..685d86f7c6 100644 --- a/packages/backend/src/server/index.ts +++ b/packages/backend/src/server/index.ts @@ -118,9 +118,8 @@ router.get("/avatar/@:acct", async (ctx) => { router.get("/identicon/:x", async (ctx) => { const instanceMeta = await fetchMeta(); if (instanceMeta.enableIdenticonGeneration) { - const identicon = await genIdenticon(ctx.params.x); const [temp, cleanup] = await createTemp(); - fs.createWriteStream(temp).write(identicon); + fs.writeFileSync(temp, await genIdenticon(ctx.params.x)); ctx.set("Content-Type", "image/png"); ctx.body = fs.createReadStream(temp).on("close", () => cleanup()); } else { From b47909169d6e9907b7e72bb063707dd1a1349a7e Mon Sep 17 00:00:00 2001 From: HinanoAira Date: Tue, 30 Jul 2024 02:00:38 +0900 Subject: [PATCH 014/117] fix: fixed arguments of userInstanceCache.fetch() I mistook true for false. --- packages/backend/src/models/repositories/user.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/backend/src/models/repositories/user.ts b/packages/backend/src/models/repositories/user.ts index c04fb9750c..f64c067687 100644 --- a/packages/backend/src/models/repositories/user.ts +++ b/packages/backend/src/models/repositories/user.ts @@ -471,6 +471,7 @@ export const UserRepository = db.getRepository(User).extend({ .fetch( user.host, () => Instances.findOneBy({ host: user.host! }), + false, (v) => v != null, ) .then((instance) => From 32beb85a5e692c2eee46f750efe8046f91f11d8d Mon Sep 17 00:00:00 2001 From: GitLab CI Date: Mon, 29 Jul 2024 20:06:03 +0000 Subject: [PATCH 015/117] chore(deps): update dependency @types/fluent-ffmpeg to v2.1.25 --- packages/backend/package.json | 2 +- pnpm-lock.yaml | 14 +++++++++----- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/packages/backend/package.json b/packages/backend/package.json index e8fbbe7919..9470963f98 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -118,7 +118,7 @@ "@types/color-convert": "2.0.3", "@types/content-disposition": "0.5.8", "@types/escape-regexp": "0.0.3", - "@types/fluent-ffmpeg": "2.1.24", + "@types/fluent-ffmpeg": "2.1.25", "@types/jsdom": "21.1.7", "@types/jsonld": "1.5.15", "@types/jsrsasign": "10.5.14", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5cb93c485d..b4f8201d9f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -338,8 +338,8 @@ importers: specifier: 0.0.3 version: 0.0.3 '@types/fluent-ffmpeg': - specifier: 2.1.24 - version: 2.1.24 + specifier: 2.1.25 + version: 2.1.25 '@types/jsdom': specifier: 21.1.7 version: 21.1.7 @@ -967,11 +967,13 @@ packages: '@biomejs/cli-darwin-arm64@1.8.3': resolution: {integrity: sha512-9DYOjclFpKrH/m1Oz75SSExR8VKvNSSsLnVIqdnKexj6NwmiMlKk94Wa1kZEdv6MCOHGHgyyoV57Cw8WzL5n3A==} engines: {node: '>=14.21.3'} + cpu: [arm64] os: [darwin] '@biomejs/cli-darwin-x64@1.8.3': resolution: {integrity: sha512-UeW44L/AtbmOF7KXLCoM+9PSgPo0IDcyEUfIoOXYeANaNXXf9mLUwV1GeF2OWjyic5zj6CnAJ9uzk2LT3v/wAw==} engines: {node: '>=14.21.3'} + cpu: [x64] os: [darwin] '@biomejs/cli-linux-arm64-musl@1.8.3': @@ -983,6 +985,7 @@ packages: '@biomejs/cli-linux-arm64@1.8.3': resolution: {integrity: sha512-fed2ji8s+I/m8upWpTJGanqiJ0rnlHOK3DdxsyVLZQ8ClY6qLuPc9uehCREBifRJLl/iJyQpHIRufLDeotsPtw==} engines: {node: '>=14.21.3'} + cpu: [arm64] os: [linux] '@biomejs/cli-linux-x64-musl@1.8.3': @@ -994,6 +997,7 @@ packages: '@biomejs/cli-linux-x64@1.8.3': resolution: {integrity: sha512-I8G2QmuE1teISyT8ie1HXsjFRz9L1m5n83U1O6m30Kw+kPMPSKjag6QGUn+sXT8V+XWIZxFFBoTDEDZW2KPDDw==} engines: {node: '>=14.21.3'} + cpu: [x64] os: [linux] '@biomejs/cli-win32-arm64@1.8.3': @@ -2376,8 +2380,8 @@ packages: '@types/express@4.17.21': resolution: {integrity: sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==} - '@types/fluent-ffmpeg@2.1.24': - resolution: {integrity: sha512-g5oQO8Jgi2kFS3tTub7wLvfLztr1s8tdXmRd8PiL/hLMLzTIAyMR2sANkTggM/rdEDAg3d63nYRRVepwBiCw5A==} + '@types/fluent-ffmpeg@2.1.25': + resolution: {integrity: sha512-a9/Jtv/RVaCG4lUwWIcuClWE5eXJFoFS/oHOecOv/RS8n+lQdJzcJVmDlxA8Xbk4B82YpO88Dijcoljb6sYTcA==} '@types/formidable@2.0.6': resolution: {integrity: sha512-L4HcrA05IgQyNYJj6kItuIkXrInJvsXTPC5B1i64FggWKKqSL+4hgt7asiSNva75AoLQjq29oPxFfU4GAQ6Z2w==} @@ -8444,7 +8448,7 @@ snapshots: '@types/qs': 6.9.15 '@types/serve-static': 1.15.7 - '@types/fluent-ffmpeg@2.1.24': + '@types/fluent-ffmpeg@2.1.25': dependencies: '@types/node': 20.14.13 From da307934e4b63956d5cf8ed76239c68a683a5695 Mon Sep 17 00:00:00 2001 From: naskya Date: Tue, 30 Jul 2024 19:37:50 +0900 Subject: [PATCH 016/117] docs: update changelog --- docs/changelog.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/changelog.md b/docs/changelog.md index 1f4729fc7f..a5eab94c92 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -7,6 +7,14 @@ This changelog is not an exhaustive list. Code refactorings, minor bug fixes, do - Server administrators must check [notice-for-admins.md](https://firefish.dev/firefish/firefish/-/blob/main/docs/notice-for-admins.md) as well. - Third-party client/bot developers may want to check [api-change.md](https://firefish.dev/firefish/firefish/-/blob/main/docs/api-change.md) as well. +## Unreleased + +- Fix bugs + +### Breaking change + +The random icon generator has been changed, so your icon will be changed if you haven't set your icon image and random icon generation is enabled on your server. + ## [v20240729](https://firefish.dev/firefish/firefish/-/merge_requests/11214/commits) - Fix bugs (including a medium severity security issue) From 6344b723210eb9fd492447222d43df4c254da795 Mon Sep 17 00:00:00 2001 From: naskya Date: Tue, 30 Jul 2024 22:39:42 +0900 Subject: [PATCH 017/117] refactor (backend): port renderEmoji to backend-rs --- docs/downgrade.sql | 4 ++ packages/backend-rs/index.d.ts | 58 ++++++++++++------- packages/backend-rs/index.js | 3 +- .../federation/activitypub/object/accept.rs | 20 +++---- .../federation/activitypub/object/emoji.rs | 51 ++++++++++++++++ .../federation/activitypub/object/follow.rs | 22 +++---- .../src/federation/activitypub/object/mod.rs | 5 +- .../1722346019160-set-emoji-public-url.ts | 18 ++++++ packages/backend/src/models/entities/emoji.ts | 1 - .../src/remote/activitypub/renderer/emoji.ts | 17 ------ .../src/remote/activitypub/renderer/like.ts | 2 +- .../src/remote/activitypub/renderer/note.ts | 2 +- .../src/remote/activitypub/renderer/person.ts | 4 +- packages/backend/src/server/activitypub.ts | 2 +- 14 files changed, 144 insertions(+), 65 deletions(-) create mode 100644 packages/backend-rs/src/federation/activitypub/object/emoji.rs create mode 100644 packages/backend/src/migration/1722346019160-set-emoji-public-url.ts delete mode 100644 packages/backend/src/remote/activitypub/renderer/emoji.ts diff --git a/docs/downgrade.sql b/docs/downgrade.sql index 24f0f4baa8..d52227acc8 100644 --- a/docs/downgrade.sql +++ b/docs/downgrade.sql @@ -1,6 +1,7 @@ BEGIN; DELETE FROM "migrations" WHERE name IN ( + 'SetEmojiPublicUrl1722346019160', 'SetAccessTokenName1722134626110', 'CreateSystemActors1720618854585', 'AddMastodonSubscriptionType1715181461692', @@ -41,6 +42,9 @@ DELETE FROM "migrations" WHERE name IN ( 'RemoveNativeUtilsMigration1705877093218' ); +-- set-emoji-public-url +ALTER TABLE "emoji" ALTER COLUMN "publicUrl" SET DEFAULT ''; + -- addMastodonSubscriptionType ALTER TABLE "sw_subscription" DROP COLUMN "subscriptionTypes"; DROP TYPE "push_subscription_type"; diff --git a/packages/backend-rs/index.d.ts b/packages/backend-rs/index.d.ts index ab4fc04bc5..4ad1992d33 100644 --- a/packages/backend-rs/index.d.ts +++ b/packages/backend-rs/index.d.ts @@ -25,13 +25,6 @@ export interface AbuseUserReportLike { comment: string } -export interface Accept { - id: string - type: Activity - actor: string - object: Follow -} - export interface AccessToken { id: string createdAt: DateTimeWithTimeZone @@ -55,9 +48,6 @@ export interface Acct { export declare function acctToString(acct: Acct): string -export type Activity = 'Accept'| -'Follow'; - export interface Ad { id: string createdAt: DateTimeWithTimeZone @@ -114,6 +104,33 @@ export type AntennaSrc = 'all'| 'list'| 'users'; +export interface ApAccept { + id: string + type: ApObject + actor: string + object: ApFollow +} + +export interface ApEmoji { + id: string + type: ApObject + name: string + updated: string + icon: Icon +} + +export interface ApFollow { + id: string + type: ApObject + actor: string + object: string +} + +export type ApObject = 'Accept'| +'Emoji'| +'Follow'| +'Image'; + export interface App { id: string createdAt: DateTimeWithTimeZone @@ -420,13 +437,6 @@ export declare function fetchMeta(): Promise /** Fetches and returns the NodeInfo (version 2.0) of a remote server. */ export declare function fetchNodeinfo(host: string): Promise -export interface Follow { - id: string - type: Activity - actor: string - object: string -} - export interface Following { id: string createdAt: DateTimeWithTimeZone @@ -532,6 +542,12 @@ export interface Hashtag { attachedRemoteUsersCount: number } +export interface Icon { + type: ApObject + mediaType: string + url: string +} + export interface IdConfig { length?: number fingerprint?: string @@ -1275,11 +1291,13 @@ export type RelayStatus = 'accepted'| /** Delete all entries in the [attestation_challenge] table created at more than 5 minutes ago */ export declare function removeOldAttestationChallenges(): Promise -export declare function renderAccept(userId: string, followObject: Follow): Accept +export declare function renderAccept(userId: string, followObject: Follow): ApAccept -export declare function renderFollow(follower: UserLike, followee: UserLike, requestId?: string | undefined | null): Follow +export declare function renderEmoji(emoji: Emoji): ApEmoji -export declare function renderFollowRelay(relayId: string): Promise +export declare function renderFollow(follower: UserLike, followee: UserLike, requestId?: string | undefined | null): ApFollow + +export declare function renderFollowRelay(relayId: string): Promise export interface RenoteMuting { id: string diff --git a/packages/backend-rs/index.js b/packages/backend-rs/index.js index 1ffacb1e3c..f7458cb3b0 100644 --- a/packages/backend-rs/index.js +++ b/packages/backend-rs/index.js @@ -362,8 +362,8 @@ if (!nativeBinding) { } module.exports.acctToString = nativeBinding.acctToString -module.exports.Activity = nativeBinding.Activity module.exports.AntennaSrc = nativeBinding.AntennaSrc +module.exports.ApObject = nativeBinding.ApObject module.exports.ChatEvent = nativeBinding.ChatEvent module.exports.ChatIndexEvent = nativeBinding.ChatIndexEvent module.exports.checkWordMute = nativeBinding.checkWordMute @@ -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.renderEmoji = nativeBinding.renderEmoji module.exports.renderFollow = nativeBinding.renderFollow module.exports.renderFollowRelay = nativeBinding.renderFollowRelay module.exports.safeForSql = nativeBinding.safeForSql diff --git a/packages/backend-rs/src/federation/activitypub/object/accept.rs b/packages/backend-rs/src/federation/activitypub/object/accept.rs index a156b84c5d..a78df18809 100644 --- a/packages/backend-rs/src/federation/activitypub/object/accept.rs +++ b/packages/backend-rs/src/federation/activitypub/object/accept.rs @@ -3,21 +3,21 @@ use crate::config::CONFIG; use uuid::Uuid; #[macros::export(object)] -pub struct Accept { +pub struct ApAccept { pub id: String, - pub r#type: Activity, + pub r#type: ApObject, pub actor: String, - pub object: follow::Follow, + pub object: follow::ApFollow, } -impl ActivityPubObject for Accept {} +impl ActivityPubObject for ApAccept {} -impl Accept { +impl ApAccept { #[allow(dead_code)] // TODO: remove this line - fn new(user_id: String, follow_object: follow::Follow) -> Self { + fn new(user_id: String, follow_object: follow::ApFollow) -> Self { Self { id: format!("{}/{}", CONFIG.url, Uuid::new_v4()), - r#type: Activity::Accept, + r#type: ApObject::Accept, actor: format!("{}/users/{}", CONFIG.url, user_id), object: follow_object, } @@ -25,9 +25,9 @@ impl Accept { } #[cfg(any(test, doctest, feature = "napi"))] -type Follow = follow::Follow; +type Follow = follow::ApFollow; #[macros::ts_export] -pub fn render_accept(user_id: String, follow_object: Follow) -> Accept { - Accept::new(user_id, follow_object) +pub fn render_accept(user_id: String, follow_object: Follow) -> ApAccept { + ApAccept::new(user_id, follow_object) } diff --git a/packages/backend-rs/src/federation/activitypub/object/emoji.rs b/packages/backend-rs/src/federation/activitypub/object/emoji.rs new file mode 100644 index 0000000000..178a885739 --- /dev/null +++ b/packages/backend-rs/src/federation/activitypub/object/emoji.rs @@ -0,0 +1,51 @@ +use super::*; +use crate::{config::CONFIG, model::entity::emoji}; +use chrono::Utc; + +#[macros::export(object)] +pub struct ApEmoji { + pub id: String, + pub r#type: ApObject, + pub name: String, + pub updated: String, + pub icon: Icon, +} + +#[macros::export(object)] +pub struct Icon { + pub r#type: ApObject, + pub media_type: String, + pub url: String, +} + +impl ActivityPubObject for ApEmoji {} + +impl ApEmoji { + #[allow(dead_code)] // TODO: remove this line + fn new(emoji: emoji::Model) -> Self { + Self { + id: format!("{}/emojis/{}", CONFIG.url, emoji.name), + r#type: ApObject::Emoji, + name: format!(":{}:", emoji.name), + updated: emoji + .updated_at + .unwrap_or_else(|| Utc::now().into()) + .to_rfc3339(), + icon: Icon { + r#type: ApObject::Image, + media_type: emoji.r#type.unwrap_or_else(|| "image/png".to_owned()), + url: emoji.public_url, + }, + } + } +} + +// for napi export +// https://github.com/napi-rs/napi-rs/issues/2060 +#[allow(dead_code)] // TODO: remove this line +type Emoji = emoji::Model; + +#[macros::ts_export] +pub fn render_emoji(emoji: Emoji) -> ApEmoji { + ApEmoji::new(emoji) +} diff --git a/packages/backend-rs/src/federation/activitypub/object/follow.rs b/packages/backend-rs/src/federation/activitypub/object/follow.rs index a609704af9..6beb55ca90 100644 --- a/packages/backend-rs/src/federation/activitypub/object/follow.rs +++ b/packages/backend-rs/src/federation/activitypub/object/follow.rs @@ -9,14 +9,14 @@ pub struct UserLike { } #[macros::export(object)] -pub struct Follow { +pub struct ApFollow { pub id: String, - pub r#type: Activity, + pub r#type: ApObject, pub actor: String, pub object: String, } -impl ActivityPubObject for Follow {} +impl ActivityPubObject for ApFollow {} #[macros::errors] pub enum Error { @@ -26,7 +26,7 @@ pub enum Error { MissingFolloweeUri, } -impl Follow { +impl ApFollow { #[allow(dead_code)] // TODO: remove this line fn new( follower: UserLike, @@ -37,7 +37,7 @@ impl Follow { id: request_id.unwrap_or_else(|| { format!("{}/follows/{}/{}", CONFIG.url, follower.id, followee.id) }), - r#type: Activity::Follow, + r#type: ApObject::Follow, actor: match user::is_local!(follower) { true => format!("{}/users/{}", CONFIG.url, follower.id), false => follower.uri.ok_or(Error::MissingFollowerUri)?, @@ -53,7 +53,7 @@ impl Follow { async fn new_relay(relay_id: String) -> Result { Ok(Self { id: format!("{}/activities/follow-relay/{}", CONFIG.url, relay_id), - r#type: Activity::Follow, + r#type: ApObject::Follow, actor: format!( "{}/users/{}", CONFIG.url, @@ -69,11 +69,13 @@ pub fn render_follow( follower: UserLike, followee: UserLike, request_id: Option, -) -> Result { - Follow::new(follower, followee, request_id) +) -> Result { + ApFollow::new(follower, followee, request_id) } #[macros::ts_export] -pub async fn render_follow_relay(relay_id: String) -> Result { - Follow::new_relay(relay_id).await +pub async fn render_follow_relay( + relay_id: String, +) -> Result { + ApFollow::new_relay(relay_id).await } diff --git a/packages/backend-rs/src/federation/activitypub/object/mod.rs b/packages/backend-rs/src/federation/activitypub/object/mod.rs index ebb83035b0..2da7787116 100644 --- a/packages/backend-rs/src/federation/activitypub/object/mod.rs +++ b/packages/backend-rs/src/federation/activitypub/object/mod.rs @@ -1,12 +1,15 @@ pub mod accept; +pub mod emoji; pub mod follow; pub trait ActivityPubObject {} #[macros::export(string_enum)] -pub enum Activity { +pub enum ApObject { Accept, + Emoji, Follow, + Image, } const AS_PUBLIC_URL: &str = "https://www.w3.org/ns/activitystreams#Public"; diff --git a/packages/backend/src/migration/1722346019160-set-emoji-public-url.ts b/packages/backend/src/migration/1722346019160-set-emoji-public-url.ts new file mode 100644 index 0000000000..8f3c95ccb9 --- /dev/null +++ b/packages/backend/src/migration/1722346019160-set-emoji-public-url.ts @@ -0,0 +1,18 @@ +import type { MigrationInterface, QueryRunner } from "typeorm"; + +export class SetEmojiPublicUrl1722346019160 implements MigrationInterface { + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `UPDATE "emoji" SET "publicUrl" = "originalUrl" WHERE "publicUrl" = ''`, + ); + await queryRunner.query( + `ALTER TABLE "emoji" ALTER COLUMN "publicUrl" DROP DEFAULT`, + ); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `ALTER TABLE "emoji" ALTER COLUMN "publicUrl" SET DEFAULT ''`, + ); + } +} diff --git a/packages/backend/src/models/entities/emoji.ts b/packages/backend/src/models/entities/emoji.ts index 87b525dc59..0e5dcc32c9 100644 --- a/packages/backend/src/models/entities/emoji.ts +++ b/packages/backend/src/models/entities/emoji.ts @@ -38,7 +38,6 @@ export class Emoji { @Column("varchar", { length: 512, - default: "", }) public publicUrl: string; diff --git a/packages/backend/src/remote/activitypub/renderer/emoji.ts b/packages/backend/src/remote/activitypub/renderer/emoji.ts deleted file mode 100644 index dab0e8cac7..0000000000 --- a/packages/backend/src/remote/activitypub/renderer/emoji.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { config } from "@/config.js"; -import type { Emoji } from "@/models/entities/emoji.js"; - -export default (emoji: Emoji) => ({ - id: `${config.url}/emojis/${emoji.name}`, - type: "Emoji", - name: `:${emoji.name}:`, - updated: - emoji.updatedAt != null - ? emoji.updatedAt.toISOString() - : new Date().toISOString, - icon: { - type: "Image", - mediaType: emoji.type || "image/png", - url: emoji.publicUrl || emoji.originalUrl, // || emoji.originalUrl してるのは後方互換性のため - }, -}); diff --git a/packages/backend/src/remote/activitypub/renderer/like.ts b/packages/backend/src/remote/activitypub/renderer/like.ts index ea0df3e359..e6eab0b261 100644 --- a/packages/backend/src/remote/activitypub/renderer/like.ts +++ b/packages/backend/src/remote/activitypub/renderer/like.ts @@ -3,7 +3,7 @@ import { config } from "@/config.js"; import type { NoteReaction } from "@/models/entities/note-reaction.js"; import type { Note } from "@/models/entities/note.js"; import { Emojis } from "@/models/index.js"; -import renderEmoji from "./emoji.js"; +import { renderEmoji } from "backend-rs"; export const renderLike = async (noteReaction: NoteReaction, note: Note) => { const reaction = noteReaction.reaction; diff --git a/packages/backend/src/remote/activitypub/renderer/note.ts b/packages/backend/src/remote/activitypub/renderer/note.ts index dc978f1e0e..e688a4ce00 100644 --- a/packages/backend/src/remote/activitypub/renderer/note.ts +++ b/packages/backend/src/remote/activitypub/renderer/note.ts @@ -6,7 +6,7 @@ import { DriveFiles, Notes, Users, Emojis, Polls } from "@/models/index.js"; import type { Emoji } from "@/models/entities/emoji.js"; import type { Poll } from "@/models/entities/poll.js"; import toHtml from "@/remote/activitypub/misc/get-note-html.js"; -import renderEmoji from "./emoji.js"; +import { renderEmoji } from "backend-rs"; import renderMention from "./mention.js"; import renderHashtag from "./hashtag.js"; import renderDocument from "./document.js"; diff --git a/packages/backend/src/remote/activitypub/renderer/person.ts b/packages/backend/src/remote/activitypub/renderer/person.ts index c6371440b4..30e067b2ac 100644 --- a/packages/backend/src/remote/activitypub/renderer/person.ts +++ b/packages/backend/src/remote/activitypub/renderer/person.ts @@ -4,11 +4,11 @@ import { config } from "@/config.js"; import type { ILocalUser } from "@/models/entities/user.js"; import { DriveFiles, UserProfiles } from "@/models/index.js"; import { getUserKeypair } from "@/misc/keypair-store.js"; -import { toHtml } from "../../../mfm/to-html.js"; +import { toHtml } from "@/mfm/to-html.js"; import renderImage from "./image.js"; import renderKey from "./key.js"; import { getEmojis } from "./note.js"; -import renderEmoji from "./emoji.js"; +import { renderEmoji } from "backend-rs"; import renderHashtag from "./hashtag.js"; import type { IIdentifier } from "../models/identifier.js"; diff --git a/packages/backend/src/server/activitypub.ts b/packages/backend/src/server/activitypub.ts index bc0442d381..e302cb198c 100644 --- a/packages/backend/src/server/activitypub.ts +++ b/packages/backend/src/server/activitypub.ts @@ -7,12 +7,12 @@ import { renderActivity } from "@/remote/activitypub/renderer/index.js"; import renderNote from "@/remote/activitypub/renderer/note.js"; import renderKey from "@/remote/activitypub/renderer/key.js"; import { renderPerson } from "@/remote/activitypub/renderer/person.js"; -import renderEmoji from "@/remote/activitypub/renderer/emoji.js"; import { inbox as processInbox } from "@/queue/index.js"; import { fetchMeta, getInstanceActor, isSelfHost, + renderEmoji, renderFollow, } from "backend-rs"; import { From e28389ed88858c4c79109ebb7e7bcabc4c0270a7 Mon Sep 17 00:00:00 2001 From: naskya Date: Tue, 30 Jul 2024 23:06:34 +0900 Subject: [PATCH 018/117] chore (macro-rs): add for_ts macro --- packages/backend-rs/index.d.ts | 2 +- .../backend-rs/src/federation/activitypub/object/accept.rs | 5 +---- .../backend-rs/src/federation/activitypub/object/emoji.rs | 4 +--- packages/backend-rs/src/federation/nodeinfo/generate.rs | 2 +- packages/macro-rs/macros/src/lib.rs | 5 +++++ 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/packages/backend-rs/index.d.ts b/packages/backend-rs/index.d.ts index 4ad1992d33..37c07f2f6a 100644 --- a/packages/backend-rs/index.d.ts +++ b/packages/backend-rs/index.d.ts @@ -1291,7 +1291,7 @@ export type RelayStatus = 'accepted'| /** Delete all entries in the [attestation_challenge] table created at more than 5 minutes ago */ export declare function removeOldAttestationChallenges(): Promise -export declare function renderAccept(userId: string, followObject: Follow): ApAccept +export declare function renderAccept(userId: string, followObject: ApFollow): ApAccept export declare function renderEmoji(emoji: Emoji): ApEmoji diff --git a/packages/backend-rs/src/federation/activitypub/object/accept.rs b/packages/backend-rs/src/federation/activitypub/object/accept.rs index a78df18809..b0b621243f 100644 --- a/packages/backend-rs/src/federation/activitypub/object/accept.rs +++ b/packages/backend-rs/src/federation/activitypub/object/accept.rs @@ -24,10 +24,7 @@ impl ApAccept { } } -#[cfg(any(test, doctest, feature = "napi"))] -type Follow = follow::ApFollow; - #[macros::ts_export] -pub fn render_accept(user_id: String, follow_object: Follow) -> ApAccept { +pub fn render_accept(user_id: String, follow_object: follow::ApFollow) -> ApAccept { ApAccept::new(user_id, follow_object) } diff --git a/packages/backend-rs/src/federation/activitypub/object/emoji.rs b/packages/backend-rs/src/federation/activitypub/object/emoji.rs index 178a885739..157234b785 100644 --- a/packages/backend-rs/src/federation/activitypub/object/emoji.rs +++ b/packages/backend-rs/src/federation/activitypub/object/emoji.rs @@ -40,9 +40,7 @@ impl ApEmoji { } } -// for napi export -// https://github.com/napi-rs/napi-rs/issues/2060 -#[allow(dead_code)] // TODO: remove this line +#[macros::for_ts] // https://github.com/napi-rs/napi-rs/issues/2060 type Emoji = emoji::Model; #[macros::ts_export] diff --git a/packages/backend-rs/src/federation/nodeinfo/generate.rs b/packages/backend-rs/src/federation/nodeinfo/generate.rs index 4ab7ef65fa..921fc547b0 100644 --- a/packages/backend-rs/src/federation/nodeinfo/generate.rs +++ b/packages/backend-rs/src/federation/nodeinfo/generate.rs @@ -152,7 +152,7 @@ pub async fn nodeinfo_2_0() -> Result { Ok(nodeinfo_2_1().await?.into()) } -#[cfg(any(test, doctest, feature = "napi"))] +#[macros::for_ts] #[macros::errors] pub enum Error { #[doc = "database error"] diff --git a/packages/macro-rs/macros/src/lib.rs b/packages/macro-rs/macros/src/lib.rs index b0beab95bd..78d3d0adb0 100644 --- a/packages/macro-rs/macros/src/lib.rs +++ b/packages/macro-rs/macros/src/lib.rs @@ -76,6 +76,11 @@ define_wrapper_proc_macro_attributes! { #item } + for_ts(_attr, item) { + #[cfg(any(test, doctest, feature = "napi"))] + #item + } + /// When applied to enums, this macro implements [`std::error::Error`] trait /// and generates a document based on error messages unless there is already a doc comment /// From f976e97784d528f63c0ce9ca0702d47297cdc7ce Mon Sep 17 00:00:00 2001 From: naskya Date: Tue, 30 Jul 2024 23:12:48 +0900 Subject: [PATCH 019/117] chore (backend-rs): use for_ts macro --- .../src/federation/internal_actor/instance.rs | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/packages/backend-rs/src/federation/internal_actor/instance.rs b/packages/backend-rs/src/federation/internal_actor/instance.rs index 957aa57492..119ecee549 100644 --- a/packages/backend-rs/src/federation/internal_actor/instance.rs +++ b/packages/backend-rs/src/federation/internal_actor/instance.rs @@ -4,12 +4,8 @@ use crate::{database::db_conn, model::entity::user}; use sea_orm::prelude::*; use tokio::sync::OnceCell; -// for napi export -// https://github.com/napi-rs/napi-rs/issues/2060 -type User = user::Model; - pub const USERNAME: &str = "instance.actor"; -static INSTANCE_ACTOR: OnceCell = OnceCell::const_new(); +static INSTANCE_ACTOR: OnceCell = OnceCell::const_new(); #[macros::errors] pub enum Error { @@ -20,7 +16,7 @@ pub enum Error { Db(#[from] DbErr), } -async fn set_cache() -> Result<&'static User, Error> { +async fn set_cache() -> Result<&'static user::Model, Error> { let instance_actor = INSTANCE_ACTOR .get_or_try_init(|| async { tracing::debug!("caching @instance.actor"); @@ -37,13 +33,16 @@ async fn set_cache() -> Result<&'static User, Error> { Ok(instance_actor) } -pub async fn get() -> Result<&'static User, Error> { +pub async fn get() -> Result<&'static user::Model, Error> { match INSTANCE_ACTOR.get() { Some(model) => Ok(model), None => set_cache().await, } } +#[macros::for_ts] // https://github.com/napi-rs/napi-rs/issues/2060 +type User = user::Model; + #[macros::ts_export(js_name = "getInstanceActor")] pub async fn get_js() -> Result { Ok(get().await?.to_owned()) From 348838bb9b738d17e5c1092a77dfbd4192bcba3b Mon Sep 17 00:00:00 2001 From: naskya Date: Tue, 30 Jul 2024 23:21:57 +0900 Subject: [PATCH 020/117] chore (backend-rs): add missing doc comment --- packages/backend-rs/src/misc/should_nyaify.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/backend-rs/src/misc/should_nyaify.rs b/packages/backend-rs/src/misc/should_nyaify.rs index 8476678c77..73d4ef17c0 100644 --- a/packages/backend-rs/src/misc/should_nyaify.rs +++ b/packages/backend-rs/src/misc/should_nyaify.rs @@ -14,6 +14,7 @@ pub enum Error { #[doc = "cache error"] #[error(transparent)] Cache(#[from] cache::Error), + #[doc = "user not found"] #[error("user {0} not found")] NotFound(String), } From 75142fb8798249e24a2ce63e775e9f4edf6421ce Mon Sep 17 00:00:00 2001 From: ltlapy Date: Mon, 29 Jul 2024 15:29:06 +0000 Subject: [PATCH 021/117] locale: update translations (Korean) Currently translated at 99.1% (1936 of 1952 strings) Translation: Firefish/locales Translate-URL: https://hosted.weblate.org/projects/firefish/locales/ko/ --- locales/ko-KR.yml | 144 +++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 130 insertions(+), 14 deletions(-) diff --git a/locales/ko-KR.yml b/locales/ko-KR.yml index 2f2c54c7e6..c4f0ee2656 100644 --- a/locales/ko-KR.yml +++ b/locales/ko-KR.yml @@ -139,9 +139,9 @@ settingGuide: "추천 설정" cacheRemoteFiles: "리모트 파일을 캐시" cacheRemoteFilesDescription: "이 설정을 해지하면 리모트 파일을 캐시하지 않고 해당 파일을 직접 링크하게 됩니다. 그에 따라 서버의 저장 공간을 절약할 수 있지만, 썸네일이 생성되지 않기 때문에 통신량이 증가합니다." -flagAsBot: "나는 봇입니다" -flagAsBotDescription: "이 계정을 자동화된 수단으로 운용할 경우에 활성화해 주세요. 이 플래그를 활성화하면, 다른 봇이 이를 참고하여 - 봇 끼리의 무한 연쇄 반응을 회피하거나, 이 계정의 시스템 상에서의 취급이 Bot 운영에 최적화되는 등의 변화가 생깁니다." +flagAsBot: "이 계정은 자동화된 계정입니다" +flagAsBotDescription: "이 계정을 자동화된 수단으로 운용할 경우에 활성화해 주세요. 이 플래그를 활성화하면, 다른 자동화 계정이 + 이를 참고하여 자동화 계정 간 무한 연쇄 반응을 회피하거나, 이 계정의 시스템 상에서의 취급이 자동화 계정 운영에 최적화되는 등의 변화가 생깁니다." flagAsCat: "나는 고양이다냥" flagAsCatDescription: "고양이귀를 쓰고 냥냥거려요!" flagShowTimelineReplies: "타임라인에 게시물의 답글을 표시하기" @@ -261,7 +261,7 @@ agreeTo: "{0}에 동의" tos: "이용 약관" start: "시작하기" home: "홈" -remoteUserCaution: "리모트 유저이기 때문에, 정보가 정확하지 않을 수 있습니다." +remoteUserCaution: "리모트 유저는 모든 정보가 표시되지 않습니다." activity: "활동" images: "이미지" birthday: "생일" @@ -441,8 +441,8 @@ usernameInvalidFormat: "a~z, A~Z, 0-9, _를 사용할 수 있습니다." tooShort: "너무 짧습니다" tooLong: "너무 깁니다" weakPassword: "약한 비밀번호" -normalPassword: "좋은 비밀번호" -veryStrongPassword: "강한 비밀번호" +normalPassword: "보통 비밀번호" +veryStrongPassword: "매우 강한 비밀번호" passwordMatched: "일치합니다" passwordNotMatched: "일치하지 않습니다" signinWith: "{x}로 로그인" @@ -605,7 +605,7 @@ emptyToDisableSmtpAuth: "SMTP 인증을 사용하지 않으려면 공란으로 smtpSecure: "SMTP 연결에 Implicit SSL/TTS 사용" smtpSecureInfo: "STARTTLS 사용 시에는 해제합니다" testEmail: "이메일 전송 테스트" -wordMute: "단어 뮤트" +wordMute: "단어 및 언어 뮤트" regexpError: "정규 표현식 오류" regexpErrorDescription: "{tab}단어 뮤트 {line}행의 정규 표현식에 오류가 발생했습니다:" instanceMute: "서버 뮤트" @@ -798,7 +798,7 @@ customCss: "CSS 사용자화" customCssWarn: "이 설정은 기능을 알고 있는 경우에만 사용해야 합니다. 잘못된 값을 입력하면 클라이언트가 정상적으로 작동하지 않을 수 있습니다." global: "글로벌" -squareAvatars: "프로필 아이콘을 사각형으로 표시" +squareAvatars: "고양이가 아닌 프로필 아이콘을 사각형으로 표시" sent: "전송" received: "수신" searchResult: "검색 결과" @@ -942,7 +942,8 @@ _accountDelete: inProgress: "삭제 진행 중" _ad: back: "뒤로" - reduceFrequencyOfThisAd: "이 광고의 표시 빈도 낮추기" + reduceFrequencyOfThisAd: "이 배너의 표시 빈도 낮추기" + adsBy: '{by}에 의한 커뮤니티 배너' _forgotPassword: enterEmail: "여기에 계정에 등록한 메일 주소를 입력해 주세요. 입력한 메일 주소로 비밀번호 재설정 링크를 발송합니다." ifNoEmail: "메일 주소를 등록하지 않은 경우, 서버 관리자에게 문의해 주십시오." @@ -1122,6 +1123,12 @@ _wordMute: soft: "보통" hard: "보다 높은 수준" mutedNotes: "뮤트된 게시물" + mutePatterns: 뮤트할 패턴 + langDescription: 설정한 언어와 일치하는 게시물을 타임라인에서 숨깁니다. + lang: 언어 + muteLangs: 뮤트할 언어 + muteLangsDescription: OR의 경우 공백 또는 줄바꿈으로 구분하십시오. + muteLangsDescription2: en, fr, ja, zh 와 같은 언어 코드를 입력하세요. _instanceMute: instanceMuteDescription: "뮤트한 서버에서 오는 답글을 포함한 모든 게시물과 부스트를 뮤트합니다." instanceMuteDescription2: "한 줄에 하나씩 입력해 주세요" @@ -1277,6 +1284,10 @@ _permissions: "write:gallery": "갤러리를 추가하거나 삭제합니다" "read:gallery-likes": "갤러리의 좋아요를 확인합니다" "write:gallery-likes": "갤러리에 좋아요를 추가하거나 취소합니다" + push: 푸시 알림 보내기 + read: 읽기 (타임라인, 알림, 리액션, 뮤트, 계정 정보 등) + write: 쓰기 (게시물 작성, 리액션 보내기, 뮤트하기, 계정 정보 수정 등) + follow: 계정 팔로우 및 팔로우 해제 _auth: shareAccess: "\"{name}\" 이 계정에 접근하는 것을 허용하시겠습니까?" shareAccessAsk: "이 애플리케이션이 계정에 접근하는 것을 허용하시겠습니까?" @@ -1760,6 +1771,7 @@ _notification: reacted: 님의 리액션 renoted: 님이 부스트 voted: 님이 투표함 + andCountUsers: 와(과) {count}명이 {acted} _deck: alwaysShowMainColumn: "메인 칼럼 항상 표시" columnAlign: "칼럼 정렬" @@ -1803,7 +1815,7 @@ privateMode: 비공개 모드 audio: 오디오 customKaTeXMacro: 커스텀 KaTeX 매크로 replayTutorial: 튜토리얼 다시 보기 -renoteMute: 부스트 뮤트 +renoteMute: 타임라인에서 부스트 숨기기 antennaInstancesDescription: 서버 호스트를 한 줄에 하나씩 입력하세요 userSaysSomethingReason: '{name} 님이 {reason}에 대해 말했습니다' userSaysSomethingReasonQuote: '{name} 님이 {reason} 을 포함하는 게시물을 인용했습니다' @@ -1874,11 +1886,11 @@ selectChannel: 채널 선택 allowedInstancesDescription: 연합을 허가하려는 서버를 한 줄에 하나씩 입력합니다. 비공개 모드에서만 유효합니다. splash: 스플래시 화면 preventAiLearningDescription: 업로드한 게시물이나 미디어를 AI 모델이 학습하지 말기를 요구합니다. -isBot: 이 계정은 봇입니다 +isBot: 이 계정은 자동화된 계정입니다 isAdmin: 관리자 newer: 새로운 게시물 older: 이전 게시물 -renoteUnmute: 부스트 뮤트 해제 +renoteUnmute: 타임라인에서 부스트 보이기 accountMoved: '이 유저는 다른 계정으로 이사했습니다:' silencedInstances: 사일런스한 서버 accessibility: 접근성 @@ -1917,8 +1929,7 @@ license: 라이선스 migrationConfirm: "정말로 이 계정을 {account}로 이사하시겠습니까? 한 번 이사하면, 현재 이 계정은 두 번 다시 사용할 수 없게 됩니다.\n또한, 이사 갈 계정에 현재 사용 중인 계정의 별칭을 올바르게 작성하였는지 다시 한 번 확인하십시오." noteId: 게시물 ID -signupsDisabled: 현재 이 서버에서는 신규 등록을 받고 있지 않습니다. 초대 코드를 가지고 계신 경우 아래 칸에 입력해 주십시오. 초대 - 코드를 가지고 있지 않더라도, 신규 등록이 열려 있는 다른 서버에 등록하실 수 있습니다! +signupsDisabled: 현재 이 서버에서는 신규 등록을 받고 있지 않습니다. 초대 코드를 가지고 계신 경우 아래 칸에 입력해 주십시오. apps: 앱 preventAiLearning: AI에 의한 학습을 막기 isLocked: 이 계정은 팔로우를 수동으로 승인합니다 @@ -2002,3 +2013,108 @@ renotes: 부스트 quotes: 인용 sentFollowRequests: 팔로우 요청 보냄 reactions: 리액션 +searchUsers: 작성한 사람 (옵션) +replaceChatButtonWithAccountButton: 채팅 버튼을 계정 전환으로 변경 +searchEngine: 검색 MFM에서 사용할 검색 엔진 +turnOffCatLanguage: 냥체 변환을 끄기 +noSentFollowRequests: 승인 대기중인 팔로우 요청이 없습니다 +squareCatAvatars: 고양이 계정의 아이콘을 사각형으로 표시 +useThisAccountConfirm: 이 계정으로 계속 진행하시겠습니까? +inputAccountId: '당신의 계정을 입력해 주세요 (예시: @firefish@info.firefish.dev)' +pullToRefreshThreshold: 새로고침하기 위해 아래로 당길 길이 +pullDownToReload: 아래로 당겨 새로고침 +searchRange: 게시시각 범위 (옵션) +showAddFileDescriptionAtFirstPost: 설명이 없는 첨부파일을 게시하려고 할 때에 자동으로 설명 작성창을 열기 +searchCwAndAlt: CW 주석과 미디어 설명에서도 검색하기 +publishTimelines: 비로그인 유저에게 타임라인을 공개 +addAlt4MeTag: '설명이 없는 파일을 게시할 때에 자동으로 #Alt4Me 해시태그를 포함하여 게시' +_emojiModPerm: + unauthorized: 없음 + full: 모두 허용 + add: 추가 + mod: 추가 및 편집 +openServerInfo: 게시물의 서버 이름을 클릭하여 서버 정보 열기 +iconSet: 아이콘 스타일 +showBigPostButton: 게시물 작성 폼에서 게시 버튼을 매우 크게 하기 +emojiModPerm: 커스텀 이모지 관리 권한 +releaseToReload: 놓아서 새로고침 +searchWords: 검색할 단어 / 조회할 ID 및 URL +_later: + secondsAgo: '{n}초 후' + minutesAgo: '{n}분 후' + hoursAgo: '{n}시간 후' + daysAgo: '{n}일 후' + weeksAgo: '{n}주 후' + monthsAgo: '{n}개월 후' + future: 미래 + justNow: 잠시 후 + yearsAgo: '{n}년 후' +makePrivateConfirm: 리모트 서버에 삭제 요청을 보내고, 게시물의 공개 범위를 '비공개'로 전환합니다. 계속하시겠습니까? +markLocalFilesNsfwByDefault: 모든 로컬 파일을 기본으로 NSFW로 처리 +markLocalFilesNsfwByDefaultDescription: 이 설정이 켜져 있더라도 유저는 직접 NSFW 설정을 해제할 수 있으며, 이 + 설정은 기존 파일에는 적용되지 않습니다. +showAttachedNotes: 이 파일이 첨부된 게시물 보기 +noLanguage: 언어 없음 +toReply: 답글 +toQuote: 인용 +replyMute: 타임라인에서 답글 숨기기 +searchPostsWithFiles: 첨부 파일이 있는 게시물만 검색 +antennaLimit: 각 유저가 생성 가능한 최대 안테나 수 +forMobile: 모바일 +reloading: 새로고침하는 중 +noAltTextWarning: 미디어 설명이 없는 파일이 있습니다. 깜빡하고 안 쓰셨나요? +publishTimelinesDescription: 활성화하면 로그인하지 않아도 {url} 에서 로컬 타임라인과 글로벌 타임라인을 확인할 수 있게 + 됩니다. +cannotEditVisibility: 공개 범위를 변경할 수 없습니다 +private: 비공개 +preventMisclick: 클릭 실수 방지 +strongPassword: 강한 비밀번호 +_iconSets: + light: 얇음 + regular: 보통 + bold: 굵음 +i18nServerInfo: 새 단말부터 {language}가 기본값으로 적용됩니다. +privateDescription: 나를 제외한 모두에게 비공개 +enableTimelineStreaming: 타임라인을 자동으로 갱신 +toPost: 게시 +replyUnmute: 타임라인에서 답글 보이기 +attachedToNotes: 이 파일이 첨부된 게시물 +ipFirstAcknowledged: IP 주소를 처음 발견한 날짜 +driveCapacityOverride: 드라이브 용량 변경 +remoteFollow: 리모트 팔로우 +emojiModPermDescription: "추가: 커스텀 이모지의 신규 추가와 태그/카테고리/라이선스를 신규 지정할 수 있습니다.\n추가 및 편집: + '추가'에 더해, 기존 이모지의 이름/카테고리/태그/라이선스를 변경할 수 있습니다.\n모두 허용: '추가 및 편집'에 더해, 기존 커스텀 이모지의 + 삭제를 허가합니다.\n관리자 및 모더레이터는 이 설정을 무시하고 '모두 허용' 권한이 주어집니다." +searchWordsDescription: "게시물을 검색하시려면, 여기에 검색어를 입력하여 주십시오. 공백으로 구분하여 AND, 'OR'으로 구분하여 + OR 검색이 가능합니다.\n예를 들어, '아침 저녁'이라고 검색할 경우 '아침'과 '저녁'을 동시에 포함하는 게시물을 검색하며, '아침 OR 저녁'이라고 + 검색할 경우 '아침' 또는 '저녁' 둘 중 하나가 포함된 게시물을 검색합니다.\n-(대시) 부호를 붙여 특정 단어를 제외할 수 있으며, AND/OR/제외는 + 괄호를 사용하여 동시에 사용할 수 있습니다. '(아침 OR 저녁) 졸려 -식곤증' 과 같이 사용합니다.\n띄어쓰기가 포함된 문자열을 검색하려는 + 경우 \"오늘 뭐하지\"와 같이 큰따옴표를 사용하십시오.\n\n특정 유저나 게시물 페이지로 이동하시려면, 이 칸에 ID 또는 URL을 입력하고 + '조회'를 눌러 주십시오. '검색'을 누르면 해당 ID 또는 URL이 포함된 게시물을 검색합니다." +searchUsersDescription: "특정 게시자가 올린 게시물을 검색할 경우, @user@example.com 혹은 (로컬 유저의 경우) + @user와 같이 게시자의 ID를 입력하십시오. 도메인을 입력하여 해당 서버의 모든 유저가 작성한 게시물을 검색할 수 있습니다.\n\nme 를 + 입력하면 자신의 게시물을 검색합니다. 자신의 검색 결과에는 미등재, 팔로워, 다이렉트, 비공개 게시물이 모두 포함됩니다.\n\nlocal 을 입력하면 + 이 서버의 게시물을 검색합니다." +searchRangeDescription: "게시 시각을 지정하실 경우, 20220615-20231031 과 같이 입력하십시오.\n\n올해 안에서 + 검색하려면 연도를 생략할 수 있습니다. (0105-0106 또는 20231105-0110 과 같이)\n\n시작 날짜와 종료 날짜를 생략할 수 있습니다. + 예를 들어 -0102 의 경우 올해 1월 2일까지의 게시물을, 20231026- 의 경우 2023년 10월 26일 이후의 게시물을 검색합니다." +showNoAltTextWarning: 설명이 없는 첨부 파일을 게시할 때에 경고 +vibrate: 진동 활성화 +clickToShowPatterns: 클릭하여 트랙을 표시 +announcement: 공지사항 +toEdit: 편집 +media: 미디어 +i18nServerChange: '{language}를 대신해서 사용합니다.' +i18nServerSet: 새 기기의 표시 언어를 {language} 로 설정합니다. +getQrCode: QR 코드 표시 +copyRemoteFollowUrl: 리모트 팔로우 URL 복사 +useCdn: 일부 구성요소를 CDN에서 가져오기 +useCdnDescription: Twemoji와 같은 일부 정적 구성요소를 JSDelivr CDN에서 가져옵니다. 비활성화할 경우 이 서버에서 가져옵니다. +suggested: 추천 +showPreviewByDefault: 게시물 작성 화면에서 항상 미리보기 켜기 +hideFollowButtons: 잘못 누르기 쉬운 위치에 있는 팔로우 버튼을 숨기기 +replaceWidgetsButtonWithReloadButton: 위젯 버튼을 새로고침으로 변경 +postSearch: 이 서버의 게시물 검색 +makePrivate: 비공개로 전환 +enablePullToRefresh: "'아래로 당겨 새로고침'을 활성화" +moderationNote: 모더레이션 노트 From c1ac98d1b82b6f3349922fd746f5ce6db0545d90 Mon Sep 17 00:00:00 2001 From: GitLab CI Date: Tue, 30 Jul 2024 20:05:44 +0000 Subject: [PATCH 022/117] fix(deps): update dependency aws-sdk to v2.1665.0 --- packages/backend/package.json | 2 +- pnpm-lock.yaml | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/backend/package.json b/packages/backend/package.json index 9470963f98..df2d27dcf9 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -33,7 +33,7 @@ "archiver": "7.0.1", "async-lock": "1.4.1", "async-mutex": "0.5.0", - "aws-sdk": "2.1664.0", + "aws-sdk": "2.1665.0", "axios": "1.7.2", "backend-rs": "workspace:*", "blurhash": "2.0.5", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b4f8201d9f..54dc1ec1b9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -88,8 +88,8 @@ importers: specifier: 0.5.0 version: 0.5.0 aws-sdk: - specifier: 2.1664.0 - version: 2.1664.0 + specifier: 2.1665.0 + version: 2.1665.0 axios: specifier: 1.7.2 version: 1.7.2 @@ -2868,8 +2868,8 @@ packages: resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} engines: {node: '>= 0.4'} - aws-sdk@2.1664.0: - resolution: {integrity: sha512-S2IA1cCGz38d8ZKsuQGwlK3LE+9cXFt7OFsSGQtKX1Mc40xFXpiqQy7jX1r0vZIiy9ZMnxeTcBPM28G/yYu2kA==} + aws-sdk@2.1665.0: + resolution: {integrity: sha512-IhEcdGmiplF3l/pCROxEYIdi0s+LZ2VkbMAq3RgoXTHxY5cgqVRNaqsEsgIHev2Clxa9V08HttnIERTIUqb1+Q==} engines: {node: '>= 10.0.0'} axios@0.24.0: @@ -9005,7 +9005,7 @@ snapshots: dependencies: possible-typed-array-names: 1.0.0 - aws-sdk@2.1664.0: + aws-sdk@2.1665.0: dependencies: buffer: 4.9.2 events: 1.1.1 @@ -9175,7 +9175,7 @@ snapshots: buffer@4.9.2: dependencies: base64-js: 1.5.1 - ieee754: 1.1.13 + ieee754: 1.2.1 isarray: 1.0.0 buffer@5.7.1: @@ -13141,7 +13141,7 @@ snapshots: xml2js@0.6.2: dependencies: - sax: 1.2.1 + sax: 1.4.1 xmlbuilder: 11.0.1 xmlbuilder@11.0.1: {} From b9782e9fc1efeb30ba94f57d38b884f30ea13e17 Mon Sep 17 00:00:00 2001 From: GitLab CI Date: Tue, 30 Jul 2024 20:06:13 +0000 Subject: [PATCH 023/117] fix(deps): update dependency bull to v4.16.0 --- packages/backend/package.json | 2 +- pnpm-lock.yaml | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/backend/package.json b/packages/backend/package.json index 9470963f98..c355a96894 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -37,7 +37,7 @@ "axios": "1.7.2", "backend-rs": "workspace:*", "blurhash": "2.0.5", - "bull": "4.15.1", + "bull": "4.16.0", "cacheable-lookup": "git+https://github.com/TheEssem/cacheable-lookup.git#dd2fb616366a3c68dcf321a57a67295967b204bf", "cbor-x": "1.6.0", "chalk": "5.3.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b4f8201d9f..f442444261 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -100,8 +100,8 @@ importers: specifier: 2.0.5 version: 2.0.5 bull: - specifier: 4.15.1 - version: 4.15.1 + specifier: 4.16.0 + version: 4.16.0 cacheable-lookup: specifier: git+https://github.com/TheEssem/cacheable-lookup.git#dd2fb616366a3c68dcf321a57a67295967b204bf version: https://codeload.github.com/TheEssem/cacheable-lookup/tar.gz/dd2fb616366a3c68dcf321a57a67295967b204bf @@ -3004,8 +3004,8 @@ packages: resolution: {integrity: sha512-4T53u4PdgsXqKaIctwF8ifXlRTTmEPJ8iEPWFdGZvcf7sbwYo6FKFEX9eNNAnzFZ7EzJAQ3CJeOtCRA4rDp7Pw==} engines: {node: '>=6.14.2'} - bull@4.15.1: - resolution: {integrity: sha512-knVKiZdrXbRkB+fWqNryDz85b3JfsT3dBrZexkztwvTH/AFmpHvsC933VB3JX18aJCz47E+xdO57xbDvxljoAg==} + bull@4.16.0: + resolution: {integrity: sha512-dgHRLULPexLkpm9wP/7F7Vlf2fdvmffdwhv3Bqu5lFhO+XDDJ4yGqlTPE61Jj1zM8CgchLmJEgIfe7y69jtuOg==} engines: {node: '>=12'} busboy@1.6.0: @@ -9192,7 +9192,7 @@ snapshots: dependencies: node-gyp-build: 4.8.1 - bull@4.15.1: + bull@4.16.0: dependencies: cron-parser: 4.9.0 get-port: 5.1.1 From 32b8bfdcec0f5abe0960a3bb792fb49c0805f9e6 Mon Sep 17 00:00:00 2001 From: Eana Hufwe Date: Mon, 29 Jul 2024 23:13:21 +0000 Subject: [PATCH 024/117] refactor(client): Logical CSS property support --- packages/backend/src/server/web/bios.css | 55 +-- packages/backend/src/server/web/cli.css | 20 +- packages/backend/src/server/web/style.css | 45 +-- .../client/src/components/MkAbuseReport.vue | 15 +- .../src/components/MkAbuseReportWindow.vue | 2 +- .../client/src/components/MkAnnouncement.vue | 13 +- .../client/src/components/MkAutocomplete.vue | 50 ++- packages/client/src/components/MkAvatars.vue | 4 +- packages/client/src/components/MkButton.vue | 45 +-- .../src/components/MkChannelFollowButton.vue | 16 +- .../src/components/MkChannelPreview.vue | 47 +-- packages/client/src/components/MkChart.vue | 8 +- .../client/src/components/MkChartTooltip.vue | 8 +- .../client/src/components/MkChatPreview.vue | 40 +- .../client/src/components/MkContainer.vue | 45 +-- .../client/src/components/MkCropperDialog.vue | 20 +- packages/client/src/components/MkCwButton.vue | 16 +- .../src/components/MkDateSeparatedList.vue | 19 +- packages/client/src/components/MkDialog.vue | 25 +- packages/client/src/components/MkDonation.vue | 38 +- .../client/src/components/MkDrive.file.vue | 46 ++- .../client/src/components/MkDrive.folder.vue | 26 +- .../src/components/MkDrive.navFolder.vue | 2 +- packages/client/src/components/MkDrive.vue | 39 +- .../src/components/MkDriveFileThumbnail.vue | 8 +- .../src/components/MkDriveSelectDialog.vue | 2 +- .../src/components/MkEmojiPicker.section.vue | 2 +- .../client/src/components/MkEmojiPicker.vue | 78 ++-- .../src/components/MkEmojiPickerDialog.vue | 4 +- .../src/components/MkFileListForAdmin.vue | 30 +- packages/client/src/components/MkFolder.vue | 26 +- .../client/src/components/MkFollowButton.vue | 31 +- .../src/components/MkForgotPassword.vue | 2 +- .../src/components/MkGalleryPostPreview.vue | 36 +- .../client/src/components/MkImageViewer.vue | 19 +- .../src/components/MkImgWithBlurhash.vue | 19 +- packages/client/src/components/MkInfo.vue | 10 +- .../src/components/MkInstanceCardMini.vue | 12 +- .../src/components/MkInstanceSelectDialog.vue | 27 +- .../client/src/components/MkInstanceStats.vue | 18 +- .../src/components/MkInstanceTicker.vue | 15 +- packages/client/src/components/MkKeyValue.vue | 16 +- .../client/src/components/MkLaunchPad.vue | 34 +- packages/client/src/components/MkLink.vue | 2 +- .../src/components/MkManyAnnouncements.vue | 9 +- packages/client/src/components/MkMedia.vue | 38 +- .../client/src/components/MkMediaBanner.vue | 11 +- .../client/src/components/MkMediaCaption.vue | 60 +-- .../client/src/components/MkMediaList.vue | 29 +- packages/client/src/components/MkMention.vue | 16 +- .../client/src/components/MkMenu.child.vue | 38 +- packages/client/src/components/MkMenu.vue | 68 ++-- .../client/src/components/MkModPlayer.vue | 41 +- packages/client/src/components/MkModal.vue | 162 ++++++-- .../src/components/MkModalPageWindow.vue | 28 +- .../client/src/components/MkModalWindow.vue | 24 +- packages/client/src/components/MkMoved.vue | 4 +- packages/client/src/components/MkNote.vue | 113 +++--- .../client/src/components/MkNoteDetailed.vue | 76 ++-- .../client/src/components/MkNotePreview.vue | 33 +- .../client/src/components/MkNoteSimple.vue | 31 +- packages/client/src/components/MkNoteSub.vue | 174 +++++---- .../client/src/components/MkNotification.vue | 40 +- .../src/components/MkNotificationFolded.vue | 24 +- .../src/components/MkNotificationToast.vue | 27 +- .../src/components/MkObjectView.value.vue | 8 +- .../client/src/components/MkPagePreview.vue | 46 +-- .../client/src/components/MkPageWindow.vue | 6 +- .../client/src/components/MkPagination.vue | 8 +- packages/client/src/components/MkPoll.vue | 20 +- .../client/src/components/MkPollEditor.vue | 31 +- .../client/src/components/MkPopupMenu.vue | 4 +- packages/client/src/components/MkPostForm.vue | 354 ++++++++++-------- .../src/components/MkPostFormAttaches.vue | 25 +- .../client/src/components/MkPostSearch.vue | 13 +- .../client/src/components/MkPullToRefresh.vue | 25 +- packages/client/src/components/MkQrCode.vue | 13 +- .../client/src/components/MkQuoteButton.vue | 7 +- .../client/src/components/MkReactedUsers.vue | 9 +- .../src/components/MkReactionTooltip.vue | 5 +- .../components/MkReactionsViewer.details.vue | 27 +- .../components/MkReactionsViewer.reaction.vue | 12 +- .../src/components/MkReactionsViewer.vue | 10 +- .../client/src/components/MkRemoteCaution.vue | 2 +- packages/client/src/components/MkRipple.vue | 4 +- .../client/src/components/MkSearchBar.vue | 12 +- .../src/components/MkShowMoreButton.vue | 18 +- packages/client/src/components/MkSignin.vue | 13 +- packages/client/src/components/MkSignup.vue | 5 +- .../src/components/MkSimpleTextWindow.vue | 8 +- packages/client/src/components/MkSparkle.vue | 4 +- .../client/src/components/MkSuperMenu.vue | 54 +-- packages/client/src/components/MkTab.vue | 42 ++- packages/client/src/components/MkTagCloud.vue | 4 +- packages/client/src/components/MkTimeline.vue | 27 +- packages/client/src/components/MkToast.vue | 20 +- .../src/components/MkTokenGenerateWindow.vue | 10 +- packages/client/src/components/MkTooltip.vue | 24 +- .../src/components/MkTutorialDialog.vue | 13 +- packages/client/src/components/MkUpdated.vue | 12 +- .../client/src/components/MkUrlPreview.vue | 39 +- .../src/components/MkUrlPreviewPopup.vue | 4 +- .../client/src/components/MkUserCardMini.vue | 16 +- packages/client/src/components/MkUserInfo.vue | 55 +-- .../client/src/components/MkUserPreview.vue | 2 +- .../src/components/MkUserSelectDialog.vue | 20 +- .../components/MkUserSelectLocalDialog.vue | 20 +- .../client/src/components/MkUsersTooltip.vue | 10 +- .../client/src/components/MkVisibility.vue | 2 +- .../src/components/MkVisibilityPicker.vue | 45 +-- .../client/src/components/MkWaitingDialog.vue | 8 +- packages/client/src/components/MkWidgets.vue | 21 +- packages/client/src/components/MkWindow.vue | 84 ++--- .../client/src/components/form/checkbox.vue | 17 +- .../client/src/components/form/folder.vue | 21 +- packages/client/src/components/form/input.vue | 45 ++- packages/client/src/components/form/link.vue | 17 +- packages/client/src/components/form/radio.vue | 22 +- .../client/src/components/form/radios.vue | 10 +- packages/client/src/components/form/range.vue | 28 +- .../client/src/components/form/section.vue | 18 +- .../client/src/components/form/select.vue | 43 ++- packages/client/src/components/form/slot.vue | 10 +- .../client/src/components/form/suspense.vue | 2 +- .../client/src/components/form/switch.vue | 27 +- .../client/src/components/form/textarea.vue | 25 +- .../client/src/components/global/MkAd.vue | 26 +- .../client/src/components/global/MkAvatar.vue | 21 +- .../client/src/components/global/MkEmoji.vue | 8 +- .../client/src/components/global/MkError.vue | 12 +- .../src/components/global/MkLoading.vue | 15 +- .../global/MkMisskeyFlavoredMarkdown.vue | 10 +- .../src/components/global/MkPageHeader.vue | 118 +++--- .../client/src/components/global/MkSpacer.vue | 7 +- .../components/global/MkStickyContainer.vue | 7 +- .../client/src/components/global/MkUrl.vue | 2 +- .../src/components/note/MkNoteContent.vue | 58 +-- .../src/components/note/MkNoteFooter.vue | 23 +- .../src/components/note/MkNoteFooterInfo.vue | 2 +- .../src/components/note/MkNoteHeader.vue | 40 +- .../src/components/note/MkNoteHeaderInfo.vue | 16 +- .../src/components/note/MkNoteMedia.vue | 38 +- .../src/components/note/MkNoteTranslation.vue | 2 +- .../src/components/note/MkRenoteBar.vue | 14 +- .../src/components/page/page.button.vue | 7 +- .../src/components/page/page.canvas.vue | 2 +- .../src/components/page/page.counter.vue | 7 +- .../client/src/components/page/page.note.vue | 3 +- .../src/components/page/page.number-input.vue | 7 +- .../client/src/components/page/page.post.vue | 6 +- .../src/components/page/page.section.vue | 18 +- .../src/components/page/page.switch.vue | 5 +- .../src/components/page/page.text-input.vue | 7 +- .../client/src/components/page/page.text.vue | 7 +- packages/client/src/init.ts | 11 +- packages/client/src/navbar.ts | 6 +- packages/client/src/pages/_error_.vue | 12 +- packages/client/src/pages/about-firefish.vue | 23 +- packages/client/src/pages/about.emojis.vue | 16 +- .../client/src/pages/about.federation.vue | 4 +- packages/client/src/pages/about.vue | 12 +- packages/client/src/pages/admin-file.vue | 9 +- packages/client/src/pages/admin/_header_.vue | 74 ++-- packages/client/src/pages/admin/abuses.vue | 12 +- .../src/pages/admin/emoji-edit-dialog.vue | 5 +- packages/client/src/pages/admin/emojis.vue | 28 +- packages/client/src/pages/admin/files.vue | 2 +- packages/client/src/pages/admin/index.vue | 20 +- .../src/pages/admin/overview.federation.vue | 19 +- .../src/pages/admin/overview.metrics.vue | 8 +- .../src/pages/admin/overview.moderators.vue | 8 +- .../client/src/pages/admin/overview.queue.vue | 7 +- .../client/src/pages/admin/overview.stats.vue | 17 +- .../client/src/pages/admin/overview.user.vue | 14 +- .../client/src/pages/admin/promotions.vue | 4 +- .../client/src/pages/admin/queue.chart.vue | 10 +- packages/client/src/pages/admin/relays.vue | 7 +- packages/client/src/pages/admin/settings.vue | 6 +- packages/client/src/pages/admin/users.vue | 8 +- packages/client/src/pages/announcements.vue | 8 +- packages/client/src/pages/channel-editor.vue | 2 +- packages/client/src/pages/channel.vue | 55 +-- packages/client/src/pages/channels.vue | 5 + packages/client/src/pages/clip.vue | 8 +- packages/client/src/pages/emojis.emoji.vue | 11 +- .../client/src/pages/explore.featured.vue | 2 +- packages/client/src/pages/explore.users.vue | 22 +- packages/client/src/pages/explore.vue | 5 + .../client/src/pages/follow-requests-sent.vue | 29 +- packages/client/src/pages/follow-requests.vue | 38 +- packages/client/src/pages/gallery/edit.vue | 10 +- packages/client/src/pages/gallery/index.vue | 8 +- packages/client/src/pages/gallery/post.vue | 49 ++- packages/client/src/pages/instance-info.vue | 27 +- packages/client/src/pages/messaging/index.vue | 14 +- .../pages/messaging/messaging-room.form.vue | 32 +- .../messaging/messaging-room.message.vue | 92 ++--- .../src/pages/messaging/messaging-room.vue | 45 ++- packages/client/src/pages/mfm-cheat-sheet.vue | 6 +- packages/client/src/pages/miauth.vue | 9 +- .../client/src/pages/my-antennas/editor.vue | 5 +- .../client/src/pages/my-antennas/index.vue | 12 +- packages/client/src/pages/my-clips/index.vue | 6 +- packages/client/src/pages/my-groups/group.vue | 7 +- packages/client/src/pages/my-groups/index.vue | 2 +- packages/client/src/pages/my-lists/index.vue | 4 +- packages/client/src/pages/my-lists/list.vue | 10 +- packages/client/src/pages/no-graze.vue | 9 +- packages/client/src/pages/note.vue | 13 +- packages/client/src/pages/notifications.vue | 5 + packages/client/src/pages/oauth.vue | 18 +- .../page-editor/els/page-editor.el.button.vue | 5 +- .../page-editor/els/page-editor.el.if.vue | 5 +- .../page-editor/els/page-editor.el.image.vue | 2 +- .../page-editor/els/page-editor.el.note.vue | 4 +- .../page-editor/els/page-editor.el.switch.vue | 5 +- .../page-editor/els/page-editor.el.text.vue | 6 +- .../els/page-editor.el.textarea.vue | 6 +- .../page-editor/page-editor.container.vue | 24 +- .../page-editor/page-editor.script-block.vue | 10 +- .../src/pages/page-editor/page-editor.vue | 40 +- packages/client/src/pages/page.vue | 58 +-- packages/client/src/pages/pages.vue | 17 +- packages/client/src/pages/scratchpad.vue | 4 +- packages/client/src/pages/search.vue | 5 + .../src/pages/settings/2fa.qrdialog.vue | 10 +- packages/client/src/pages/settings/2fa.vue | 8 +- .../client/src/pages/settings/accounts.vue | 13 +- packages/client/src/pages/settings/apps.vue | 11 +- packages/client/src/pages/settings/deck.vue | 2 +- packages/client/src/pages/settings/drive.vue | 4 +- .../src/pages/settings/import-export.vue | 2 +- packages/client/src/pages/settings/index.vue | 28 +- .../src/pages/settings/instance-mute.vue | 2 +- .../client/src/pages/settings/migration.vue | 2 +- .../client/src/pages/settings/mute-block.vue | 2 +- packages/client/src/pages/settings/navbar.vue | 21 +- packages/client/src/pages/settings/other.vue | 2 +- packages/client/src/pages/settings/plugin.vue | 2 +- .../client/src/pages/settings/profile.vue | 17 +- .../client/src/pages/settings/reaction.vue | 18 +- .../client/src/pages/settings/security.vue | 20 +- packages/client/src/pages/settings/sounds.vue | 2 +- .../client/src/pages/settings/statusbar.vue | 2 +- packages/client/src/pages/settings/theme.vue | 119 +++--- .../client/src/pages/settings/word-mute.vue | 2 +- packages/client/src/pages/share.vue | 3 +- packages/client/src/pages/tag.vue | 5 + packages/client/src/pages/theme-editor.vue | 13 +- packages/client/src/pages/timeline.vue | 13 +- packages/client/src/pages/user-info.vue | 23 +- .../client/src/pages/user-list-timeline.vue | 2 +- packages/client/src/pages/user/clips.vue | 6 +- packages/client/src/pages/user/home.vue | 156 ++++---- .../client/src/pages/user/index.photos.vue | 6 +- .../client/src/pages/user/index.timeline.vue | 6 +- packages/client/src/pages/user/index.vue | 2 +- packages/client/src/pages/user/media-list.vue | 2 +- packages/client/src/pages/user/reactions.vue | 19 +- .../client/src/pages/welcome.entrance.a.vue | 132 ++++--- .../client/src/pages/welcome.entrance.b.vue | 66 ++-- .../client/src/pages/welcome.entrance.c.vue | 86 +++-- packages/client/src/pages/welcome.setup.vue | 10 +- .../client/src/pages/welcome.timeline.vue | 20 +- packages/client/src/scripts/get-note-menu.ts | 4 +- packages/client/src/scripts/get-user-menu.ts | 2 +- packages/client/src/style.scss | 225 +++++++---- packages/client/src/ui/_common_/common.vue | 19 +- .../src/ui/_common_/navbar-for-mobile.vue | 97 +++-- packages/client/src/ui/_common_/navbar.vue | 171 ++++----- .../src/ui/_common_/statusbar-federation.vue | 10 +- .../client/src/ui/_common_/statusbar-rss.vue | 9 +- .../src/ui/_common_/statusbar-user-list.vue | 13 +- .../client/src/ui/_common_/statusbars.vue | 9 +- .../src/ui/_common_/stream-indicator.vue | 9 +- packages/client/src/ui/_common_/upload.vue | 42 ++- packages/client/src/ui/deck.vue | 81 ++-- .../client/src/ui/deck/antenna-column.vue | 2 +- .../client/src/ui/deck/channel-column.vue | 2 +- packages/client/src/ui/deck/column.vue | 49 +-- packages/client/src/ui/deck/direct-column.vue | 2 +- packages/client/src/ui/deck/list-column.vue | 4 +- .../client/src/ui/deck/mentions-column.vue | 2 +- .../src/ui/deck/notifications-column.vue | 2 +- packages/client/src/ui/deck/tl-column.vue | 2 +- .../client/src/ui/deck/widgets-column.vue | 5 +- packages/client/src/ui/universal.vue | 128 ++++--- packages/client/src/ui/universal.widgets.vue | 16 +- packages/client/src/ui/visitor/a.vue | 41 +- packages/client/src/ui/visitor/b.vue | 44 +-- packages/client/src/ui/visitor/header.vue | 64 ++-- packages/client/src/ui/visitor/kanban.vue | 62 +-- packages/client/src/ui/zen.vue | 5 +- packages/client/src/widgets/aiscript.vue | 19 +- packages/client/src/widgets/calendar.vue | 43 ++- packages/client/src/widgets/clock.vue | 22 +- packages/client/src/widgets/digital-clock.vue | 3 +- packages/client/src/widgets/federation.vue | 19 +- .../client/src/widgets/instance-cloud.vue | 2 +- packages/client/src/widgets/job-queue.vue | 4 +- packages/client/src/widgets/memo.vue | 19 +- packages/client/src/widgets/notifications.vue | 2 +- packages/client/src/widgets/online-users.vue | 3 +- packages/client/src/widgets/photos.vue | 4 +- packages/client/src/widgets/rss-ticker.vue | 11 +- packages/client/src/widgets/rss.vue | 5 +- packages/client/src/widgets/server-info.vue | 11 +- .../src/widgets/server-metric/cpu-mem.vue | 6 +- .../client/src/widgets/server-metric/cpu.vue | 8 +- .../client/src/widgets/server-metric/disk.vue | 8 +- .../client/src/widgets/server-metric/mem.vue | 8 +- .../client/src/widgets/server-metric/pie.vue | 2 +- packages/client/src/widgets/slideshow.vue | 14 +- packages/client/src/widgets/timeline.vue | 14 +- packages/client/src/widgets/trends.vue | 11 +- packages/client/src/widgets/unix-clock.vue | 3 +- 316 files changed, 4183 insertions(+), 3214 deletions(-) diff --git a/packages/backend/src/server/web/bios.css b/packages/backend/src/server/web/bios.css index d6a1285e94..db00beae8d 100644 --- a/packages/backend/src/server/web/bios.css +++ b/packages/backend/src/server/web/bios.css @@ -1,6 +1,6 @@ main > .tabs { padding: 16px; - border-bottom: 4px solid #908caa; + border-block-end: 4px solid #908caa; } #lsEditor > .adder { margin: 16px; @@ -9,21 +9,21 @@ main > .tabs { } #lsEditor > .adder > textarea { display: block; - width: 100%; - min-height: 5em; + inline-size: 100%; + min-block-size: 5em; box-sizing: border-box; } #lsEditor > .record { padding: 16px; - border-bottom: 1px solid #908caa; + border-block-end: 1px solid #908caa; } #lsEditor > .record > header { font-weight: 700; } #lsEditor > .record > textarea { display: block; - width: 100%; - min-height: 5em; + inline-size: 100%; + min-block-size: 5em; box-sizing: border-box; } @@ -36,7 +36,7 @@ main { } #tl > div { padding: 16px; - border-bottom: 1px solid #908caa; + border-block-end: 1px solid #908caa; } #tl > div > header { font-weight: 700; @@ -59,11 +59,14 @@ html { } button { border-radius: 999px; - padding: 0px 12px 0px 12px; + padding-block-start: 0px; + padding-inline-end: 12px; + padding-block-end: 0px; + padding-inline-start: 12px; border: none; cursor: pointer; - margin-bottom: 12px; - background: linear-gradient(90deg, rgb(156, 207, 216), rgb(49, 116, 143)); + margin-block-end: 12px; + background: linear-gradient(var(--gradient-to-inline-end), rgb(156, 207, 216), rgb(49, 116, 143)); line-height: 50px; color: #191724; font-weight: bold; @@ -72,25 +75,29 @@ button { } button { border-radius: 999px; - padding: 0px 12px 0px 12px; + padding-block-start: 0px; + padding-inline-end: 12px; + padding-block-end: 0px; + padding-inline-start: 12px; border: none; cursor: pointer; - margin-bottom: 12px; + margin-block-end: 12px; } button { background: #444; line-height: 40px; color: rgb(156, 207, 216); font-size: 16px; - padding: 0 20px; - margin-right: 5px; - margin-left: 5px; + padding-block: 0; + padding-inline: 20px; + margin-inline-end: 5px; + margin-inline-start: 5px; } button:hover { background: #555; } #ls { - background: linear-gradient(90deg, rgb(156, 207, 216), rgb(49, 116, 143)); + background: linear-gradient(var(--gradient-to-inline-end), rgb(156, 207, 216), rgb(49, 116, 143)); line-height: 30px; color: #191724; font-weight: bold; @@ -120,10 +127,10 @@ textarea { border: solid #aaa; border-radius: 10px; color: #e0def4; - margin-top: 1rem; - margin-bottom: 1rem; - width: 20rem; - height: 7.5rem; + margin-block-start: 1rem; + margin-block-end: 1rem; + inline-size: 20rem; + block-size: 7.5rem; padding: 0.5rem; } @@ -135,10 +142,10 @@ input { border: solid #aaa; border-radius: 10px; color: #e0def4; - margin-top: 1rem; - margin-bottom: 1rem; - width: 10rem; - height: 1rem; + margin-block-start: 1rem; + margin-block-end: 1rem; + inline-size: 10rem; + block-size: 1rem; padding: 0.5rem; } diff --git a/packages/backend/src/server/web/cli.css b/packages/backend/src/server/web/cli.css index 740a2aa1a2..311a962e59 100644 --- a/packages/backend/src/server/web/cli.css +++ b/packages/backend/src/server/web/cli.css @@ -10,7 +10,7 @@ main { border-radius: 10px; margin: 10px; padding: 10px; - width: fit-content; + inline-size: fit-content; } #tl > div > header { font-weight: 700; @@ -19,7 +19,7 @@ main { img { border-radius: 10px; - margin-right: 10px; + margin-inline-end: 10px; } #form { @@ -42,11 +42,11 @@ html { button { border-radius:999px; padding:0 40px; - margin-top: 1rem; + margin-block-start: 1rem; border:none; cursor:pointer; - margin-bottom:12px; - background:linear-gradient(90deg,#9ccfd8,#31748f); + margin-block-end:12px; + background:linear-gradient(var(--gradient-to-inline-end),#9ccfd8,#31748f); line-height:50px; color:#191724; font-weight:700; @@ -75,9 +75,9 @@ code { border: solid #aaa; border-radius: 10px; color: #e0def4; - margin-top: 3rem; - width: 20rem; - height: 5rem; + margin-block-start: 3rem; + inline-size: 20rem; + block-size: 5rem; padding: 0.5rem; } @@ -85,8 +85,8 @@ code { border: solid #eee; } -@media screen and (max-width: 500px) { +@media screen and (max-inline-size: 500px) { #text { - width: 80% + inline-size: 80% } } diff --git a/packages/backend/src/server/web/style.css b/packages/backend/src/server/web/style.css index 2a93253992..6477874698 100644 --- a/packages/backend/src/server/web/style.css +++ b/packages/backend/src/server/web/style.css @@ -23,10 +23,10 @@ html { #splash { position: fixed; z-index: 10000; - top: 0; - left: 0; - width: 100vw; - height: 100vh; + inset-block-start: 0; + inset-inline-start: 0; + inline-size: 100vi; + block-size: 100vb; cursor: wait; background-color: var(--bg); opacity: 1; @@ -35,36 +35,30 @@ html { #splashIcon { position: absolute; - top: 0; - right: 0; - bottom: 0; - left: 0; + inset: 0; margin: auto; - width: 64px; - height: 64px; + inline-size: 64px; + block-size: 64px; pointer-events: none; } #splashSpinner { position: absolute; - top: 0; - right: 0; - bottom: 0; - left: 0; + inset: 0; margin: auto; display: inline-block; - width: 28px; - height: 28px; + inline-size: 28px; + block-size: 28px; transform: translateY(110px); display: none; color: var(--accent); } #splashSpinner > .spinner { position: absolute; - top: 0; - left: 0; - width: 28px; - height: 28px; + inset-block-start: 0; + inset-inline-start: 0; + inline-size: 28px; + block-size: 28px; fill-rule: evenodd; clip-rule: evenodd; stroke-linecap: round; @@ -123,15 +117,12 @@ html { #splashText { position: absolute; - top: 0; - right: 0; - bottom: 0; - left: 0; + inset: 0; margin: auto; display: inline-block; - width: 70%; - height: 0; + inline-size: 70%; + block-size: 0; text-align: center; - padding-top: 100px; + padding-block-start: 100px; font-family: "Atkinson Hyperlegible", sans-serif; } diff --git a/packages/client/src/components/MkAbuseReport.vue b/packages/client/src/components/MkAbuseReport.vue index b190652052..a361f2fc54 100644 --- a/packages/client/src/components/MkAbuseReport.vue +++ b/packages/client/src/components/MkAbuseReport.vue @@ -99,11 +99,11 @@ function resolve() { display: flex; > .target { - width: 35%; + inline-size: 35%; box-sizing: border-box; - text-align: left; + text-align: start; padding: 24px; - border-right: solid 1px var(--divider); + border-inline-end: solid 1px var(--divider); > .info { display: flex; @@ -125,13 +125,14 @@ function resolve() { background-size: 16px 16px; > .avatar { - width: 42px; - height: 42px; + inline-size: 42px; + block-size: 42px; } > .names { - margin-left: 0.3em; - padding: 0 8px; + margin-inline-start: 0.3em; + padding-block: 0; + padding-inline: 8px; flex: 1; > .name { diff --git a/packages/client/src/components/MkAbuseReportWindow.vue b/packages/client/src/components/MkAbuseReportWindow.vue index bde54b7d7e..3f3b02aa5a 100644 --- a/packages/client/src/components/MkAbuseReportWindow.vue +++ b/packages/client/src/components/MkAbuseReportWindow.vue @@ -9,7 +9,7 @@