From de4da3c1fd491376e4b59585e28d339e26722989 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=80=81=E5=91=A8=E9=83=A8=E8=90=BD?= Date: Tue, 19 Mar 2024 22:37:46 +0800 Subject: [PATCH 01/52] docs: add minimum dependencies --- dev/docs/local-installation.md | 2 ++ docs/install.md | 30 ++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/dev/docs/local-installation.md b/dev/docs/local-installation.md index a13aa6437f..132d86bd56 100644 --- a/dev/docs/local-installation.md +++ b/dev/docs/local-installation.md @@ -42,6 +42,8 @@ cargo --version ### PostgreSQL and PGroonga +Firefish requires PostgreSQL v12 or later. While you can choose any versions between v12 and the latest version (v16.2 as of writing), we recommend that you install v12.x so as not to use new features inadvertently and introduce incompatibility issues. + PostgreSQL install instructions can be found at [this page](https://www.postgresql.org/download/). ```sh diff --git a/docs/install.md b/docs/install.md index 061000fa32..f030e87125 100644 --- a/docs/install.md +++ b/docs/install.md @@ -4,6 +4,8 @@ This document shows an example procedure for installing Firefish on Debian 12. N If you want to use the pre-built container image, please refer to [`install-container.md`](./install-container.md). +If you do not prepare your environment as document, be sure to meet the minimum dependencies given at the bottom of the page. + Make sure that you can use the `sudo` command before proceeding. ## 1. Install dependencies @@ -315,3 +317,31 @@ cd ~/firefish - Run `psql -d firefish` (or whatever the database name is) - Run `UPDATE "user" SET "isAdmin" = true WHERE id='999999';` (replace `999999` with the copied ID) - Restart your Firefish server + +## Dependencies + +**We only recommend that you use components that are still within the upstream support cycle for better performance and security, and it is recommended that new sites meet the recommended dependency version requirements.** + +- At least [NodeJS](https://nodejs.org/en/) v18.17.0 (v20/v21 recommended) +- At least [PostgreSQL](https://www.postgresql.org/) v12 (v16 recommended) with [PGroonga](https://pgroonga.github.io/) extension +- At least [Redis](https://redis.io/) v7 +- Web Proxy (one of the following) + - Caddy (recommended for new users) + - Nginx (recommended) + - Apache + +### Optional dependencies + +- [FFmpeg](https://ffmpeg.org/) for video transcoding +- Caching server (one of the following) + - [DragonflyDB](https://www.dragonflydb.io/) (recommended) + - [KeyDB](https://keydb.dev/) + - Another [Redis](https://redis.io/) server + +### Build dependencies + +- At least [Rust](https://www.rust-lang.org/) v1.74 +- C/C++ compiler & build tools + - `build-essential` on Debian/Ubuntu Linux + - `base-devel` on Arch Linux +- [Python 3](https://www.python.org/) From db0bd21edcc4681dac033b7ec4184cb555940607 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=80=81=E5=91=A8=E9=83=A8=E8=90=BD?= Date: Mon, 11 Mar 2024 08:33:47 +0800 Subject: [PATCH 02/52] feat(client): attachment without description opened when choose add alt --- packages/client/src/components/MkPostForm.vue | 81 ++++++++++++++++++- 1 file changed, 79 insertions(+), 2 deletions(-) diff --git a/packages/client/src/components/MkPostForm.vue b/packages/client/src/components/MkPostForm.vue index 3890908026..ad8c4c5ba3 100644 --- a/packages/client/src/components/MkPostForm.vue +++ b/packages/client/src/components/MkPostForm.vue @@ -500,6 +500,8 @@ const withHashtags = computed( ); const hashtags = computed(defaultStore.makeGetterSetter("postFormHashtags")); +let firstTryPost = true; + watch(text, () => { checkMissingMention(); }); @@ -1048,16 +1050,91 @@ async function post() { defaultStore.state.showNoAltTextWarning && files.value.some((f) => f.comment == null || f.comment.length === 0) ) { + if (firstTryPost) { + for (const file of files.value) { + if (file.comment == null || file.comment.length === 0) { + os.popup( + defineAsyncComponent( + () => import("@/components/MkMediaCaption.vue"), + ), + { + title: i18n.ts.describeFile, + input: { + placeholder: i18n.ts.inputNewDescription, + default: + file.comment !== null ? file.comment : "", + }, + image: file, + }, + { + done: (result) => { + if (!result || result.canceled) return; + const comment = + result.result.length === 0 + ? null + : result.result; + os.api("drive/files/update", { + fileId: file.id, + comment, + }).then(() => { + file.comment = comment; + }); + }, + }, + "closed", + ); + } + } + firstTryPost = false; + return; + } + // "canceled" means "post anyway" const { canceled } = await os.confirm({ type: "warning", text: i18n.ts.noAltTextWarning, - okText: i18n.ts.goBack, + okText: i18n.ts.describeFile, cancelText: i18n.ts.toPost, isPlaintext: true, }); - if (!canceled) return; + if (!canceled) { + for (const file of files.value) { + if (file.comment == null || file.comment.length === 0) { + os.popup( + defineAsyncComponent( + () => import("@/components/MkMediaCaption.vue"), + ), + { + title: i18n.ts.describeFile, + input: { + placeholder: i18n.ts.inputNewDescription, + default: + file.comment !== null ? file.comment : "", + }, + image: file, + }, + { + done: (result) => { + if (!result || result.canceled) return; + const comment = + result.result.length === 0 + ? null + : result.result; + os.api("drive/files/update", { + fileId: file.id, + comment, + }).then(() => { + file.comment = comment; + }); + }, + }, + "closed", + ); + } + } + return; + } } const processedText = preprocess(text.value); From 2267e90d3bfb9ac51ed6dcdaee051c39c594bd19 Mon Sep 17 00:00:00 2001 From: naskya Date: Mon, 25 Mar 2024 03:12:59 +0900 Subject: [PATCH 03/52] refactor (client): await asynchronous processes, remove duplicate code --- packages/client/src/components/MkPostForm.vue | 99 +++++++------------ 1 file changed, 35 insertions(+), 64 deletions(-) diff --git a/packages/client/src/components/MkPostForm.vue b/packages/client/src/components/MkPostForm.vue index ad8c4c5ba3..6478838f4e 100644 --- a/packages/client/src/components/MkPostForm.vue +++ b/packages/client/src/components/MkPostForm.vue @@ -309,6 +309,8 @@ import XNoteSimple from "@/components/MkNoteSimple.vue"; import XNotePreview from "@/components/MkNotePreview.vue"; import XPostFormAttaches from "@/components/MkPostFormAttaches.vue"; import XPollEditor from "@/components/MkPollEditor.vue"; +import XCheatSheet from "@/components/MkCheatSheetDialog.vue"; +import XMediaCaption from "@/components/MkMediaCaption.vue"; import { host, url } from "@/config"; import { erase, unique } from "@/scripts/array"; import { extractMentions } from "@/scripts/extract-mentions"; @@ -325,7 +327,6 @@ import { getAccounts, openAccountMenu as openAccountMenu_ } from "@/account"; import { me } from "@/me"; import { uploadFile } from "@/scripts/upload"; import { deepClone } from "@/scripts/clone"; -import XCheatSheet from "@/components/MkCheatSheetDialog.vue"; import preprocess from "@/scripts/preprocess"; import { vibrate } from "@/scripts/vibrate"; import { langmap } from "@/scripts/langmap"; @@ -500,7 +501,7 @@ const withHashtags = computed( ); const hashtags = computed(defaultStore.makeGetterSetter("postFormHashtags")); -let firstTryPost = true; +let isFirstPostAttempt = true; watch(text, () => { checkMissingMention(); @@ -1012,6 +1013,34 @@ function deleteDraft() { localStorage.setItem("drafts", JSON.stringify(draftData)); } +async function openFileDescriptionWindow(file: DriveFile) { + await os.popup( + XMediaCaption, + { + title: i18n.ts.describeFile, + input: { + placeholder: i18n.ts.inputNewDescription, + default: file.comment !== null ? file.comment : "", + }, + image: file, + }, + { + done: (result) => { + if (!result || result.canceled) return; + const comment = + result.result.length === 0 ? null : result.result; + os.api("drive/files/update", { + fileId: file.id, + comment, + }).then(() => { + file.comment = comment; + }); + }, + }, + "closed", + ); +} + async function post() { // For text that is too short, the false positive rate may be too high, so we don't show alarm. if (defaultStore.state.autocorrectNoteLanguage && text.value.length > 10) { @@ -1050,42 +1079,13 @@ async function post() { defaultStore.state.showNoAltTextWarning && files.value.some((f) => f.comment == null || f.comment.length === 0) ) { - if (firstTryPost) { + if (isFirstPostAttempt) { for (const file of files.value) { if (file.comment == null || file.comment.length === 0) { - os.popup( - defineAsyncComponent( - () => import("@/components/MkMediaCaption.vue"), - ), - { - title: i18n.ts.describeFile, - input: { - placeholder: i18n.ts.inputNewDescription, - default: - file.comment !== null ? file.comment : "", - }, - image: file, - }, - { - done: (result) => { - if (!result || result.canceled) return; - const comment = - result.result.length === 0 - ? null - : result.result; - os.api("drive/files/update", { - fileId: file.id, - comment, - }).then(() => { - file.comment = comment; - }); - }, - }, - "closed", - ); + await openFileDescriptionWindow(file); } } - firstTryPost = false; + isFirstPostAttempt = false; return; } @@ -1101,36 +1101,7 @@ async function post() { if (!canceled) { for (const file of files.value) { if (file.comment == null || file.comment.length === 0) { - os.popup( - defineAsyncComponent( - () => import("@/components/MkMediaCaption.vue"), - ), - { - title: i18n.ts.describeFile, - input: { - placeholder: i18n.ts.inputNewDescription, - default: - file.comment !== null ? file.comment : "", - }, - image: file, - }, - { - done: (result) => { - if (!result || result.canceled) return; - const comment = - result.result.length === 0 - ? null - : result.result; - os.api("drive/files/update", { - fileId: file.id, - comment, - }).then(() => { - file.comment = comment; - }); - }, - }, - "closed", - ); + await openFileDescriptionWindow(file); } } return; From f346d2e2f6b4674c9af03e761bf991b1c98f7d17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=80=81=E5=91=A8=E9=83=A8=E8=90=BD?= Date: Mon, 25 Mar 2024 22:52:37 +0800 Subject: [PATCH 04/52] feat: add showAddFileDescriptionAtFirstPost and allow cancel adding alt-text midway --- locales/en-US.yml | 2 + locales/zh-CN.yml | 1 + packages/client/src/components/MkPostForm.vue | 86 ++++++++++++------- .../client/src/pages/settings/general.vue | 6 ++ .../pages/settings/preferences-backups.vue | 1 + packages/client/src/store.ts | 4 + 6 files changed, 71 insertions(+), 29 deletions(-) diff --git a/locales/en-US.yml b/locales/en-US.yml index d736a7d881..116b8eabd0 100644 --- a/locales/en-US.yml +++ b/locales/en-US.yml @@ -1226,6 +1226,8 @@ publishTimelinesDescription: "If enabled, the Local and Global timelines will be on {url} even when signed out." noAltTextWarning: "Some attached file(s) have no description. Did you forget to write?" showNoAltTextWarning: "Show a warning if you attempt to post files without a description" +showAddFileDescriptionAtFirstPost: "Show add description page automatically when + first try to post a post attachment without a description" _emojiModPerm: unauthorized: "None" diff --git a/locales/zh-CN.yml b/locales/zh-CN.yml index f67bf4a600..8f5d009acc 100644 --- a/locales/zh-CN.yml +++ b/locales/zh-CN.yml @@ -2058,5 +2058,6 @@ searchRangeDescription: "如果您要过滤时间段,请按以下格式输入 messagingUnencryptedInfo: "Firefish 上的聊天没有经过端到端加密,请不要在聊天中分享您的敏感信息。" noAltTextWarning: 有些附件没有描述。您是否忘记写描述了? showNoAltTextWarning: 当您尝试发布没有描述的帖子附件时显示警告 +showAddFileDescriptionAtFirstPost: 当您首次尝试发布没有描述的帖子附件时自动弹出添加描述页面 autocorrectNoteLanguage: 当帖子语言不符合自动检测的结果的时候显示警告 incorrectLanguageWarning: "看上去您帖子使用的语言是{detected},但您选择的语言是{current}。\n要改为以{detected}发帖吗?" diff --git a/packages/client/src/components/MkPostForm.vue b/packages/client/src/components/MkPostForm.vue index 6478838f4e..fee812317e 100644 --- a/packages/client/src/components/MkPostForm.vue +++ b/packages/client/src/components/MkPostForm.vue @@ -1013,32 +1013,43 @@ function deleteDraft() { localStorage.setItem("drafts", JSON.stringify(draftData)); } -async function openFileDescriptionWindow(file: DriveFile) { - await os.popup( - XMediaCaption, - { - title: i18n.ts.describeFile, - input: { - placeholder: i18n.ts.inputNewDescription, - default: file.comment !== null ? file.comment : "", +/** + * @returns whether the file is described + */ + function openFileDescriptionWindow(file: entities.DriveFile) { + return new Promise((resolve, reject) => { + os.popup( + XMediaCaption, + { + title: i18n.ts.describeFile, + input: { + placeholder: i18n.ts.inputNewDescription, + default: file.comment !== null ? file.comment : "", + }, + image: file, }, - image: file, - }, - { - done: (result) => { - if (!result || result.canceled) return; - const comment = - result.result.length === 0 ? null : result.result; - os.api("drive/files/update", { - fileId: file.id, - comment, - }).then(() => { - file.comment = comment; - }); + { + done: (result) => { + if (!result || result.canceled) { + resolve(false); + return; + } + const comment = + result.result.length === 0 ? null : result.result; + os.api("drive/files/update", { + fileId: file.id, + comment, + }).then(() => { + resolve(true); + file.comment = comment; + }).catch((err: unknown) => { + reject(err); + }); + }, }, - }, - "closed", - ); + "closed", + ); + }) } async function post() { @@ -1076,19 +1087,30 @@ async function post() { } if ( - defaultStore.state.showNoAltTextWarning && + defaultStore.state.showAddFileDescriptionAtFirstPost && files.value.some((f) => f.comment == null || f.comment.length === 0) ) { if (isFirstPostAttempt) { for (const file of files.value) { if (file.comment == null || file.comment.length === 0) { - await openFileDescriptionWindow(file); + const described = await openFileDescriptionWindow(file); + if (!described) { + return; + } } } isFirstPostAttempt = false; - return; + // Continue if all files have alt-text added. + if (files.value.some((f) => f.comment == null || f.comment.length === 0)) { + return; + } } + } + if ( + defaultStore.state.showNoAltTextWarning && + files.value.some((f) => f.comment == null || f.comment.length === 0) + ) { // "canceled" means "post anyway" const { canceled } = await os.confirm({ type: "warning", @@ -1101,10 +1123,16 @@ async function post() { if (!canceled) { for (const file of files.value) { if (file.comment == null || file.comment.length === 0) { - await openFileDescriptionWindow(file); + const described = await openFileDescriptionWindow(file); + if (!described) { + return; + } } } - return; + // Continue if all files have alt-text added. + if (files.value.some((f) => f.comment == null || f.comment.length === 0)) { + return; + } } } diff --git a/packages/client/src/pages/settings/general.vue b/packages/client/src/pages/settings/general.vue index 15e1172169..bc21efc132 100644 --- a/packages/client/src/pages/settings/general.vue +++ b/packages/client/src/pages/settings/general.vue @@ -124,6 +124,9 @@ {{ i18n.ts.showNoAltTextWarning }} + {{ + i18n.ts.showAddFileDescriptionAtFirstPost + }} {{ i18n.ts.autocorrectNoteLanguage }} @@ -533,6 +536,9 @@ const pullToRefreshThreshold = computed( const showNoAltTextWarning = computed( defaultStore.makeGetterSetter("showNoAltTextWarning"), ); +const showAddFileDescriptionAtFirstPost = computed( + defaultStore.makeGetterSetter("showAddFileDescriptionAtFirstPost"), +); const autocorrectNoteLanguage = computed( defaultStore.makeGetterSetter("autocorrectNoteLanguage"), ); diff --git a/packages/client/src/pages/settings/preferences-backups.vue b/packages/client/src/pages/settings/preferences-backups.vue index 202de0a082..885fec70c1 100644 --- a/packages/client/src/pages/settings/preferences-backups.vue +++ b/packages/client/src/pages/settings/preferences-backups.vue @@ -125,6 +125,7 @@ const defaultStoreSaveKeys: (keyof (typeof defaultStore)["state"])[] = [ "enablePullToRefresh", "pullToRefreshThreshold", "showNoAltTextWarning", + "showAddFileDescriptionAtFirstPost", "autocorrectNoteLanguage", ]; const coldDeviceStorageSaveKeys: (keyof typeof ColdDeviceStorage.default)[] = [ diff --git a/packages/client/src/store.ts b/packages/client/src/store.ts index cf17917477..11abb2e30f 100644 --- a/packages/client/src/store.ts +++ b/packages/client/src/store.ts @@ -432,6 +432,10 @@ export const defaultStore = markRaw( where: "account", default: true, }, + showAddFileDescriptionAtFirstPost: { + where: "account", + default: false, + }, autocorrectNoteLanguage: { where: "account", default: true, From 46bf02cdd591df1bed64677ccb15e358aa6b921d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=80=81=E5=91=A8=E9=83=A8=E8=90=BD?= Date: Sun, 31 Mar 2024 06:44:00 +0800 Subject: [PATCH 05/52] chore: format --- packages/client/src/components/MkPostForm.vue | 31 +++++++++++-------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/packages/client/src/components/MkPostForm.vue b/packages/client/src/components/MkPostForm.vue index fee812317e..ffeb1a1cc5 100644 --- a/packages/client/src/components/MkPostForm.vue +++ b/packages/client/src/components/MkPostForm.vue @@ -1016,7 +1016,7 @@ function deleteDraft() { /** * @returns whether the file is described */ - function openFileDescriptionWindow(file: entities.DriveFile) { +function openFileDescriptionWindow(file: entities.DriveFile) { return new Promise((resolve, reject) => { os.popup( XMediaCaption, @@ -1034,22 +1034,23 @@ function deleteDraft() { resolve(false); return; } - const comment = - result.result.length === 0 ? null : result.result; - os.api("drive/files/update", { + const comment = result.result.length === 0 ? null : result.result; + os.api("drive/files/update", { fileId: file.id, comment, - }).then(() => { - resolve(true); - file.comment = comment; - }).catch((err: unknown) => { - reject(err); - }); + }) + .then(() => { + resolve(true); + file.comment = comment; + }) + .catch((err: unknown) => { + reject(err); + }); }, }, "closed", ); - }) + }); } async function post() { @@ -1101,7 +1102,9 @@ async function post() { } isFirstPostAttempt = false; // Continue if all files have alt-text added. - if (files.value.some((f) => f.comment == null || f.comment.length === 0)) { + if ( + files.value.some((f) => f.comment == null || f.comment.length === 0) + ) { return; } } @@ -1130,7 +1133,9 @@ async function post() { } } // Continue if all files have alt-text added. - if (files.value.some((f) => f.comment == null || f.comment.length === 0)) { + if ( + files.value.some((f) => f.comment == null || f.comment.length === 0) + ) { return; } } From f44a2937d4a7ab3c8b15f00b74623a158909e35b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=80=81=E5=91=A8=E9=83=A8=E8=90=BD?= Date: Sat, 13 Apr 2024 07:41:11 +0800 Subject: [PATCH 06/52] fix: download-url should use proxy bypass hosts --- packages/backend/src/misc/download-url.ts | 7 ++----- packages/backend/src/misc/fetch.ts | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/packages/backend/src/misc/download-url.ts b/packages/backend/src/misc/download-url.ts index ab04e8aa9c..663d354ead 100644 --- a/packages/backend/src/misc/download-url.ts +++ b/packages/backend/src/misc/download-url.ts @@ -2,7 +2,7 @@ import * as fs from "node:fs"; import * as stream from "node:stream"; import * as util from "node:util"; import got, * as Got from "got"; -import { httpAgent, httpsAgent, StatusError } from "./fetch.js"; +import { getAgentByHostname, StatusError } from "./fetch.js"; import config from "@/config/index.js"; import chalk from "chalk"; import Logger from "@/services/logger.js"; @@ -40,10 +40,7 @@ export async function downloadUrl(url: string, path: string): Promise { send: timeout, request: operationTimeout, // whole operation timeout }, - agent: { - http: httpAgent, - https: httpsAgent, - }, + agent: getAgentByHostname(new URL(url).hostname), http2: false, // default retry: { limit: 0, diff --git a/packages/backend/src/misc/fetch.ts b/packages/backend/src/misc/fetch.ts index 4b8fc048e2..2cfd6b95f7 100644 --- a/packages/backend/src/misc/fetch.ts +++ b/packages/backend/src/misc/fetch.ts @@ -171,6 +171,25 @@ export function getAgentByUrl(url: URL, bypassProxy = false) { } } +/** + * Get agent by Hostname + * @param hostname Hostname + * @param bypassProxy Allways bypass proxy + */ +export function getAgentByHostname(hostname: string, bypassProxy = false) { + if (bypassProxy || (config.proxyBypassHosts || []).includes(hostname)) { + return { + http: _http, + https: _https, + }; + } else { + return { + http: httpAgent, + https: httpsAgent, + }; + } +} + export class StatusError extends Error { public statusCode: number; public statusMessage?: string; From f0a50bc2889416c8fb741147523b077719621130 Mon Sep 17 00:00:00 2001 From: Lhcfl Date: Sun, 14 Apr 2024 13:59:27 +0800 Subject: [PATCH 07/52] feat: show MkRemoteCaution in note history page --- packages/client/src/pages/note-history.vue | 74 ++++++++++++---------- 1 file changed, 39 insertions(+), 35 deletions(-) diff --git a/packages/client/src/pages/note-history.vue b/packages/client/src/pages/note-history.vue index f6fbf517a3..33cae5860a 100644 --- a/packages/client/src/pages/note-history.vue +++ b/packages/client/src/pages/note-history.vue @@ -4,30 +4,35 @@ > - - -
- - - -
-
+ +
+ + +
+ + + +
+
+
@@ -42,6 +47,7 @@ import XNote from "@/components/MkNote.vue"; import { i18n } from "@/i18n"; import { definePageMetadata } from "@/scripts/page-metadata"; import icon from "@/scripts/icon"; +import MkRemoteCaution from "@/components/MkRemoteCaution.vue"; const pagingComponent = ref>(); @@ -65,8 +71,7 @@ definePageMetadata( })), ); -const note = ref({} as entities.Note); -const loaded = ref(false); +const note = ref(null); onMounted(() => { api("notes/show", { @@ -79,20 +84,19 @@ onMounted(() => { res.replyId = null; note.value = res; - loaded.value = true; }); }); function convertNoteEditsToNotes(noteEdits: entities.NoteEdit[]) { const now: entities.NoteEdit = { id: "EditionNow", - noteId: note.value.id, - updatedAt: note.value.createdAt, - text: note.value.text, - cw: note.value.cw, - files: note.value.files, - fileIds: note.value.fileIds, - emojis: note.value.emojis, + noteId: note.value!.id, + updatedAt: note.value!.createdAt, + text: note.value!.text, + cw: note.value!.cw, + files: note.value!.files, + fileIds: note.value!.fileIds, + emojis: note.value!.emojis, }; return [now] @@ -108,7 +112,7 @@ function convertNoteEditsToNotes(noteEdits: entities.NoteEdit[]) { _shouldInsertAd_: false, files: noteEdit.files, fileIds: noteEdit.fileIds, - emojis: note.value.emojis.concat(noteEdit.emojis), + emojis: note.value!.emojis.concat(noteEdit.emojis), }); }); } From 54d9916fecaab64a8b61ea59fe52e6a51ebcc97e Mon Sep 17 00:00:00 2001 From: Lhcfl Date: Sun, 14 Apr 2024 16:34:33 +0800 Subject: [PATCH 08/52] fix: rss feed no HTML --- packages/backend/src/server/web/feed.ts | 47 ++++++++++++++++++------- 1 file changed, 34 insertions(+), 13 deletions(-) diff --git a/packages/backend/src/server/web/feed.ts b/packages/backend/src/server/web/feed.ts index e6b09b4f4f..3b1b9d6fa5 100644 --- a/packages/backend/src/server/web/feed.ts +++ b/packages/backend/src/server/web/feed.ts @@ -2,7 +2,19 @@ import { Feed } from "feed"; import { In, IsNull } from "typeorm"; import config from "@/config/index.js"; import type { User } from "@/models/entities/user.js"; +import type { Note } from "@/models/entities/note.js"; import { Notes, DriveFiles, UserProfiles, Users } from "@/models/index.js"; +import getNoteHtml from "@/remote/activitypub/misc/get-note-html.js"; + +/** + * If there is this part in the note, it will cause CDATA to be terminated early. + * So I inserted two zero-width spaces in the middle, which doesn't make a visual difference + * Although this is not a good solution, there seems no other way. + * Anyway, it is not common to encounter such extreme situations. + */ +function escapeCDATA(str: string) { + return str.replaceAll("]]>", "]​]​>"); +} export default async function ( user: User, @@ -15,7 +27,7 @@ export default async function ( const author = { link: `${config.url}/@${user.username}`, email: `${user.username}@${config.host}`, - name: user.name || user.username, + name: escapeCDATA(user.name || user.username), }; const profile = await UserProfiles.findOneByOrFail({ userId: user.id }); @@ -44,11 +56,13 @@ export default async function ( title: `${author.name} (@${user.username}@${config.host})`, updated: notes[0].createdAt, generator: "Firefish", - description: `${user.notesCount} Notes, ${ - profile.ffVisibility === "public" ? user.followingCount : "?" - } Following, ${ - profile.ffVisibility === "public" ? user.followersCount : "?" - } Followers${profile.description ? ` · ${profile.description}` : ""}`, + description: escapeCDATA( + `${user.notesCount} Notes, ${ + profile.ffVisibility === "public" ? user.followingCount : "?" + } Following, ${ + profile.ffVisibility === "public" ? user.followersCount : "?" + } Followers${profile.description ? ` · ${profile.description}` : ""}`, + ), link: author.link, image: await Users.getAvatarUrl(user), feedLinks: { @@ -88,19 +102,23 @@ export default async function ( } feed.addItem({ - title: title - .replace(/[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]/g, "") - .substring(0, 100), + title: escapeCDATA( + title + .replace(/[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]/g, "") + .substring(0, 100), + ), link: `${config.url}/notes/${note.id}`, date: note.createdAt, description: note.cw - ? note.cw.replace(/[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]/g, "") + ? escapeCDATA(note.cw.replace(/[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]/g, "")) : undefined, - content: contentStr.replace(/[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]/g, ""), + content: escapeCDATA( + contentStr.replace(/[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]/g, ""), + ), }); } - async function noteToString(note, isTheNote = false) { + async function noteToString(note: Note, isTheNote = false) { const author = isTheNote ? null : await Users.findOneBy({ id: note.userId }); @@ -135,7 +153,10 @@ export default async function ( }">${file.name}`; } } - outstr += `${note.cw ? note.cw + "
" : ""}${note.text || ""}${fileEle}`; + + outstr += `${note.cw ? note.cw + "
" : ""}${ + getNoteHtml(note) || "" + }${fileEle}`; if (isTheNote) { outstr += ` Date: Sun, 14 Apr 2024 16:44:12 +0800 Subject: [PATCH 09/52] fix: use better `]]>` replacer --- packages/backend/src/server/web/feed.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/packages/backend/src/server/web/feed.ts b/packages/backend/src/server/web/feed.ts index 3b1b9d6fa5..f3b3c97c32 100644 --- a/packages/backend/src/server/web/feed.ts +++ b/packages/backend/src/server/web/feed.ts @@ -8,12 +8,9 @@ import getNoteHtml from "@/remote/activitypub/misc/get-note-html.js"; /** * If there is this part in the note, it will cause CDATA to be terminated early. - * So I inserted two zero-width spaces in the middle, which doesn't make a visual difference - * Although this is not a good solution, there seems no other way. - * Anyway, it is not common to encounter such extreme situations. */ function escapeCDATA(str: string) { - return str.replaceAll("]]>", "]​]​>"); + return str.replaceAll("]]>", "]]]]>"); } export default async function ( From 3b89a8bfa692cfeb9b71e7489bf493c40ab6a701 Mon Sep 17 00:00:00 2001 From: naskya Date: Sat, 20 Apr 2024 02:07:08 +0900 Subject: [PATCH 10/52] refactor (backend): port config loader to backend-rs completely --- packages/backend-rs/index.d.ts | 70 +++++- packages/backend-rs/index.js | 6 +- packages/backend-rs/src/config/environment.rs | 2 +- packages/backend-rs/src/config/server.rs | 201 +++++++++++++++++- packages/backend-rs/src/database/mod.rs | 12 +- packages/backend-rs/src/misc/convert_host.rs | 8 +- packages/backend/src/boot/index.ts | 2 +- packages/backend/src/boot/master.ts | 30 +-- packages/backend/src/boot/worker.ts | 2 +- packages/backend/src/config.ts | 4 + packages/backend/src/config/index.ts | 5 - packages/backend/src/config/load.ts | 89 -------- packages/backend/src/config/types.ts | 20 -- packages/backend/src/const.ts | 2 +- packages/backend/src/db/postgre.ts | 2 +- packages/backend/src/db/redis.ts | 2 +- packages/backend/src/mfm/to-html.ts | 2 +- packages/backend/src/misc/captcha.ts | 2 +- packages/backend/src/misc/download-url.ts | 2 +- packages/backend/src/misc/fetch.ts | 2 +- packages/backend/src/misc/populate-emojis.ts | 2 +- .../src/models/repositories/drive-file.ts | 2 +- .../backend/src/models/repositories/user.ts | 2 +- .../src/models/schema/federation-instance.ts | 2 +- packages/backend/src/queue/index.ts | 6 +- packages/backend/src/queue/initialize.ts | 2 +- .../processors/db/export-custom-emojis.ts | 2 +- .../src/queue/processors/webhook-deliver.ts | 2 +- packages/backend/src/queue/queues.ts | 2 +- .../src/remote/activitypub/check-fetch.ts | 2 +- .../src/remote/activitypub/db-resolver.ts | 2 +- .../remote/activitypub/kernel/flag/index.ts | 2 +- .../src/remote/activitypub/renderer/accept.ts | 2 +- .../src/remote/activitypub/renderer/add.ts | 2 +- .../remote/activitypub/renderer/announce.ts | 2 +- .../src/remote/activitypub/renderer/block.ts | 2 +- .../src/remote/activitypub/renderer/create.ts | 2 +- .../src/remote/activitypub/renderer/delete.ts | 2 +- .../src/remote/activitypub/renderer/emoji.ts | 2 +- .../src/remote/activitypub/renderer/flag.ts | 2 +- .../activitypub/renderer/follow-relay.ts | 2 +- .../activitypub/renderer/follow-user.ts | 2 +- .../src/remote/activitypub/renderer/follow.ts | 2 +- .../remote/activitypub/renderer/hashtag.ts | 2 +- .../src/remote/activitypub/renderer/index.ts | 2 +- .../src/remote/activitypub/renderer/key.ts | 2 +- .../src/remote/activitypub/renderer/like.ts | 2 +- .../remote/activitypub/renderer/mention.ts | 2 +- .../src/remote/activitypub/renderer/note.ts | 2 +- .../src/remote/activitypub/renderer/person.ts | 2 +- .../remote/activitypub/renderer/question.ts | 2 +- .../src/remote/activitypub/renderer/read.ts | 2 +- .../src/remote/activitypub/renderer/reject.ts | 2 +- .../src/remote/activitypub/renderer/remove.ts | 2 +- .../src/remote/activitypub/renderer/undo.ts | 2 +- .../src/remote/activitypub/renderer/update.ts | 2 +- .../src/remote/activitypub/renderer/vote.ts | 2 +- .../backend/src/remote/activitypub/request.ts | 2 +- .../src/remote/activitypub/resolver.ts | 2 +- packages/backend/src/remote/resolve-user.ts | 2 +- packages/backend/src/server/activitypub.ts | 2 +- .../src/server/activitypub/featured.ts | 2 +- .../src/server/activitypub/followers.ts | 2 +- .../src/server/activitypub/following.ts | 2 +- .../backend/src/server/activitypub/outbox.ts | 2 +- packages/backend/src/server/api/2fa.ts | 2 +- .../backend/src/server/api/common/signin.ts | 2 +- .../backend/src/server/api/common/signup.ts | 2 +- .../api/endpoints/admin/accounts/hosted.ts | 2 +- .../src/server/api/endpoints/admin/meta.ts | 2 +- .../api/endpoints/auth/session/generate.ts | 2 +- .../src/server/api/endpoints/fetch-rss.ts | 2 +- .../server/api/endpoints/i/2fa/key-done.ts | 2 +- .../server/api/endpoints/i/2fa/register.ts | 2 +- .../src/server/api/endpoints/i/move.ts | 2 +- .../server/api/endpoints/i/update-email.ts | 2 +- .../backend/src/server/api/endpoints/meta.ts | 2 +- .../api/endpoints/request-reset-password.ts | 2 +- .../api/endpoints/username/available.ts | 2 +- packages/backend/src/server/api/index.ts | 2 +- .../src/server/api/mastodon/endpoints/meta.ts | 2 +- .../src/server/api/openapi/gen-spec.ts | 2 +- .../backend/src/server/api/private/signin.ts | 2 +- .../backend/src/server/api/private/signup.ts | 2 +- packages/backend/src/server/index.ts | 2 +- packages/backend/src/server/nodeinfo.ts | 2 +- packages/backend/src/server/web/feed.ts | 2 +- packages/backend/src/server/web/index.ts | 2 +- packages/backend/src/server/web/manifest.ts | 2 +- .../backend/src/server/web/url-preview.ts | 2 +- packages/backend/src/server/well-known.ts | 2 +- .../src/services/drive/internal-storage.ts | 2 +- packages/backend/src/services/fetch-rel-me.ts | 2 +- .../src/services/following/requests/create.ts | 2 +- packages/backend/src/services/i/pin.ts | 2 +- packages/backend/src/services/logger.ts | 2 +- .../backend/src/services/messages/delete.ts | 2 +- packages/backend/src/services/note/create.ts | 2 +- packages/backend/src/services/note/delete.ts | 2 +- .../backend/src/services/push-notification.ts | 2 +- packages/backend/src/services/send-email.ts | 2 +- packages/backend/src/services/stream.ts | 2 +- packages/backend/src/services/suspend-user.ts | 2 +- .../backend/src/services/unsuspend-user.ts | 2 +- 104 files changed, 375 insertions(+), 262 deletions(-) create mode 100644 packages/backend/src/config.ts delete mode 100644 packages/backend/src/config/index.ts delete mode 100644 packages/backend/src/config/load.ts delete mode 100644 packages/backend/src/config/types.ts diff --git a/packages/backend-rs/index.d.ts b/packages/backend-rs/index.d.ts index 1cf961bd30..d985eb368d 100644 --- a/packages/backend-rs/index.d.ts +++ b/packages/backend-rs/index.d.ts @@ -12,7 +12,7 @@ export interface EnvConfig { withLogTime: boolean slow: boolean } -export function readEnvironmentConfig(): EnvConfig +export function loadEnv(): EnvConfig export interface ServerConfig { url: string port: number @@ -29,7 +29,7 @@ export interface ServerConfig { /** `NapiValue` is not implemented for `u64` */ maxFileSize?: number accessLog?: string - clusterLimits?: WorkerConfig + clusterLimits?: _WorkerConfig cuid?: IdConfig outgoingAddress?: string deliverJobConcurrency?: number @@ -76,6 +76,10 @@ export interface TlsConfig { host: string rejectUnauthorized: boolean } +export interface WorkerConfig { + web: number + queue: number +} export interface WorkerConfig { web?: number queue?: number @@ -121,7 +125,67 @@ export interface ObjectStorageConfig { setPublicReadOnUpload?: boolean s3ForcePathStyle?: boolean } -export function readServerConfig(): ServerConfig +export interface Config { + url: string + port: number + bind?: string + disableHsts?: boolean + db: DbConfig + redis: RedisConfig + cacheServer?: RedisConfig + proxy?: string + proxySmtp?: string + proxyBypassHosts?: Array + allowedPrivateNetworks?: Array + maxFileSize?: number + accessLog?: string + clusterLimits: WorkerConfig + cuid?: IdConfig + outgoingAddress?: string + deliverJobConcurrency?: number + inboxJobConcurrency?: number + deliverJobPerSec?: number + inboxJobPerSec?: number + deliverJobMaxAttempts?: number + inboxJobMaxAttempts?: number + logLevel?: Array + syslog?: SysLogConfig + proxyRemoteFiles?: boolean + mediaProxy?: string + summalyProxyUrl?: string + reservedUsernames?: Array + maxUserSignups?: number + isManagedHosting?: boolean + maxNoteLength?: number + maxCaptionLength?: number + deepl?: DeepLConfig + libreTranslate?: LibreTranslateConfig + email?: EmailConfig + objectStorage?: ObjectStorageConfig + version: string + host: string + hostname: string + scheme: string + wsScheme: string + apiUrl: string + wsUrl: string + authUrl: string + driveUrl: string + userAgent: string + clientEntry: Manifest +} +export interface Manifest { + file: string + name: string + src: string + isEntry: boolean + isDynamicEntry: boolean + imports: Array + dynamicImports: Array + css: Array + assets: Array +} +export function loadConfig(): Config export interface Acct { username: string host: string | null diff --git a/packages/backend-rs/index.js b/packages/backend-rs/index.js index 1ea7bb5bed..5fd1e9d784 100644 --- a/packages/backend-rs/index.js +++ b/packages/backend-rs/index.js @@ -310,10 +310,10 @@ if (!nativeBinding) { throw new Error(`Failed to load native binding`) } -const { readEnvironmentConfig, readServerConfig, stringToAcct, acctToString, checkWordMute, getFullApAccount, isSelfHost, isSameOrigin, extractHost, toPuny, isUnicodeEmoji, sqlLikeEscape, safeForSql, formatMilliseconds, getNoteSummary, toMastodonId, fromMastodonId, fetchMeta, metaToPugArgs, nyaify, hashPassword, verifyPassword, isOldPasswordAlgorithm, decodeReaction, countReactions, toDbReaction, AntennaSrcEnum, MutedNoteReasonEnum, NoteVisibilityEnum, NotificationTypeEnum, PageVisibilityEnum, PollNotevisibilityEnum, RelayStatusEnum, UserEmojimodpermEnum, UserProfileFfvisibilityEnum, UserProfileMutingnotificationtypesEnum, initIdGenerator, getTimestamp, genId, secureRndstr } = nativeBinding +const { loadEnv, loadConfig, stringToAcct, acctToString, checkWordMute, getFullApAccount, isSelfHost, isSameOrigin, extractHost, toPuny, isUnicodeEmoji, sqlLikeEscape, safeForSql, formatMilliseconds, getNoteSummary, toMastodonId, fromMastodonId, fetchMeta, metaToPugArgs, nyaify, hashPassword, verifyPassword, isOldPasswordAlgorithm, decodeReaction, countReactions, toDbReaction, AntennaSrcEnum, MutedNoteReasonEnum, NoteVisibilityEnum, NotificationTypeEnum, PageVisibilityEnum, PollNotevisibilityEnum, RelayStatusEnum, UserEmojimodpermEnum, UserProfileFfvisibilityEnum, UserProfileMutingnotificationtypesEnum, initIdGenerator, getTimestamp, genId, secureRndstr } = nativeBinding -module.exports.readEnvironmentConfig = readEnvironmentConfig -module.exports.readServerConfig = readServerConfig +module.exports.loadEnv = loadEnv +module.exports.loadConfig = loadConfig module.exports.stringToAcct = stringToAcct module.exports.acctToString = acctToString module.exports.checkWordMute = checkWordMute diff --git a/packages/backend-rs/src/config/environment.rs b/packages/backend-rs/src/config/environment.rs index 7d66aec7ba..1825af326a 100644 --- a/packages/backend-rs/src/config/environment.rs +++ b/packages/backend-rs/src/config/environment.rs @@ -11,7 +11,7 @@ pub struct EnvConfig { } #[crate::export] -pub fn read_environment_config() -> EnvConfig { +pub fn load_env() -> EnvConfig { let node_env = std::env::var("NODE_ENV").unwrap_or_default().to_lowercase(); let is_testing = node_env == "test"; diff --git a/packages/backend-rs/src/config/server.rs b/packages/backend-rs/src/config/server.rs index 125bae90b9..4b9fbc7131 100644 --- a/packages/backend-rs/src/config/server.rs +++ b/packages/backend-rs/src/config/server.rs @@ -6,7 +6,7 @@ use std::fs; #[derive(Clone, Debug, PartialEq, Deserialize)] #[serde(rename_all = "camelCase")] #[crate::export(object, use_nullable = false)] -pub struct ServerConfig { +struct ServerConfig { pub url: String, pub port: u16, /// host to listen on @@ -25,7 +25,7 @@ pub struct ServerConfig { /// `NapiValue` is not implemented for `u64` pub max_file_size: Option, pub access_log: Option, - pub cluster_limits: Option, + pub cluster_limits: Option<_WorkerConfig>, pub cuid: Option, pub outgoing_address: Option, @@ -94,10 +94,16 @@ pub struct TlsConfig { pub reject_unauthorized: bool, } +#[crate::export(object, use_nullable = false)] +pub struct WorkerConfig { + pub web: u32, + pub queue: u32, +} + #[derive(Clone, Debug, PartialEq, Deserialize)] #[serde(rename_all = "camelCase")] #[crate::export(object, use_nullable = false)] -pub struct WorkerConfig { +pub struct _WorkerConfig { pub web: Option, pub queue: Option, } @@ -167,17 +173,198 @@ pub struct ObjectStorageConfig { pub s3_force_path_style: Option, } -#[crate::export] -pub fn read_server_config() -> ServerConfig { +#[crate::export(object, use_nullable = false)] +pub struct Config { + // ServerConfig (from default.yml) + pub url: String, + pub port: u16, + pub bind: Option, + pub disable_hsts: Option, + pub db: DbConfig, + pub redis: RedisConfig, + pub cache_server: Option, + pub proxy: Option, + pub proxy_smtp: Option, + pub proxy_bypass_hosts: Option>, + pub allowed_private_networks: Option>, + pub max_file_size: Option, + pub access_log: Option, + pub cluster_limits: WorkerConfig, + pub cuid: Option, + pub outgoing_address: Option, + pub deliver_job_concurrency: Option, + pub inbox_job_concurrency: Option, + pub deliver_job_per_sec: Option, + pub inbox_job_per_sec: Option, + pub deliver_job_max_attempts: Option, + pub inbox_job_max_attempts: Option, + pub log_level: Option>, + pub syslog: Option, + pub proxy_remote_files: Option, + pub media_proxy: Option, + pub summaly_proxy_url: Option, + pub reserved_usernames: Option>, + pub max_user_signups: Option, + pub is_managed_hosting: Option, + pub max_note_length: Option, + pub max_caption_length: Option, + pub deepl: Option, + pub libre_translate: Option, + pub email: Option, + pub object_storage: Option, + + // Mixin + pub version: String, + pub host: String, + pub hostname: String, + pub scheme: String, + pub ws_scheme: String, + pub api_url: String, + pub ws_url: String, + pub auth_url: String, + pub drive_url: String, + pub user_agent: String, + pub client_entry: Manifest, +} + +#[derive(Clone, Debug, PartialEq, Deserialize)] +#[serde(rename_all = "camelCase")] +struct Meta { + pub version: String, +} + +#[derive(Clone, Debug, PartialEq, Deserialize)] +struct ManifestJson { + #[serde(rename = "src/init.ts")] + pub init_ts: Manifest, +} + +#[derive(Clone, Debug, PartialEq, Deserialize)] +#[serde(rename_all = "camelCase")] +#[crate::export(object, use_nullable = false)] +pub struct Manifest { + pub file: String, + pub name: String, + pub src: String, + pub is_entry: bool, + pub is_dynamic_entry: bool, + pub imports: Vec, + pub dynamic_imports: Vec, + pub css: Vec, + pub assets: Vec, +} + +fn read_config_file() -> ServerConfig { let cwd = env::current_dir().unwrap(); let yml = fs::File::open(cwd.join("../../.config/default.yml")) .expect("Failed to open '.config/default.yml'"); - let mut data: ServerConfig = serde_yaml::from_reader(yml).expect("Failed to parse yaml"); + let mut data: ServerConfig = + serde_yaml::from_reader(yml).expect("Failed to parse .config/default.yml"); + data.url = url::Url::parse(&data.url) .expect("Config url is invalid") .origin() .ascii_serialization(); + + if data.bind.is_none() { + data.bind = std::env::var("BIND").ok() + } + data } -pub static SERVER_CONFIG: Lazy = Lazy::new(read_server_config); +fn read_meta() -> Meta { + let cwd = env::current_dir().unwrap(); + let meta_json = fs::File::open(cwd.join("../../built/meta.json")) + .expect("Failed to open 'built/meta.json'"); + serde_json::from_reader(meta_json).expect("Failed to parse built/meta.json") +} + +fn read_manifest() -> Manifest { + let cwd = env::current_dir().unwrap(); + let manifest_json = fs::File::open(cwd.join("../../built/_client_dist_/manifest.json")) + .expect("Failed to open 'built/_client_dist_/manifest.json'"); + let manifest: ManifestJson = serde_json::from_reader(manifest_json) + .expect("Failed to parse built/_client_dist_/manifest.json"); + + manifest.init_ts +} + +#[crate::export] +fn load_config() -> Config { + let server_config = read_config_file(); + let version = read_meta().version; + let manifest = read_manifest(); + let url = url::Url::parse(&server_config.url).expect("Config url is invalid"); + let host = url + .host_str() + .expect("Hostname is missing in the config url") + .to_owned(); + let hostname = url + .domain() + .expect("Domain is missing in the config url") + .to_owned(); + let scheme = url.scheme().to_owned(); + let ws_scheme = scheme.replace("http", "ws"); + + let cluster_limits = match server_config.cluster_limits { + Some(cl) => WorkerConfig { + web: cl.web.unwrap_or(1), + queue: cl.queue.unwrap_or(1), + }, + None => WorkerConfig { web: 1, queue: 1 }, + }; + + Config { + url: server_config.url, + port: server_config.port, + bind: server_config.bind, + disable_hsts: server_config.disable_hsts, + db: server_config.db, + redis: server_config.redis, + cache_server: server_config.cache_server, + proxy: server_config.proxy, + proxy_smtp: server_config.proxy_smtp, + proxy_bypass_hosts: server_config.proxy_bypass_hosts, + allowed_private_networks: server_config.allowed_private_networks, + max_file_size: server_config.max_file_size, + access_log: server_config.access_log, + cluster_limits, + cuid: server_config.cuid, + outgoing_address: server_config.outgoing_address, + deliver_job_concurrency: server_config.deliver_job_concurrency, + inbox_job_concurrency: server_config.inbox_job_concurrency, + deliver_job_per_sec: server_config.deliver_job_per_sec, + inbox_job_per_sec: server_config.inbox_job_per_sec, + deliver_job_max_attempts: server_config.deliver_job_max_attempts, + inbox_job_max_attempts: server_config.inbox_job_max_attempts, + log_level: server_config.log_level, + syslog: server_config.syslog, + proxy_remote_files: server_config.proxy_remote_files, + media_proxy: server_config.media_proxy, + summaly_proxy_url: server_config.summaly_proxy_url, + reserved_usernames: server_config.reserved_usernames, + max_user_signups: server_config.max_user_signups, + is_managed_hosting: server_config.is_managed_hosting, + max_note_length: server_config.max_note_length, + max_caption_length: server_config.max_caption_length, + deepl: server_config.deepl, + libre_translate: server_config.libre_translate, + email: server_config.email, + object_storage: server_config.object_storage, + + ws_url: format!("{}://{}", ws_scheme, host), + api_url: format!("{}://{}/api", scheme, host), + auth_url: format!("{}://{}/auth", scheme, host), + drive_url: format!("{}://{}/files", scheme, host), + user_agent: format!("Firefish/{} ({})", version, url), + version, + host, + hostname, + scheme, + ws_scheme, + client_entry: manifest, + } +} + +pub static CONFIG: Lazy = Lazy::new(load_config); diff --git a/packages/backend-rs/src/database/mod.rs b/packages/backend-rs/src/database/mod.rs index f598e35cc7..a60d20af9c 100644 --- a/packages/backend-rs/src/database/mod.rs +++ b/packages/backend-rs/src/database/mod.rs @@ -1,4 +1,4 @@ -use crate::config::server::SERVER_CONFIG; +use crate::config::server::CONFIG; use sea_orm::{Database, DbConn, DbErr}; static DB_CONN: once_cell::sync::OnceCell = once_cell::sync::OnceCell::new(); @@ -6,11 +6,11 @@ static DB_CONN: once_cell::sync::OnceCell = once_cell::sync::OnceCell::n async fn init_database() -> Result<&'static DbConn, DbErr> { let database_uri = format!( "postgres://{}:{}@{}:{}/{}", - SERVER_CONFIG.db.user, - urlencoding::encode(&SERVER_CONFIG.db.pass), - SERVER_CONFIG.db.host, - SERVER_CONFIG.db.port, - SERVER_CONFIG.db.db, + CONFIG.db.user, + urlencoding::encode(&CONFIG.db.pass), + CONFIG.db.host, + CONFIG.db.port, + CONFIG.db.db, ); let conn = Database::connect(database_uri).await?; Ok(DB_CONN.get_or_init(move || conn)) diff --git a/packages/backend-rs/src/misc/convert_host.rs b/packages/backend-rs/src/misc/convert_host.rs index 34a0792c62..cff52aeb07 100644 --- a/packages/backend-rs/src/misc/convert_host.rs +++ b/packages/backend-rs/src/misc/convert_host.rs @@ -1,4 +1,4 @@ -use crate::config::server::SERVER_CONFIG; +use crate::config::server::CONFIG; #[derive(thiserror::Error, Debug)] pub enum Error { @@ -14,21 +14,21 @@ pub enum Error { pub fn get_full_ap_account(username: &str, host: Option<&str>) -> Result { Ok(match host { Some(host) => format!("{}@{}", username, to_puny(host)?), - None => format!("{}@{}", username, extract_host(&SERVER_CONFIG.url)?), + None => format!("{}@{}", username, extract_host(&CONFIG.url)?), }) } #[crate::export] pub fn is_self_host(host: Option<&str>) -> Result { Ok(match host { - Some(host) => extract_host(&SERVER_CONFIG.url)? == to_puny(host)?, + Some(host) => extract_host(&CONFIG.url)? == to_puny(host)?, None => true, }) } #[crate::export] pub fn is_same_origin(uri: &str) -> Result { - Ok(url::Url::parse(uri)?.origin().ascii_serialization() == SERVER_CONFIG.url) + Ok(url::Url::parse(uri)?.origin().ascii_serialization() == CONFIG.url) } #[crate::export] diff --git a/packages/backend/src/boot/index.ts b/packages/backend/src/boot/index.ts index 9854d2dce4..3e542a6e36 100644 --- a/packages/backend/src/boot/index.ts +++ b/packages/backend/src/boot/index.ts @@ -3,7 +3,7 @@ import chalk from "chalk"; import Xev from "xev"; import Logger from "@/services/logger.js"; -import { envOption } from "@/config/index.js"; +import { envOption } from "@/config.js"; import { inspect } from "node:util"; // for typeorm diff --git a/packages/backend/src/boot/master.ts b/packages/backend/src/boot/master.ts index 3ba2d0cf50..44c4a8a2f1 100644 --- a/packages/backend/src/boot/master.ts +++ b/packages/backend/src/boot/master.ts @@ -8,9 +8,8 @@ import chalkTemplate from "chalk-template"; import semver from "semver"; import Logger from "@/services/logger.js"; -import loadConfig from "@/config/load.js"; -import type { Config } from "@/config/types.js"; -import { envOption } from "@/config/index.js"; +import type { Config } from "backend-rs"; +import { config, envOption } from "@/config.js"; import { showMachineInfo } from "@/misc/show-machine-info.js"; import { db, initDb } from "@/db/postgre.js"; import { inspect } from "node:util"; @@ -87,15 +86,12 @@ function greet() { * Init master process */ export async function masterMain() { - let config!: Config; - // initialize app try { greet(); showEnvironment(); await showMachineInfo(bootLogger); showNodejsVersion(); - config = loadConfigBoot(); await connectDb(); } catch (e) { bootLogger.error( @@ -154,28 +150,6 @@ function showNodejsVersion(): void { } } -function loadConfigBoot(): Config { - const configLogger = bootLogger.createSubLogger("config"); - let config; - - try { - config = loadConfig(); - } catch (exception) { - if (exception.code === "ENOENT") { - configLogger.error("Configuration file not found", null, true); - process.exit(1); - } else if (e instanceof Error) { - configLogger.error(e.message); - process.exit(1); - } - throw exception; - } - - configLogger.succ("Loaded"); - - return config; -} - async function connectDb(): Promise { const dbLogger = bootLogger.createSubLogger("db"); diff --git a/packages/backend/src/boot/worker.ts b/packages/backend/src/boot/worker.ts index 647ea40fbd..cae861230f 100644 --- a/packages/backend/src/boot/worker.ts +++ b/packages/backend/src/boot/worker.ts @@ -1,5 +1,5 @@ import cluster from "node:cluster"; -import config from "@/config/index.js"; +import { config } from "@/config.js"; import { initDb } from "@/db/postgre.js"; import { initIdGenerator } from "backend-rs"; import os from "node:os"; diff --git a/packages/backend/src/config.ts b/packages/backend/src/config.ts new file mode 100644 index 0000000000..c91294b611 --- /dev/null +++ b/packages/backend/src/config.ts @@ -0,0 +1,4 @@ +import { loadConfig, loadEnv } from "backend-rs"; + +export const config = loadConfig(); +export const envOption = loadEnv(); diff --git a/packages/backend/src/config/index.ts b/packages/backend/src/config/index.ts deleted file mode 100644 index fe87e5026a..0000000000 --- a/packages/backend/src/config/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -import load from "./load.js"; -import { readEnvironmentConfig } from "backend-rs"; - -export default load(); -export const envOption = readEnvironmentConfig(); diff --git a/packages/backend/src/config/load.ts b/packages/backend/src/config/load.ts deleted file mode 100644 index 682bf309d2..0000000000 --- a/packages/backend/src/config/load.ts +++ /dev/null @@ -1,89 +0,0 @@ -/** - * Config loader - */ - -import * as fs from "node:fs"; -import { fileURLToPath } from "node:url"; -import { dirname } from "node:path"; -import type { Mixin } from "./types.js"; -import { readServerConfig } from "backend-rs"; - -const _filename = fileURLToPath(import.meta.url); -const _dirname = dirname(_filename); - -/** - * Path of configuration directory - */ -const dir = `${_dirname}/../../../../.config`; - -/** - * Path of configuration file - */ -const path = - process.env.NODE_ENV === "test" ? `${dir}/test.yml` : `${dir}/default.yml`; - -export default function load() { - const meta = JSON.parse( - fs.readFileSync(`${_dirname}/../../../../built/meta.json`, "utf-8"), - ); - const clientManifest = JSON.parse( - fs.readFileSync( - `${_dirname}/../../../../built/_client_dist_/manifest.json`, - "utf-8", - ), - ); - const config = readServerConfig(); - - const mixin = {} as Mixin; - - const url = tryCreateUrl(config.url); - - config.url = url.origin; - - config.port = config.port || parseInt(process.env.PORT || "", 10); - config.bind = config.bind || process.env.BIND; - - mixin.version = meta.version; - mixin.host = url.host; - mixin.hostname = url.hostname; - mixin.scheme = url.protocol.replace(/:$/, ""); - mixin.wsScheme = mixin.scheme.replace("http", "ws"); - mixin.wsUrl = `${mixin.wsScheme}://${mixin.host}`; - mixin.apiUrl = `${mixin.scheme}://${mixin.host}/api`; - mixin.authUrl = `${mixin.scheme}://${mixin.host}/auth`; - mixin.driveUrl = `${mixin.scheme}://${mixin.host}/files`; - mixin.userAgent = `Firefish/${meta.version} (${config.url})`; - mixin.clientEntry = clientManifest["src/init.ts"]; - - if (config.proxyRemoteFiles == null) config.proxyRemoteFiles = true; - if (!config.redis.prefix) config.redis.prefix = mixin.hostname; - if (config.cacheServer && !config.cacheServer.prefix) - config.cacheServer.prefix = mixin.hostname; - - if (!config.clusterLimits) { - config.clusterLimits = { - web: 1, - queue: 1, - }; - } else { - config.clusterLimits = { - web: 1, - queue: 1, - ...config.clusterLimits, - }; - - if (config.clusterLimits.web! < 1 || config.clusterLimits.queue! < 1) { - throw new Error("Invalid cluster limits"); - } - } - - return Object.assign(config, mixin); -} - -function tryCreateUrl(url: string) { - try { - return new URL(url); - } catch (e) { - throw new Error(`url="${url}" is not a valid URL.`); - } -} diff --git a/packages/backend/src/config/types.ts b/packages/backend/src/config/types.ts deleted file mode 100644 index 6b593d3b2d..0000000000 --- a/packages/backend/src/config/types.ts +++ /dev/null @@ -1,20 +0,0 @@ -import type { ServerConfig } from "backend-rs"; - -/** - * Firefish が自動的に(ユーザーが設定した情報から推論して)設定する情報 - */ -export type Mixin = { - version: string; - host: string; - hostname: string; - scheme: string; - wsScheme: string; - apiUrl: string; - wsUrl: string; - authUrl: string; - driveUrl: string; - userAgent: string; - clientEntry: string; -}; - -export type Config = ServerConfig & Mixin; diff --git a/packages/backend/src/const.ts b/packages/backend/src/const.ts index 39ff99fda7..2c52e2b009 100644 --- a/packages/backend/src/const.ts +++ b/packages/backend/src/const.ts @@ -1,4 +1,4 @@ -import config from "@/config/index.js"; +import { config } from "@/config.js"; import { DB_MAX_IMAGE_COMMENT_LENGTH, DB_MAX_NOTE_TEXT_LENGTH, diff --git a/packages/backend/src/db/postgre.ts b/packages/backend/src/db/postgre.ts index 6baccaa271..e0ab9d6d37 100644 --- a/packages/backend/src/db/postgre.ts +++ b/packages/backend/src/db/postgre.ts @@ -5,7 +5,7 @@ pg.types.setTypeParser(20, Number); import type { Logger } from "typeorm"; import { DataSource } from "typeorm"; import * as highlight from "cli-highlight"; -import config from "@/config/index.js"; +import { config } from "@/config.js"; import { User } from "@/models/entities/user.js"; import { DriveFile } from "@/models/entities/drive-file.js"; diff --git a/packages/backend/src/db/redis.ts b/packages/backend/src/db/redis.ts index 215effd8ea..dc703e9d47 100644 --- a/packages/backend/src/db/redis.ts +++ b/packages/backend/src/db/redis.ts @@ -1,5 +1,5 @@ import Redis from "ioredis"; -import config from "@/config/index.js"; +import { config } from "@/config.js"; export function createConnection() { let source = config.redis; diff --git a/packages/backend/src/mfm/to-html.ts b/packages/backend/src/mfm/to-html.ts index 7b7c0967a1..64aa9d7164 100644 --- a/packages/backend/src/mfm/to-html.ts +++ b/packages/backend/src/mfm/to-html.ts @@ -1,7 +1,7 @@ import { type HTMLElement, Window } from "happy-dom"; import type * as mfm from "mfm-js"; import katex from "katex"; -import config from "@/config/index.js"; +import { config } from "@/config.js"; import { intersperse } from "@/prelude/array.js"; import type { IMentionedRemoteUsers } from "@/models/entities/note.js"; diff --git a/packages/backend/src/misc/captcha.ts b/packages/backend/src/misc/captcha.ts index c163d4d82d..d0969b0205 100644 --- a/packages/backend/src/misc/captcha.ts +++ b/packages/backend/src/misc/captcha.ts @@ -1,7 +1,7 @@ import fetch from "node-fetch"; import { URLSearchParams } from "node:url"; import { getAgentByUrl } from "@/misc/fetch.js"; -import config from "@/config/index.js"; +import { config } from "@/config.js"; import { inspect } from "node:util"; export async function verifyRecaptcha(secret: string, response: string) { diff --git a/packages/backend/src/misc/download-url.ts b/packages/backend/src/misc/download-url.ts index ab04e8aa9c..1bfd0a9f80 100644 --- a/packages/backend/src/misc/download-url.ts +++ b/packages/backend/src/misc/download-url.ts @@ -3,7 +3,7 @@ import * as stream from "node:stream"; import * as util from "node:util"; import got, * as Got from "got"; import { httpAgent, httpsAgent, StatusError } from "./fetch.js"; -import config from "@/config/index.js"; +import { config } from "@/config.js"; import chalk from "chalk"; import Logger from "@/services/logger.js"; import IPCIDR from "ip-cidr"; diff --git a/packages/backend/src/misc/fetch.ts b/packages/backend/src/misc/fetch.ts index 4b8fc048e2..b26fa83052 100644 --- a/packages/backend/src/misc/fetch.ts +++ b/packages/backend/src/misc/fetch.ts @@ -4,7 +4,7 @@ import type { URL } from "node:url"; import CacheableLookup from "cacheable-lookup"; import fetch, { type RequestRedirect } from "node-fetch"; import { HttpProxyAgent, HttpsProxyAgent } from "hpagent"; -import config from "@/config/index.js"; +import { config } from "@/config.js"; import { isValidUrl } from "./is-valid-url.js"; export async function getJson( diff --git a/packages/backend/src/misc/populate-emojis.ts b/packages/backend/src/misc/populate-emojis.ts index 4ca60b222f..f2656ea28a 100644 --- a/packages/backend/src/misc/populate-emojis.ts +++ b/packages/backend/src/misc/populate-emojis.ts @@ -4,7 +4,7 @@ import type { Emoji } from "@/models/entities/emoji.js"; import type { Note } from "@/models/entities/note.js"; import { Cache } from "./cache.js"; import { decodeReaction, isSelfHost, toPuny } from "backend-rs"; -import config from "@/config/index.js"; +import { config } from "@/config.js"; import { query } from "@/prelude/url.js"; import { redisClient } from "@/db/redis.js"; import type { NoteEdit } from "@/models/entities/note-edit.js"; diff --git a/packages/backend/src/models/repositories/drive-file.ts b/packages/backend/src/models/repositories/drive-file.ts index 2321f20d4c..757bd77ad6 100644 --- a/packages/backend/src/models/repositories/drive-file.ts +++ b/packages/backend/src/models/repositories/drive-file.ts @@ -4,7 +4,7 @@ import type { User } from "@/models/entities/user.js"; import { toPuny } from "backend-rs"; import { awaitAll } from "@/prelude/await-all.js"; import type { Packed } from "@/misc/schema.js"; -import config from "@/config/index.js"; +import { config } from "@/config.js"; import { query, appendQuery } from "@/prelude/url.js"; import { Users, DriveFolders } from "../index.js"; import { deepClone } from "@/misc/clone.js"; diff --git a/packages/backend/src/models/repositories/user.ts b/packages/backend/src/models/repositories/user.ts index 3bc943965b..040106b410 100644 --- a/packages/backend/src/models/repositories/user.ts +++ b/packages/backend/src/models/repositories/user.ts @@ -2,7 +2,7 @@ import { In, Not } from "typeorm"; import Ajv from "ajv"; import type { ILocalUser, IRemoteUser } from "@/models/entities/user.js"; import { User } from "@/models/entities/user.js"; -import config from "@/config/index.js"; +import { config } from "@/config.js"; import type { Packed } from "@/misc/schema.js"; import type { Promiseable } from "@/prelude/await-all.js"; import { awaitAll } from "@/prelude/await-all.js"; diff --git a/packages/backend/src/models/schema/federation-instance.ts b/packages/backend/src/models/schema/federation-instance.ts index 7a8af7f51d..338e079e28 100644 --- a/packages/backend/src/models/schema/federation-instance.ts +++ b/packages/backend/src/models/schema/federation-instance.ts @@ -1,4 +1,4 @@ -import config from "@/config/index.js"; +import { config } from "@/config.js"; export const packedFederationInstanceSchema = { type: "object", diff --git a/packages/backend/src/queue/index.ts b/packages/backend/src/queue/index.ts index e4e413be52..6272a5e668 100644 --- a/packages/backend/src/queue/index.ts +++ b/packages/backend/src/queue/index.ts @@ -1,11 +1,10 @@ import type httpSignature from "@peertube/http-signature"; import { v4 as uuid } from "uuid"; -import config from "@/config/index.js"; +import { config, envOption } from "@/config.js"; import type { DriveFile } from "@/models/entities/drive-file.js"; import type { IActivity } from "@/remote/activitypub/type.js"; import type { Webhook, webhookEventTypes } from "@/models/entities/webhook.js"; -import { envOption } from "@/config/index.js"; import processDeliver from "./processors/deliver.js"; import processInbox from "./processors/inbox.js"; @@ -24,10 +23,9 @@ import { objectStorageQueue, endedPollNotificationQueue, webhookDeliverQueue, - backgroundQueue, } from "./queues.js"; import type { ThinUser } from "./types.js"; -import { Note } from "@/models/entities/note.js"; +import type { Note } from "@/models/entities/note.js"; function renderError(e: Error): any { return { diff --git a/packages/backend/src/queue/initialize.ts b/packages/backend/src/queue/initialize.ts index 0f9c83132f..3291d47675 100644 --- a/packages/backend/src/queue/initialize.ts +++ b/packages/backend/src/queue/initialize.ts @@ -1,5 +1,5 @@ import Bull from "bull"; -import config from "@/config/index.js"; +import { config } from "@/config.js"; export function initialize(name: string, limitPerSec = -1) { return new Bull(name, { diff --git a/packages/backend/src/queue/processors/db/export-custom-emojis.ts b/packages/backend/src/queue/processors/db/export-custom-emojis.ts index a1ca3a91c5..157751c1aa 100644 --- a/packages/backend/src/queue/processors/db/export-custom-emojis.ts +++ b/packages/backend/src/queue/processors/db/export-custom-emojis.ts @@ -9,7 +9,7 @@ import { format as dateFormat } from "date-fns"; import { Users, Emojis } from "@/models/index.js"; import { createTemp, createTempDir } from "@/misc/create-temp.js"; import { downloadUrl } from "@/misc/download-url.js"; -import config from "@/config/index.js"; +import { config } from "@/config.js"; import { IsNull } from "typeorm"; import { inspect } from "node:util"; diff --git a/packages/backend/src/queue/processors/webhook-deliver.ts b/packages/backend/src/queue/processors/webhook-deliver.ts index 12c9a05498..63a16c373b 100644 --- a/packages/backend/src/queue/processors/webhook-deliver.ts +++ b/packages/backend/src/queue/processors/webhook-deliver.ts @@ -3,7 +3,7 @@ import Logger from "@/services/logger.js"; import type { WebhookDeliverJobData } from "../types.js"; import { getResponse, StatusError } from "@/misc/fetch.js"; import { Webhooks } from "@/models/index.js"; -import config from "@/config/index.js"; +import { config } from "@/config.js"; const logger = new Logger("webhook"); diff --git a/packages/backend/src/queue/queues.ts b/packages/backend/src/queue/queues.ts index 6b0eb2de42..06b9567e74 100644 --- a/packages/backend/src/queue/queues.ts +++ b/packages/backend/src/queue/queues.ts @@ -1,4 +1,4 @@ -import config from "@/config/index.js"; +import { config } from "@/config.js"; import { initialize as initializeQueue } from "./initialize.js"; import type { DeliverJobData, diff --git a/packages/backend/src/remote/activitypub/check-fetch.ts b/packages/backend/src/remote/activitypub/check-fetch.ts index 12ea63a931..04d989064f 100644 --- a/packages/backend/src/remote/activitypub/check-fetch.ts +++ b/packages/backend/src/remote/activitypub/check-fetch.ts @@ -1,6 +1,6 @@ import { URL } from "url"; import httpSignature, { IParsedSignature } from "@peertube/http-signature"; -import config from "@/config/index.js"; +import { config } from "@/config.js"; import { fetchMeta } from "backend-rs"; import { toPuny } from "backend-rs"; import DbResolver from "@/remote/activitypub/db-resolver.js"; diff --git a/packages/backend/src/remote/activitypub/db-resolver.ts b/packages/backend/src/remote/activitypub/db-resolver.ts index a753606a14..088a2db9da 100644 --- a/packages/backend/src/remote/activitypub/db-resolver.ts +++ b/packages/backend/src/remote/activitypub/db-resolver.ts @@ -1,5 +1,5 @@ import escapeRegexp from "escape-regexp"; -import config from "@/config/index.js"; +import { config } from "@/config.js"; import type { Note } from "@/models/entities/note.js"; import type { CacheableRemoteUser, diff --git a/packages/backend/src/remote/activitypub/kernel/flag/index.ts b/packages/backend/src/remote/activitypub/kernel/flag/index.ts index 0f83f6b449..c556605865 100644 --- a/packages/backend/src/remote/activitypub/kernel/flag/index.ts +++ b/packages/backend/src/remote/activitypub/kernel/flag/index.ts @@ -1,5 +1,5 @@ import type { CacheableRemoteUser } from "@/models/entities/user.js"; -import config from "@/config/index.js"; +import { config } from "@/config.js"; import type { IFlag } from "../../type.js"; import { getApIds } from "../../type.js"; import { AbuseUserReports, Users } from "@/models/index.js"; diff --git a/packages/backend/src/remote/activitypub/renderer/accept.ts b/packages/backend/src/remote/activitypub/renderer/accept.ts index fd145dcf97..2d27a1b29d 100644 --- a/packages/backend/src/remote/activitypub/renderer/accept.ts +++ b/packages/backend/src/remote/activitypub/renderer/accept.ts @@ -1,4 +1,4 @@ -import config from "@/config/index.js"; +import { config } from "@/config.js"; import type { User } from "@/models/entities/user.js"; export default (object: any, user: { id: User["id"]; host: null }) => ({ diff --git a/packages/backend/src/remote/activitypub/renderer/add.ts b/packages/backend/src/remote/activitypub/renderer/add.ts index d8203ac1ea..14c71694e1 100644 --- a/packages/backend/src/remote/activitypub/renderer/add.ts +++ b/packages/backend/src/remote/activitypub/renderer/add.ts @@ -1,4 +1,4 @@ -import config from "@/config/index.js"; +import { config } from "@/config.js"; import type { ILocalUser } from "@/models/entities/user.js"; export default (user: ILocalUser, target: any, object: any) => ({ diff --git a/packages/backend/src/remote/activitypub/renderer/announce.ts b/packages/backend/src/remote/activitypub/renderer/announce.ts index 1fd1842acf..0cc9bec6f4 100644 --- a/packages/backend/src/remote/activitypub/renderer/announce.ts +++ b/packages/backend/src/remote/activitypub/renderer/announce.ts @@ -1,4 +1,4 @@ -import config from "@/config/index.js"; +import { config } from "@/config.js"; import type { Note } from "@/models/entities/note.js"; export default (object: any, note: Note) => { diff --git a/packages/backend/src/remote/activitypub/renderer/block.ts b/packages/backend/src/remote/activitypub/renderer/block.ts index c2ea267f38..5169e0d550 100644 --- a/packages/backend/src/remote/activitypub/renderer/block.ts +++ b/packages/backend/src/remote/activitypub/renderer/block.ts @@ -1,4 +1,4 @@ -import config from "@/config/index.js"; +import { config } from "@/config.js"; import type { Blocking } from "@/models/entities/blocking.js"; /** diff --git a/packages/backend/src/remote/activitypub/renderer/create.ts b/packages/backend/src/remote/activitypub/renderer/create.ts index 857f5722cc..89b14b88b2 100644 --- a/packages/backend/src/remote/activitypub/renderer/create.ts +++ b/packages/backend/src/remote/activitypub/renderer/create.ts @@ -1,4 +1,4 @@ -import config from "@/config/index.js"; +import { config } from "@/config.js"; import type { Note } from "@/models/entities/note.js"; export default (object: any, note: Note) => { diff --git a/packages/backend/src/remote/activitypub/renderer/delete.ts b/packages/backend/src/remote/activitypub/renderer/delete.ts index 70bdc34922..0d2105941e 100644 --- a/packages/backend/src/remote/activitypub/renderer/delete.ts +++ b/packages/backend/src/remote/activitypub/renderer/delete.ts @@ -1,4 +1,4 @@ -import config from "@/config/index.js"; +import { config } from "@/config.js"; import type { User } from "@/models/entities/user.js"; export default (object: any, user: { id: User["id"]; host: null }) => ({ diff --git a/packages/backend/src/remote/activitypub/renderer/emoji.ts b/packages/backend/src/remote/activitypub/renderer/emoji.ts index 3d9b8cd55b..dab0e8cac7 100644 --- a/packages/backend/src/remote/activitypub/renderer/emoji.ts +++ b/packages/backend/src/remote/activitypub/renderer/emoji.ts @@ -1,4 +1,4 @@ -import config from "@/config/index.js"; +import { config } from "@/config.js"; import type { Emoji } from "@/models/entities/emoji.js"; export default (emoji: Emoji) => ({ diff --git a/packages/backend/src/remote/activitypub/renderer/flag.ts b/packages/backend/src/remote/activitypub/renderer/flag.ts index 44da33f5c2..1fa260be5e 100644 --- a/packages/backend/src/remote/activitypub/renderer/flag.ts +++ b/packages/backend/src/remote/activitypub/renderer/flag.ts @@ -1,4 +1,4 @@ -import config from "@/config/index.js"; +import { config } from "@/config.js"; import type { ILocalUser } from "@/models/entities/user.js"; // to anonymise reporters, the reporting actor must be a system user diff --git a/packages/backend/src/remote/activitypub/renderer/follow-relay.ts b/packages/backend/src/remote/activitypub/renderer/follow-relay.ts index ad7f05bf84..b62d9c4011 100644 --- a/packages/backend/src/remote/activitypub/renderer/follow-relay.ts +++ b/packages/backend/src/remote/activitypub/renderer/follow-relay.ts @@ -1,4 +1,4 @@ -import config from "@/config/index.js"; +import { config } from "@/config.js"; import type { Relay } from "@/models/entities/relay.js"; import type { ILocalUser } from "@/models/entities/user.js"; diff --git a/packages/backend/src/remote/activitypub/renderer/follow-user.ts b/packages/backend/src/remote/activitypub/renderer/follow-user.ts index 22ee429ff6..93228a6327 100644 --- a/packages/backend/src/remote/activitypub/renderer/follow-user.ts +++ b/packages/backend/src/remote/activitypub/renderer/follow-user.ts @@ -1,4 +1,4 @@ -import config from "@/config/index.js"; +import { config } from "@/config.js"; import { Users } from "@/models/index.js"; import type { User } from "@/models/entities/user.js"; diff --git a/packages/backend/src/remote/activitypub/renderer/follow.ts b/packages/backend/src/remote/activitypub/renderer/follow.ts index 3ff89c12aa..30ad799507 100644 --- a/packages/backend/src/remote/activitypub/renderer/follow.ts +++ b/packages/backend/src/remote/activitypub/renderer/follow.ts @@ -1,4 +1,4 @@ -import config from "@/config/index.js"; +import { config } from "@/config.js"; import type { User } from "@/models/entities/user.js"; import { Users } from "@/models/index.js"; diff --git a/packages/backend/src/remote/activitypub/renderer/hashtag.ts b/packages/backend/src/remote/activitypub/renderer/hashtag.ts index a00cd1ff5e..ab6651f55d 100644 --- a/packages/backend/src/remote/activitypub/renderer/hashtag.ts +++ b/packages/backend/src/remote/activitypub/renderer/hashtag.ts @@ -1,4 +1,4 @@ -import config from "@/config/index.js"; +import { config } from "@/config.js"; export default (tag: string) => ({ type: "Hashtag", diff --git a/packages/backend/src/remote/activitypub/renderer/index.ts b/packages/backend/src/remote/activitypub/renderer/index.ts index 2b6229b3e4..a085443d23 100644 --- a/packages/backend/src/remote/activitypub/renderer/index.ts +++ b/packages/backend/src/remote/activitypub/renderer/index.ts @@ -1,5 +1,5 @@ import { v4 as uuid } from "uuid"; -import config from "@/config/index.js"; +import { config } from "@/config.js"; import { getUserKeypair } from "@/misc/keypair-store.js"; import type { User } from "@/models/entities/user.js"; import { LdSignature } from "../misc/ld-signature.js"; diff --git a/packages/backend/src/remote/activitypub/renderer/key.ts b/packages/backend/src/remote/activitypub/renderer/key.ts index 084bb5361a..1e01640e59 100644 --- a/packages/backend/src/remote/activitypub/renderer/key.ts +++ b/packages/backend/src/remote/activitypub/renderer/key.ts @@ -1,4 +1,4 @@ -import config from "@/config/index.js"; +import { config } from "@/config.js"; import type { ILocalUser } from "@/models/entities/user.js"; import type { UserKeypair } from "@/models/entities/user-keypair.js"; import { createPublicKey } from "node:crypto"; diff --git a/packages/backend/src/remote/activitypub/renderer/like.ts b/packages/backend/src/remote/activitypub/renderer/like.ts index 6f810cd201..ea0df3e359 100644 --- a/packages/backend/src/remote/activitypub/renderer/like.ts +++ b/packages/backend/src/remote/activitypub/renderer/like.ts @@ -1,5 +1,5 @@ import { IsNull } from "typeorm"; -import config from "@/config/index.js"; +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"; diff --git a/packages/backend/src/remote/activitypub/renderer/mention.ts b/packages/backend/src/remote/activitypub/renderer/mention.ts index e7f0435c16..c935c7d325 100644 --- a/packages/backend/src/remote/activitypub/renderer/mention.ts +++ b/packages/backend/src/remote/activitypub/renderer/mention.ts @@ -1,4 +1,4 @@ -import config from "@/config/index.js"; +import { config } from "@/config.js"; import type { User, ILocalUser } from "@/models/entities/user.js"; import { Users } from "@/models/index.js"; diff --git a/packages/backend/src/remote/activitypub/renderer/note.ts b/packages/backend/src/remote/activitypub/renderer/note.ts index f1344c1b03..dc978f1e0e 100644 --- a/packages/backend/src/remote/activitypub/renderer/note.ts +++ b/packages/backend/src/remote/activitypub/renderer/note.ts @@ -1,5 +1,5 @@ import { In, IsNull } from "typeorm"; -import config from "@/config/index.js"; +import { config } from "@/config.js"; import type { Note, IMentionedRemoteUsers } from "@/models/entities/note.js"; import type { DriveFile } from "@/models/entities/drive-file.js"; import { DriveFiles, Notes, Users, Emojis, Polls } from "@/models/index.js"; diff --git a/packages/backend/src/remote/activitypub/renderer/person.ts b/packages/backend/src/remote/activitypub/renderer/person.ts index bba963d72e..c6371440b4 100644 --- a/packages/backend/src/remote/activitypub/renderer/person.ts +++ b/packages/backend/src/remote/activitypub/renderer/person.ts @@ -1,6 +1,6 @@ import { URL } from "node:url"; import * as mfm from "mfm-js"; -import config from "@/config/index.js"; +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"; diff --git a/packages/backend/src/remote/activitypub/renderer/question.ts b/packages/backend/src/remote/activitypub/renderer/question.ts index cb89aa7583..ac62734395 100644 --- a/packages/backend/src/remote/activitypub/renderer/question.ts +++ b/packages/backend/src/remote/activitypub/renderer/question.ts @@ -1,4 +1,4 @@ -import config from "@/config/index.js"; +import { config } from "@/config.js"; import type { User } from "@/models/entities/user.js"; import type { Note } from "@/models/entities/note.js"; import type { Poll } from "@/models/entities/poll.js"; diff --git a/packages/backend/src/remote/activitypub/renderer/read.ts b/packages/backend/src/remote/activitypub/renderer/read.ts index 212e7e8ddf..9ea15b10f7 100644 --- a/packages/backend/src/remote/activitypub/renderer/read.ts +++ b/packages/backend/src/remote/activitypub/renderer/read.ts @@ -1,4 +1,4 @@ -import config from "@/config/index.js"; +import { config } from "@/config.js"; import type { User } from "@/models/entities/user.js"; import type { MessagingMessage } from "@/models/entities/messaging-message.js"; diff --git a/packages/backend/src/remote/activitypub/renderer/reject.ts b/packages/backend/src/remote/activitypub/renderer/reject.ts index 7ac4452411..75c3b9d065 100644 --- a/packages/backend/src/remote/activitypub/renderer/reject.ts +++ b/packages/backend/src/remote/activitypub/renderer/reject.ts @@ -1,4 +1,4 @@ -import config from "@/config/index.js"; +import { config } from "@/config.js"; import type { User } from "@/models/entities/user.js"; export default (object: any, user: { id: User["id"] }) => ({ diff --git a/packages/backend/src/remote/activitypub/renderer/remove.ts b/packages/backend/src/remote/activitypub/renderer/remove.ts index e3b3fef856..270744dd30 100644 --- a/packages/backend/src/remote/activitypub/renderer/remove.ts +++ b/packages/backend/src/remote/activitypub/renderer/remove.ts @@ -1,4 +1,4 @@ -import config from "@/config/index.js"; +import { config } from "@/config.js"; import type { User } from "@/models/entities/user.js"; export default (user: { id: User["id"] }, target: any, object: any) => ({ diff --git a/packages/backend/src/remote/activitypub/renderer/undo.ts b/packages/backend/src/remote/activitypub/renderer/undo.ts index 4394c4bf2f..a0285ea9c7 100644 --- a/packages/backend/src/remote/activitypub/renderer/undo.ts +++ b/packages/backend/src/remote/activitypub/renderer/undo.ts @@ -1,4 +1,4 @@ -import config from "@/config/index.js"; +import { config } from "@/config.js"; import type { User } from "@/models/entities/user.js"; export default (object: any, user: { id: User["id"] }) => { diff --git a/packages/backend/src/remote/activitypub/renderer/update.ts b/packages/backend/src/remote/activitypub/renderer/update.ts index ecb0ed2192..b47f7c5cda 100644 --- a/packages/backend/src/remote/activitypub/renderer/update.ts +++ b/packages/backend/src/remote/activitypub/renderer/update.ts @@ -1,4 +1,4 @@ -import config from "@/config/index.js"; +import { config } from "@/config.js"; import type { User } from "@/models/entities/user.js"; export default (object: any, user: { id: User["id"] }) => { diff --git a/packages/backend/src/remote/activitypub/renderer/vote.ts b/packages/backend/src/remote/activitypub/renderer/vote.ts index 21234a112d..118e6761ab 100644 --- a/packages/backend/src/remote/activitypub/renderer/vote.ts +++ b/packages/backend/src/remote/activitypub/renderer/vote.ts @@ -1,4 +1,4 @@ -import config from "@/config/index.js"; +import { config } from "@/config.js"; import type { Note } from "@/models/entities/note.js"; import type { IRemoteUser, User } from "@/models/entities/user.js"; import type { PollVote } from "@/models/entities/poll-vote.js"; diff --git a/packages/backend/src/remote/activitypub/request.ts b/packages/backend/src/remote/activitypub/request.ts index f6d33b8549..8e3bc764d3 100644 --- a/packages/backend/src/remote/activitypub/request.ts +++ b/packages/backend/src/remote/activitypub/request.ts @@ -1,4 +1,4 @@ -import config from "@/config/index.js"; +import { config } from "@/config.js"; import { getUserKeypair } from "@/misc/keypair-store.js"; import type { User, ILocalUser } from "@/models/entities/user.js"; import { StatusError, getResponse } from "@/misc/fetch.js"; diff --git a/packages/backend/src/remote/activitypub/resolver.ts b/packages/backend/src/remote/activitypub/resolver.ts index 79b7962b72..65e6f1d635 100644 --- a/packages/backend/src/remote/activitypub/resolver.ts +++ b/packages/backend/src/remote/activitypub/resolver.ts @@ -1,4 +1,4 @@ -import config from "@/config/index.js"; +import { config } from "@/config.js"; import type { ILocalUser } from "@/models/entities/user.js"; import { getInstanceActor } from "@/services/instance-actor.js"; import { fetchMeta } from "backend-rs"; diff --git a/packages/backend/src/remote/resolve-user.ts b/packages/backend/src/remote/resolve-user.ts index 0883386371..69a99c767a 100644 --- a/packages/backend/src/remote/resolve-user.ts +++ b/packages/backend/src/remote/resolve-user.ts @@ -1,7 +1,7 @@ import { URL } from "node:url"; import chalk from "chalk"; import { IsNull } from "typeorm"; -import config from "@/config/index.js"; +import { config } from "@/config.js"; import type { User, IRemoteUser } from "@/models/entities/user.js"; import { Users } from "@/models/index.js"; import { toPuny } from "backend-rs"; diff --git a/packages/backend/src/server/activitypub.ts b/packages/backend/src/server/activitypub.ts index 00c8a6babe..2de7ab1827 100644 --- a/packages/backend/src/server/activitypub.ts +++ b/packages/backend/src/server/activitypub.ts @@ -31,7 +31,7 @@ import Following from "./activitypub/following.js"; import Followers from "./activitypub/followers.js"; import Outbox, { packActivity } from "./activitypub/outbox.js"; import { serverLogger } from "./index.js"; -import config from "@/config/index.js"; +import { config } from "@/config.js"; import Koa from "koa"; import * as crypto from "node:crypto"; import { inspect } from "node:util"; diff --git a/packages/backend/src/server/activitypub/featured.ts b/packages/backend/src/server/activitypub/featured.ts index e7ea6f238e..671c7ac67e 100644 --- a/packages/backend/src/server/activitypub/featured.ts +++ b/packages/backend/src/server/activitypub/featured.ts @@ -1,5 +1,5 @@ import { IsNull } from "typeorm"; -import config from "@/config/index.js"; +import { config } from "@/config.js"; import { renderActivity } from "@/remote/activitypub/renderer/index.js"; import renderOrderedCollection from "@/remote/activitypub/renderer/ordered-collection.js"; import renderNote from "@/remote/activitypub/renderer/note.js"; diff --git a/packages/backend/src/server/activitypub/followers.ts b/packages/backend/src/server/activitypub/followers.ts index 576a672d6d..603e93ebe8 100644 --- a/packages/backend/src/server/activitypub/followers.ts +++ b/packages/backend/src/server/activitypub/followers.ts @@ -1,5 +1,5 @@ import { IsNull, LessThan } from "typeorm"; -import config from "@/config/index.js"; +import { config } from "@/config.js"; import * as url from "@/prelude/url.js"; import { renderActivity } from "@/remote/activitypub/renderer/index.js"; import renderOrderedCollection from "@/remote/activitypub/renderer/ordered-collection.js"; diff --git a/packages/backend/src/server/activitypub/following.ts b/packages/backend/src/server/activitypub/following.ts index 76b4e79716..be5a4e9643 100644 --- a/packages/backend/src/server/activitypub/following.ts +++ b/packages/backend/src/server/activitypub/following.ts @@ -1,5 +1,5 @@ import { LessThan, IsNull } from "typeorm"; -import config from "@/config/index.js"; +import { config } from "@/config.js"; import * as url from "@/prelude/url.js"; import { renderActivity } from "@/remote/activitypub/renderer/index.js"; import renderOrderedCollection from "@/remote/activitypub/renderer/ordered-collection.js"; diff --git a/packages/backend/src/server/activitypub/outbox.ts b/packages/backend/src/server/activitypub/outbox.ts index 305102cf12..06319565e5 100644 --- a/packages/backend/src/server/activitypub/outbox.ts +++ b/packages/backend/src/server/activitypub/outbox.ts @@ -1,5 +1,5 @@ import { Brackets, IsNull } from "typeorm"; -import config from "@/config/index.js"; +import { config } from "@/config.js"; import { renderActivity } from "@/remote/activitypub/renderer/index.js"; import renderOrderedCollection from "@/remote/activitypub/renderer/ordered-collection.js"; import renderOrderedCollectionPage from "@/remote/activitypub/renderer/ordered-collection-page.js"; diff --git a/packages/backend/src/server/api/2fa.ts b/packages/backend/src/server/api/2fa.ts index 7318f0f433..5a6479939d 100644 --- a/packages/backend/src/server/api/2fa.ts +++ b/packages/backend/src/server/api/2fa.ts @@ -1,6 +1,6 @@ import * as crypto from "node:crypto"; import * as jsrsasign from "jsrsasign"; -import config from "@/config/index.js"; +import { config } from "@/config.js"; const ECC_PRELUDE = Buffer.from([0x04]); const NULL_BYTE = Buffer.from([0]); diff --git a/packages/backend/src/server/api/common/signin.ts b/packages/backend/src/server/api/common/signin.ts index e59a39ac41..e5ca09df95 100644 --- a/packages/backend/src/server/api/common/signin.ts +++ b/packages/backend/src/server/api/common/signin.ts @@ -1,6 +1,6 @@ import type Koa from "koa"; -import config from "@/config/index.js"; +import { config } from "@/config.js"; import type { ILocalUser } from "@/models/entities/user.js"; import { Signins } from "@/models/index.js"; import { genId } from "backend-rs"; diff --git a/packages/backend/src/server/api/common/signup.ts b/packages/backend/src/server/api/common/signup.ts index 58b88b7d02..40b59c8ed5 100644 --- a/packages/backend/src/server/api/common/signup.ts +++ b/packages/backend/src/server/api/common/signup.ts @@ -8,7 +8,7 @@ import { genId, hashPassword, toPuny } from "backend-rs"; import { UserKeypair } from "@/models/entities/user-keypair.js"; import { UsedUsername } from "@/models/entities/used-username.js"; import { db } from "@/db/postgre.js"; -import config from "@/config/index.js"; +import { config } from "@/config.js"; export async function signup(opts: { username: User["username"]; diff --git a/packages/backend/src/server/api/endpoints/admin/accounts/hosted.ts b/packages/backend/src/server/api/endpoints/admin/accounts/hosted.ts index fd4ad9401a..01d08f7a3d 100644 --- a/packages/backend/src/server/api/endpoints/admin/accounts/hosted.ts +++ b/packages/backend/src/server/api/endpoints/admin/accounts/hosted.ts @@ -1,4 +1,4 @@ -import config from "@/config/index.js"; +import { config } from "@/config.js"; import { Meta } from "@/models/entities/meta.js"; import { insertModerationLog } from "@/services/insert-moderation-log.js"; import { db } from "@/db/postgre.js"; diff --git a/packages/backend/src/server/api/endpoints/admin/meta.ts b/packages/backend/src/server/api/endpoints/admin/meta.ts index c7731c6c81..d0e639fcf1 100644 --- a/packages/backend/src/server/api/endpoints/admin/meta.ts +++ b/packages/backend/src/server/api/endpoints/admin/meta.ts @@ -1,4 +1,4 @@ -import config from "@/config/index.js"; +import { config } from "@/config.js"; import { fetchMeta } from "backend-rs"; import { MAX_NOTE_TEXT_LENGTH, MAX_CAPTION_TEXT_LENGTH } from "@/const.js"; import define from "@/server/api/define.js"; diff --git a/packages/backend/src/server/api/endpoints/auth/session/generate.ts b/packages/backend/src/server/api/endpoints/auth/session/generate.ts index 26a1fddfcb..f20219aa82 100644 --- a/packages/backend/src/server/api/endpoints/auth/session/generate.ts +++ b/packages/backend/src/server/api/endpoints/auth/session/generate.ts @@ -1,5 +1,5 @@ import { v4 as uuid } from "uuid"; -import config from "@/config/index.js"; +import { config } from "@/config.js"; import define from "@/server/api/define.js"; import { ApiError } from "@/server/api/error.js"; import { Apps, AuthSessions } from "@/models/index.js"; diff --git a/packages/backend/src/server/api/endpoints/fetch-rss.ts b/packages/backend/src/server/api/endpoints/fetch-rss.ts index bda3c455d1..489aaab0f5 100644 --- a/packages/backend/src/server/api/endpoints/fetch-rss.ts +++ b/packages/backend/src/server/api/endpoints/fetch-rss.ts @@ -1,6 +1,6 @@ import Parser from "rss-parser"; import { getResponse } from "@/misc/fetch.js"; -import config from "@/config/index.js"; +import { config } from "@/config.js"; import define from "@/server/api/define.js"; const rssParser = new Parser(); diff --git a/packages/backend/src/server/api/endpoints/i/2fa/key-done.ts b/packages/backend/src/server/api/endpoints/i/2fa/key-done.ts index 6c99217e7d..0951369dd8 100644 --- a/packages/backend/src/server/api/endpoints/i/2fa/key-done.ts +++ b/packages/backend/src/server/api/endpoints/i/2fa/key-done.ts @@ -6,7 +6,7 @@ import { AttestationChallenges, Users, } from "@/models/index.js"; -import config from "@/config/index.js"; +import { config } from "@/config.js"; import { procedures, hash } from "@/server/api/2fa.js"; import { publishMainStream } from "@/services/stream.js"; import { verifyPassword } from "backend-rs"; diff --git a/packages/backend/src/server/api/endpoints/i/2fa/register.ts b/packages/backend/src/server/api/endpoints/i/2fa/register.ts index c0e6137d5d..eb926a6098 100644 --- a/packages/backend/src/server/api/endpoints/i/2fa/register.ts +++ b/packages/backend/src/server/api/endpoints/i/2fa/register.ts @@ -1,6 +1,6 @@ import * as OTPAuth from "otpauth"; import * as QRCode from "qrcode"; -import config from "@/config/index.js"; +import { config } from "@/config.js"; import { UserProfiles } from "@/models/index.js"; import define from "@/server/api/define.js"; import { verifyPassword } from "backend-rs"; diff --git a/packages/backend/src/server/api/endpoints/i/move.ts b/packages/backend/src/server/api/endpoints/i/move.ts index 4784d3ee20..381bb1dea9 100644 --- a/packages/backend/src/server/api/endpoints/i/move.ts +++ b/packages/backend/src/server/api/endpoints/i/move.ts @@ -10,7 +10,7 @@ import deleteFollowing from "@/services/following/delete.js"; import create from "@/services/following/create.js"; import { getUser } from "@/server/api/common/getters.js"; import { Followings, Users } from "@/models/index.js"; -import config from "@/config/index.js"; +import { config } from "@/config.js"; import { publishMainStream } from "@/services/stream.js"; import { stringToAcct } from "backend-rs"; import { inspect } from "node:util"; diff --git a/packages/backend/src/server/api/endpoints/i/update-email.ts b/packages/backend/src/server/api/endpoints/i/update-email.ts index 234127f584..185d1c8dc9 100644 --- a/packages/backend/src/server/api/endpoints/i/update-email.ts +++ b/packages/backend/src/server/api/endpoints/i/update-email.ts @@ -1,7 +1,7 @@ import { publishMainStream } from "@/services/stream.js"; import define from "@/server/api/define.js"; import rndstr from "rndstr"; -import config from "@/config/index.js"; +import { config } from "@/config.js"; import { Users, UserProfiles } from "@/models/index.js"; import { sendEmail } from "@/services/send-email.js"; import { ApiError } from "@/server/api/error.js"; diff --git a/packages/backend/src/server/api/endpoints/meta.ts b/packages/backend/src/server/api/endpoints/meta.ts index 31677ee2ef..0167377944 100644 --- a/packages/backend/src/server/api/endpoints/meta.ts +++ b/packages/backend/src/server/api/endpoints/meta.ts @@ -1,6 +1,6 @@ import JSON5 from "json5"; import { IsNull, MoreThan } from "typeorm"; -import config from "@/config/index.js"; +import { config } from "@/config.js"; import { fetchMeta } from "backend-rs"; import { Ads, Emojis, Users } from "@/models/index.js"; import { MAX_NOTE_TEXT_LENGTH, MAX_CAPTION_TEXT_LENGTH } from "@/const.js"; diff --git a/packages/backend/src/server/api/endpoints/request-reset-password.ts b/packages/backend/src/server/api/endpoints/request-reset-password.ts index 9855b06513..00936c9d22 100644 --- a/packages/backend/src/server/api/endpoints/request-reset-password.ts +++ b/packages/backend/src/server/api/endpoints/request-reset-password.ts @@ -1,6 +1,6 @@ import rndstr from "rndstr"; import { IsNull } from "typeorm"; -import config from "@/config/index.js"; +import { config } from "@/config.js"; import { Users, UserProfiles, PasswordResetRequests } from "@/models/index.js"; import { sendEmail } from "@/services/send-email.js"; import { genId } from "backend-rs"; diff --git a/packages/backend/src/server/api/endpoints/username/available.ts b/packages/backend/src/server/api/endpoints/username/available.ts index cd634a798a..3818a3c28f 100644 --- a/packages/backend/src/server/api/endpoints/username/available.ts +++ b/packages/backend/src/server/api/endpoints/username/available.ts @@ -1,6 +1,6 @@ import { IsNull } from "typeorm"; import { Users, UsedUsernames } from "@/models/index.js"; -import config from "@/config/index.js"; +import { config } from "@/config.js"; import define from "@/server/api/define.js"; export const meta = { diff --git a/packages/backend/src/server/api/index.ts b/packages/backend/src/server/api/index.ts index 493661b2a2..7e5cd892bc 100644 --- a/packages/backend/src/server/api/index.ts +++ b/packages/backend/src/server/api/index.ts @@ -12,7 +12,7 @@ import { getClient, } from "./mastodon/ApiMastodonCompatibleService.js"; import { AccessTokens, Users } from "@/models/index.js"; -import config from "@/config/index.js"; +import { config } from "@/config.js"; import endpoints from "./endpoints.js"; import compatibility from "./compatibility.js"; import handler from "./api-handler.js"; diff --git a/packages/backend/src/server/api/mastodon/endpoints/meta.ts b/packages/backend/src/server/api/mastodon/endpoints/meta.ts index 5c304929a1..862310fb3e 100644 --- a/packages/backend/src/server/api/mastodon/endpoints/meta.ts +++ b/packages/backend/src/server/api/mastodon/endpoints/meta.ts @@ -1,5 +1,5 @@ import { Entity } from "megalodon"; -import config from "@/config/index.js"; +import { config } from "@/config.js"; import { fetchMeta } from "backend-rs"; import { Users, Notes } from "@/models/index.js"; import { IsNull } from "typeorm"; diff --git a/packages/backend/src/server/api/openapi/gen-spec.ts b/packages/backend/src/server/api/openapi/gen-spec.ts index 8b2f92b745..79dc48a8bb 100644 --- a/packages/backend/src/server/api/openapi/gen-spec.ts +++ b/packages/backend/src/server/api/openapi/gen-spec.ts @@ -1,5 +1,5 @@ import endpoints from "@/server/api/endpoints.js"; -import config from "@/config/index.js"; +import { config } from "@/config.js"; import { errors as basicErrors } from "./errors.js"; import { schemas, convertSchemaToOpenApiSchema } from "./schemas.js"; diff --git a/packages/backend/src/server/api/private/signin.ts b/packages/backend/src/server/api/private/signin.ts index a7eb623062..d8bbbf74ad 100644 --- a/packages/backend/src/server/api/private/signin.ts +++ b/packages/backend/src/server/api/private/signin.ts @@ -1,7 +1,7 @@ import type Koa from "koa"; import * as OTPAuth from "otpauth"; import signin from "@/server/api/common/signin.js"; -import config from "@/config/index.js"; +import { config } from "@/config.js"; import { Users, Signins, diff --git a/packages/backend/src/server/api/private/signup.ts b/packages/backend/src/server/api/private/signup.ts index 5af5d65b50..4dd4ffb231 100644 --- a/packages/backend/src/server/api/private/signup.ts +++ b/packages/backend/src/server/api/private/signup.ts @@ -3,7 +3,7 @@ import rndstr from "rndstr"; import { verifyHcaptcha, verifyRecaptcha } from "@/misc/captcha.js"; import { Users, RegistrationTickets, UserPendings } from "@/models/index.js"; import { signup } from "@/server/api/common/signup.js"; -import config from "@/config/index.js"; +import { config } from "@/config.js"; import { sendEmail } from "@/services/send-email.js"; import { fetchMeta, genId, hashPassword } from "backend-rs"; import { validateEmailForAccount } from "@/services/validate-email-for-account.js"; diff --git a/packages/backend/src/server/index.ts b/packages/backend/src/server/index.ts index 17358a4758..54d6e8bf5f 100644 --- a/packages/backend/src/server/index.ts +++ b/packages/backend/src/server/index.ts @@ -13,7 +13,7 @@ import koaLogger from "koa-logger"; import * as slow from "koa-slow"; import { IsNull } from "typeorm"; -import config, { envOption } from "@/config/index.js"; +import { config, envOption } from "@/config.js"; import Logger from "@/services/logger.js"; import { Users } from "@/models/index.js"; import { fetchMeta } from "backend-rs"; diff --git a/packages/backend/src/server/nodeinfo.ts b/packages/backend/src/server/nodeinfo.ts index 7359878b19..91e5fd8034 100644 --- a/packages/backend/src/server/nodeinfo.ts +++ b/packages/backend/src/server/nodeinfo.ts @@ -1,5 +1,5 @@ import Router from "@koa/router"; -import config from "@/config/index.js"; +import { config } from "@/config.js"; import { fetchMeta } from "backend-rs"; import { Users, Notes } from "@/models/index.js"; import { IsNull, MoreThan } from "typeorm"; diff --git a/packages/backend/src/server/web/feed.ts b/packages/backend/src/server/web/feed.ts index e6b09b4f4f..5208ee70e4 100644 --- a/packages/backend/src/server/web/feed.ts +++ b/packages/backend/src/server/web/feed.ts @@ -1,6 +1,6 @@ import { Feed } from "feed"; import { In, IsNull } from "typeorm"; -import config from "@/config/index.js"; +import { config } from "@/config.js"; import type { User } from "@/models/entities/user.js"; import { Notes, DriveFiles, UserProfiles, Users } from "@/models/index.js"; diff --git a/packages/backend/src/server/web/index.ts b/packages/backend/src/server/web/index.ts index 939fcfab14..dfc1cdc475 100644 --- a/packages/backend/src/server/web/index.ts +++ b/packages/backend/src/server/web/index.ts @@ -16,7 +16,7 @@ import { KoaAdapter } from "@bull-board/koa"; import { In, IsNull } from "typeorm"; import { fetchMeta, metaToPugArgs } from "backend-rs"; -import config from "@/config/index.js"; +import { config } from "@/config.js"; import { Users, Notes, diff --git a/packages/backend/src/server/web/manifest.ts b/packages/backend/src/server/web/manifest.ts index a4c615c7ab..77c8a57cf4 100644 --- a/packages/backend/src/server/web/manifest.ts +++ b/packages/backend/src/server/web/manifest.ts @@ -1,6 +1,6 @@ import type Koa from "koa"; import { fetchMeta } from "backend-rs"; -import config from "@/config/index.js"; +import { config } from "@/config.js"; import manifest from "./manifest.json" assert { type: "json" }; export const manifestHandler = async (ctx: Koa.Context) => { diff --git a/packages/backend/src/server/web/url-preview.ts b/packages/backend/src/server/web/url-preview.ts index f59f3f357a..8fd757ef14 100644 --- a/packages/backend/src/server/web/url-preview.ts +++ b/packages/backend/src/server/web/url-preview.ts @@ -2,7 +2,7 @@ import type Koa from "koa"; import summaly from "summaly"; import { fetchMeta } from "backend-rs"; import Logger from "@/services/logger.js"; -import config from "@/config/index.js"; +import { config } from "@/config.js"; import { query } from "@/prelude/url.js"; import { getJson } from "@/misc/fetch.js"; import { inspect } from "node:util"; diff --git a/packages/backend/src/server/well-known.ts b/packages/backend/src/server/well-known.ts index fc339eaad6..4a244db57f 100644 --- a/packages/backend/src/server/well-known.ts +++ b/packages/backend/src/server/well-known.ts @@ -1,6 +1,6 @@ import Router from "@koa/router"; -import config from "@/config/index.js"; +import { config } from "@/config.js"; import { type Acct, stringToAcct } from "backend-rs"; import { links } from "./nodeinfo.js"; import { escapeAttribute, escapeValue } from "@/prelude/xml.js"; diff --git a/packages/backend/src/services/drive/internal-storage.ts b/packages/backend/src/services/drive/internal-storage.ts index b2a663b3ea..6413f7920e 100644 --- a/packages/backend/src/services/drive/internal-storage.ts +++ b/packages/backend/src/services/drive/internal-storage.ts @@ -3,7 +3,7 @@ import * as fsPromises from "node:fs/promises"; import * as Path from "node:path"; import { fileURLToPath } from "node:url"; import { dirname } from "node:path"; -import config from "@/config/index.js"; +import { config } from "@/config.js"; const _filename = fileURLToPath(import.meta.url); const _dirname = dirname(_filename); diff --git a/packages/backend/src/services/fetch-rel-me.ts b/packages/backend/src/services/fetch-rel-me.ts index c9a37d1c88..e9736f8c33 100644 --- a/packages/backend/src/services/fetch-rel-me.ts +++ b/packages/backend/src/services/fetch-rel-me.ts @@ -1,5 +1,5 @@ import { Window } from "happy-dom"; -import config from "@/config/index.js"; +import { config } from "@/config.js"; async function getRelMeLinks(url: string): Promise { try { diff --git a/packages/backend/src/services/following/requests/create.ts b/packages/backend/src/services/following/requests/create.ts index d2f2c1ca41..146e20efd9 100644 --- a/packages/backend/src/services/following/requests/create.ts +++ b/packages/backend/src/services/following/requests/create.ts @@ -6,7 +6,7 @@ import type { User } from "@/models/entities/user.js"; import { Blockings, FollowRequests, Users } from "@/models/index.js"; import { genId } from "backend-rs"; import { createNotification } from "@/services/create-notification.js"; -import config from "@/config/index.js"; +import { config } from "@/config.js"; export default async function ( follower: { diff --git a/packages/backend/src/services/i/pin.ts b/packages/backend/src/services/i/pin.ts index 2d2675a535..b44ba5f9fa 100644 --- a/packages/backend/src/services/i/pin.ts +++ b/packages/backend/src/services/i/pin.ts @@ -1,4 +1,4 @@ -import config from "@/config/index.js"; +import { config } from "@/config.js"; import renderAdd from "@/remote/activitypub/renderer/add.js"; import renderRemove from "@/remote/activitypub/renderer/remove.js"; import { renderActivity } from "@/remote/activitypub/renderer/index.js"; diff --git a/packages/backend/src/services/logger.ts b/packages/backend/src/services/logger.ts index e53279e31c..bd2ca74793 100644 --- a/packages/backend/src/services/logger.ts +++ b/packages/backend/src/services/logger.ts @@ -2,7 +2,7 @@ import cluster from "node:cluster"; import chalk from "chalk"; import { default as convertColor } from "color-convert"; import { format as dateFormat } from "date-fns"; -import config, { envOption } from "@/config/index.js"; +import { config, envOption } from "@/config.js"; import * as SyslogPro from "syslog-pro"; diff --git a/packages/backend/src/services/messages/delete.ts b/packages/backend/src/services/messages/delete.ts index 77caba80ce..2d8f6b9baf 100644 --- a/packages/backend/src/services/messages/delete.ts +++ b/packages/backend/src/services/messages/delete.ts @@ -1,4 +1,4 @@ -import config from "@/config/index.js"; +import { config } from "@/config.js"; import { MessagingMessages, Users } from "@/models/index.js"; import type { MessagingMessage } from "@/models/entities/messaging-message.js"; import { diff --git a/packages/backend/src/services/note/create.ts b/packages/backend/src/services/note/create.ts index 0a4ddc517f..662064da57 100644 --- a/packages/backend/src/services/note/create.ts +++ b/packages/backend/src/services/note/create.ts @@ -10,7 +10,7 @@ import renderCreate from "@/remote/activitypub/renderer/create.js"; import renderAnnounce from "@/remote/activitypub/renderer/announce.js"; import { renderActivity } from "@/remote/activitypub/renderer/index.js"; import { resolveUser } from "@/remote/resolve-user.js"; -import config from "@/config/index.js"; +import { config } from "@/config.js"; import { updateHashtags } from "@/services/update-hashtag.js"; import { concat } from "@/prelude/array.js"; import { insertNoteUnread } from "@/services/note/unread.js"; diff --git a/packages/backend/src/services/note/delete.ts b/packages/backend/src/services/note/delete.ts index be3bf1e8b2..c709792fef 100644 --- a/packages/backend/src/services/note/delete.ts +++ b/packages/backend/src/services/note/delete.ts @@ -5,7 +5,7 @@ import renderAnnounce from "@/remote/activitypub/renderer/announce.js"; import renderUndo from "@/remote/activitypub/renderer/undo.js"; import { renderActivity } from "@/remote/activitypub/renderer/index.js"; import renderTombstone from "@/remote/activitypub/renderer/tombstone.js"; -import config from "@/config/index.js"; +import { config } from "@/config.js"; import type { User, ILocalUser, IRemoteUser } from "@/models/entities/user.js"; import type { Note, IMentionedRemoteUsers } from "@/models/entities/note.js"; import { Notes, Users, Instances } from "@/models/index.js"; diff --git a/packages/backend/src/services/push-notification.ts b/packages/backend/src/services/push-notification.ts index 3f1f2cfb1a..86dd2a32e2 100644 --- a/packages/backend/src/services/push-notification.ts +++ b/packages/backend/src/services/push-notification.ts @@ -1,5 +1,5 @@ import push from "web-push"; -import config from "@/config/index.js"; +import { config } from "@/config.js"; import { SwSubscriptions } from "@/models/index.js"; import { fetchMeta, getNoteSummary } from "backend-rs"; import type { Packed } from "@/misc/schema.js"; diff --git a/packages/backend/src/services/send-email.ts b/packages/backend/src/services/send-email.ts index 11a899d267..bcbecce356 100644 --- a/packages/backend/src/services/send-email.ts +++ b/packages/backend/src/services/send-email.ts @@ -1,7 +1,7 @@ import * as nodemailer from "nodemailer"; import { fetchMeta } from "backend-rs"; import Logger from "@/services/logger.js"; -import config from "@/config/index.js"; +import { config } from "@/config.js"; import { inspect } from "node:util"; export const logger = new Logger("email"); diff --git a/packages/backend/src/services/stream.ts b/packages/backend/src/services/stream.ts index bd09bc3f2c..0e2395e87e 100644 --- a/packages/backend/src/services/stream.ts +++ b/packages/backend/src/services/stream.ts @@ -3,7 +3,7 @@ import type { User } from "@/models/entities/user.js"; import type { Note } from "@/models/entities/note.js"; import type { UserList } from "@/models/entities/user-list.js"; import type { UserGroup } from "@/models/entities/user-group.js"; -import config from "@/config/index.js"; +import { config } from "@/config.js"; import type { Antenna } from "@/models/entities/antenna.js"; import type { Channel } from "@/models/entities/channel.js"; import type { diff --git a/packages/backend/src/services/suspend-user.ts b/packages/backend/src/services/suspend-user.ts index f72b8ffcb1..0babd31bc5 100644 --- a/packages/backend/src/services/suspend-user.ts +++ b/packages/backend/src/services/suspend-user.ts @@ -1,7 +1,7 @@ import renderDelete from "@/remote/activitypub/renderer/delete.js"; import { renderActivity } from "@/remote/activitypub/renderer/index.js"; import { deliver } from "@/queue/index.js"; -import config from "@/config/index.js"; +import { config } from "@/config.js"; import type { User } from "@/models/entities/user.js"; import { Users, Followings } from "@/models/index.js"; import { Not, IsNull } from "typeorm"; diff --git a/packages/backend/src/services/unsuspend-user.ts b/packages/backend/src/services/unsuspend-user.ts index 69447a4a26..72d7e30d66 100644 --- a/packages/backend/src/services/unsuspend-user.ts +++ b/packages/backend/src/services/unsuspend-user.ts @@ -2,7 +2,7 @@ import renderDelete from "@/remote/activitypub/renderer/delete.js"; import renderUndo from "@/remote/activitypub/renderer/undo.js"; import { renderActivity } from "@/remote/activitypub/renderer/index.js"; import { deliver } from "@/queue/index.js"; -import config from "@/config/index.js"; +import { config } from "@/config.js"; import type { User } from "@/models/entities/user.js"; import { Users, Followings } from "@/models/index.js"; import { Not, IsNull } from "typeorm"; From e60898b4b056726aff09d120b055d3205bbcb3b6 Mon Sep 17 00:00:00 2001 From: naskya Date: Sat, 20 Apr 2024 02:11:41 +0900 Subject: [PATCH 11/52] refactor (backend-rs): separate postgresql connector from database/mod.rs --- packages/backend-rs/src/database/mod.rs | 36 ++----------------- .../backend-rs/src/database/postgresql.rs | 34 ++++++++++++++++++ 2 files changed, 36 insertions(+), 34 deletions(-) create mode 100644 packages/backend-rs/src/database/postgresql.rs diff --git a/packages/backend-rs/src/database/mod.rs b/packages/backend-rs/src/database/mod.rs index a60d20af9c..26db81c644 100644 --- a/packages/backend-rs/src/database/mod.rs +++ b/packages/backend-rs/src/database/mod.rs @@ -1,34 +1,2 @@ -use crate::config::server::CONFIG; -use sea_orm::{Database, DbConn, DbErr}; - -static DB_CONN: once_cell::sync::OnceCell = once_cell::sync::OnceCell::new(); - -async fn init_database() -> Result<&'static DbConn, DbErr> { - let database_uri = format!( - "postgres://{}:{}@{}:{}/{}", - CONFIG.db.user, - urlencoding::encode(&CONFIG.db.pass), - CONFIG.db.host, - CONFIG.db.port, - CONFIG.db.db, - ); - let conn = Database::connect(database_uri).await?; - Ok(DB_CONN.get_or_init(move || conn)) -} - -pub async fn db_conn() -> Result<&'static DbConn, DbErr> { - match DB_CONN.get() { - Some(conn) => Ok(conn), - None => init_database().await, - } -} - -#[cfg(test)] -mod unit_test { - use super::db_conn; - - #[tokio::test] - async fn connect_test() { - assert!(db_conn().await.is_ok()); - } -} +pub use postgresql::db_conn; +pub mod postgresql; diff --git a/packages/backend-rs/src/database/postgresql.rs b/packages/backend-rs/src/database/postgresql.rs new file mode 100644 index 0000000000..a60d20af9c --- /dev/null +++ b/packages/backend-rs/src/database/postgresql.rs @@ -0,0 +1,34 @@ +use crate::config::server::CONFIG; +use sea_orm::{Database, DbConn, DbErr}; + +static DB_CONN: once_cell::sync::OnceCell = once_cell::sync::OnceCell::new(); + +async fn init_database() -> Result<&'static DbConn, DbErr> { + let database_uri = format!( + "postgres://{}:{}@{}:{}/{}", + CONFIG.db.user, + urlencoding::encode(&CONFIG.db.pass), + CONFIG.db.host, + CONFIG.db.port, + CONFIG.db.db, + ); + let conn = Database::connect(database_uri).await?; + Ok(DB_CONN.get_or_init(move || conn)) +} + +pub async fn db_conn() -> Result<&'static DbConn, DbErr> { + match DB_CONN.get() { + Some(conn) => Ok(conn), + None => init_database().await, + } +} + +#[cfg(test)] +mod unit_test { + use super::db_conn; + + #[tokio::test] + async fn connect_test() { + assert!(db_conn().await.is_ok()); + } +} From e82a07c03d9c1f35ae96a51d4e3a3a2e0e16ca43 Mon Sep 17 00:00:00 2001 From: naskya Date: Sat, 20 Apr 2024 02:17:03 +0900 Subject: [PATCH 12/52] dev (backend-rs): make backend-rs accessible to Redis --- Cargo.lock | 32 +++++++++++++++ Cargo.toml | 1 + packages/backend-rs/Cargo.toml | 1 + packages/backend-rs/index.d.ts | 4 +- packages/backend-rs/src/config/server.rs | 4 +- packages/backend-rs/src/database/mod.rs | 4 ++ packages/backend-rs/src/database/redis.rs | 47 +++++++++++++++++++++++ 7 files changed, 89 insertions(+), 4 deletions(-) create mode 100644 packages/backend-rs/src/database/redis.rs diff --git a/Cargo.lock b/Cargo.lock index c6ba96e683..52ef14933f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -220,6 +220,7 @@ dependencies = [ "parse-display", "pretty_assertions", "rand", + "redis", "regex", "schemars", "sea-orm", @@ -524,6 +525,16 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" +[[package]] +name = "combine" +version = "4.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" +dependencies = [ + "bytes", + "memchr", +] + [[package]] name = "const-oid" version = "0.9.6" @@ -1858,6 +1869,21 @@ dependencies = [ "getrandom", ] +[[package]] +name = "redis" +version = "0.25.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6472825949c09872e8f2c50bde59fcefc17748b6be5c90fd67cd8b4daca73bfd" +dependencies = [ + "combine", + "itoa", + "percent-encoding", + "ryu", + "sha1_smol", + "socket2", + "url", +] + [[package]] name = "redox_syscall" version = "0.4.1" @@ -2295,6 +2321,12 @@ dependencies = [ "digest", ] +[[package]] +name = "sha1_smol" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae1a47186c03a32177042e55dbc5fd5aee900b8e0069a8d70fba96a9375cd012" + [[package]] name = "sha2" version = "0.10.8" diff --git a/Cargo.toml b/Cargo.toml index 7ca43c960b..b82635d8b4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,6 +26,7 @@ pretty_assertions = "1.4.0" proc-macro2 = "1.0.79" quote = "1.0.36" rand = "0.8.5" +redis = "0.25.3" regex = "1.10.4" schemars = "0.8.16" sea-orm = "0.12.15" diff --git a/packages/backend-rs/Cargo.toml b/packages/backend-rs/Cargo.toml index af9e10cdc1..d077028e13 100644 --- a/packages/backend-rs/Cargo.toml +++ b/packages/backend-rs/Cargo.toml @@ -30,6 +30,7 @@ jsonschema = { workspace = true } once_cell = { workspace = true } parse-display = { workspace = true } rand = { workspace = true } +redis = { workspace = true } regex = { workspace = true } schemars = { workspace = true, features = ["chrono"] } sea-orm = { workspace = true, features = ["sqlx-postgres", "runtime-tokio-rustls"] } diff --git a/packages/backend-rs/index.d.ts b/packages/backend-rs/index.d.ts index d985eb368d..433e80999c 100644 --- a/packages/backend-rs/index.d.ts +++ b/packages/backend-rs/index.d.ts @@ -29,7 +29,7 @@ export interface ServerConfig { /** `NapiValue` is not implemented for `u64` */ maxFileSize?: number accessLog?: string - clusterLimits?: _WorkerConfig + clusterLimits?: WorkerConfigInternal cuid?: IdConfig outgoingAddress?: string deliverJobConcurrency?: number @@ -80,7 +80,7 @@ export interface WorkerConfig { web: number queue: number } -export interface WorkerConfig { +export interface WorkerConfigInternal { web?: number queue?: number } diff --git a/packages/backend-rs/src/config/server.rs b/packages/backend-rs/src/config/server.rs index 4b9fbc7131..edfdf6109c 100644 --- a/packages/backend-rs/src/config/server.rs +++ b/packages/backend-rs/src/config/server.rs @@ -25,7 +25,7 @@ struct ServerConfig { /// `NapiValue` is not implemented for `u64` pub max_file_size: Option, pub access_log: Option, - pub cluster_limits: Option<_WorkerConfig>, + pub cluster_limits: Option, pub cuid: Option, pub outgoing_address: Option, @@ -103,7 +103,7 @@ pub struct WorkerConfig { #[derive(Clone, Debug, PartialEq, Deserialize)] #[serde(rename_all = "camelCase")] #[crate::export(object, use_nullable = false)] -pub struct _WorkerConfig { +pub struct WorkerConfigInternal { pub web: Option, pub queue: Option, } diff --git a/packages/backend-rs/src/database/mod.rs b/packages/backend-rs/src/database/mod.rs index 26db81c644..7a6277068b 100644 --- a/packages/backend-rs/src/database/mod.rs +++ b/packages/backend-rs/src/database/mod.rs @@ -1,2 +1,6 @@ pub use postgresql::db_conn; +pub use redis::key as redis_key; +pub use redis::redis_conn; + pub mod postgresql; +pub mod redis; diff --git a/packages/backend-rs/src/database/redis.rs b/packages/backend-rs/src/database/redis.rs new file mode 100644 index 0000000000..863f57b35d --- /dev/null +++ b/packages/backend-rs/src/database/redis.rs @@ -0,0 +1,47 @@ +use crate::config::server::CONFIG; +use redis::{Client, Connection, RedisError}; + +static REDIS_CLIENT: once_cell::sync::OnceCell = once_cell::sync::OnceCell::new(); + +fn init_redis() -> Result { + let redis_url = { + let mut params = vec!["redis://".to_owned()]; + + if let Some(user) = &CONFIG.redis.user { + params.push(user.to_string()) + } + if let Some(pass) = &CONFIG.redis.pass { + params.push(format!(":{}@", pass)) + } + params.push(CONFIG.redis.host.to_string()); + params.push(format!(":{}", CONFIG.redis.port)); + params.push(format!("/{}", CONFIG.redis.db)); + + params.concat() + }; + + Client::open(redis_url) +} + +pub fn redis_conn() -> Result { + match REDIS_CLIENT.get() { + Some(client) => Ok(client.get_connection()?), + None => init_redis()?.get_connection(), + } +} + +#[inline] +/// prefix redis key with the hostname +pub fn key(key: &str) -> String { + format!("{}:{}", CONFIG.hostname, key) +} + +#[cfg(test)] +mod unit_test { + use super::init_redis; + + #[test] + fn connect_test() { + assert!(init_redis().is_ok()); + } +} From 037b7950a264123396982dd9dfeaa0f31d1c336b Mon Sep 17 00:00:00 2001 From: naskya Date: Sat, 20 Apr 2024 02:58:39 +0900 Subject: [PATCH 13/52] refactor (backend): clean the booting process a bit --- packages/backend/src/boot/master.ts | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/packages/backend/src/boot/master.ts b/packages/backend/src/boot/master.ts index 44c4a8a2f1..090a84f6ea 100644 --- a/packages/backend/src/boot/master.ts +++ b/packages/backend/src/boot/master.ts @@ -169,23 +169,31 @@ async function connectDb(): Promise { } async function spawnWorkers( - clusterLimits: Required, + clusterLimits: Config["clusterLimits"], ): Promise { - const modes = ["web", "queue"]; const cpus = os.cpus().length; - for (const mode of modes.filter((mode) => clusterLimits[mode] > cpus)) { + + if (clusterLimits.queue > cpus) { bootLogger.warn( - `configuration warning: cluster limit for ${mode} exceeds number of cores (${cpus})`, + "config: queue cluster limit exceeds the number of cpu cores", ); } - const total = modes.reduce((acc, mode) => acc + clusterLimits[mode], 0); + if (clusterLimits.web > cpus) { + bootLogger.warn( + "config: web cluster limit exceeds the number of cpu cores", + ); + } + + const total = clusterLimits.queue + clusterLimits.web; + + // workers = ["web", "web", ..., "web", "queue", "queue", ..., "queue"] const workers = new Array(total); - workers.fill("web", 0, clusterLimits?.web); - workers.fill("queue", clusterLimits?.web); + workers.fill("web", 0, clusterLimits.web); + workers.fill("queue", clusterLimits.web); bootLogger.info( - `Starting ${clusterLimits?.web} web workers and ${clusterLimits?.queue} queue workers (total ${total})...`, + `Starting ${clusterLimits.web} web workers and ${clusterLimits.queue} queue workers (total ${total})...`, ); await Promise.all(workers.map((mode) => spawnWorker(mode))); bootLogger.succ("All workers started"); From 56038b174d146330a6f8d367020455d5d26b67ca Mon Sep 17 00:00:00 2001 From: naskya Date: Sat, 20 Apr 2024 03:01:13 +0900 Subject: [PATCH 14/52] fix (backend): correct import path --- packages/backend/src/ormconfig.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/backend/src/ormconfig.ts b/packages/backend/src/ormconfig.ts index a1891e00df..293be57cae 100644 --- a/packages/backend/src/ormconfig.ts +++ b/packages/backend/src/ormconfig.ts @@ -1,6 +1,6 @@ import { DataSource } from "typeorm"; -import config from "./config/index.js"; -import { entities } from "./db/postgre.js"; +import { config } from "@/config.js"; +import { entities } from "@/db/postgre.js"; export default new DataSource({ type: "postgres", From def62ff1cecfd36e24e48aabc3d45bc89a362d6b Mon Sep 17 00:00:00 2001 From: naskya Date: Sat, 20 Apr 2024 03:04:34 +0900 Subject: [PATCH 15/52] chore (minor, backend): remove unused import --- packages/backend/src/db/postgre.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/backend/src/db/postgre.ts b/packages/backend/src/db/postgre.ts index e0ab9d6d37..1295136054 100644 --- a/packages/backend/src/db/postgre.ts +++ b/packages/backend/src/db/postgre.ts @@ -77,7 +77,6 @@ import { NoteFile } from "@/models/entities/note-file.js"; import { entities as charts } from "@/services/chart/entities.js"; import { dbLogger } from "./logger.js"; -import { redisClient } from "./redis.js"; const sqlLogger = dbLogger.createSubLogger("sql", "gray", false); From ccb17977c36eec325517e7f5090053c07292a0db Mon Sep 17 00:00:00 2001 From: naskya Date: Sat, 20 Apr 2024 03:08:35 +0900 Subject: [PATCH 16/52] chore (minor, backend): use type import --- packages/backend/src/misc/cache.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/backend/src/misc/cache.ts b/packages/backend/src/misc/cache.ts index 30a50e5714..e99b17a5f7 100644 --- a/packages/backend/src/misc/cache.ts +++ b/packages/backend/src/misc/cache.ts @@ -1,6 +1,6 @@ import { redisClient } from "@/db/redis.js"; import { encode, decode } from "msgpackr"; -import { ChainableCommander } from "ioredis"; +import type { ChainableCommander } from "ioredis"; export class Cache { private ttl: number; From b157cbe79a30d2fa10b53008c4447dc878ccc9aa Mon Sep 17 00:00:00 2001 From: naskya Date: Sat, 20 Apr 2024 04:41:47 +0900 Subject: [PATCH 17/52] chore (backend-rs): make entities serializable --- packages/backend-rs/Makefile | 4 +- .../src/model/entity/abuse_user_report.rs | 2 +- .../src/model/entity/access_token.rs | 2 +- packages/backend-rs/src/model/entity/ad.rs | 2 +- .../src/model/entity/announcement.rs | 2 +- .../src/model/entity/announcement_read.rs | 2 +- .../backend-rs/src/model/entity/antenna.rs | 2 +- .../src/model/entity/antenna_note.rs | 49 ------------------- packages/backend-rs/src/model/entity/app.rs | 2 +- .../src/model/entity/attestation_challenge.rs | 2 +- .../src/model/entity/auth_session.rs | 2 +- .../backend-rs/src/model/entity/blocking.rs | 2 +- .../backend-rs/src/model/entity/channel.rs | 2 +- .../src/model/entity/channel_following.rs | 2 +- .../src/model/entity/channel_note_pining.rs | 2 +- packages/backend-rs/src/model/entity/clip.rs | 2 +- .../backend-rs/src/model/entity/clip_note.rs | 2 +- .../backend-rs/src/model/entity/drive_file.rs | 2 +- .../src/model/entity/drive_folder.rs | 2 +- packages/backend-rs/src/model/entity/emoji.rs | 2 +- .../src/model/entity/follow_request.rs | 2 +- .../backend-rs/src/model/entity/following.rs | 2 +- .../src/model/entity/gallery_like.rs | 2 +- .../src/model/entity/gallery_post.rs | 2 +- .../backend-rs/src/model/entity/hashtag.rs | 2 +- .../backend-rs/src/model/entity/instance.rs | 2 +- .../src/model/entity/messaging_message.rs | 2 +- packages/backend-rs/src/model/entity/meta.rs | 2 +- .../backend-rs/src/model/entity/migrations.rs | 2 +- .../src/model/entity/moderation_log.rs | 2 +- .../backend-rs/src/model/entity/muted_note.rs | 2 +- .../backend-rs/src/model/entity/muting.rs | 2 +- packages/backend-rs/src/model/entity/note.rs | 2 +- .../backend-rs/src/model/entity/note_edit.rs | 2 +- .../src/model/entity/note_favorite.rs | 2 +- .../backend-rs/src/model/entity/note_file.rs | 2 +- .../src/model/entity/note_reaction.rs | 2 +- .../src/model/entity/note_thread_muting.rs | 2 +- .../src/model/entity/note_unread.rs | 2 +- .../src/model/entity/note_watching.rs | 2 +- .../src/model/entity/notification.rs | 2 +- packages/backend-rs/src/model/entity/page.rs | 2 +- .../backend-rs/src/model/entity/page_like.rs | 2 +- .../model/entity/password_reset_request.rs | 2 +- packages/backend-rs/src/model/entity/poll.rs | 2 +- .../backend-rs/src/model/entity/poll_vote.rs | 2 +- .../backend-rs/src/model/entity/promo_note.rs | 2 +- .../backend-rs/src/model/entity/promo_read.rs | 2 +- .../src/model/entity/registration_ticket.rs | 2 +- .../src/model/entity/registry_item.rs | 2 +- packages/backend-rs/src/model/entity/relay.rs | 2 +- .../src/model/entity/renote_muting.rs | 2 +- .../src/model/entity/reply_muting.rs | 2 +- .../src/model/entity/sea_orm_active_enums.rs | 20 ++++---- .../backend-rs/src/model/entity/signin.rs | 2 +- .../src/model/entity/sw_subscription.rs | 2 +- .../src/model/entity/used_username.rs | 2 +- packages/backend-rs/src/model/entity/user.rs | 2 +- .../backend-rs/src/model/entity/user_group.rs | 2 +- .../src/model/entity/user_group_invitation.rs | 2 +- .../src/model/entity/user_group_invite.rs | 2 +- .../src/model/entity/user_group_joining.rs | 2 +- .../backend-rs/src/model/entity/user_ip.rs | 2 +- .../src/model/entity/user_keypair.rs | 2 +- .../backend-rs/src/model/entity/user_list.rs | 2 +- .../src/model/entity/user_list_joining.rs | 2 +- .../src/model/entity/user_note_pining.rs | 2 +- .../src/model/entity/user_pending.rs | 2 +- .../src/model/entity/user_profile.rs | 2 +- .../src/model/entity/user_publickey.rs | 2 +- .../src/model/entity/user_security_key.rs | 2 +- .../backend-rs/src/model/entity/webhook.rs | 2 +- 72 files changed, 82 insertions(+), 129 deletions(-) delete mode 100644 packages/backend-rs/src/model/entity/antenna_note.rs diff --git a/packages/backend-rs/Makefile b/packages/backend-rs/Makefile index 11b614c82a..29a00e847d 100644 --- a/packages/backend-rs/Makefile +++ b/packages/backend-rs/Makefile @@ -6,6 +6,7 @@ SRC += $(call recursive_wildcard, src, *) .PHONY: regenerate-entities regenerate-entities: + rm --recursive --force src/model/entity sea-orm-cli generate entity \ --output-dir='src/model/entity' \ --database-url='postgres://$(POSTGRES_USER):$(POSTGRES_PASSWORD)@localhost:25432/$(POSTGRES_DB)' \ @@ -16,8 +17,9 @@ regenerate-entities: jsname=$$(printf '%s\n' "$${base%.*}" | perl -pe 's/(^|_)./uc($$&)/ge;s/_//g'); \ attribute=$$(printf 'cfg_attr(feature = "napi", napi_derive::napi(object, js_name = "%s", use_nullable = true))' "$${jsname}"); \ sed -i "s/NAPI_EXTRA_ATTR_PLACEHOLDER/$${attribute}/" "$${file}"; \ + sed -i 's/#\[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)\]/#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)]/' "$${file}"; \ done - sed -i 's/#\[derive(Debug, Clone, PartialEq, Eq, EnumIter, DeriveActiveEnum)\]/#[derive(Debug, PartialEq, Eq, EnumIter, DeriveActiveEnum)]\n#[cfg_attr(not(feature = "napi"), derive(Clone))]\n#[cfg_attr(feature = "napi", napi_derive::napi(string_enum = "camelCase"))]/' \ + sed -i 's/#\[derive(Debug, Clone, PartialEq, Eq, EnumIter, DeriveActiveEnum)\]/#[derive(Debug, PartialEq, Eq, EnumIter, DeriveActiveEnum, serde::Serialize)]\n#[cfg_attr(not(feature = "napi"), derive(Clone))]\n#[cfg_attr(feature = "napi", napi_derive::napi(string_enum = "camelCase"))]/' \ src/model/entity/sea_orm_active_enums.rs cargo fmt --all -- diff --git a/packages/backend-rs/src/model/entity/abuse_user_report.rs b/packages/backend-rs/src/model/entity/abuse_user_report.rs index 4d781f06dd..4d46581a89 100644 --- a/packages/backend-rs/src/model/entity/abuse_user_report.rs +++ b/packages/backend-rs/src/model/entity/abuse_user_report.rs @@ -2,7 +2,7 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] #[sea_orm(table_name = "abuse_user_report")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/access_token.rs b/packages/backend-rs/src/model/entity/access_token.rs index 3083bb8c90..ffe4fd9914 100644 --- a/packages/backend-rs/src/model/entity/access_token.rs +++ b/packages/backend-rs/src/model/entity/access_token.rs @@ -2,7 +2,7 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] #[sea_orm(table_name = "access_token")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/ad.rs b/packages/backend-rs/src/model/entity/ad.rs index 98ec50ea91..f8de656383 100644 --- a/packages/backend-rs/src/model/entity/ad.rs +++ b/packages/backend-rs/src/model/entity/ad.rs @@ -2,7 +2,7 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] #[sea_orm(table_name = "ad")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/announcement.rs b/packages/backend-rs/src/model/entity/announcement.rs index 311571c113..73b9c84080 100644 --- a/packages/backend-rs/src/model/entity/announcement.rs +++ b/packages/backend-rs/src/model/entity/announcement.rs @@ -2,7 +2,7 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] #[sea_orm(table_name = "announcement")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/announcement_read.rs b/packages/backend-rs/src/model/entity/announcement_read.rs index 157e402aa6..5f0c27599d 100644 --- a/packages/backend-rs/src/model/entity/announcement_read.rs +++ b/packages/backend-rs/src/model/entity/announcement_read.rs @@ -2,7 +2,7 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] #[sea_orm(table_name = "announcement_read")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/antenna.rs b/packages/backend-rs/src/model/entity/antenna.rs index 1edd6e8761..2abe216cda 100644 --- a/packages/backend-rs/src/model/entity/antenna.rs +++ b/packages/backend-rs/src/model/entity/antenna.rs @@ -3,7 +3,7 @@ use super::sea_orm_active_enums::AntennaSrcEnum; use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] #[sea_orm(table_name = "antenna")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/antenna_note.rs b/packages/backend-rs/src/model/entity/antenna_note.rs deleted file mode 100644 index c86fb349d4..0000000000 --- a/packages/backend-rs/src/model/entity/antenna_note.rs +++ /dev/null @@ -1,49 +0,0 @@ -//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3 - -use sea_orm::entity::prelude::*; - -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)] -#[sea_orm(table_name = "antenna_note")] -pub struct Model { - #[sea_orm(primary_key, auto_increment = false)] - pub id: String, - #[sea_orm(column_name = "noteId")] - pub note_id: String, - #[sea_orm(column_name = "antennaId")] - pub antenna_id: String, - pub read: bool, -} - -#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] -pub enum Relation { - #[sea_orm( - belongs_to = "super::antenna::Entity", - from = "Column::AntennaId", - to = "super::antenna::Column::Id", - on_update = "NoAction", - on_delete = "Cascade" - )] - Antenna, - #[sea_orm( - belongs_to = "super::note::Entity", - from = "Column::NoteId", - to = "super::note::Column::Id", - on_update = "NoAction", - on_delete = "Cascade" - )] - Note, -} - -impl Related for Entity { - fn to() -> RelationDef { - Relation::Antenna.def() - } -} - -impl Related for Entity { - fn to() -> RelationDef { - Relation::Note.def() - } -} - -impl ActiveModelBehavior for ActiveModel {} diff --git a/packages/backend-rs/src/model/entity/app.rs b/packages/backend-rs/src/model/entity/app.rs index d9517ed211..72c908e87a 100644 --- a/packages/backend-rs/src/model/entity/app.rs +++ b/packages/backend-rs/src/model/entity/app.rs @@ -2,7 +2,7 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] #[sea_orm(table_name = "app")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/attestation_challenge.rs b/packages/backend-rs/src/model/entity/attestation_challenge.rs index 0c131066dd..9513a584e7 100644 --- a/packages/backend-rs/src/model/entity/attestation_challenge.rs +++ b/packages/backend-rs/src/model/entity/attestation_challenge.rs @@ -2,7 +2,7 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] #[sea_orm(table_name = "attestation_challenge")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/auth_session.rs b/packages/backend-rs/src/model/entity/auth_session.rs index f022a5e632..873a15ec3d 100644 --- a/packages/backend-rs/src/model/entity/auth_session.rs +++ b/packages/backend-rs/src/model/entity/auth_session.rs @@ -2,7 +2,7 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] #[sea_orm(table_name = "auth_session")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/blocking.rs b/packages/backend-rs/src/model/entity/blocking.rs index 2f5a3e0482..5ffc685f80 100644 --- a/packages/backend-rs/src/model/entity/blocking.rs +++ b/packages/backend-rs/src/model/entity/blocking.rs @@ -2,7 +2,7 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] #[sea_orm(table_name = "blocking")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/channel.rs b/packages/backend-rs/src/model/entity/channel.rs index 52f8059030..e309a7ead6 100644 --- a/packages/backend-rs/src/model/entity/channel.rs +++ b/packages/backend-rs/src/model/entity/channel.rs @@ -2,7 +2,7 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] #[sea_orm(table_name = "channel")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/channel_following.rs b/packages/backend-rs/src/model/entity/channel_following.rs index 01a25ccb83..ee5a5a9bbc 100644 --- a/packages/backend-rs/src/model/entity/channel_following.rs +++ b/packages/backend-rs/src/model/entity/channel_following.rs @@ -2,7 +2,7 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] #[sea_orm(table_name = "channel_following")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/channel_note_pining.rs b/packages/backend-rs/src/model/entity/channel_note_pining.rs index 0a41efd3e8..28431d2999 100644 --- a/packages/backend-rs/src/model/entity/channel_note_pining.rs +++ b/packages/backend-rs/src/model/entity/channel_note_pining.rs @@ -2,7 +2,7 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] #[sea_orm(table_name = "channel_note_pining")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/clip.rs b/packages/backend-rs/src/model/entity/clip.rs index 6cbbcf4756..7316831088 100644 --- a/packages/backend-rs/src/model/entity/clip.rs +++ b/packages/backend-rs/src/model/entity/clip.rs @@ -2,7 +2,7 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] #[sea_orm(table_name = "clip")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/clip_note.rs b/packages/backend-rs/src/model/entity/clip_note.rs index 262f4a9b50..c7b089d35b 100644 --- a/packages/backend-rs/src/model/entity/clip_note.rs +++ b/packages/backend-rs/src/model/entity/clip_note.rs @@ -2,7 +2,7 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] #[sea_orm(table_name = "clip_note")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/drive_file.rs b/packages/backend-rs/src/model/entity/drive_file.rs index e3e4622a62..5527d79530 100644 --- a/packages/backend-rs/src/model/entity/drive_file.rs +++ b/packages/backend-rs/src/model/entity/drive_file.rs @@ -2,7 +2,7 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] #[sea_orm(table_name = "drive_file")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/drive_folder.rs b/packages/backend-rs/src/model/entity/drive_folder.rs index 727a698ce3..717a28b8b0 100644 --- a/packages/backend-rs/src/model/entity/drive_folder.rs +++ b/packages/backend-rs/src/model/entity/drive_folder.rs @@ -2,7 +2,7 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] #[sea_orm(table_name = "drive_folder")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/emoji.rs b/packages/backend-rs/src/model/entity/emoji.rs index 530dfe12f5..19c080bc4d 100644 --- a/packages/backend-rs/src/model/entity/emoji.rs +++ b/packages/backend-rs/src/model/entity/emoji.rs @@ -2,7 +2,7 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] #[sea_orm(table_name = "emoji")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/follow_request.rs b/packages/backend-rs/src/model/entity/follow_request.rs index 4a6b572433..0ee2f954f6 100644 --- a/packages/backend-rs/src/model/entity/follow_request.rs +++ b/packages/backend-rs/src/model/entity/follow_request.rs @@ -2,7 +2,7 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] #[sea_orm(table_name = "follow_request")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/following.rs b/packages/backend-rs/src/model/entity/following.rs index f19e46140e..25a9caf226 100644 --- a/packages/backend-rs/src/model/entity/following.rs +++ b/packages/backend-rs/src/model/entity/following.rs @@ -2,7 +2,7 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] #[sea_orm(table_name = "following")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/gallery_like.rs b/packages/backend-rs/src/model/entity/gallery_like.rs index f4ede4169a..b07ad74266 100644 --- a/packages/backend-rs/src/model/entity/gallery_like.rs +++ b/packages/backend-rs/src/model/entity/gallery_like.rs @@ -2,7 +2,7 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] #[sea_orm(table_name = "gallery_like")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/gallery_post.rs b/packages/backend-rs/src/model/entity/gallery_post.rs index 797bf38242..396075c252 100644 --- a/packages/backend-rs/src/model/entity/gallery_post.rs +++ b/packages/backend-rs/src/model/entity/gallery_post.rs @@ -2,7 +2,7 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] #[sea_orm(table_name = "gallery_post")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/hashtag.rs b/packages/backend-rs/src/model/entity/hashtag.rs index e2bb816b26..a689e110b7 100644 --- a/packages/backend-rs/src/model/entity/hashtag.rs +++ b/packages/backend-rs/src/model/entity/hashtag.rs @@ -2,7 +2,7 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] #[sea_orm(table_name = "hashtag")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/instance.rs b/packages/backend-rs/src/model/entity/instance.rs index 8b598f72b1..8b534eae6e 100644 --- a/packages/backend-rs/src/model/entity/instance.rs +++ b/packages/backend-rs/src/model/entity/instance.rs @@ -2,7 +2,7 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] #[sea_orm(table_name = "instance")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/messaging_message.rs b/packages/backend-rs/src/model/entity/messaging_message.rs index 304f876d1a..0997d18013 100644 --- a/packages/backend-rs/src/model/entity/messaging_message.rs +++ b/packages/backend-rs/src/model/entity/messaging_message.rs @@ -2,7 +2,7 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] #[sea_orm(table_name = "messaging_message")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/meta.rs b/packages/backend-rs/src/model/entity/meta.rs index b9a89914bd..67cf3d96e7 100644 --- a/packages/backend-rs/src/model/entity/meta.rs +++ b/packages/backend-rs/src/model/entity/meta.rs @@ -2,7 +2,7 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] #[sea_orm(table_name = "meta")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/migrations.rs b/packages/backend-rs/src/model/entity/migrations.rs index 235156ba4e..9487b29f0f 100644 --- a/packages/backend-rs/src/model/entity/migrations.rs +++ b/packages/backend-rs/src/model/entity/migrations.rs @@ -2,7 +2,7 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] #[sea_orm(table_name = "migrations")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/moderation_log.rs b/packages/backend-rs/src/model/entity/moderation_log.rs index b76f2c33df..097f620318 100644 --- a/packages/backend-rs/src/model/entity/moderation_log.rs +++ b/packages/backend-rs/src/model/entity/moderation_log.rs @@ -2,7 +2,7 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] #[sea_orm(table_name = "moderation_log")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/muted_note.rs b/packages/backend-rs/src/model/entity/muted_note.rs index 7c2880a03d..580f13b1aa 100644 --- a/packages/backend-rs/src/model/entity/muted_note.rs +++ b/packages/backend-rs/src/model/entity/muted_note.rs @@ -3,7 +3,7 @@ use super::sea_orm_active_enums::MutedNoteReasonEnum; use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] #[sea_orm(table_name = "muted_note")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/muting.rs b/packages/backend-rs/src/model/entity/muting.rs index 917e6a2e20..5ae9bf3dfa 100644 --- a/packages/backend-rs/src/model/entity/muting.rs +++ b/packages/backend-rs/src/model/entity/muting.rs @@ -2,7 +2,7 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] #[sea_orm(table_name = "muting")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/note.rs b/packages/backend-rs/src/model/entity/note.rs index 5903216c1a..1344fe8fad 100644 --- a/packages/backend-rs/src/model/entity/note.rs +++ b/packages/backend-rs/src/model/entity/note.rs @@ -3,7 +3,7 @@ use super::sea_orm_active_enums::NoteVisibilityEnum; use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] #[sea_orm(table_name = "note")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/note_edit.rs b/packages/backend-rs/src/model/entity/note_edit.rs index edfb35029a..e594704fe8 100644 --- a/packages/backend-rs/src/model/entity/note_edit.rs +++ b/packages/backend-rs/src/model/entity/note_edit.rs @@ -2,7 +2,7 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] #[sea_orm(table_name = "note_edit")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/note_favorite.rs b/packages/backend-rs/src/model/entity/note_favorite.rs index 76d45e9e98..c201b82092 100644 --- a/packages/backend-rs/src/model/entity/note_favorite.rs +++ b/packages/backend-rs/src/model/entity/note_favorite.rs @@ -2,7 +2,7 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] #[sea_orm(table_name = "note_favorite")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/note_file.rs b/packages/backend-rs/src/model/entity/note_file.rs index 2c52a4e5e8..fad63db8bd 100644 --- a/packages/backend-rs/src/model/entity/note_file.rs +++ b/packages/backend-rs/src/model/entity/note_file.rs @@ -2,7 +2,7 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] #[sea_orm(table_name = "note_file")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/note_reaction.rs b/packages/backend-rs/src/model/entity/note_reaction.rs index dd870a3e7f..ab4c87d76d 100644 --- a/packages/backend-rs/src/model/entity/note_reaction.rs +++ b/packages/backend-rs/src/model/entity/note_reaction.rs @@ -2,7 +2,7 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] #[sea_orm(table_name = "note_reaction")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/note_thread_muting.rs b/packages/backend-rs/src/model/entity/note_thread_muting.rs index 965001189e..fa7a4365a0 100644 --- a/packages/backend-rs/src/model/entity/note_thread_muting.rs +++ b/packages/backend-rs/src/model/entity/note_thread_muting.rs @@ -2,7 +2,7 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] #[sea_orm(table_name = "note_thread_muting")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/note_unread.rs b/packages/backend-rs/src/model/entity/note_unread.rs index ba96aed69f..9e15f631ec 100644 --- a/packages/backend-rs/src/model/entity/note_unread.rs +++ b/packages/backend-rs/src/model/entity/note_unread.rs @@ -2,7 +2,7 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] #[sea_orm(table_name = "note_unread")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/note_watching.rs b/packages/backend-rs/src/model/entity/note_watching.rs index 5b3b331e90..00433a08e0 100644 --- a/packages/backend-rs/src/model/entity/note_watching.rs +++ b/packages/backend-rs/src/model/entity/note_watching.rs @@ -2,7 +2,7 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] #[sea_orm(table_name = "note_watching")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/notification.rs b/packages/backend-rs/src/model/entity/notification.rs index 6ed5f718aa..b5d1dced95 100644 --- a/packages/backend-rs/src/model/entity/notification.rs +++ b/packages/backend-rs/src/model/entity/notification.rs @@ -3,7 +3,7 @@ use super::sea_orm_active_enums::NotificationTypeEnum; use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] #[sea_orm(table_name = "notification")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/page.rs b/packages/backend-rs/src/model/entity/page.rs index e1652a372b..3256bfff1c 100644 --- a/packages/backend-rs/src/model/entity/page.rs +++ b/packages/backend-rs/src/model/entity/page.rs @@ -3,7 +3,7 @@ use super::sea_orm_active_enums::PageVisibilityEnum; use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] #[sea_orm(table_name = "page")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/page_like.rs b/packages/backend-rs/src/model/entity/page_like.rs index c1e59ef0e1..e7a477e922 100644 --- a/packages/backend-rs/src/model/entity/page_like.rs +++ b/packages/backend-rs/src/model/entity/page_like.rs @@ -2,7 +2,7 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] #[sea_orm(table_name = "page_like")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/password_reset_request.rs b/packages/backend-rs/src/model/entity/password_reset_request.rs index 058eaedebe..76e89bd8d5 100644 --- a/packages/backend-rs/src/model/entity/password_reset_request.rs +++ b/packages/backend-rs/src/model/entity/password_reset_request.rs @@ -2,7 +2,7 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] #[sea_orm(table_name = "password_reset_request")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/poll.rs b/packages/backend-rs/src/model/entity/poll.rs index 6bcbcac08b..9572a3c728 100644 --- a/packages/backend-rs/src/model/entity/poll.rs +++ b/packages/backend-rs/src/model/entity/poll.rs @@ -3,7 +3,7 @@ use super::sea_orm_active_enums::PollNotevisibilityEnum; use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] #[sea_orm(table_name = "poll")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/poll_vote.rs b/packages/backend-rs/src/model/entity/poll_vote.rs index 0f2df2f5db..8208c3a95a 100644 --- a/packages/backend-rs/src/model/entity/poll_vote.rs +++ b/packages/backend-rs/src/model/entity/poll_vote.rs @@ -2,7 +2,7 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] #[sea_orm(table_name = "poll_vote")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/promo_note.rs b/packages/backend-rs/src/model/entity/promo_note.rs index c4e012b1a9..5e38b3440f 100644 --- a/packages/backend-rs/src/model/entity/promo_note.rs +++ b/packages/backend-rs/src/model/entity/promo_note.rs @@ -2,7 +2,7 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] #[sea_orm(table_name = "promo_note")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/promo_read.rs b/packages/backend-rs/src/model/entity/promo_read.rs index 10fe176405..f4d8854e39 100644 --- a/packages/backend-rs/src/model/entity/promo_read.rs +++ b/packages/backend-rs/src/model/entity/promo_read.rs @@ -2,7 +2,7 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] #[sea_orm(table_name = "promo_read")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/registration_ticket.rs b/packages/backend-rs/src/model/entity/registration_ticket.rs index 55d60d78b0..e06f2b295e 100644 --- a/packages/backend-rs/src/model/entity/registration_ticket.rs +++ b/packages/backend-rs/src/model/entity/registration_ticket.rs @@ -2,7 +2,7 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] #[sea_orm(table_name = "registration_ticket")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/registry_item.rs b/packages/backend-rs/src/model/entity/registry_item.rs index 74ae18cef3..7c7fcbf4b5 100644 --- a/packages/backend-rs/src/model/entity/registry_item.rs +++ b/packages/backend-rs/src/model/entity/registry_item.rs @@ -2,7 +2,7 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] #[sea_orm(table_name = "registry_item")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/relay.rs b/packages/backend-rs/src/model/entity/relay.rs index c035a74bec..24e4fb81c0 100644 --- a/packages/backend-rs/src/model/entity/relay.rs +++ b/packages/backend-rs/src/model/entity/relay.rs @@ -3,7 +3,7 @@ use super::sea_orm_active_enums::RelayStatusEnum; use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] #[sea_orm(table_name = "relay")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/renote_muting.rs b/packages/backend-rs/src/model/entity/renote_muting.rs index b6604cad88..80b0f57f59 100644 --- a/packages/backend-rs/src/model/entity/renote_muting.rs +++ b/packages/backend-rs/src/model/entity/renote_muting.rs @@ -2,7 +2,7 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] #[sea_orm(table_name = "renote_muting")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/reply_muting.rs b/packages/backend-rs/src/model/entity/reply_muting.rs index 84fe0cbbfa..8d2e00eb3f 100644 --- a/packages/backend-rs/src/model/entity/reply_muting.rs +++ b/packages/backend-rs/src/model/entity/reply_muting.rs @@ -2,7 +2,7 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] #[sea_orm(table_name = "reply_muting")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/sea_orm_active_enums.rs b/packages/backend-rs/src/model/entity/sea_orm_active_enums.rs index 38820e1bd8..2232800070 100644 --- a/packages/backend-rs/src/model/entity/sea_orm_active_enums.rs +++ b/packages/backend-rs/src/model/entity/sea_orm_active_enums.rs @@ -2,7 +2,7 @@ use sea_orm::entity::prelude::*; -#[derive(Debug, PartialEq, Eq, EnumIter, DeriveActiveEnum)] +#[derive(Debug, PartialEq, Eq, EnumIter, DeriveActiveEnum, serde::Serialize)] #[cfg_attr(not(feature = "napi"), derive(Clone))] #[cfg_attr(feature = "napi", napi_derive::napi(string_enum = "camelCase"))] #[sea_orm(rs_type = "String", db_type = "Enum", enum_name = "antenna_src_enum")] @@ -20,7 +20,7 @@ pub enum AntennaSrcEnum { #[sea_orm(string_value = "users")] Users, } -#[derive(Debug, PartialEq, Eq, EnumIter, DeriveActiveEnum)] +#[derive(Debug, PartialEq, Eq, EnumIter, DeriveActiveEnum, serde::Serialize)] #[cfg_attr(not(feature = "napi"), derive(Clone))] #[cfg_attr(feature = "napi", napi_derive::napi(string_enum = "camelCase"))] #[sea_orm( @@ -38,7 +38,7 @@ pub enum MutedNoteReasonEnum { #[sea_orm(string_value = "word")] Word, } -#[derive(Debug, PartialEq, Eq, EnumIter, DeriveActiveEnum)] +#[derive(Debug, PartialEq, Eq, EnumIter, DeriveActiveEnum, serde::Serialize)] #[cfg_attr(not(feature = "napi"), derive(Clone))] #[cfg_attr(feature = "napi", napi_derive::napi(string_enum = "camelCase"))] #[sea_orm( @@ -58,7 +58,7 @@ pub enum NoteVisibilityEnum { #[sea_orm(string_value = "specified")] Specified, } -#[derive(Debug, PartialEq, Eq, EnumIter, DeriveActiveEnum)] +#[derive(Debug, PartialEq, Eq, EnumIter, DeriveActiveEnum, serde::Serialize)] #[cfg_attr(not(feature = "napi"), derive(Clone))] #[cfg_attr(feature = "napi", napi_derive::napi(string_enum = "camelCase"))] #[sea_orm( @@ -92,7 +92,7 @@ pub enum NotificationTypeEnum { #[sea_orm(string_value = "reply")] Reply, } -#[derive(Debug, PartialEq, Eq, EnumIter, DeriveActiveEnum)] +#[derive(Debug, PartialEq, Eq, EnumIter, DeriveActiveEnum, serde::Serialize)] #[cfg_attr(not(feature = "napi"), derive(Clone))] #[cfg_attr(feature = "napi", napi_derive::napi(string_enum = "camelCase"))] #[sea_orm( @@ -108,7 +108,7 @@ pub enum PageVisibilityEnum { #[sea_orm(string_value = "specified")] Specified, } -#[derive(Debug, PartialEq, Eq, EnumIter, DeriveActiveEnum)] +#[derive(Debug, PartialEq, Eq, EnumIter, DeriveActiveEnum, serde::Serialize)] #[cfg_attr(not(feature = "napi"), derive(Clone))] #[cfg_attr(feature = "napi", napi_derive::napi(string_enum = "camelCase"))] #[sea_orm( @@ -126,7 +126,7 @@ pub enum PollNotevisibilityEnum { #[sea_orm(string_value = "specified")] Specified, } -#[derive(Debug, PartialEq, Eq, EnumIter, DeriveActiveEnum)] +#[derive(Debug, PartialEq, Eq, EnumIter, DeriveActiveEnum, serde::Serialize)] #[cfg_attr(not(feature = "napi"), derive(Clone))] #[cfg_attr(feature = "napi", napi_derive::napi(string_enum = "camelCase"))] #[sea_orm(rs_type = "String", db_type = "Enum", enum_name = "relay_status_enum")] @@ -138,7 +138,7 @@ pub enum RelayStatusEnum { #[sea_orm(string_value = "requesting")] Requesting, } -#[derive(Debug, PartialEq, Eq, EnumIter, DeriveActiveEnum)] +#[derive(Debug, PartialEq, Eq, EnumIter, DeriveActiveEnum, serde::Serialize)] #[cfg_attr(not(feature = "napi"), derive(Clone))] #[cfg_attr(feature = "napi", napi_derive::napi(string_enum = "camelCase"))] #[sea_orm( @@ -156,7 +156,7 @@ pub enum UserEmojimodpermEnum { #[sea_orm(string_value = "unauthorized")] Unauthorized, } -#[derive(Debug, PartialEq, Eq, EnumIter, DeriveActiveEnum)] +#[derive(Debug, PartialEq, Eq, EnumIter, DeriveActiveEnum, serde::Serialize)] #[cfg_attr(not(feature = "napi"), derive(Clone))] #[cfg_attr(feature = "napi", napi_derive::napi(string_enum = "camelCase"))] #[sea_orm( @@ -172,7 +172,7 @@ pub enum UserProfileFfvisibilityEnum { #[sea_orm(string_value = "public")] Public, } -#[derive(Debug, PartialEq, Eq, EnumIter, DeriveActiveEnum)] +#[derive(Debug, PartialEq, Eq, EnumIter, DeriveActiveEnum, serde::Serialize)] #[cfg_attr(not(feature = "napi"), derive(Clone))] #[cfg_attr(feature = "napi", napi_derive::napi(string_enum = "camelCase"))] #[sea_orm( diff --git a/packages/backend-rs/src/model/entity/signin.rs b/packages/backend-rs/src/model/entity/signin.rs index 491f079a82..08c7ad59f1 100644 --- a/packages/backend-rs/src/model/entity/signin.rs +++ b/packages/backend-rs/src/model/entity/signin.rs @@ -2,7 +2,7 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] #[sea_orm(table_name = "signin")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/sw_subscription.rs b/packages/backend-rs/src/model/entity/sw_subscription.rs index 4aa275f77b..a1bf0a9b3d 100644 --- a/packages/backend-rs/src/model/entity/sw_subscription.rs +++ b/packages/backend-rs/src/model/entity/sw_subscription.rs @@ -2,7 +2,7 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] #[sea_orm(table_name = "sw_subscription")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/used_username.rs b/packages/backend-rs/src/model/entity/used_username.rs index 9e108a8a4f..af038530b4 100644 --- a/packages/backend-rs/src/model/entity/used_username.rs +++ b/packages/backend-rs/src/model/entity/used_username.rs @@ -2,7 +2,7 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] #[sea_orm(table_name = "used_username")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/user.rs b/packages/backend-rs/src/model/entity/user.rs index 8af0b27e88..25c8854abe 100644 --- a/packages/backend-rs/src/model/entity/user.rs +++ b/packages/backend-rs/src/model/entity/user.rs @@ -3,7 +3,7 @@ use super::sea_orm_active_enums::UserEmojimodpermEnum; use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] #[sea_orm(table_name = "user")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/user_group.rs b/packages/backend-rs/src/model/entity/user_group.rs index 7d9ae71b24..8c5b08514f 100644 --- a/packages/backend-rs/src/model/entity/user_group.rs +++ b/packages/backend-rs/src/model/entity/user_group.rs @@ -2,7 +2,7 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] #[sea_orm(table_name = "user_group")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/user_group_invitation.rs b/packages/backend-rs/src/model/entity/user_group_invitation.rs index c449a48078..c676248ce4 100644 --- a/packages/backend-rs/src/model/entity/user_group_invitation.rs +++ b/packages/backend-rs/src/model/entity/user_group_invitation.rs @@ -2,7 +2,7 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] #[sea_orm(table_name = "user_group_invitation")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/user_group_invite.rs b/packages/backend-rs/src/model/entity/user_group_invite.rs index 3df43af3f6..41d47eb1b5 100644 --- a/packages/backend-rs/src/model/entity/user_group_invite.rs +++ b/packages/backend-rs/src/model/entity/user_group_invite.rs @@ -2,7 +2,7 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] #[sea_orm(table_name = "user_group_invite")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/user_group_joining.rs b/packages/backend-rs/src/model/entity/user_group_joining.rs index 2ff31b3a5f..3289b7e1e4 100644 --- a/packages/backend-rs/src/model/entity/user_group_joining.rs +++ b/packages/backend-rs/src/model/entity/user_group_joining.rs @@ -2,7 +2,7 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] #[sea_orm(table_name = "user_group_joining")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/user_ip.rs b/packages/backend-rs/src/model/entity/user_ip.rs index d6eadc7f71..77caeec313 100644 --- a/packages/backend-rs/src/model/entity/user_ip.rs +++ b/packages/backend-rs/src/model/entity/user_ip.rs @@ -2,7 +2,7 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] #[sea_orm(table_name = "user_ip")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/user_keypair.rs b/packages/backend-rs/src/model/entity/user_keypair.rs index d59853158a..f5fc9cd6b5 100644 --- a/packages/backend-rs/src/model/entity/user_keypair.rs +++ b/packages/backend-rs/src/model/entity/user_keypair.rs @@ -2,7 +2,7 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] #[sea_orm(table_name = "user_keypair")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/user_list.rs b/packages/backend-rs/src/model/entity/user_list.rs index 356ec5318c..399767fb25 100644 --- a/packages/backend-rs/src/model/entity/user_list.rs +++ b/packages/backend-rs/src/model/entity/user_list.rs @@ -2,7 +2,7 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] #[sea_orm(table_name = "user_list")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/user_list_joining.rs b/packages/backend-rs/src/model/entity/user_list_joining.rs index 037d7af181..adfdda8560 100644 --- a/packages/backend-rs/src/model/entity/user_list_joining.rs +++ b/packages/backend-rs/src/model/entity/user_list_joining.rs @@ -2,7 +2,7 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] #[sea_orm(table_name = "user_list_joining")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/user_note_pining.rs b/packages/backend-rs/src/model/entity/user_note_pining.rs index f0a80a66c9..74f4e1c1cd 100644 --- a/packages/backend-rs/src/model/entity/user_note_pining.rs +++ b/packages/backend-rs/src/model/entity/user_note_pining.rs @@ -2,7 +2,7 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] #[sea_orm(table_name = "user_note_pining")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/user_pending.rs b/packages/backend-rs/src/model/entity/user_pending.rs index 1fa13c2829..ddab5f2aee 100644 --- a/packages/backend-rs/src/model/entity/user_pending.rs +++ b/packages/backend-rs/src/model/entity/user_pending.rs @@ -2,7 +2,7 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] #[sea_orm(table_name = "user_pending")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/user_profile.rs b/packages/backend-rs/src/model/entity/user_profile.rs index a121118926..076729669f 100644 --- a/packages/backend-rs/src/model/entity/user_profile.rs +++ b/packages/backend-rs/src/model/entity/user_profile.rs @@ -4,7 +4,7 @@ use super::sea_orm_active_enums::UserProfileFfvisibilityEnum; use super::sea_orm_active_enums::UserProfileMutingnotificationtypesEnum; use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] #[sea_orm(table_name = "user_profile")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/user_publickey.rs b/packages/backend-rs/src/model/entity/user_publickey.rs index ad6a456ead..3683a25a7c 100644 --- a/packages/backend-rs/src/model/entity/user_publickey.rs +++ b/packages/backend-rs/src/model/entity/user_publickey.rs @@ -2,7 +2,7 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] #[sea_orm(table_name = "user_publickey")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/user_security_key.rs b/packages/backend-rs/src/model/entity/user_security_key.rs index aae6dfa8c6..bd0a7a493a 100644 --- a/packages/backend-rs/src/model/entity/user_security_key.rs +++ b/packages/backend-rs/src/model/entity/user_security_key.rs @@ -2,7 +2,7 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] #[sea_orm(table_name = "user_security_key")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/webhook.rs b/packages/backend-rs/src/model/entity/webhook.rs index e7656056b9..72c1c7e011 100644 --- a/packages/backend-rs/src/model/entity/webhook.rs +++ b/packages/backend-rs/src/model/entity/webhook.rs @@ -2,7 +2,7 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] #[sea_orm(table_name = "webhook")] #[cfg_attr( feature = "napi", From b017f9ce94a4c4678468f570958458106cb5a088 Mon Sep 17 00:00:00 2001 From: naskya Date: Sat, 20 Apr 2024 06:53:34 +0900 Subject: [PATCH 18/52] fix (backend-rs): use cache server if present --- packages/backend-rs/src/database/redis.rs | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/packages/backend-rs/src/database/redis.rs b/packages/backend-rs/src/database/redis.rs index 863f57b35d..8652c6b53c 100644 --- a/packages/backend-rs/src/database/redis.rs +++ b/packages/backend-rs/src/database/redis.rs @@ -7,15 +7,21 @@ fn init_redis() -> Result { let redis_url = { let mut params = vec!["redis://".to_owned()]; - if let Some(user) = &CONFIG.redis.user { + let redis = if let Some(cache_server) = &CONFIG.cache_server { + cache_server + } else { + &CONFIG.redis + }; + + if let Some(user) = &redis.user { params.push(user.to_string()) } - if let Some(pass) = &CONFIG.redis.pass { + if let Some(pass) = &redis.pass { params.push(format!(":{}@", pass)) } - params.push(CONFIG.redis.host.to_string()); - params.push(format!(":{}", CONFIG.redis.port)); - params.push(format!("/{}", CONFIG.redis.db)); + params.push(redis.host.to_string()); + params.push(format!(":{}", redis.port)); + params.push(format!("/{}", redis.db)); params.concat() }; @@ -31,9 +37,9 @@ pub fn redis_conn() -> Result { } #[inline] -/// prefix redis key with the hostname -pub fn key(key: &str) -> String { - format!("{}:{}", CONFIG.hostname, key) +/// prefix redis key +pub fn key(key: impl ToString) -> String { + format!("{}:{}", CONFIG.redis.prefix, key.to_string()) } #[cfg(test)] From f486caf24477d8bbaf6097a5beb53fd520d7ddc1 Mon Sep 17 00:00:00 2001 From: naskya Date: Sat, 20 Apr 2024 06:52:27 +0900 Subject: [PATCH 19/52] fix (backend-rs): use correct Redis key prefix --- packages/backend-rs/index.d.ts | 3 ++- packages/backend-rs/src/config/server.rs | 12 ++++++++++-- packages/backend-rs/src/database/redis.rs | 2 +- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/packages/backend-rs/index.d.ts b/packages/backend-rs/index.d.ts index 433e80999c..0c75def671 100644 --- a/packages/backend-rs/index.d.ts +++ b/packages/backend-rs/index.d.ts @@ -70,7 +70,7 @@ export interface RedisConfig { pass?: string tls?: TlsConfig db: number - prefix: string + prefix?: string } export interface TlsConfig { host: string @@ -165,6 +165,7 @@ export interface Config { version: string host: string hostname: string + redisKeyPrefix: string scheme: string wsScheme: string apiUrl: string diff --git a/packages/backend-rs/src/config/server.rs b/packages/backend-rs/src/config/server.rs index edfdf6109c..720e1a9c49 100644 --- a/packages/backend-rs/src/config/server.rs +++ b/packages/backend-rs/src/config/server.rs @@ -82,8 +82,7 @@ pub struct RedisConfig { pub tls: Option, #[serde(default)] pub db: u32, - #[serde(default)] - pub prefix: String, + pub prefix: Option, } #[derive(Clone, Debug, PartialEq, Deserialize)] @@ -217,6 +216,7 @@ pub struct Config { pub version: String, pub host: String, pub hostname: String, + pub redis_key_prefix: String, pub scheme: String, pub ws_scheme: String, pub api_url: String, @@ -315,6 +315,13 @@ fn load_config() -> Config { None => WorkerConfig { web: 1, queue: 1 }, }; + let redis_key_prefix = if let Some(cache_server) = &server_config.cache_server { + cache_server.prefix.clone() + } else { + server_config.redis.prefix.clone() + } + .unwrap_or(hostname.clone()); + Config { url: server_config.url, port: server_config.port, @@ -361,6 +368,7 @@ fn load_config() -> Config { version, host, hostname, + redis_key_prefix, scheme, ws_scheme, client_entry: manifest, diff --git a/packages/backend-rs/src/database/redis.rs b/packages/backend-rs/src/database/redis.rs index 8652c6b53c..e717201f95 100644 --- a/packages/backend-rs/src/database/redis.rs +++ b/packages/backend-rs/src/database/redis.rs @@ -39,7 +39,7 @@ pub fn redis_conn() -> Result { #[inline] /// prefix redis key pub fn key(key: impl ToString) -> String { - format!("{}:{}", CONFIG.redis.prefix, key.to_string()) + format!("{}:{}", CONFIG.redis_key_prefix, key.to_string()) } #[cfg(test)] From ccbd6178e4336f801adae8a5d49c3f3f9f93525a Mon Sep 17 00:00:00 2001 From: naskya Date: Sat, 20 Apr 2024 06:54:06 +0900 Subject: [PATCH 20/52] refactor (backend): port add-note-to-antenna to backend-rs I hit this bug: https://github.com/napi-rs/napi-rs/issues/2060 --- Cargo.lock | 31 ++++++- Cargo.toml | 1 + packages/backend-rs/Cargo.toml | 1 + packages/backend-rs/index.d.ts | 1 + packages/backend-rs/index.js | 3 +- packages/backend-rs/src/lib.rs | 1 + .../src/service/add_note_to_antenna.rs | 20 +++++ packages/backend-rs/src/service/mod.rs | 2 + packages/backend-rs/src/service/stream.rs | 86 +++++++++++++++++++ packages/backend/package.json | 1 + .../backend/src/prelude/undefined-to-null.ts | 76 ++++++++++++++++ .../src/services/add-note-to-antenna.ts | 24 ------ packages/backend/src/services/note/create.ts | 7 +- packages/backend/src/services/stream.ts | 28 +++--- pnpm-lock.yaml | 8 ++ 15 files changed, 247 insertions(+), 43 deletions(-) create mode 100644 packages/backend-rs/src/service/add_note_to_antenna.rs create mode 100644 packages/backend-rs/src/service/mod.rs create mode 100644 packages/backend-rs/src/service/stream.rs create mode 100644 packages/backend/src/prelude/undefined-to-null.ts delete mode 100644 packages/backend/src/services/add-note-to-antenna.ts diff --git a/Cargo.lock b/Cargo.lock index 52ef14933f..6cb32a21d0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -227,6 +227,7 @@ dependencies = [ "serde", "serde_json", "serde_yaml", + "strum 0.26.2", "thiserror", "tokio", "url", @@ -2096,6 +2097,12 @@ dependencies = [ "untrusted", ] +[[package]] +name = "rustversion" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80af6f9131f277a45a3fba6ce8e2258037bb0477a67e610d3c1fe046ab31de47" + [[package]] name = "ryu" version = "1.0.17" @@ -2176,7 +2183,7 @@ dependencies = [ "serde", "serde_json", "sqlx", - "strum", + "strum 0.25.0", "thiserror", "time", "tracing", @@ -2708,6 +2715,28 @@ version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125" +[[package]] +name = "strum" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d8cec3501a5194c432b2b7976db6b7d10ec95c253208b45f83f7136aa985e29" +dependencies = [ + "strum_macros", +] + +[[package]] +name = "strum_macros" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6cf59daf282c0a494ba14fd21610a0325f9f90ec9d1231dea26bcb1d696c946" +dependencies = [ + "heck 0.4.1", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.58", +] + [[package]] name = "subtle" version = "2.5.0" diff --git a/Cargo.toml b/Cargo.toml index b82635d8b4..0bde324447 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,6 +33,7 @@ sea-orm = "0.12.15" serde = "1.0.197" serde_json = "1.0.115" serde_yaml = "0.9.34" +strum = "0.26.2" syn = "2.0.58" thiserror = "1.0.58" tokio = "1.37.0" diff --git a/packages/backend-rs/Cargo.toml b/packages/backend-rs/Cargo.toml index d077028e13..93c57dc321 100644 --- a/packages/backend-rs/Cargo.toml +++ b/packages/backend-rs/Cargo.toml @@ -37,6 +37,7 @@ sea-orm = { workspace = true, features = ["sqlx-postgres", "runtime-tokio-rustls serde = { workspace = true, features = ["derive"] } serde_json = { workspace = true } serde_yaml = { workspace = true } +strum = { workspace = true, features = ["derive"] } thiserror = { workspace = true } tokio = { workspace = true, features = ["full"] } url = { workspace = true } diff --git a/packages/backend-rs/index.d.ts b/packages/backend-rs/index.d.ts index 0c75def671..f13cb0bc45 100644 --- a/packages/backend-rs/index.d.ts +++ b/packages/backend-rs/index.d.ts @@ -1098,6 +1098,7 @@ export interface Webhook { latestSentAt: Date | null latestStatus: number | null } +export function addNoteToAntenna(antennaId: string, note: Note): void /** Initializes Cuid2 generator. Must be called before any [create_id]. */ export function initIdGenerator(length: number, fingerprint: string): void export function getTimestamp(id: string): number diff --git a/packages/backend-rs/index.js b/packages/backend-rs/index.js index 5fd1e9d784..fbaf1dc352 100644 --- a/packages/backend-rs/index.js +++ b/packages/backend-rs/index.js @@ -310,7 +310,7 @@ if (!nativeBinding) { throw new Error(`Failed to load native binding`) } -const { loadEnv, loadConfig, stringToAcct, acctToString, checkWordMute, getFullApAccount, isSelfHost, isSameOrigin, extractHost, toPuny, isUnicodeEmoji, sqlLikeEscape, safeForSql, formatMilliseconds, getNoteSummary, toMastodonId, fromMastodonId, fetchMeta, metaToPugArgs, nyaify, hashPassword, verifyPassword, isOldPasswordAlgorithm, decodeReaction, countReactions, toDbReaction, AntennaSrcEnum, MutedNoteReasonEnum, NoteVisibilityEnum, NotificationTypeEnum, PageVisibilityEnum, PollNotevisibilityEnum, RelayStatusEnum, UserEmojimodpermEnum, UserProfileFfvisibilityEnum, UserProfileMutingnotificationtypesEnum, initIdGenerator, getTimestamp, genId, secureRndstr } = nativeBinding +const { loadEnv, loadConfig, stringToAcct, acctToString, checkWordMute, getFullApAccount, isSelfHost, isSameOrigin, extractHost, toPuny, isUnicodeEmoji, sqlLikeEscape, safeForSql, formatMilliseconds, getNoteSummary, toMastodonId, fromMastodonId, fetchMeta, metaToPugArgs, nyaify, hashPassword, verifyPassword, isOldPasswordAlgorithm, decodeReaction, countReactions, toDbReaction, AntennaSrcEnum, MutedNoteReasonEnum, NoteVisibilityEnum, NotificationTypeEnum, PageVisibilityEnum, PollNotevisibilityEnum, RelayStatusEnum, UserEmojimodpermEnum, UserProfileFfvisibilityEnum, UserProfileMutingnotificationtypesEnum, addNoteToAntenna, initIdGenerator, getTimestamp, genId, secureRndstr } = nativeBinding module.exports.loadEnv = loadEnv module.exports.loadConfig = loadConfig @@ -348,6 +348,7 @@ module.exports.RelayStatusEnum = RelayStatusEnum module.exports.UserEmojimodpermEnum = UserEmojimodpermEnum module.exports.UserProfileFfvisibilityEnum = UserProfileFfvisibilityEnum module.exports.UserProfileMutingnotificationtypesEnum = UserProfileMutingnotificationtypesEnum +module.exports.addNoteToAntenna = addNoteToAntenna module.exports.initIdGenerator = initIdGenerator module.exports.getTimestamp = getTimestamp module.exports.genId = genId diff --git a/packages/backend-rs/src/lib.rs b/packages/backend-rs/src/lib.rs index bef7a41808..0dcc4e6251 100644 --- a/packages/backend-rs/src/lib.rs +++ b/packages/backend-rs/src/lib.rs @@ -4,4 +4,5 @@ pub mod config; pub mod database; pub mod misc; pub mod model; +pub mod service; pub mod util; diff --git a/packages/backend-rs/src/service/add_note_to_antenna.rs b/packages/backend-rs/src/service/add_note_to_antenna.rs new file mode 100644 index 0000000000..b919f4e1a0 --- /dev/null +++ b/packages/backend-rs/src/service/add_note_to_antenna.rs @@ -0,0 +1,20 @@ +use crate::database::{redis_conn, redis_key}; +use crate::model::entity::note; +use crate::service::stream::{publish, Error, Stream}; +use crate::util::id::get_timestamp; +use redis::{streams::StreamMaxlen, Commands}; + +#[crate::export] +pub fn add_note_to_antenna(antenna_id: &str, note: ¬e::Model) -> Result<(), Error> { + redis_conn()?.xadd_maxlen( + redis_key(format!("antennaTimeline:{}", antenna_id)), + StreamMaxlen::Approx(200), + format!("{}-*", get_timestamp(¬e.id)), + &[("note", ¬e.id)], + )?; + + let stream = Stream::Antenna { + id: antenna_id.to_string(), + }; + publish(&stream, Some("note"), Some(serde_json::to_value(note)?)) +} diff --git a/packages/backend-rs/src/service/mod.rs b/packages/backend-rs/src/service/mod.rs new file mode 100644 index 0000000000..cc239e3f9e --- /dev/null +++ b/packages/backend-rs/src/service/mod.rs @@ -0,0 +1,2 @@ +pub mod add_note_to_antenna; +pub mod stream; diff --git a/packages/backend-rs/src/service/stream.rs b/packages/backend-rs/src/service/stream.rs new file mode 100644 index 0000000000..fc545fa95c --- /dev/null +++ b/packages/backend-rs/src/service/stream.rs @@ -0,0 +1,86 @@ +use crate::database::redis_conn; +use redis::{Commands, RedisError}; + +#[derive(strum::Display, serde::Serialize)] +pub enum Stream { + #[strum(serialize = "internal")] + Internal, + #[strum(serialize = "broadcast")] + Broadcast, + #[strum(to_string = "adminStream:{id}")] + Admin { id: String }, + #[strum(to_string = "user:{id}")] + User { id: String }, + #[strum(to_string = "channelStream:{id}")] + Channel { id: String }, + #[strum(to_string = "noteStream:{id}")] + Note { id: String }, + #[strum(serialize = "notesStream")] + Notes, + #[strum(to_string = "userListStream:{id}")] + UserList { id: String }, + #[strum(to_string = "mainStream:{id}")] + Main { id: String }, + #[strum(to_string = "driveStream:{id}")] + Drive { id: String }, + #[strum(to_string = "antennaStream:{id}")] + Antenna { id: String }, + #[strum(to_string = "messagingStream:{id}")] + Messaging { id: String }, + #[strum(to_string = "messagingIndexStream:{id}")] + MessagingIndex { id: String }, +} + +#[derive(thiserror::Error, Debug)] +pub enum Error { + #[error("Redis error: {0}")] + RedisError(#[from] RedisError), + #[error("Json serialization error: {0}")] + JsonError(#[from] serde_json::Error), + #[error("Value error: {0}")] + ValueError(String), +} + +pub fn publish( + channel: &Stream, + kind: Option<&str>, + value: Option, +) -> Result<(), Error> { + #[derive(serde::Serialize)] + struct Message { + r#type: String, + body: Option, + } + + let message = if let Some(kind) = kind { + serde_json::to_value(Message { + r#type: kind.to_string(), + body: value, + })? + } else { + value.ok_or(Error::ValueError("Invalid streaming message".to_string()))? + }; + + redis_conn()?.publish(channel.to_string(), message.to_string())?; + + Ok(()) +} + +#[cfg(test)] +mod unit_test { + use super::Stream; + use pretty_assertions::assert_eq; + + #[test] + fn channel_to_string() { + assert_eq!(Stream::Internal.to_string(), "internal"); + assert_eq!(Stream::Broadcast.to_string(), "broadcast"); + assert_eq!( + Stream::Admin { + id: "9tb42br63g5apjcq".to_string() + } + .to_string(), + "adminStream:9tb42br63g5apjcq" + ); + } +} diff --git a/packages/backend/package.json b/packages/backend/package.json index 9289c2f7ea..0599a39d4b 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -178,6 +178,7 @@ "ts-loader": "9.5.1", "ts-node": "10.9.2", "tsconfig-paths": "4.2.0", + "type-fest": "4.15.0", "typescript": "5.4.5", "webpack": "^5.91.0", "ws": "8.16.0" diff --git a/packages/backend/src/prelude/undefined-to-null.ts b/packages/backend/src/prelude/undefined-to-null.ts new file mode 100644 index 0000000000..013be3cf9e --- /dev/null +++ b/packages/backend/src/prelude/undefined-to-null.ts @@ -0,0 +1,76 @@ +// https://gist.github.com/tkrotoff/a6baf96eb6b61b445a9142e5555511a0 +import type { Primitive } from "type-fest"; + +type NullToUndefined = T extends null + ? undefined + : T extends Primitive | Function | Date | RegExp + ? T + : T extends Array + ? Array> + : T extends Map + ? Map> + : T extends Set + ? Set> + : T extends object + ? { [K in keyof T]: NullToUndefined } + : unknown; + +type UndefinedToNull = T extends undefined + ? null + : T extends Primitive | Function | Date | RegExp + ? T + : T extends Array + ? Array> + : T extends Map + ? Map> + : T extends Set + ? Set> + : T extends object + ? { [K in keyof T]: UndefinedToNull } + : unknown; + +function _nullToUndefined(obj: T): NullToUndefined { + if (obj === null) { + return undefined as any; + } + + if (typeof obj === "object") { + if (obj instanceof Map) { + obj.forEach((value, key) => obj.set(key, _nullToUndefined(value))); + } else { + for (const key in obj) { + obj[key] = _nullToUndefined(obj[key]) as any; + } + } + } + + return obj as any; +} + +function _undefinedToNull(obj: T): UndefinedToNull { + if (obj === undefined) { + return null as any; + } + + if (typeof obj === "object") { + if (obj instanceof Map) { + obj.forEach((value, key) => obj.set(key, _undefinedToNull(value))); + } else { + for (const key in obj) { + obj[key] = _undefinedToNull(obj[key]) as any; + } + } + } + + return obj as any; +} + +/** + * Recursively converts all undefined values to null. + * + * @param obj object to convert + * @returns a copy of the object with all its undefined values converted to null + */ +export function undefinedToNull(obj: T) { + return _undefinedToNull(structuredClone(obj)); +} diff --git a/packages/backend/src/services/add-note-to-antenna.ts b/packages/backend/src/services/add-note-to-antenna.ts deleted file mode 100644 index 66bc898263..0000000000 --- a/packages/backend/src/services/add-note-to-antenna.ts +++ /dev/null @@ -1,24 +0,0 @@ -import type { Antenna } from "@/models/entities/antenna.js"; -import type { Note } from "@/models/entities/note.js"; -import { getTimestamp } from "backend-rs"; -import { redisClient } from "@/db/redis.js"; -import { publishAntennaStream } from "@/services/stream.js"; -import type { User } from "@/models/entities/user.js"; - -export async function addNoteToAntenna( - antenna: Antenna, - note: Note, - _noteUser: { id: User["id"] }, -) { - redisClient.xadd( - `antennaTimeline:${antenna.id}`, - "MAXLEN", - "~", - "200", - `${getTimestamp(note.id)}-*`, - "note", - note.id, - ); - - publishAntennaStream(antenna.id, "note", note); -} diff --git a/packages/backend/src/services/note/create.ts b/packages/backend/src/services/note/create.ts index 662064da57..206f6a50ad 100644 --- a/packages/backend/src/services/note/create.ts +++ b/packages/backend/src/services/note/create.ts @@ -44,8 +44,7 @@ import { Poll } from "@/models/entities/poll.js"; import { createNotification } from "@/services/create-notification.js"; import { isDuplicateKeyValueError } from "@/misc/is-duplicate-key-value-error.js"; import { checkHitAntenna } from "@/misc/check-hit-antenna.js"; -import { checkWordMute } from "backend-rs"; -import { addNoteToAntenna } from "@/services/add-note-to-antenna.js"; +import { addNoteToAntenna, checkWordMute } from "backend-rs"; import { countSameRenotes } from "@/misc/count-same-renotes.js"; import { deliverToRelays, getCachedRelays } from "../relay.js"; import type { Channel } from "@/models/entities/channel.js"; @@ -63,6 +62,7 @@ import { Mutex } from "redis-semaphore"; import { langmap } from "@/misc/langmap.js"; import Logger from "@/services/logger.js"; import { inspect } from "node:util"; +import { undefinedToNull } from "@/prelude/undefined-to-null.js"; const logger = new Logger("create-note"); @@ -399,7 +399,8 @@ export default async ( for (const antenna of await getAntennas()) { checkHitAntenna(antenna, note, user).then((hit) => { if (hit) { - addNoteToAntenna(antenna, note, user); + // TODO: do this more sanely + addNoteToAntenna(antenna.id, undefinedToNull(note) as Note); } }); } diff --git a/packages/backend/src/services/stream.ts b/packages/backend/src/services/stream.ts index 0e2395e87e..6dff9602cd 100644 --- a/packages/backend/src/services/stream.ts +++ b/packages/backend/src/services/stream.ts @@ -4,12 +4,12 @@ import type { Note } from "@/models/entities/note.js"; import type { UserList } from "@/models/entities/user-list.js"; import type { UserGroup } from "@/models/entities/user-group.js"; import { config } from "@/config.js"; -import type { Antenna } from "@/models/entities/antenna.js"; +// import type { Antenna } from "@/models/entities/antenna.js"; import type { Channel } from "@/models/entities/channel.js"; import type { StreamChannels, AdminStreamTypes, - AntennaStreamTypes, + // AntennaStreamTypes, BroadcastTypes, ChannelStreamTypes, DriveStreamTypes, @@ -134,17 +134,17 @@ class Publisher { ); }; - public publishAntennaStream = ( - antennaId: Antenna["id"], - type: K, - value?: AntennaStreamTypes[K], - ): void => { - this.publish( - `antennaStream:${antennaId}`, - type, - typeof value === "undefined" ? null : value, - ); - }; + // public publishAntennaStream = ( + // antennaId: Antenna["id"], + // type: K, + // value?: AntennaStreamTypes[K], + // ): void => { + // this.publish( + // `antennaStream:${antennaId}`, + // type, + // typeof value === "undefined" ? null : value, + // ); + // }; public publishMessagingStream = ( userId: User["id"], @@ -217,7 +217,7 @@ export const publishNoteStream = publisher.publishNoteStream; export const publishNotesStream = publisher.publishNotesStream; export const publishChannelStream = publisher.publishChannelStream; export const publishUserListStream = publisher.publishUserListStream; -export const publishAntennaStream = publisher.publishAntennaStream; +// export const publishAntennaStream = publisher.publishAntennaStream; export const publishMessagingStream = publisher.publishMessagingStream; export const publishGroupMessagingStream = publisher.publishGroupMessagingStream; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b591ffe9c1..16a4ad6ad4 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -521,6 +521,9 @@ importers: tsconfig-paths: specifier: 4.2.0 version: 4.2.0 + type-fest: + specifier: 4.15.0 + version: 4.15.0 typescript: specifier: 5.4.5 version: 5.4.5 @@ -16632,6 +16635,11 @@ packages: engines: {node: '>=8'} dev: true + /type-fest@4.15.0: + resolution: {integrity: sha512-tB9lu0pQpX5KJq54g+oHOLumOx+pMep4RaM6liXh2PKmVRFF+/vAtUP0ZaJ0kOySfVNjF6doBWPHhBhISKdlIA==} + engines: {node: '>=16'} + dev: true + /type-is@1.6.18: resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} engines: {node: '>= 0.6'} From d41b462a893ec57717ca3c2527485927f00ce6e1 Mon Sep 17 00:00:00 2001 From: naskya Date: Sat, 20 Apr 2024 07:43:09 +0900 Subject: [PATCH 21/52] fix (backend): fix redis key prefix --- packages/backend/src/db/redis.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/backend/src/db/redis.ts b/packages/backend/src/db/redis.ts index dc703e9d47..72c23d84e2 100644 --- a/packages/backend/src/db/redis.ts +++ b/packages/backend/src/db/redis.ts @@ -12,7 +12,7 @@ export function createConnection() { family: source.family ?? 0, password: source.pass, username: source.user ?? "default", - keyPrefix: `${source.prefix}:`, + keyPrefix: `${config.redisKeyPrefix}:`, db: source.db || 0, tls: source.tls, }); From f33c7c6c94074acba664acde306803cd53bfa3b5 Mon Sep 17 00:00:00 2001 From: naskya Date: Sat, 20 Apr 2024 08:48:48 +0900 Subject: [PATCH 22/52] fix (backend): host and hostname was messed up --- packages/backend-rs/src/config/server.rs | 12 ++++++------ .../src/server/api/stream/channels/user-list.ts | 2 +- packages/backend/src/server/api/stream/index.ts | 2 +- packages/backend/src/server/api/stream/types.ts | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/packages/backend-rs/src/config/server.rs b/packages/backend-rs/src/config/server.rs index 720e1a9c49..b822d0d300 100644 --- a/packages/backend-rs/src/config/server.rs +++ b/packages/backend-rs/src/config/server.rs @@ -296,14 +296,14 @@ fn load_config() -> Config { let version = read_meta().version; let manifest = read_manifest(); let url = url::Url::parse(&server_config.url).expect("Config url is invalid"); - let host = url + let hostname = url .host_str() .expect("Hostname is missing in the config url") .to_owned(); - let hostname = url - .domain() - .expect("Domain is missing in the config url") - .to_owned(); + let host = match url.port() { + Some(port) => format!("{}:{}", hostname, port), + None => hostname.clone(), + }; let scheme = url.scheme().to_owned(); let ws_scheme = scheme.replace("http", "ws"); @@ -320,7 +320,7 @@ fn load_config() -> Config { } else { server_config.redis.prefix.clone() } - .unwrap_or(hostname.clone()); + .unwrap_or(host.clone()); Config { url: server_config.url, diff --git a/packages/backend/src/server/api/stream/channels/user-list.ts b/packages/backend/src/server/api/stream/channels/user-list.ts index fcfb7ecda3..2722a6610a 100644 --- a/packages/backend/src/server/api/stream/channels/user-list.ts +++ b/packages/backend/src/server/api/stream/channels/user-list.ts @@ -22,7 +22,7 @@ export default class extends Channel { this.listId = params.listId as string; // Check existence and owner - const exist = await UserLists.exist({ + const exist = await UserLists.exists({ where: { id: this.listId, userId: this.user!.id, diff --git a/packages/backend/src/server/api/stream/index.ts b/packages/backend/src/server/api/stream/index.ts index 416a041b52..313719e207 100644 --- a/packages/backend/src/server/api/stream/index.ts +++ b/packages/backend/src/server/api/stream/index.ts @@ -1,4 +1,4 @@ -import type { EventEmitter } from "events"; +import type { EventEmitter } from "node:events"; import type * as websocket from "websocket"; import readNote from "@/services/note/read.js"; import type { User } from "@/models/entities/user.js"; diff --git a/packages/backend/src/server/api/stream/types.ts b/packages/backend/src/server/api/stream/types.ts index 91095a46d3..8b4ac9e502 100644 --- a/packages/backend/src/server/api/stream/types.ts +++ b/packages/backend/src/server/api/stream/types.ts @@ -1,4 +1,4 @@ -import type { EventEmitter } from "events"; +import type { EventEmitter } from "node:events"; import type Emitter from "strict-event-emitter-types"; import type { Channel } from "@/models/entities/channel.js"; import type { User } from "@/models/entities/user.js"; From f13df7e2022992b53bea07f19a13ca956bac85f1 Mon Sep 17 00:00:00 2001 From: naskya Date: Sat, 20 Apr 2024 09:13:14 +0900 Subject: [PATCH 23/52] chore (backend-rs): make entities deserializable --- packages/backend-rs/Makefile | 4 +- .../src/model/entity/abuse_user_report.rs | 3 +- .../src/model/entity/access_token.rs | 3 +- packages/backend-rs/src/model/entity/ad.rs | 3 +- .../src/model/entity/announcement.rs | 3 +- .../src/model/entity/announcement_read.rs | 3 +- .../backend-rs/src/model/entity/antenna.rs | 3 +- packages/backend-rs/src/model/entity/app.rs | 3 +- .../src/model/entity/attestation_challenge.rs | 3 +- .../src/model/entity/auth_session.rs | 3 +- .../backend-rs/src/model/entity/blocking.rs | 3 +- .../backend-rs/src/model/entity/channel.rs | 3 +- .../src/model/entity/channel_following.rs | 3 +- .../src/model/entity/channel_note_pining.rs | 3 +- packages/backend-rs/src/model/entity/clip.rs | 3 +- .../backend-rs/src/model/entity/clip_note.rs | 3 +- .../backend-rs/src/model/entity/drive_file.rs | 3 +- .../src/model/entity/drive_folder.rs | 3 +- packages/backend-rs/src/model/entity/emoji.rs | 3 +- .../src/model/entity/follow_request.rs | 3 +- .../backend-rs/src/model/entity/following.rs | 3 +- .../src/model/entity/gallery_like.rs | 3 +- .../src/model/entity/gallery_post.rs | 3 +- .../backend-rs/src/model/entity/hashtag.rs | 3 +- .../backend-rs/src/model/entity/instance.rs | 3 +- .../src/model/entity/messaging_message.rs | 3 +- packages/backend-rs/src/model/entity/meta.rs | 3 +- .../backend-rs/src/model/entity/migrations.rs | 3 +- .../src/model/entity/moderation_log.rs | 3 +- .../backend-rs/src/model/entity/muted_note.rs | 3 +- .../backend-rs/src/model/entity/muting.rs | 3 +- packages/backend-rs/src/model/entity/note.rs | 3 +- .../backend-rs/src/model/entity/note_edit.rs | 3 +- .../src/model/entity/note_favorite.rs | 3 +- .../backend-rs/src/model/entity/note_file.rs | 3 +- .../src/model/entity/note_reaction.rs | 3 +- .../src/model/entity/note_thread_muting.rs | 3 +- .../src/model/entity/note_unread.rs | 3 +- .../src/model/entity/note_watching.rs | 3 +- .../src/model/entity/notification.rs | 3 +- packages/backend-rs/src/model/entity/page.rs | 3 +- .../backend-rs/src/model/entity/page_like.rs | 3 +- .../model/entity/password_reset_request.rs | 3 +- packages/backend-rs/src/model/entity/poll.rs | 3 +- .../backend-rs/src/model/entity/poll_vote.rs | 3 +- .../backend-rs/src/model/entity/promo_note.rs | 3 +- .../backend-rs/src/model/entity/promo_read.rs | 3 +- .../src/model/entity/registration_ticket.rs | 3 +- .../src/model/entity/registry_item.rs | 3 +- packages/backend-rs/src/model/entity/relay.rs | 3 +- .../src/model/entity/renote_muting.rs | 3 +- .../src/model/entity/reply_muting.rs | 3 +- .../src/model/entity/sea_orm_active_enums.rs | 50 +++++++++++++++---- .../backend-rs/src/model/entity/signin.rs | 3 +- .../src/model/entity/sw_subscription.rs | 3 +- .../src/model/entity/used_username.rs | 3 +- packages/backend-rs/src/model/entity/user.rs | 3 +- .../backend-rs/src/model/entity/user_group.rs | 3 +- .../src/model/entity/user_group_invitation.rs | 3 +- .../src/model/entity/user_group_invite.rs | 3 +- .../src/model/entity/user_group_joining.rs | 3 +- .../backend-rs/src/model/entity/user_ip.rs | 3 +- .../src/model/entity/user_keypair.rs | 3 +- .../backend-rs/src/model/entity/user_list.rs | 3 +- .../src/model/entity/user_list_joining.rs | 3 +- .../src/model/entity/user_note_pining.rs | 3 +- .../src/model/entity/user_pending.rs | 3 +- .../src/model/entity/user_profile.rs | 3 +- .../src/model/entity/user_publickey.rs | 3 +- .../src/model/entity/user_security_key.rs | 3 +- .../backend-rs/src/model/entity/webhook.rs | 3 +- 71 files changed, 180 insertions(+), 81 deletions(-) diff --git a/packages/backend-rs/Makefile b/packages/backend-rs/Makefile index 29a00e847d..abe6045801 100644 --- a/packages/backend-rs/Makefile +++ b/packages/backend-rs/Makefile @@ -17,9 +17,9 @@ regenerate-entities: jsname=$$(printf '%s\n' "$${base%.*}" | perl -pe 's/(^|_)./uc($$&)/ge;s/_//g'); \ attribute=$$(printf 'cfg_attr(feature = "napi", napi_derive::napi(object, js_name = "%s", use_nullable = true))' "$${jsname}"); \ sed -i "s/NAPI_EXTRA_ATTR_PLACEHOLDER/$${attribute}/" "$${file}"; \ - sed -i 's/#\[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)\]/#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)]/' "$${file}"; \ + sed -i 's/#\[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)\]/#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize, serde::Deserialize)]\n#[serde(rename_all = "camelCase")]/' "$${file}"; \ done - sed -i 's/#\[derive(Debug, Clone, PartialEq, Eq, EnumIter, DeriveActiveEnum)\]/#[derive(Debug, PartialEq, Eq, EnumIter, DeriveActiveEnum, serde::Serialize)]\n#[cfg_attr(not(feature = "napi"), derive(Clone))]\n#[cfg_attr(feature = "napi", napi_derive::napi(string_enum = "camelCase"))]/' \ + sed -i 's/#\[derive(Debug, Clone, PartialEq, Eq, EnumIter, DeriveActiveEnum)\]/#[derive(Debug, PartialEq, Eq, EnumIter, DeriveActiveEnum, serde::Serialize, serde::Deserialize)]\n#[serde(rename_all = "camelCase")]\n#[cfg_attr(not(feature = "napi"), derive(Clone))]\n#[cfg_attr(feature = "napi", napi_derive::napi(string_enum = "camelCase"))]/' \ src/model/entity/sea_orm_active_enums.rs cargo fmt --all -- diff --git a/packages/backend-rs/src/model/entity/abuse_user_report.rs b/packages/backend-rs/src/model/entity/abuse_user_report.rs index 4d46581a89..e12b2f4d31 100644 --- a/packages/backend-rs/src/model/entity/abuse_user_report.rs +++ b/packages/backend-rs/src/model/entity/abuse_user_report.rs @@ -2,7 +2,8 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize, serde::Deserialize)] +#[serde(rename_all = "camelCase")] #[sea_orm(table_name = "abuse_user_report")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/access_token.rs b/packages/backend-rs/src/model/entity/access_token.rs index ffe4fd9914..8b79877b8b 100644 --- a/packages/backend-rs/src/model/entity/access_token.rs +++ b/packages/backend-rs/src/model/entity/access_token.rs @@ -2,7 +2,8 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize, serde::Deserialize)] +#[serde(rename_all = "camelCase")] #[sea_orm(table_name = "access_token")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/ad.rs b/packages/backend-rs/src/model/entity/ad.rs index f8de656383..8a7b9abb86 100644 --- a/packages/backend-rs/src/model/entity/ad.rs +++ b/packages/backend-rs/src/model/entity/ad.rs @@ -2,7 +2,8 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize, serde::Deserialize)] +#[serde(rename_all = "camelCase")] #[sea_orm(table_name = "ad")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/announcement.rs b/packages/backend-rs/src/model/entity/announcement.rs index 73b9c84080..4532614a24 100644 --- a/packages/backend-rs/src/model/entity/announcement.rs +++ b/packages/backend-rs/src/model/entity/announcement.rs @@ -2,7 +2,8 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize, serde::Deserialize)] +#[serde(rename_all = "camelCase")] #[sea_orm(table_name = "announcement")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/announcement_read.rs b/packages/backend-rs/src/model/entity/announcement_read.rs index 5f0c27599d..de54dae082 100644 --- a/packages/backend-rs/src/model/entity/announcement_read.rs +++ b/packages/backend-rs/src/model/entity/announcement_read.rs @@ -2,7 +2,8 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize, serde::Deserialize)] +#[serde(rename_all = "camelCase")] #[sea_orm(table_name = "announcement_read")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/antenna.rs b/packages/backend-rs/src/model/entity/antenna.rs index 2abe216cda..4074f5f106 100644 --- a/packages/backend-rs/src/model/entity/antenna.rs +++ b/packages/backend-rs/src/model/entity/antenna.rs @@ -3,7 +3,8 @@ use super::sea_orm_active_enums::AntennaSrcEnum; use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize, serde::Deserialize)] +#[serde(rename_all = "camelCase")] #[sea_orm(table_name = "antenna")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/app.rs b/packages/backend-rs/src/model/entity/app.rs index 72c908e87a..8d2aa5373a 100644 --- a/packages/backend-rs/src/model/entity/app.rs +++ b/packages/backend-rs/src/model/entity/app.rs @@ -2,7 +2,8 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize, serde::Deserialize)] +#[serde(rename_all = "camelCase")] #[sea_orm(table_name = "app")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/attestation_challenge.rs b/packages/backend-rs/src/model/entity/attestation_challenge.rs index 9513a584e7..999952943d 100644 --- a/packages/backend-rs/src/model/entity/attestation_challenge.rs +++ b/packages/backend-rs/src/model/entity/attestation_challenge.rs @@ -2,7 +2,8 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize, serde::Deserialize)] +#[serde(rename_all = "camelCase")] #[sea_orm(table_name = "attestation_challenge")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/auth_session.rs b/packages/backend-rs/src/model/entity/auth_session.rs index 873a15ec3d..fac397308d 100644 --- a/packages/backend-rs/src/model/entity/auth_session.rs +++ b/packages/backend-rs/src/model/entity/auth_session.rs @@ -2,7 +2,8 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize, serde::Deserialize)] +#[serde(rename_all = "camelCase")] #[sea_orm(table_name = "auth_session")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/blocking.rs b/packages/backend-rs/src/model/entity/blocking.rs index 5ffc685f80..d7773108ab 100644 --- a/packages/backend-rs/src/model/entity/blocking.rs +++ b/packages/backend-rs/src/model/entity/blocking.rs @@ -2,7 +2,8 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize, serde::Deserialize)] +#[serde(rename_all = "camelCase")] #[sea_orm(table_name = "blocking")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/channel.rs b/packages/backend-rs/src/model/entity/channel.rs index e309a7ead6..4f3ec777ee 100644 --- a/packages/backend-rs/src/model/entity/channel.rs +++ b/packages/backend-rs/src/model/entity/channel.rs @@ -2,7 +2,8 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize, serde::Deserialize)] +#[serde(rename_all = "camelCase")] #[sea_orm(table_name = "channel")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/channel_following.rs b/packages/backend-rs/src/model/entity/channel_following.rs index ee5a5a9bbc..d45b2c9706 100644 --- a/packages/backend-rs/src/model/entity/channel_following.rs +++ b/packages/backend-rs/src/model/entity/channel_following.rs @@ -2,7 +2,8 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize, serde::Deserialize)] +#[serde(rename_all = "camelCase")] #[sea_orm(table_name = "channel_following")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/channel_note_pining.rs b/packages/backend-rs/src/model/entity/channel_note_pining.rs index 28431d2999..9080c0181e 100644 --- a/packages/backend-rs/src/model/entity/channel_note_pining.rs +++ b/packages/backend-rs/src/model/entity/channel_note_pining.rs @@ -2,7 +2,8 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize, serde::Deserialize)] +#[serde(rename_all = "camelCase")] #[sea_orm(table_name = "channel_note_pining")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/clip.rs b/packages/backend-rs/src/model/entity/clip.rs index 7316831088..05dc66fa48 100644 --- a/packages/backend-rs/src/model/entity/clip.rs +++ b/packages/backend-rs/src/model/entity/clip.rs @@ -2,7 +2,8 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize, serde::Deserialize)] +#[serde(rename_all = "camelCase")] #[sea_orm(table_name = "clip")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/clip_note.rs b/packages/backend-rs/src/model/entity/clip_note.rs index c7b089d35b..a76b5d5d8a 100644 --- a/packages/backend-rs/src/model/entity/clip_note.rs +++ b/packages/backend-rs/src/model/entity/clip_note.rs @@ -2,7 +2,8 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize, serde::Deserialize)] +#[serde(rename_all = "camelCase")] #[sea_orm(table_name = "clip_note")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/drive_file.rs b/packages/backend-rs/src/model/entity/drive_file.rs index 5527d79530..cff9aa5a92 100644 --- a/packages/backend-rs/src/model/entity/drive_file.rs +++ b/packages/backend-rs/src/model/entity/drive_file.rs @@ -2,7 +2,8 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize, serde::Deserialize)] +#[serde(rename_all = "camelCase")] #[sea_orm(table_name = "drive_file")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/drive_folder.rs b/packages/backend-rs/src/model/entity/drive_folder.rs index 717a28b8b0..e4f6fccb6f 100644 --- a/packages/backend-rs/src/model/entity/drive_folder.rs +++ b/packages/backend-rs/src/model/entity/drive_folder.rs @@ -2,7 +2,8 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize, serde::Deserialize)] +#[serde(rename_all = "camelCase")] #[sea_orm(table_name = "drive_folder")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/emoji.rs b/packages/backend-rs/src/model/entity/emoji.rs index 19c080bc4d..374781c4d2 100644 --- a/packages/backend-rs/src/model/entity/emoji.rs +++ b/packages/backend-rs/src/model/entity/emoji.rs @@ -2,7 +2,8 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize, serde::Deserialize)] +#[serde(rename_all = "camelCase")] #[sea_orm(table_name = "emoji")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/follow_request.rs b/packages/backend-rs/src/model/entity/follow_request.rs index 0ee2f954f6..332eeed204 100644 --- a/packages/backend-rs/src/model/entity/follow_request.rs +++ b/packages/backend-rs/src/model/entity/follow_request.rs @@ -2,7 +2,8 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize, serde::Deserialize)] +#[serde(rename_all = "camelCase")] #[sea_orm(table_name = "follow_request")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/following.rs b/packages/backend-rs/src/model/entity/following.rs index 25a9caf226..6f3255ecc9 100644 --- a/packages/backend-rs/src/model/entity/following.rs +++ b/packages/backend-rs/src/model/entity/following.rs @@ -2,7 +2,8 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize, serde::Deserialize)] +#[serde(rename_all = "camelCase")] #[sea_orm(table_name = "following")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/gallery_like.rs b/packages/backend-rs/src/model/entity/gallery_like.rs index b07ad74266..db519bc91b 100644 --- a/packages/backend-rs/src/model/entity/gallery_like.rs +++ b/packages/backend-rs/src/model/entity/gallery_like.rs @@ -2,7 +2,8 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize, serde::Deserialize)] +#[serde(rename_all = "camelCase")] #[sea_orm(table_name = "gallery_like")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/gallery_post.rs b/packages/backend-rs/src/model/entity/gallery_post.rs index 396075c252..5492417911 100644 --- a/packages/backend-rs/src/model/entity/gallery_post.rs +++ b/packages/backend-rs/src/model/entity/gallery_post.rs @@ -2,7 +2,8 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize, serde::Deserialize)] +#[serde(rename_all = "camelCase")] #[sea_orm(table_name = "gallery_post")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/hashtag.rs b/packages/backend-rs/src/model/entity/hashtag.rs index a689e110b7..56b9314e08 100644 --- a/packages/backend-rs/src/model/entity/hashtag.rs +++ b/packages/backend-rs/src/model/entity/hashtag.rs @@ -2,7 +2,8 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize, serde::Deserialize)] +#[serde(rename_all = "camelCase")] #[sea_orm(table_name = "hashtag")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/instance.rs b/packages/backend-rs/src/model/entity/instance.rs index 8b534eae6e..839c6206df 100644 --- a/packages/backend-rs/src/model/entity/instance.rs +++ b/packages/backend-rs/src/model/entity/instance.rs @@ -2,7 +2,8 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize, serde::Deserialize)] +#[serde(rename_all = "camelCase")] #[sea_orm(table_name = "instance")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/messaging_message.rs b/packages/backend-rs/src/model/entity/messaging_message.rs index 0997d18013..b5f5d818a0 100644 --- a/packages/backend-rs/src/model/entity/messaging_message.rs +++ b/packages/backend-rs/src/model/entity/messaging_message.rs @@ -2,7 +2,8 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize, serde::Deserialize)] +#[serde(rename_all = "camelCase")] #[sea_orm(table_name = "messaging_message")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/meta.rs b/packages/backend-rs/src/model/entity/meta.rs index 67cf3d96e7..a1e50228d5 100644 --- a/packages/backend-rs/src/model/entity/meta.rs +++ b/packages/backend-rs/src/model/entity/meta.rs @@ -2,7 +2,8 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize, serde::Deserialize)] +#[serde(rename_all = "camelCase")] #[sea_orm(table_name = "meta")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/migrations.rs b/packages/backend-rs/src/model/entity/migrations.rs index 9487b29f0f..f0d55ba123 100644 --- a/packages/backend-rs/src/model/entity/migrations.rs +++ b/packages/backend-rs/src/model/entity/migrations.rs @@ -2,7 +2,8 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize, serde::Deserialize)] +#[serde(rename_all = "camelCase")] #[sea_orm(table_name = "migrations")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/moderation_log.rs b/packages/backend-rs/src/model/entity/moderation_log.rs index 097f620318..e51ac4cc0d 100644 --- a/packages/backend-rs/src/model/entity/moderation_log.rs +++ b/packages/backend-rs/src/model/entity/moderation_log.rs @@ -2,7 +2,8 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize, serde::Deserialize)] +#[serde(rename_all = "camelCase")] #[sea_orm(table_name = "moderation_log")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/muted_note.rs b/packages/backend-rs/src/model/entity/muted_note.rs index 580f13b1aa..b1345565b7 100644 --- a/packages/backend-rs/src/model/entity/muted_note.rs +++ b/packages/backend-rs/src/model/entity/muted_note.rs @@ -3,7 +3,8 @@ use super::sea_orm_active_enums::MutedNoteReasonEnum; use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize, serde::Deserialize)] +#[serde(rename_all = "camelCase")] #[sea_orm(table_name = "muted_note")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/muting.rs b/packages/backend-rs/src/model/entity/muting.rs index 5ae9bf3dfa..b9850b3a42 100644 --- a/packages/backend-rs/src/model/entity/muting.rs +++ b/packages/backend-rs/src/model/entity/muting.rs @@ -2,7 +2,8 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize, serde::Deserialize)] +#[serde(rename_all = "camelCase")] #[sea_orm(table_name = "muting")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/note.rs b/packages/backend-rs/src/model/entity/note.rs index 1344fe8fad..85947ea35d 100644 --- a/packages/backend-rs/src/model/entity/note.rs +++ b/packages/backend-rs/src/model/entity/note.rs @@ -3,7 +3,8 @@ use super::sea_orm_active_enums::NoteVisibilityEnum; use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize, serde::Deserialize)] +#[serde(rename_all = "camelCase")] #[sea_orm(table_name = "note")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/note_edit.rs b/packages/backend-rs/src/model/entity/note_edit.rs index e594704fe8..0fb10b82a8 100644 --- a/packages/backend-rs/src/model/entity/note_edit.rs +++ b/packages/backend-rs/src/model/entity/note_edit.rs @@ -2,7 +2,8 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize, serde::Deserialize)] +#[serde(rename_all = "camelCase")] #[sea_orm(table_name = "note_edit")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/note_favorite.rs b/packages/backend-rs/src/model/entity/note_favorite.rs index c201b82092..12e5c641b1 100644 --- a/packages/backend-rs/src/model/entity/note_favorite.rs +++ b/packages/backend-rs/src/model/entity/note_favorite.rs @@ -2,7 +2,8 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize, serde::Deserialize)] +#[serde(rename_all = "camelCase")] #[sea_orm(table_name = "note_favorite")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/note_file.rs b/packages/backend-rs/src/model/entity/note_file.rs index fad63db8bd..9d13c7506d 100644 --- a/packages/backend-rs/src/model/entity/note_file.rs +++ b/packages/backend-rs/src/model/entity/note_file.rs @@ -2,7 +2,8 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize, serde::Deserialize)] +#[serde(rename_all = "camelCase")] #[sea_orm(table_name = "note_file")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/note_reaction.rs b/packages/backend-rs/src/model/entity/note_reaction.rs index ab4c87d76d..9d5de3fab4 100644 --- a/packages/backend-rs/src/model/entity/note_reaction.rs +++ b/packages/backend-rs/src/model/entity/note_reaction.rs @@ -2,7 +2,8 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize, serde::Deserialize)] +#[serde(rename_all = "camelCase")] #[sea_orm(table_name = "note_reaction")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/note_thread_muting.rs b/packages/backend-rs/src/model/entity/note_thread_muting.rs index fa7a4365a0..fbbb30e948 100644 --- a/packages/backend-rs/src/model/entity/note_thread_muting.rs +++ b/packages/backend-rs/src/model/entity/note_thread_muting.rs @@ -2,7 +2,8 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize, serde::Deserialize)] +#[serde(rename_all = "camelCase")] #[sea_orm(table_name = "note_thread_muting")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/note_unread.rs b/packages/backend-rs/src/model/entity/note_unread.rs index 9e15f631ec..2b74e3a63c 100644 --- a/packages/backend-rs/src/model/entity/note_unread.rs +++ b/packages/backend-rs/src/model/entity/note_unread.rs @@ -2,7 +2,8 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize, serde::Deserialize)] +#[serde(rename_all = "camelCase")] #[sea_orm(table_name = "note_unread")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/note_watching.rs b/packages/backend-rs/src/model/entity/note_watching.rs index 00433a08e0..817431daaa 100644 --- a/packages/backend-rs/src/model/entity/note_watching.rs +++ b/packages/backend-rs/src/model/entity/note_watching.rs @@ -2,7 +2,8 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize, serde::Deserialize)] +#[serde(rename_all = "camelCase")] #[sea_orm(table_name = "note_watching")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/notification.rs b/packages/backend-rs/src/model/entity/notification.rs index b5d1dced95..e2273017e5 100644 --- a/packages/backend-rs/src/model/entity/notification.rs +++ b/packages/backend-rs/src/model/entity/notification.rs @@ -3,7 +3,8 @@ use super::sea_orm_active_enums::NotificationTypeEnum; use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize, serde::Deserialize)] +#[serde(rename_all = "camelCase")] #[sea_orm(table_name = "notification")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/page.rs b/packages/backend-rs/src/model/entity/page.rs index 3256bfff1c..a88b53459d 100644 --- a/packages/backend-rs/src/model/entity/page.rs +++ b/packages/backend-rs/src/model/entity/page.rs @@ -3,7 +3,8 @@ use super::sea_orm_active_enums::PageVisibilityEnum; use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize, serde::Deserialize)] +#[serde(rename_all = "camelCase")] #[sea_orm(table_name = "page")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/page_like.rs b/packages/backend-rs/src/model/entity/page_like.rs index e7a477e922..7f7caabde5 100644 --- a/packages/backend-rs/src/model/entity/page_like.rs +++ b/packages/backend-rs/src/model/entity/page_like.rs @@ -2,7 +2,8 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize, serde::Deserialize)] +#[serde(rename_all = "camelCase")] #[sea_orm(table_name = "page_like")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/password_reset_request.rs b/packages/backend-rs/src/model/entity/password_reset_request.rs index 76e89bd8d5..de78019087 100644 --- a/packages/backend-rs/src/model/entity/password_reset_request.rs +++ b/packages/backend-rs/src/model/entity/password_reset_request.rs @@ -2,7 +2,8 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize, serde::Deserialize)] +#[serde(rename_all = "camelCase")] #[sea_orm(table_name = "password_reset_request")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/poll.rs b/packages/backend-rs/src/model/entity/poll.rs index 9572a3c728..2e65674b15 100644 --- a/packages/backend-rs/src/model/entity/poll.rs +++ b/packages/backend-rs/src/model/entity/poll.rs @@ -3,7 +3,8 @@ use super::sea_orm_active_enums::PollNotevisibilityEnum; use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize, serde::Deserialize)] +#[serde(rename_all = "camelCase")] #[sea_orm(table_name = "poll")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/poll_vote.rs b/packages/backend-rs/src/model/entity/poll_vote.rs index 8208c3a95a..47e68084cc 100644 --- a/packages/backend-rs/src/model/entity/poll_vote.rs +++ b/packages/backend-rs/src/model/entity/poll_vote.rs @@ -2,7 +2,8 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize, serde::Deserialize)] +#[serde(rename_all = "camelCase")] #[sea_orm(table_name = "poll_vote")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/promo_note.rs b/packages/backend-rs/src/model/entity/promo_note.rs index 5e38b3440f..8b13b8987b 100644 --- a/packages/backend-rs/src/model/entity/promo_note.rs +++ b/packages/backend-rs/src/model/entity/promo_note.rs @@ -2,7 +2,8 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize, serde::Deserialize)] +#[serde(rename_all = "camelCase")] #[sea_orm(table_name = "promo_note")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/promo_read.rs b/packages/backend-rs/src/model/entity/promo_read.rs index f4d8854e39..3e6d822d29 100644 --- a/packages/backend-rs/src/model/entity/promo_read.rs +++ b/packages/backend-rs/src/model/entity/promo_read.rs @@ -2,7 +2,8 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize, serde::Deserialize)] +#[serde(rename_all = "camelCase")] #[sea_orm(table_name = "promo_read")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/registration_ticket.rs b/packages/backend-rs/src/model/entity/registration_ticket.rs index e06f2b295e..ab735b2422 100644 --- a/packages/backend-rs/src/model/entity/registration_ticket.rs +++ b/packages/backend-rs/src/model/entity/registration_ticket.rs @@ -2,7 +2,8 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize, serde::Deserialize)] +#[serde(rename_all = "camelCase")] #[sea_orm(table_name = "registration_ticket")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/registry_item.rs b/packages/backend-rs/src/model/entity/registry_item.rs index 7c7fcbf4b5..cb129128b7 100644 --- a/packages/backend-rs/src/model/entity/registry_item.rs +++ b/packages/backend-rs/src/model/entity/registry_item.rs @@ -2,7 +2,8 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize, serde::Deserialize)] +#[serde(rename_all = "camelCase")] #[sea_orm(table_name = "registry_item")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/relay.rs b/packages/backend-rs/src/model/entity/relay.rs index 24e4fb81c0..f2eeb571f4 100644 --- a/packages/backend-rs/src/model/entity/relay.rs +++ b/packages/backend-rs/src/model/entity/relay.rs @@ -3,7 +3,8 @@ use super::sea_orm_active_enums::RelayStatusEnum; use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize, serde::Deserialize)] +#[serde(rename_all = "camelCase")] #[sea_orm(table_name = "relay")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/renote_muting.rs b/packages/backend-rs/src/model/entity/renote_muting.rs index 80b0f57f59..308e4c1563 100644 --- a/packages/backend-rs/src/model/entity/renote_muting.rs +++ b/packages/backend-rs/src/model/entity/renote_muting.rs @@ -2,7 +2,8 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize, serde::Deserialize)] +#[serde(rename_all = "camelCase")] #[sea_orm(table_name = "renote_muting")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/reply_muting.rs b/packages/backend-rs/src/model/entity/reply_muting.rs index 8d2e00eb3f..77891d1ee2 100644 --- a/packages/backend-rs/src/model/entity/reply_muting.rs +++ b/packages/backend-rs/src/model/entity/reply_muting.rs @@ -2,7 +2,8 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize, serde::Deserialize)] +#[serde(rename_all = "camelCase")] #[sea_orm(table_name = "reply_muting")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/sea_orm_active_enums.rs b/packages/backend-rs/src/model/entity/sea_orm_active_enums.rs index 2232800070..e8a53acdd3 100644 --- a/packages/backend-rs/src/model/entity/sea_orm_active_enums.rs +++ b/packages/backend-rs/src/model/entity/sea_orm_active_enums.rs @@ -2,7 +2,10 @@ use sea_orm::entity::prelude::*; -#[derive(Debug, PartialEq, Eq, EnumIter, DeriveActiveEnum, serde::Serialize)] +#[derive( + Debug, PartialEq, Eq, EnumIter, DeriveActiveEnum, serde::Serialize, serde::Deserialize, +)] +#[serde(rename_all = "camelCase")] #[cfg_attr(not(feature = "napi"), derive(Clone))] #[cfg_attr(feature = "napi", napi_derive::napi(string_enum = "camelCase"))] #[sea_orm(rs_type = "String", db_type = "Enum", enum_name = "antenna_src_enum")] @@ -20,7 +23,10 @@ pub enum AntennaSrcEnum { #[sea_orm(string_value = "users")] Users, } -#[derive(Debug, PartialEq, Eq, EnumIter, DeriveActiveEnum, serde::Serialize)] +#[derive( + Debug, PartialEq, Eq, EnumIter, DeriveActiveEnum, serde::Serialize, serde::Deserialize, +)] +#[serde(rename_all = "camelCase")] #[cfg_attr(not(feature = "napi"), derive(Clone))] #[cfg_attr(feature = "napi", napi_derive::napi(string_enum = "camelCase"))] #[sea_orm( @@ -38,7 +44,10 @@ pub enum MutedNoteReasonEnum { #[sea_orm(string_value = "word")] Word, } -#[derive(Debug, PartialEq, Eq, EnumIter, DeriveActiveEnum, serde::Serialize)] +#[derive( + Debug, PartialEq, Eq, EnumIter, DeriveActiveEnum, serde::Serialize, serde::Deserialize, +)] +#[serde(rename_all = "camelCase")] #[cfg_attr(not(feature = "napi"), derive(Clone))] #[cfg_attr(feature = "napi", napi_derive::napi(string_enum = "camelCase"))] #[sea_orm( @@ -58,7 +67,10 @@ pub enum NoteVisibilityEnum { #[sea_orm(string_value = "specified")] Specified, } -#[derive(Debug, PartialEq, Eq, EnumIter, DeriveActiveEnum, serde::Serialize)] +#[derive( + Debug, PartialEq, Eq, EnumIter, DeriveActiveEnum, serde::Serialize, serde::Deserialize, +)] +#[serde(rename_all = "camelCase")] #[cfg_attr(not(feature = "napi"), derive(Clone))] #[cfg_attr(feature = "napi", napi_derive::napi(string_enum = "camelCase"))] #[sea_orm( @@ -92,7 +104,10 @@ pub enum NotificationTypeEnum { #[sea_orm(string_value = "reply")] Reply, } -#[derive(Debug, PartialEq, Eq, EnumIter, DeriveActiveEnum, serde::Serialize)] +#[derive( + Debug, PartialEq, Eq, EnumIter, DeriveActiveEnum, serde::Serialize, serde::Deserialize, +)] +#[serde(rename_all = "camelCase")] #[cfg_attr(not(feature = "napi"), derive(Clone))] #[cfg_attr(feature = "napi", napi_derive::napi(string_enum = "camelCase"))] #[sea_orm( @@ -108,7 +123,10 @@ pub enum PageVisibilityEnum { #[sea_orm(string_value = "specified")] Specified, } -#[derive(Debug, PartialEq, Eq, EnumIter, DeriveActiveEnum, serde::Serialize)] +#[derive( + Debug, PartialEq, Eq, EnumIter, DeriveActiveEnum, serde::Serialize, serde::Deserialize, +)] +#[serde(rename_all = "camelCase")] #[cfg_attr(not(feature = "napi"), derive(Clone))] #[cfg_attr(feature = "napi", napi_derive::napi(string_enum = "camelCase"))] #[sea_orm( @@ -126,7 +144,10 @@ pub enum PollNotevisibilityEnum { #[sea_orm(string_value = "specified")] Specified, } -#[derive(Debug, PartialEq, Eq, EnumIter, DeriveActiveEnum, serde::Serialize)] +#[derive( + Debug, PartialEq, Eq, EnumIter, DeriveActiveEnum, serde::Serialize, serde::Deserialize, +)] +#[serde(rename_all = "camelCase")] #[cfg_attr(not(feature = "napi"), derive(Clone))] #[cfg_attr(feature = "napi", napi_derive::napi(string_enum = "camelCase"))] #[sea_orm(rs_type = "String", db_type = "Enum", enum_name = "relay_status_enum")] @@ -138,7 +159,10 @@ pub enum RelayStatusEnum { #[sea_orm(string_value = "requesting")] Requesting, } -#[derive(Debug, PartialEq, Eq, EnumIter, DeriveActiveEnum, serde::Serialize)] +#[derive( + Debug, PartialEq, Eq, EnumIter, DeriveActiveEnum, serde::Serialize, serde::Deserialize, +)] +#[serde(rename_all = "camelCase")] #[cfg_attr(not(feature = "napi"), derive(Clone))] #[cfg_attr(feature = "napi", napi_derive::napi(string_enum = "camelCase"))] #[sea_orm( @@ -156,7 +180,10 @@ pub enum UserEmojimodpermEnum { #[sea_orm(string_value = "unauthorized")] Unauthorized, } -#[derive(Debug, PartialEq, Eq, EnumIter, DeriveActiveEnum, serde::Serialize)] +#[derive( + Debug, PartialEq, Eq, EnumIter, DeriveActiveEnum, serde::Serialize, serde::Deserialize, +)] +#[serde(rename_all = "camelCase")] #[cfg_attr(not(feature = "napi"), derive(Clone))] #[cfg_attr(feature = "napi", napi_derive::napi(string_enum = "camelCase"))] #[sea_orm( @@ -172,7 +199,10 @@ pub enum UserProfileFfvisibilityEnum { #[sea_orm(string_value = "public")] Public, } -#[derive(Debug, PartialEq, Eq, EnumIter, DeriveActiveEnum, serde::Serialize)] +#[derive( + Debug, PartialEq, Eq, EnumIter, DeriveActiveEnum, serde::Serialize, serde::Deserialize, +)] +#[serde(rename_all = "camelCase")] #[cfg_attr(not(feature = "napi"), derive(Clone))] #[cfg_attr(feature = "napi", napi_derive::napi(string_enum = "camelCase"))] #[sea_orm( diff --git a/packages/backend-rs/src/model/entity/signin.rs b/packages/backend-rs/src/model/entity/signin.rs index 08c7ad59f1..d5584f9d84 100644 --- a/packages/backend-rs/src/model/entity/signin.rs +++ b/packages/backend-rs/src/model/entity/signin.rs @@ -2,7 +2,8 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize, serde::Deserialize)] +#[serde(rename_all = "camelCase")] #[sea_orm(table_name = "signin")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/sw_subscription.rs b/packages/backend-rs/src/model/entity/sw_subscription.rs index a1bf0a9b3d..fe694177f3 100644 --- a/packages/backend-rs/src/model/entity/sw_subscription.rs +++ b/packages/backend-rs/src/model/entity/sw_subscription.rs @@ -2,7 +2,8 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize, serde::Deserialize)] +#[serde(rename_all = "camelCase")] #[sea_orm(table_name = "sw_subscription")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/used_username.rs b/packages/backend-rs/src/model/entity/used_username.rs index af038530b4..8557955034 100644 --- a/packages/backend-rs/src/model/entity/used_username.rs +++ b/packages/backend-rs/src/model/entity/used_username.rs @@ -2,7 +2,8 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize, serde::Deserialize)] +#[serde(rename_all = "camelCase")] #[sea_orm(table_name = "used_username")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/user.rs b/packages/backend-rs/src/model/entity/user.rs index 25c8854abe..f8a2b09324 100644 --- a/packages/backend-rs/src/model/entity/user.rs +++ b/packages/backend-rs/src/model/entity/user.rs @@ -3,7 +3,8 @@ use super::sea_orm_active_enums::UserEmojimodpermEnum; use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize, serde::Deserialize)] +#[serde(rename_all = "camelCase")] #[sea_orm(table_name = "user")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/user_group.rs b/packages/backend-rs/src/model/entity/user_group.rs index 8c5b08514f..387c50d422 100644 --- a/packages/backend-rs/src/model/entity/user_group.rs +++ b/packages/backend-rs/src/model/entity/user_group.rs @@ -2,7 +2,8 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize, serde::Deserialize)] +#[serde(rename_all = "camelCase")] #[sea_orm(table_name = "user_group")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/user_group_invitation.rs b/packages/backend-rs/src/model/entity/user_group_invitation.rs index c676248ce4..289acf89df 100644 --- a/packages/backend-rs/src/model/entity/user_group_invitation.rs +++ b/packages/backend-rs/src/model/entity/user_group_invitation.rs @@ -2,7 +2,8 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize, serde::Deserialize)] +#[serde(rename_all = "camelCase")] #[sea_orm(table_name = "user_group_invitation")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/user_group_invite.rs b/packages/backend-rs/src/model/entity/user_group_invite.rs index 41d47eb1b5..62fcf0c524 100644 --- a/packages/backend-rs/src/model/entity/user_group_invite.rs +++ b/packages/backend-rs/src/model/entity/user_group_invite.rs @@ -2,7 +2,8 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize, serde::Deserialize)] +#[serde(rename_all = "camelCase")] #[sea_orm(table_name = "user_group_invite")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/user_group_joining.rs b/packages/backend-rs/src/model/entity/user_group_joining.rs index 3289b7e1e4..b29bdd11eb 100644 --- a/packages/backend-rs/src/model/entity/user_group_joining.rs +++ b/packages/backend-rs/src/model/entity/user_group_joining.rs @@ -2,7 +2,8 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize, serde::Deserialize)] +#[serde(rename_all = "camelCase")] #[sea_orm(table_name = "user_group_joining")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/user_ip.rs b/packages/backend-rs/src/model/entity/user_ip.rs index 77caeec313..9847fb8d65 100644 --- a/packages/backend-rs/src/model/entity/user_ip.rs +++ b/packages/backend-rs/src/model/entity/user_ip.rs @@ -2,7 +2,8 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize, serde::Deserialize)] +#[serde(rename_all = "camelCase")] #[sea_orm(table_name = "user_ip")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/user_keypair.rs b/packages/backend-rs/src/model/entity/user_keypair.rs index f5fc9cd6b5..dad29ab3b3 100644 --- a/packages/backend-rs/src/model/entity/user_keypair.rs +++ b/packages/backend-rs/src/model/entity/user_keypair.rs @@ -2,7 +2,8 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize, serde::Deserialize)] +#[serde(rename_all = "camelCase")] #[sea_orm(table_name = "user_keypair")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/user_list.rs b/packages/backend-rs/src/model/entity/user_list.rs index 399767fb25..30dc6db715 100644 --- a/packages/backend-rs/src/model/entity/user_list.rs +++ b/packages/backend-rs/src/model/entity/user_list.rs @@ -2,7 +2,8 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize, serde::Deserialize)] +#[serde(rename_all = "camelCase")] #[sea_orm(table_name = "user_list")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/user_list_joining.rs b/packages/backend-rs/src/model/entity/user_list_joining.rs index adfdda8560..972cc34bb6 100644 --- a/packages/backend-rs/src/model/entity/user_list_joining.rs +++ b/packages/backend-rs/src/model/entity/user_list_joining.rs @@ -2,7 +2,8 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize, serde::Deserialize)] +#[serde(rename_all = "camelCase")] #[sea_orm(table_name = "user_list_joining")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/user_note_pining.rs b/packages/backend-rs/src/model/entity/user_note_pining.rs index 74f4e1c1cd..26f05274fd 100644 --- a/packages/backend-rs/src/model/entity/user_note_pining.rs +++ b/packages/backend-rs/src/model/entity/user_note_pining.rs @@ -2,7 +2,8 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize, serde::Deserialize)] +#[serde(rename_all = "camelCase")] #[sea_orm(table_name = "user_note_pining")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/user_pending.rs b/packages/backend-rs/src/model/entity/user_pending.rs index ddab5f2aee..43a5c2f1e2 100644 --- a/packages/backend-rs/src/model/entity/user_pending.rs +++ b/packages/backend-rs/src/model/entity/user_pending.rs @@ -2,7 +2,8 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize, serde::Deserialize)] +#[serde(rename_all = "camelCase")] #[sea_orm(table_name = "user_pending")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/user_profile.rs b/packages/backend-rs/src/model/entity/user_profile.rs index 076729669f..644817aa8d 100644 --- a/packages/backend-rs/src/model/entity/user_profile.rs +++ b/packages/backend-rs/src/model/entity/user_profile.rs @@ -4,7 +4,8 @@ use super::sea_orm_active_enums::UserProfileFfvisibilityEnum; use super::sea_orm_active_enums::UserProfileMutingnotificationtypesEnum; use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize, serde::Deserialize)] +#[serde(rename_all = "camelCase")] #[sea_orm(table_name = "user_profile")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/user_publickey.rs b/packages/backend-rs/src/model/entity/user_publickey.rs index 3683a25a7c..f8bc8629eb 100644 --- a/packages/backend-rs/src/model/entity/user_publickey.rs +++ b/packages/backend-rs/src/model/entity/user_publickey.rs @@ -2,7 +2,8 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize, serde::Deserialize)] +#[serde(rename_all = "camelCase")] #[sea_orm(table_name = "user_publickey")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/user_security_key.rs b/packages/backend-rs/src/model/entity/user_security_key.rs index bd0a7a493a..a4694cf177 100644 --- a/packages/backend-rs/src/model/entity/user_security_key.rs +++ b/packages/backend-rs/src/model/entity/user_security_key.rs @@ -2,7 +2,8 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize, serde::Deserialize)] +#[serde(rename_all = "camelCase")] #[sea_orm(table_name = "user_security_key")] #[cfg_attr( feature = "napi", diff --git a/packages/backend-rs/src/model/entity/webhook.rs b/packages/backend-rs/src/model/entity/webhook.rs index 72c1c7e011..430cf9fcc0 100644 --- a/packages/backend-rs/src/model/entity/webhook.rs +++ b/packages/backend-rs/src/model/entity/webhook.rs @@ -2,7 +2,8 @@ use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize)] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, serde::Serialize, serde::Deserialize)] +#[serde(rename_all = "camelCase")] #[sea_orm(table_name = "webhook")] #[cfg_attr( feature = "napi", From 2b0668dacd3f540b93c932e504d1e86a1337afc1 Mon Sep 17 00:00:00 2001 From: naskya Date: Sat, 20 Apr 2024 09:54:02 +0900 Subject: [PATCH 24/52] fix (backend-rs): Redis streaming --- .../src/service/add_note_to_antenna.rs | 2 +- packages/backend-rs/src/service/stream.rs | 35 ++++++++++--------- 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/packages/backend-rs/src/service/add_note_to_antenna.rs b/packages/backend-rs/src/service/add_note_to_antenna.rs index b919f4e1a0..6a06fb6993 100644 --- a/packages/backend-rs/src/service/add_note_to_antenna.rs +++ b/packages/backend-rs/src/service/add_note_to_antenna.rs @@ -16,5 +16,5 @@ pub fn add_note_to_antenna(antenna_id: &str, note: ¬e::Model) -> Result<(), E let stream = Stream::Antenna { id: antenna_id.to_string(), }; - publish(&stream, Some("note"), Some(serde_json::to_value(note)?)) + publish(&stream, Some("note"), Some(serde_json::to_string(note)?)) } diff --git a/packages/backend-rs/src/service/stream.rs b/packages/backend-rs/src/service/stream.rs index fc545fa95c..6fbe699f44 100644 --- a/packages/backend-rs/src/service/stream.rs +++ b/packages/backend-rs/src/service/stream.rs @@ -1,3 +1,4 @@ +use crate::config::server::CONFIG; use crate::database::redis_conn; use redis::{Commands, RedisError}; @@ -35,33 +36,33 @@ pub enum Stream { pub enum Error { #[error("Redis error: {0}")] RedisError(#[from] RedisError), - #[error("Json serialization error: {0}")] + #[error("Json (de)serialization error: {0}")] JsonError(#[from] serde_json::Error), #[error("Value error: {0}")] ValueError(String), } -pub fn publish( - channel: &Stream, - kind: Option<&str>, - value: Option, -) -> Result<(), Error> { - #[derive(serde::Serialize)] - struct Message { - r#type: String, - body: Option, - } - +pub fn publish(channel: &Stream, kind: Option<&str>, value: Option) -> Result<(), Error> { let message = if let Some(kind) = kind { - serde_json::to_value(Message { - r#type: kind.to_string(), - body: value, - })? + format!( + "{{ \"type\": \"{}\", \"body\": {} }}", + kind, + match value { + Some(v) => v, + None => "null".to_string(), + } + ) } else { value.ok_or(Error::ValueError("Invalid streaming message".to_string()))? }; - redis_conn()?.publish(channel.to_string(), message.to_string())?; + redis_conn()?.publish( + &CONFIG.host, + format!( + "{{ \"channel\": \"{}\", \"message\": {} }}", + channel, message, + ), + )?; Ok(()) } From 6349705fb24d01e35bb8f53e53d2ec9ec9cfe629 Mon Sep 17 00:00:00 2001 From: naskya Date: Sat, 20 Apr 2024 23:55:40 +0900 Subject: [PATCH 25/52] test (backend-rs): add db connection tests --- .../backend-rs/src/database/postgresql.rs | 3 ++- packages/backend-rs/src/database/redis.rs | 21 ++++++++++++++++--- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/packages/backend-rs/src/database/postgresql.rs b/packages/backend-rs/src/database/postgresql.rs index a60d20af9c..c365da84dc 100644 --- a/packages/backend-rs/src/database/postgresql.rs +++ b/packages/backend-rs/src/database/postgresql.rs @@ -28,7 +28,8 @@ mod unit_test { use super::db_conn; #[tokio::test] - async fn connect_test() { + async fn connect() { + assert!(db_conn().await.is_ok()); assert!(db_conn().await.is_ok()); } } diff --git a/packages/backend-rs/src/database/redis.rs b/packages/backend-rs/src/database/redis.rs index e717201f95..d722e2c00a 100644 --- a/packages/backend-rs/src/database/redis.rs +++ b/packages/backend-rs/src/database/redis.rs @@ -44,10 +44,25 @@ pub fn key(key: impl ToString) -> String { #[cfg(test)] mod unit_test { - use super::init_redis; + use super::redis_conn; + use pretty_assertions::assert_eq; + use redis::Commands; #[test] - fn connect_test() { - assert!(init_redis().is_ok()); + fn connect() { + assert!(redis_conn().is_ok()); + assert!(redis_conn().is_ok()); + } + + #[test] + fn access() { + let mut redis = redis_conn().unwrap(); + + let key = "CARGO_UNIT_TEST_KEY"; + let value = "CARGO_UNIT_TEST_VALUE"; + + assert_eq!(redis.set::<&str, &str, String>(key, value).unwrap(), "OK"); + assert_eq!(redis.get::<&str, String>(key).unwrap(), value); + assert_eq!(redis.del::<&str, u32>(key).unwrap(), 1); } } From 3b65ebcb3e26d58db78f86c92fac9c06f199f18f Mon Sep 17 00:00:00 2001 From: naskya Date: Sun, 21 Apr 2024 05:47:11 +0900 Subject: [PATCH 26/52] refactor (backend): it turns out that sending the entire note object was redundant --- packages/backend-rs/index.d.ts | 2 +- .../src/service/add_note_to_antenna.rs | 13 ++-- packages/backend/package.json | 1 - .../backend/src/prelude/undefined-to-null.ts | 76 ------------------- packages/backend/src/services/note/create.ts | 4 +- pnpm-lock.yaml | 8 -- 6 files changed, 10 insertions(+), 94 deletions(-) delete mode 100644 packages/backend/src/prelude/undefined-to-null.ts diff --git a/packages/backend-rs/index.d.ts b/packages/backend-rs/index.d.ts index f13cb0bc45..3b8a4c929b 100644 --- a/packages/backend-rs/index.d.ts +++ b/packages/backend-rs/index.d.ts @@ -1098,7 +1098,7 @@ export interface Webhook { latestSentAt: Date | null latestStatus: number | null } -export function addNoteToAntenna(antennaId: string, note: Note): void +export function addNoteToAntenna(antennaId: string, noteId: string): void /** Initializes Cuid2 generator. Must be called before any [create_id]. */ export function initIdGenerator(length: number, fingerprint: string): void export function getTimestamp(id: string): number diff --git a/packages/backend-rs/src/service/add_note_to_antenna.rs b/packages/backend-rs/src/service/add_note_to_antenna.rs index 6a06fb6993..ea6e5fe76e 100644 --- a/packages/backend-rs/src/service/add_note_to_antenna.rs +++ b/packages/backend-rs/src/service/add_note_to_antenna.rs @@ -1,20 +1,23 @@ use crate::database::{redis_conn, redis_key}; -use crate::model::entity::note; use crate::service::stream::{publish, Error, Stream}; use crate::util::id::get_timestamp; use redis::{streams::StreamMaxlen, Commands}; #[crate::export] -pub fn add_note_to_antenna(antenna_id: &str, note: ¬e::Model) -> Result<(), Error> { +pub fn add_note_to_antenna(antenna_id: &str, note_id: &str) -> Result<(), Error> { redis_conn()?.xadd_maxlen( redis_key(format!("antennaTimeline:{}", antenna_id)), StreamMaxlen::Approx(200), - format!("{}-*", get_timestamp(¬e.id)), - &[("note", ¬e.id)], + format!("{}-*", get_timestamp(¬e_id)), + &[("note", ¬e_id)], )?; let stream = Stream::Antenna { id: antenna_id.to_string(), }; - publish(&stream, Some("note"), Some(serde_json::to_string(note)?)) + publish( + &stream, + Some("note"), + Some(format!("{{ \"id\": \"{}\" }}", note_id)), + ) } diff --git a/packages/backend/package.json b/packages/backend/package.json index 0599a39d4b..9289c2f7ea 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -178,7 +178,6 @@ "ts-loader": "9.5.1", "ts-node": "10.9.2", "tsconfig-paths": "4.2.0", - "type-fest": "4.15.0", "typescript": "5.4.5", "webpack": "^5.91.0", "ws": "8.16.0" diff --git a/packages/backend/src/prelude/undefined-to-null.ts b/packages/backend/src/prelude/undefined-to-null.ts deleted file mode 100644 index 013be3cf9e..0000000000 --- a/packages/backend/src/prelude/undefined-to-null.ts +++ /dev/null @@ -1,76 +0,0 @@ -// https://gist.github.com/tkrotoff/a6baf96eb6b61b445a9142e5555511a0 -import type { Primitive } from "type-fest"; - -type NullToUndefined = T extends null - ? undefined - : T extends Primitive | Function | Date | RegExp - ? T - : T extends Array - ? Array> - : T extends Map - ? Map> - : T extends Set - ? Set> - : T extends object - ? { [K in keyof T]: NullToUndefined } - : unknown; - -type UndefinedToNull = T extends undefined - ? null - : T extends Primitive | Function | Date | RegExp - ? T - : T extends Array - ? Array> - : T extends Map - ? Map> - : T extends Set - ? Set> - : T extends object - ? { [K in keyof T]: UndefinedToNull } - : unknown; - -function _nullToUndefined(obj: T): NullToUndefined { - if (obj === null) { - return undefined as any; - } - - if (typeof obj === "object") { - if (obj instanceof Map) { - obj.forEach((value, key) => obj.set(key, _nullToUndefined(value))); - } else { - for (const key in obj) { - obj[key] = _nullToUndefined(obj[key]) as any; - } - } - } - - return obj as any; -} - -function _undefinedToNull(obj: T): UndefinedToNull { - if (obj === undefined) { - return null as any; - } - - if (typeof obj === "object") { - if (obj instanceof Map) { - obj.forEach((value, key) => obj.set(key, _undefinedToNull(value))); - } else { - for (const key in obj) { - obj[key] = _undefinedToNull(obj[key]) as any; - } - } - } - - return obj as any; -} - -/** - * Recursively converts all undefined values to null. - * - * @param obj object to convert - * @returns a copy of the object with all its undefined values converted to null - */ -export function undefinedToNull(obj: T) { - return _undefinedToNull(structuredClone(obj)); -} diff --git a/packages/backend/src/services/note/create.ts b/packages/backend/src/services/note/create.ts index 206f6a50ad..8fa2b4e23b 100644 --- a/packages/backend/src/services/note/create.ts +++ b/packages/backend/src/services/note/create.ts @@ -62,7 +62,6 @@ import { Mutex } from "redis-semaphore"; import { langmap } from "@/misc/langmap.js"; import Logger from "@/services/logger.js"; import { inspect } from "node:util"; -import { undefinedToNull } from "@/prelude/undefined-to-null.js"; const logger = new Logger("create-note"); @@ -399,8 +398,7 @@ export default async ( for (const antenna of await getAntennas()) { checkHitAntenna(antenna, note, user).then((hit) => { if (hit) { - // TODO: do this more sanely - addNoteToAntenna(antenna.id, undefinedToNull(note) as Note); + addNoteToAntenna(antenna.id, note.id); } }); } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 16a4ad6ad4..b591ffe9c1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -521,9 +521,6 @@ importers: tsconfig-paths: specifier: 4.2.0 version: 4.2.0 - type-fest: - specifier: 4.15.0 - version: 4.15.0 typescript: specifier: 5.4.5 version: 5.4.5 @@ -16635,11 +16632,6 @@ packages: engines: {node: '>=8'} dev: true - /type-fest@4.15.0: - resolution: {integrity: sha512-tB9lu0pQpX5KJq54g+oHOLumOx+pMep4RaM6liXh2PKmVRFF+/vAtUP0ZaJ0kOySfVNjF6doBWPHhBhISKdlIA==} - engines: {node: '>=16'} - dev: true - /type-is@1.6.18: resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} engines: {node: '>= 0.6'} From 9b91035a796c2f4844ffdfe8c9cd59c89233bcc3 Mon Sep 17 00:00:00 2001 From: naskya Date: Sun, 21 Apr 2024 22:40:58 +0900 Subject: [PATCH 27/52] chore (backend-rs): remove unneeded reference --- packages/backend-rs/src/service/add_note_to_antenna.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/backend-rs/src/service/add_note_to_antenna.rs b/packages/backend-rs/src/service/add_note_to_antenna.rs index ea6e5fe76e..4ba8856dc4 100644 --- a/packages/backend-rs/src/service/add_note_to_antenna.rs +++ b/packages/backend-rs/src/service/add_note_to_antenna.rs @@ -8,8 +8,8 @@ pub fn add_note_to_antenna(antenna_id: &str, note_id: &str) -> Result<(), Error> redis_conn()?.xadd_maxlen( redis_key(format!("antennaTimeline:{}", antenna_id)), StreamMaxlen::Approx(200), - format!("{}-*", get_timestamp(¬e_id)), - &[("note", ¬e_id)], + format!("{}-*", get_timestamp(note_id)), + &[("note", note_id)], )?; let stream = Stream::Antenna { From ec940bb0681f1cd8ad6b2ee0acb20eed30a49013 Mon Sep 17 00:00:00 2001 From: naskya Date: Sun, 21 Apr 2024 22:43:09 +0900 Subject: [PATCH 28/52] chore (backend-rs): publish -> publish_to_stream --- packages/backend-rs/src/service/add_note_to_antenna.rs | 4 ++-- packages/backend-rs/src/service/stream.rs | 8 ++++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/packages/backend-rs/src/service/add_note_to_antenna.rs b/packages/backend-rs/src/service/add_note_to_antenna.rs index 4ba8856dc4..0509db9ccb 100644 --- a/packages/backend-rs/src/service/add_note_to_antenna.rs +++ b/packages/backend-rs/src/service/add_note_to_antenna.rs @@ -1,5 +1,5 @@ use crate::database::{redis_conn, redis_key}; -use crate::service::stream::{publish, Error, Stream}; +use crate::service::stream::{publish_to_stream, Error, Stream}; use crate::util::id::get_timestamp; use redis::{streams::StreamMaxlen, Commands}; @@ -15,7 +15,7 @@ pub fn add_note_to_antenna(antenna_id: &str, note_id: &str) -> Result<(), Error> let stream = Stream::Antenna { id: antenna_id.to_string(), }; - publish( + publish_to_stream( &stream, Some("note"), Some(format!("{{ \"id\": \"{}\" }}", note_id)), diff --git a/packages/backend-rs/src/service/stream.rs b/packages/backend-rs/src/service/stream.rs index 6fbe699f44..e7d0cce628 100644 --- a/packages/backend-rs/src/service/stream.rs +++ b/packages/backend-rs/src/service/stream.rs @@ -42,7 +42,11 @@ pub enum Error { ValueError(String), } -pub fn publish(channel: &Stream, kind: Option<&str>, value: Option) -> Result<(), Error> { +pub fn publish_to_stream( + stream: &Stream, + kind: Option<&str>, + value: Option, +) -> Result<(), Error> { let message = if let Some(kind) = kind { format!( "{{ \"type\": \"{}\", \"body\": {} }}", @@ -60,7 +64,7 @@ pub fn publish(channel: &Stream, kind: Option<&str>, value: Option) -> R &CONFIG.host, format!( "{{ \"channel\": \"{}\", \"message\": {} }}", - channel, message, + stream, message, ), )?; From 77e6479a67a20ea182f92c90651bc31f0dfb38db Mon Sep 17 00:00:00 2001 From: naskya Date: Mon, 22 Apr 2024 00:14:19 +0900 Subject: [PATCH 29/52] chore (backend-rs): separate one-to-one/group chat stream types --- packages/backend-rs/src/service/stream.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/backend-rs/src/service/stream.rs b/packages/backend-rs/src/service/stream.rs index e7d0cce628..98733a96fc 100644 --- a/packages/backend-rs/src/service/stream.rs +++ b/packages/backend-rs/src/service/stream.rs @@ -26,8 +26,10 @@ pub enum Stream { Drive { id: String }, #[strum(to_string = "antennaStream:{id}")] Antenna { id: String }, + #[strum(to_string = "messagingStream:{id_1}-{id_2}")] + Chat { id_1: String, id_2: String }, #[strum(to_string = "messagingStream:{id}")] - Messaging { id: String }, + GroupChat { id: String }, #[strum(to_string = "messagingIndexStream:{id}")] MessagingIndex { id: String }, } From 2d8f4b945f0b60f8bb9fabda1ba6da818ec096ca Mon Sep 17 00:00:00 2001 From: naskya Date: Mon, 22 Apr 2024 00:17:33 +0900 Subject: [PATCH 30/52] chore (backend-rs): remove unneeded serialize derivation for now --- packages/backend-rs/src/service/stream.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/backend-rs/src/service/stream.rs b/packages/backend-rs/src/service/stream.rs index 98733a96fc..8ca79cd96c 100644 --- a/packages/backend-rs/src/service/stream.rs +++ b/packages/backend-rs/src/service/stream.rs @@ -2,7 +2,7 @@ use crate::config::server::CONFIG; use crate::database::redis_conn; use redis::{Commands, RedisError}; -#[derive(strum::Display, serde::Serialize)] +#[derive(strum::Display)] pub enum Stream { #[strum(serialize = "internal")] Internal, @@ -38,8 +38,6 @@ pub enum Stream { pub enum Error { #[error("Redis error: {0}")] RedisError(#[from] RedisError), - #[error("Json (de)serialization error: {0}")] - JsonError(#[from] serde_json::Error), #[error("Value error: {0}")] ValueError(String), } From 5c6f1c818adfa59921ac3ef61ed6b61c6eb44791 Mon Sep 17 00:00:00 2001 From: naskya Date: Mon, 22 Apr 2024 00:21:10 +0900 Subject: [PATCH 31/52] chore (backend-rs): clean redundant match expression --- packages/backend-rs/src/service/stream.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/packages/backend-rs/src/service/stream.rs b/packages/backend-rs/src/service/stream.rs index 8ca79cd96c..700a834c83 100644 --- a/packages/backend-rs/src/service/stream.rs +++ b/packages/backend-rs/src/service/stream.rs @@ -51,10 +51,7 @@ pub fn publish_to_stream( format!( "{{ \"type\": \"{}\", \"body\": {} }}", kind, - match value { - Some(v) => v, - None => "null".to_string(), - } + value.unwrap_or("null".to_string()), ) } else { value.ok_or(Error::ValueError("Invalid streaming message".to_string()))? From 137d0fe3e54e45a2c3eee0a0111e75bbc38364c2 Mon Sep 17 00:00:00 2001 From: naskya Date: Mon, 22 Apr 2024 00:28:05 +0900 Subject: [PATCH 32/52] chore (backend-rs): make variable names clearer --- .../src/service/add_note_to_antenna.rs | 2 +- packages/backend-rs/src/service/stream.rs | 49 ++++++++++--------- 2 files changed, 27 insertions(+), 24 deletions(-) diff --git a/packages/backend-rs/src/service/add_note_to_antenna.rs b/packages/backend-rs/src/service/add_note_to_antenna.rs index 0509db9ccb..eefd242dfb 100644 --- a/packages/backend-rs/src/service/add_note_to_antenna.rs +++ b/packages/backend-rs/src/service/add_note_to_antenna.rs @@ -13,7 +13,7 @@ pub fn add_note_to_antenna(antenna_id: &str, note_id: &str) -> Result<(), Error> )?; let stream = Stream::Antenna { - id: antenna_id.to_string(), + antenna_id: antenna_id.to_string(), }; publish_to_stream( &stream, diff --git a/packages/backend-rs/src/service/stream.rs b/packages/backend-rs/src/service/stream.rs index 700a834c83..511954ec81 100644 --- a/packages/backend-rs/src/service/stream.rs +++ b/packages/backend-rs/src/service/stream.rs @@ -8,30 +8,33 @@ pub enum Stream { Internal, #[strum(serialize = "broadcast")] Broadcast, - #[strum(to_string = "adminStream:{id}")] - Admin { id: String }, - #[strum(to_string = "user:{id}")] - User { id: String }, - #[strum(to_string = "channelStream:{id}")] - Channel { id: String }, - #[strum(to_string = "noteStream:{id}")] - Note { id: String }, + #[strum(to_string = "adminStream:{user_id}")] + Admin { user_id: String }, + #[strum(to_string = "user:{user_id}")] + User { user_id: String }, + #[strum(to_string = "channelStream:{channel_id}")] + Channel { channel_id: String }, + #[strum(to_string = "noteStream:{note_id}")] + Note { note_id: String }, #[strum(serialize = "notesStream")] Notes, - #[strum(to_string = "userListStream:{id}")] - UserList { id: String }, - #[strum(to_string = "mainStream:{id}")] - Main { id: String }, - #[strum(to_string = "driveStream:{id}")] - Drive { id: String }, - #[strum(to_string = "antennaStream:{id}")] - Antenna { id: String }, - #[strum(to_string = "messagingStream:{id_1}-{id_2}")] - Chat { id_1: String, id_2: String }, - #[strum(to_string = "messagingStream:{id}")] - GroupChat { id: String }, - #[strum(to_string = "messagingIndexStream:{id}")] - MessagingIndex { id: String }, + #[strum(to_string = "userListStream:{list_id}")] + UserList { list_id: String }, + #[strum(to_string = "mainStream:{user_id}")] + Main { user_id: String }, + #[strum(to_string = "driveStream:{user_id}")] + Drive { user_id: String }, + #[strum(to_string = "antennaStream:{antenna_id}")] + Antenna { antenna_id: String }, + #[strum(to_string = "messagingStream:{sender_user_id}-{receiver_user_id}")] + Chat { + sender_user_id: String, + receiver_user_id: String, + }, + #[strum(to_string = "messagingStream:{group_id}")] + GroupChat { group_id: String }, + #[strum(to_string = "messagingIndexStream:{user_id}")] + MessagingIndex { user_id: String }, } #[derive(thiserror::Error, Debug)] @@ -79,7 +82,7 @@ mod unit_test { assert_eq!(Stream::Broadcast.to_string(), "broadcast"); assert_eq!( Stream::Admin { - id: "9tb42br63g5apjcq".to_string() + user_id: "9tb42br63g5apjcq".to_string() } .to_string(), "adminStream:9tb42br63g5apjcq" From 574d3b3fe58f7c21c755958c8b671d229173bdea Mon Sep 17 00:00:00 2001 From: naskya Date: Mon, 22 Apr 2024 00:30:59 +0900 Subject: [PATCH 33/52] chore (backend-rs): in the current implementation we need to call to_string() anyway There's room for refactoring --- packages/backend-rs/src/service/add_note_to_antenna.rs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/packages/backend-rs/src/service/add_note_to_antenna.rs b/packages/backend-rs/src/service/add_note_to_antenna.rs index eefd242dfb..a92e8dc301 100644 --- a/packages/backend-rs/src/service/add_note_to_antenna.rs +++ b/packages/backend-rs/src/service/add_note_to_antenna.rs @@ -4,7 +4,7 @@ use crate::util::id::get_timestamp; use redis::{streams::StreamMaxlen, Commands}; #[crate::export] -pub fn add_note_to_antenna(antenna_id: &str, note_id: &str) -> Result<(), Error> { +pub fn add_note_to_antenna(antenna_id: String, note_id: &str) -> Result<(), Error> { redis_conn()?.xadd_maxlen( redis_key(format!("antennaTimeline:{}", antenna_id)), StreamMaxlen::Approx(200), @@ -12,11 +12,8 @@ pub fn add_note_to_antenna(antenna_id: &str, note_id: &str) -> Result<(), Error> &[("note", note_id)], )?; - let stream = Stream::Antenna { - antenna_id: antenna_id.to_string(), - }; publish_to_stream( - &stream, + &Stream::Antenna { antenna_id }, Some("note"), Some(format!("{{ \"id\": \"{}\" }}", note_id)), ) From 3039458c4c715e648a3cb25b52b10926975c1024 Mon Sep 17 00:00:00 2001 From: naskya Date: Mon, 22 Apr 2024 00:36:06 +0900 Subject: [PATCH 34/52] chore (backend-rs): config::server::CONFIG -> config::CONFIG --- packages/backend-rs/src/config/mod.rs | 2 ++ packages/backend-rs/src/database/postgresql.rs | 2 +- packages/backend-rs/src/database/redis.rs | 2 +- packages/backend-rs/src/misc/convert_host.rs | 2 +- packages/backend-rs/src/service/stream.rs | 2 +- 5 files changed, 6 insertions(+), 4 deletions(-) diff --git a/packages/backend-rs/src/config/mod.rs b/packages/backend-rs/src/config/mod.rs index b708f2b265..6155f15e54 100644 --- a/packages/backend-rs/src/config/mod.rs +++ b/packages/backend-rs/src/config/mod.rs @@ -1,2 +1,4 @@ +pub use server::CONFIG; + pub mod environment; pub mod server; diff --git a/packages/backend-rs/src/database/postgresql.rs b/packages/backend-rs/src/database/postgresql.rs index c365da84dc..ec0945fbe3 100644 --- a/packages/backend-rs/src/database/postgresql.rs +++ b/packages/backend-rs/src/database/postgresql.rs @@ -1,4 +1,4 @@ -use crate::config::server::CONFIG; +use crate::config::CONFIG; use sea_orm::{Database, DbConn, DbErr}; static DB_CONN: once_cell::sync::OnceCell = once_cell::sync::OnceCell::new(); diff --git a/packages/backend-rs/src/database/redis.rs b/packages/backend-rs/src/database/redis.rs index d722e2c00a..f8f6c712de 100644 --- a/packages/backend-rs/src/database/redis.rs +++ b/packages/backend-rs/src/database/redis.rs @@ -1,4 +1,4 @@ -use crate::config::server::CONFIG; +use crate::config::CONFIG; use redis::{Client, Connection, RedisError}; static REDIS_CLIENT: once_cell::sync::OnceCell = once_cell::sync::OnceCell::new(); diff --git a/packages/backend-rs/src/misc/convert_host.rs b/packages/backend-rs/src/misc/convert_host.rs index cff52aeb07..8f054488de 100644 --- a/packages/backend-rs/src/misc/convert_host.rs +++ b/packages/backend-rs/src/misc/convert_host.rs @@ -1,4 +1,4 @@ -use crate::config::server::CONFIG; +use crate::config::CONFIG; #[derive(thiserror::Error, Debug)] pub enum Error { diff --git a/packages/backend-rs/src/service/stream.rs b/packages/backend-rs/src/service/stream.rs index 511954ec81..3ef13961ce 100644 --- a/packages/backend-rs/src/service/stream.rs +++ b/packages/backend-rs/src/service/stream.rs @@ -1,4 +1,4 @@ -use crate::config::server::CONFIG; +use crate::config::CONFIG; use crate::database::redis_conn; use redis::{Commands, RedisError}; From 2a30b4a536201e0ae4e2d748c48d2ec7503401b0 Mon Sep 17 00:00:00 2001 From: naskya Date: Mon, 22 Apr 2024 01:47:56 +0900 Subject: [PATCH 35/52] Revert "refactor (backend): it turns out that sending the entire note object was redundant" This reverts commit 3b65ebcb3e26d58db78f86c92fac9c06f199f18f. --- packages/backend-rs/index.d.ts | 2 +- .../src/service/add_note_to_antenna.rs | 11 ++- packages/backend-rs/src/service/stream.rs | 2 + packages/backend/package.json | 1 + .../backend/src/prelude/undefined-to-null.ts | 76 +++++++++++++++++++ packages/backend/src/services/note/create.ts | 4 +- pnpm-lock.yaml | 8 ++ 7 files changed, 98 insertions(+), 6 deletions(-) create mode 100644 packages/backend/src/prelude/undefined-to-null.ts diff --git a/packages/backend-rs/index.d.ts b/packages/backend-rs/index.d.ts index 1e086c88ff..7fd93a3845 100644 --- a/packages/backend-rs/index.d.ts +++ b/packages/backend-rs/index.d.ts @@ -1103,7 +1103,7 @@ export interface Webhook { latestSentAt: Date | null latestStatus: number | null } -export function addNoteToAntenna(antennaId: string, noteId: string): void +export function addNoteToAntenna(antennaId: string, note: Note): void /** Initializes Cuid2 generator. Must be called before any [create_id]. */ export function initIdGenerator(length: number, fingerprint: string): void export function getTimestamp(id: string): number diff --git a/packages/backend-rs/src/service/add_note_to_antenna.rs b/packages/backend-rs/src/service/add_note_to_antenna.rs index a92e8dc301..199a5cde5f 100644 --- a/packages/backend-rs/src/service/add_note_to_antenna.rs +++ b/packages/backend-rs/src/service/add_note_to_antenna.rs @@ -1,20 +1,23 @@ use crate::database::{redis_conn, redis_key}; use crate::service::stream::{publish_to_stream, Error, Stream}; +use crate::model::entity::note; use crate::util::id::get_timestamp; use redis::{streams::StreamMaxlen, Commands}; +type Note = note::Model; + #[crate::export] -pub fn add_note_to_antenna(antenna_id: String, note_id: &str) -> Result<(), Error> { +pub fn add_note_to_antenna(antenna_id: String, note: &Note) -> Result<(), Error> { redis_conn()?.xadd_maxlen( redis_key(format!("antennaTimeline:{}", antenna_id)), StreamMaxlen::Approx(200), - format!("{}-*", get_timestamp(note_id)), - &[("note", note_id)], + format!("{}-*", get_timestamp(¬e.id)), + &[("note", ¬e.id)], )?; publish_to_stream( &Stream::Antenna { antenna_id }, Some("note"), - Some(format!("{{ \"id\": \"{}\" }}", note_id)), + Some(serde_json::to_string(note)?), ) } diff --git a/packages/backend-rs/src/service/stream.rs b/packages/backend-rs/src/service/stream.rs index 3ef13961ce..6c5e6be4dd 100644 --- a/packages/backend-rs/src/service/stream.rs +++ b/packages/backend-rs/src/service/stream.rs @@ -41,6 +41,8 @@ pub enum Stream { pub enum Error { #[error("Redis error: {0}")] RedisError(#[from] RedisError), + #[error("Json (de)serialization error: {0}")] + JsonError(#[from] serde_json::Error), #[error("Value error: {0}")] ValueError(String), } diff --git a/packages/backend/package.json b/packages/backend/package.json index 9289c2f7ea..0599a39d4b 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -178,6 +178,7 @@ "ts-loader": "9.5.1", "ts-node": "10.9.2", "tsconfig-paths": "4.2.0", + "type-fest": "4.15.0", "typescript": "5.4.5", "webpack": "^5.91.0", "ws": "8.16.0" diff --git a/packages/backend/src/prelude/undefined-to-null.ts b/packages/backend/src/prelude/undefined-to-null.ts new file mode 100644 index 0000000000..013be3cf9e --- /dev/null +++ b/packages/backend/src/prelude/undefined-to-null.ts @@ -0,0 +1,76 @@ +// https://gist.github.com/tkrotoff/a6baf96eb6b61b445a9142e5555511a0 +import type { Primitive } from "type-fest"; + +type NullToUndefined = T extends null + ? undefined + : T extends Primitive | Function | Date | RegExp + ? T + : T extends Array + ? Array> + : T extends Map + ? Map> + : T extends Set + ? Set> + : T extends object + ? { [K in keyof T]: NullToUndefined } + : unknown; + +type UndefinedToNull = T extends undefined + ? null + : T extends Primitive | Function | Date | RegExp + ? T + : T extends Array + ? Array> + : T extends Map + ? Map> + : T extends Set + ? Set> + : T extends object + ? { [K in keyof T]: UndefinedToNull } + : unknown; + +function _nullToUndefined(obj: T): NullToUndefined { + if (obj === null) { + return undefined as any; + } + + if (typeof obj === "object") { + if (obj instanceof Map) { + obj.forEach((value, key) => obj.set(key, _nullToUndefined(value))); + } else { + for (const key in obj) { + obj[key] = _nullToUndefined(obj[key]) as any; + } + } + } + + return obj as any; +} + +function _undefinedToNull(obj: T): UndefinedToNull { + if (obj === undefined) { + return null as any; + } + + if (typeof obj === "object") { + if (obj instanceof Map) { + obj.forEach((value, key) => obj.set(key, _undefinedToNull(value))); + } else { + for (const key in obj) { + obj[key] = _undefinedToNull(obj[key]) as any; + } + } + } + + return obj as any; +} + +/** + * Recursively converts all undefined values to null. + * + * @param obj object to convert + * @returns a copy of the object with all its undefined values converted to null + */ +export function undefinedToNull(obj: T) { + return _undefinedToNull(structuredClone(obj)); +} diff --git a/packages/backend/src/services/note/create.ts b/packages/backend/src/services/note/create.ts index 8fa2b4e23b..206f6a50ad 100644 --- a/packages/backend/src/services/note/create.ts +++ b/packages/backend/src/services/note/create.ts @@ -62,6 +62,7 @@ import { Mutex } from "redis-semaphore"; import { langmap } from "@/misc/langmap.js"; import Logger from "@/services/logger.js"; import { inspect } from "node:util"; +import { undefinedToNull } from "@/prelude/undefined-to-null.js"; const logger = new Logger("create-note"); @@ -398,7 +399,8 @@ export default async ( for (const antenna of await getAntennas()) { checkHitAntenna(antenna, note, user).then((hit) => { if (hit) { - addNoteToAntenna(antenna.id, note.id); + // TODO: do this more sanely + addNoteToAntenna(antenna.id, undefinedToNull(note) as Note); } }); } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b591ffe9c1..16a4ad6ad4 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -521,6 +521,9 @@ importers: tsconfig-paths: specifier: 4.2.0 version: 4.2.0 + type-fest: + specifier: 4.15.0 + version: 4.15.0 typescript: specifier: 5.4.5 version: 5.4.5 @@ -16632,6 +16635,11 @@ packages: engines: {node: '>=8'} dev: true + /type-fest@4.15.0: + resolution: {integrity: sha512-tB9lu0pQpX5KJq54g+oHOLumOx+pMep4RaM6liXh2PKmVRFF+/vAtUP0ZaJ0kOySfVNjF6doBWPHhBhISKdlIA==} + engines: {node: '>=16'} + dev: true + /type-is@1.6.18: resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} engines: {node: '>= 0.6'} From b4ae877462f2dca837260bded569b7fbd53b56a9 Mon Sep 17 00:00:00 2001 From: naskya Date: Mon, 22 Apr 2024 01:54:44 +0900 Subject: [PATCH 36/52] chore: format --- packages/backend-rs/src/service/add_note_to_antenna.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/backend-rs/src/service/add_note_to_antenna.rs b/packages/backend-rs/src/service/add_note_to_antenna.rs index 199a5cde5f..4f294cc881 100644 --- a/packages/backend-rs/src/service/add_note_to_antenna.rs +++ b/packages/backend-rs/src/service/add_note_to_antenna.rs @@ -1,6 +1,6 @@ use crate::database::{redis_conn, redis_key}; -use crate::service::stream::{publish_to_stream, Error, Stream}; use crate::model::entity::note; +use crate::service::stream::{publish_to_stream, Error, Stream}; use crate::util::id::get_timestamp; use redis::{streams::StreamMaxlen, Commands}; From 9fef36e80c73d4483b61df1281c1205e9544898f Mon Sep 17 00:00:00 2001 From: naskya Date: Mon, 22 Apr 2024 01:56:34 +0900 Subject: [PATCH 37/52] chore (backend): add comment --- packages/backend/src/services/stream.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/backend/src/services/stream.ts b/packages/backend/src/services/stream.ts index 6dff9602cd..7f1862b74d 100644 --- a/packages/backend/src/services/stream.ts +++ b/packages/backend/src/services/stream.ts @@ -134,6 +134,7 @@ class Publisher { ); }; + /* ported to backend-rs */ // public publishAntennaStream = ( // antennaId: Antenna["id"], // type: K, From 0c9dc92f07c47aa570291e246b187b147a4cf408 Mon Sep 17 00:00:00 2001 From: naskya Date: Mon, 22 Apr 2024 05:16:14 +0900 Subject: [PATCH 38/52] fix (backend-rs): use hostname for Redis key prefix and host for Redis streams I suspect this is a bug, but I keep this behavior for compatibility for now --- packages/backend-rs/src/config/server.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/backend-rs/src/config/server.rs b/packages/backend-rs/src/config/server.rs index b822d0d300..5a4ee481cd 100644 --- a/packages/backend-rs/src/config/server.rs +++ b/packages/backend-rs/src/config/server.rs @@ -320,7 +320,7 @@ fn load_config() -> Config { } else { server_config.redis.prefix.clone() } - .unwrap_or(host.clone()); + .unwrap_or(hostname.clone()); Config { url: server_config.url, From ebaefb9697f7705313ce477a1c6a7ed9ec71ad98 Mon Sep 17 00:00:00 2001 From: naskya Date: Mon, 22 Apr 2024 06:02:08 +0900 Subject: [PATCH 39/52] chore (minor, client): remove redundant attribute --- packages/client/src/pages/note-history.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/client/src/pages/note-history.vue b/packages/client/src/pages/note-history.vue index c3665d41bc..8c97448f72 100644 --- a/packages/client/src/pages/note-history.vue +++ b/packages/client/src/pages/note-history.vue @@ -5,7 +5,7 @@ /> -
+
Date: Mon, 22 Apr 2024 06:32:07 +0900 Subject: [PATCH 40/52] docs (minor): paraphrase a bit --- dev/docs/local-installation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/docs/local-installation.md b/dev/docs/local-installation.md index 132d86bd56..38d8a4a07d 100644 --- a/dev/docs/local-installation.md +++ b/dev/docs/local-installation.md @@ -42,7 +42,7 @@ cargo --version ### PostgreSQL and PGroonga -Firefish requires PostgreSQL v12 or later. While you can choose any versions between v12 and the latest version (v16.2 as of writing), we recommend that you install v12.x so as not to use new features inadvertently and introduce incompatibility issues. +Firefish requires PostgreSQL v12 or later. We recommend that you install v12.x for the same reason as Node.js. PostgreSQL install instructions can be found at [this page](https://www.postgresql.org/download/). From d98c564ead4117ecdcd2c9379675835566ecb9de Mon Sep 17 00:00:00 2001 From: naskya Date: Mon, 22 Apr 2024 06:39:20 +0900 Subject: [PATCH 41/52] docs: move the dependencies section to the top --- docs/install.md | 55 +++++++++++++++++++++++-------------------------- 1 file changed, 26 insertions(+), 29 deletions(-) diff --git a/docs/install.md b/docs/install.md index f030e87125..5f2d7859ae 100644 --- a/docs/install.md +++ b/docs/install.md @@ -1,6 +1,31 @@ # Install Firefish -This document shows an example procedure for installing Firefish on Debian 12. Note that there is much room for customizing the server setup; this document merely demonstrates a simple installation. +Firefish depends on the following software. + +## Runtime dependencies + +- At least [NodeJS](https://nodejs.org/en/) v18.17.0 (v20/v21 recommended) +- At least [PostgreSQL](https://www.postgresql.org/) v12 (v16 recommended) with [PGroonga](https://pgroonga.github.io/) extension +- At least [Redis](https://redis.io/) v7 +- Web Proxy (one of the following) + - Caddy (recommended) + - Nginx (recommended) + - Apache +- [FFmpeg](https://ffmpeg.org/) for video transcoding (**optional**) +- Caching server (**optional**, one of the following) + - [DragonflyDB](https://www.dragonflydb.io/) + - [KeyDB](https://keydb.dev/) + - Another [Redis](https://redis.io/) server + +## Build dependencies + +- At least [Rust](https://www.rust-lang.org/) v1.74 +- C/C++ compiler & build tools + - `build-essential` on Debian/Ubuntu Linux + - `base-devel` on Arch Linux +- [Python 3](https://www.python.org/) + +This document shows an example procedure for installing these dependencies and Firefish on Debian 12. Note that there is much room for customizing the server setup; this document merely demonstrates a simple installation. If you want to use the pre-built container image, please refer to [`install-container.md`](./install-container.md). @@ -317,31 +342,3 @@ cd ~/firefish - Run `psql -d firefish` (or whatever the database name is) - Run `UPDATE "user" SET "isAdmin" = true WHERE id='999999';` (replace `999999` with the copied ID) - Restart your Firefish server - -## Dependencies - -**We only recommend that you use components that are still within the upstream support cycle for better performance and security, and it is recommended that new sites meet the recommended dependency version requirements.** - -- At least [NodeJS](https://nodejs.org/en/) v18.17.0 (v20/v21 recommended) -- At least [PostgreSQL](https://www.postgresql.org/) v12 (v16 recommended) with [PGroonga](https://pgroonga.github.io/) extension -- At least [Redis](https://redis.io/) v7 -- Web Proxy (one of the following) - - Caddy (recommended for new users) - - Nginx (recommended) - - Apache - -### Optional dependencies - -- [FFmpeg](https://ffmpeg.org/) for video transcoding -- Caching server (one of the following) - - [DragonflyDB](https://www.dragonflydb.io/) (recommended) - - [KeyDB](https://keydb.dev/) - - Another [Redis](https://redis.io/) server - -### Build dependencies - -- At least [Rust](https://www.rust-lang.org/) v1.74 -- C/C++ compiler & build tools - - `build-essential` on Debian/Ubuntu Linux - - `base-devel` on Arch Linux -- [Python 3](https://www.python.org/) From fbdc0681151e8eee959b3d50b842a19ee857683c Mon Sep 17 00:00:00 2001 From: naskya Date: Mon, 22 Apr 2024 07:09:54 +0900 Subject: [PATCH 42/52] locale: update en-US.yml --- locales/en-US.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/locales/en-US.yml b/locales/en-US.yml index 5d0e8ae2f8..a70eb2406f 100644 --- a/locales/en-US.yml +++ b/locales/en-US.yml @@ -1227,8 +1227,8 @@ publishTimelinesDescription: "If enabled, the Local and Global timelines will be on {url} even when signed out." noAltTextWarning: "Some attached file(s) have no description. Did you forget to write?" showNoAltTextWarning: "Show a warning if you attempt to post files without a description" -showAddFileDescriptionAtFirstPost: "Show add description page automatically when - first try to post a post attachment without a description" +showAddFileDescriptionAtFirstPost: "Automatically open a form to write a description when you + attempt to post files without a description" _emojiModPerm: unauthorized: "None" From 9a4988eaad2b305295308462f9424beb1579b72f Mon Sep 17 00:00:00 2001 From: naskya Date: Mon, 22 Apr 2024 07:14:56 +0900 Subject: [PATCH 43/52] chore (client): fix type errors --- packages/client/src/components/MkPostForm.vue | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/client/src/components/MkPostForm.vue b/packages/client/src/components/MkPostForm.vue index 2d36408d9d..e7ec45a37b 100644 --- a/packages/client/src/components/MkPostForm.vue +++ b/packages/client/src/components/MkPostForm.vue @@ -1046,14 +1046,14 @@ function openFileDescriptionWindow(file: entities.DriveFile) { resolve(false); return; } - const comment = result.result.length === 0 ? null : result.result; + const comment = result.result?.length === 0 ? null : result.result; os.api("drive/files/update", { fileId: file.id, comment, }) .then(() => { resolve(true); - file.comment = comment; + file.comment = comment ?? null; }) .catch((err: unknown) => { reject(err); From 9ced0d96adca51b68dc574b396d9bd659cc391c1 Mon Sep 17 00:00:00 2001 From: naskya Date: Mon, 22 Apr 2024 07:20:07 +0900 Subject: [PATCH 44/52] chore (client): don't make a new post as soon as you add descriptions --- packages/client/src/components/MkPostForm.vue | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/packages/client/src/components/MkPostForm.vue b/packages/client/src/components/MkPostForm.vue index e7ec45a37b..5850fdf498 100644 --- a/packages/client/src/components/MkPostForm.vue +++ b/packages/client/src/components/MkPostForm.vue @@ -1113,12 +1113,7 @@ async function post() { } } isFirstPostAttempt = false; - // Continue if all files have alt-text added. - if ( - files.value.some((f) => f.comment == null || f.comment.length === 0) - ) { - return; - } + return; } } @@ -1144,12 +1139,7 @@ async function post() { } } } - // Continue if all files have alt-text added. - if ( - files.value.some((f) => f.comment == null || f.comment.length === 0) - ) { - return; - } + return; } } From 0c1e7cdd72a4eda2045d117a274d4c28e6b1484f Mon Sep 17 00:00:00 2001 From: naskya Date: Mon, 22 Apr 2024 08:31:28 +0900 Subject: [PATCH 45/52] refactor (backend): port should-block-instance to backend-rs --- packages/backend-rs/index.d.ts | 17 ++++++- packages/backend-rs/index.js | 5 +- .../backend-rs/src/misc/check_server_block.rs | 49 +++++++++++++++++++ packages/backend-rs/src/misc/mod.rs | 1 + .../backend/src/misc/should-block-instance.ts | 38 -------------- .../backend/src/misc/skipped-instances.ts | 9 ++-- .../src/models/repositories/instance.ts | 9 ++-- .../backend/src/queue/processors/inbox.ts | 10 ++-- .../src/remote/activitypub/check-fetch.ts | 13 ++--- .../activitypub/kernel/announce/note.ts | 4 +- .../src/remote/activitypub/kernel/index.ts | 5 +- .../src/remote/activitypub/models/note.ts | 7 ++- .../src/remote/activitypub/resolver.ts | 24 +++++---- .../src/server/api/endpoints/ap/show.ts | 5 +- .../src/services/create-notification.ts | 7 ++- .../backend/src/services/following/create.ts | 5 +- packages/backend/src/services/note/create.ts | 11 +++-- 17 files changed, 117 insertions(+), 102 deletions(-) create mode 100644 packages/backend-rs/src/misc/check_server_block.rs delete mode 100644 packages/backend/src/misc/should-block-instance.ts diff --git a/packages/backend-rs/index.d.ts b/packages/backend-rs/index.d.ts index 50489a846d..69de833dcc 100644 --- a/packages/backend-rs/index.d.ts +++ b/packages/backend-rs/index.d.ts @@ -193,6 +193,21 @@ export interface Acct { } export function stringToAcct(acct: string): Acct export function acctToString(acct: Acct): string +/** + * @param host punycoded instance host + * @returns whether the given host should be blocked +*/ +export function isBlockedServer(host: string): Promise +/** + * @param host punycoded instance host + * @returns whether the given host should be limited +*/ +export function isSilencedServer(host: string): Promise +/** + * @param host punycoded instance host + * @returns whether the given host is allowlisted (this is always true if private mode is disabled) +*/ +export function isAllowedServer(host: string): Promise /** TODO: handle name collisions better */ export interface NoteLikeForCheckWordMute { fileIds: Array @@ -557,7 +572,6 @@ export interface Meta { recaptchaSecretKey: string | null localDriveCapacityMb: number remoteDriveCapacityMb: number - antennaLimit: number summalyProxy: string | null enableEmail: boolean email: string | null @@ -620,6 +634,7 @@ export interface Meta { donationLink: string | null moreUrls: Json markLocalFilesNsfwByDefault: boolean + antennaLimit: number } export interface Migrations { id: number diff --git a/packages/backend-rs/index.js b/packages/backend-rs/index.js index 9a5e3d1a92..b4d86dccdf 100644 --- a/packages/backend-rs/index.js +++ b/packages/backend-rs/index.js @@ -310,12 +310,15 @@ if (!nativeBinding) { throw new Error(`Failed to load native binding`) } -const { loadEnv, loadConfig, stringToAcct, acctToString, checkWordMute, getFullApAccount, isSelfHost, isSameOrigin, extractHost, toPuny, isUnicodeEmoji, sqlLikeEscape, safeForSql, formatMilliseconds, getNoteSummary, toMastodonId, fromMastodonId, fetchMeta, metaToPugArgs, nyaify, hashPassword, verifyPassword, isOldPasswordAlgorithm, decodeReaction, countReactions, toDbReaction, AntennaSrcEnum, DriveFileUsageHintEnum, MutedNoteReasonEnum, NoteVisibilityEnum, NotificationTypeEnum, PageVisibilityEnum, PollNotevisibilityEnum, RelayStatusEnum, UserEmojimodpermEnum, UserProfileFfvisibilityEnum, UserProfileMutingnotificationtypesEnum, addNoteToAntenna, initIdGenerator, getTimestamp, genId, secureRndstr } = nativeBinding +const { loadEnv, loadConfig, stringToAcct, acctToString, isBlockedServer, isSilencedServer, isAllowedServer, checkWordMute, getFullApAccount, isSelfHost, isSameOrigin, extractHost, toPuny, isUnicodeEmoji, sqlLikeEscape, safeForSql, formatMilliseconds, getNoteSummary, toMastodonId, fromMastodonId, fetchMeta, metaToPugArgs, nyaify, hashPassword, verifyPassword, isOldPasswordAlgorithm, decodeReaction, countReactions, toDbReaction, AntennaSrcEnum, DriveFileUsageHintEnum, MutedNoteReasonEnum, NoteVisibilityEnum, NotificationTypeEnum, PageVisibilityEnum, PollNotevisibilityEnum, RelayStatusEnum, UserEmojimodpermEnum, UserProfileFfvisibilityEnum, UserProfileMutingnotificationtypesEnum, addNoteToAntenna, initIdGenerator, getTimestamp, genId, secureRndstr } = nativeBinding module.exports.loadEnv = loadEnv module.exports.loadConfig = loadConfig module.exports.stringToAcct = stringToAcct module.exports.acctToString = acctToString +module.exports.isBlockedServer = isBlockedServer +module.exports.isSilencedServer = isSilencedServer +module.exports.isAllowedServer = isAllowedServer module.exports.checkWordMute = checkWordMute module.exports.getFullApAccount = getFullApAccount module.exports.isSelfHost = isSelfHost diff --git a/packages/backend-rs/src/misc/check_server_block.rs b/packages/backend-rs/src/misc/check_server_block.rs new file mode 100644 index 0000000000..b5e262aa87 --- /dev/null +++ b/packages/backend-rs/src/misc/check_server_block.rs @@ -0,0 +1,49 @@ +use crate::misc::meta::fetch_meta; +use sea_orm::DbErr; + +/** + * @param host punycoded instance host + * @returns whether the given host should be blocked + */ +#[crate::export] +pub async fn is_blocked_server(host: &str) -> Result { + Ok(fetch_meta(true) + .await? + .blocked_hosts + .iter() + .any(|blocked_host| { + host == blocked_host || host.ends_with(format!(".{}", blocked_host).as_str()) + })) +} + +/** + * @param host punycoded instance host + * @returns whether the given host should be limited + */ +#[crate::export] +pub async fn is_silenced_server(host: &str) -> Result { + Ok(fetch_meta(true) + .await? + .silenced_hosts + .iter() + .any(|silenced_host| { + host == silenced_host || host.ends_with(format!(".{}", silenced_host).as_str()) + })) +} + +/** + * @param host punycoded instance host + * @returns whether the given host is allowlisted (this is always true if private mode is disabled) + */ +#[crate::export] +pub async fn is_allowed_server(host: &str) -> Result { + let meta = fetch_meta(true).await?; + + if !meta.private_mode.unwrap_or(false) { + return Ok(true); + } + if let Some(allowed_hosts) = meta.allowed_hosts { + return Ok(allowed_hosts.contains(&host.to_string())); + } + Ok(false) +} diff --git a/packages/backend-rs/src/misc/mod.rs b/packages/backend-rs/src/misc/mod.rs index a9d7074dbf..56aae3b552 100644 --- a/packages/backend-rs/src/misc/mod.rs +++ b/packages/backend-rs/src/misc/mod.rs @@ -1,4 +1,5 @@ pub mod acct; +pub mod check_server_block; pub mod check_word_mute; pub mod convert_host; pub mod emoji; diff --git a/packages/backend/src/misc/should-block-instance.ts b/packages/backend/src/misc/should-block-instance.ts deleted file mode 100644 index 465be41f2a..0000000000 --- a/packages/backend/src/misc/should-block-instance.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { fetchMeta } from "backend-rs"; -import type { Instance } from "@/models/entities/instance.js"; -import type { Meta } from "@/models/entities/meta.js"; - -/** - * Returns whether a specific host (punycoded) should be blocked. - * - * @param host punycoded instance host - * @param meta a resolved Meta table - * @returns whether the given host should be blocked - */ -export async function shouldBlockInstance( - host: Instance["host"], - meta?: Meta, -): Promise { - const { blockedHosts } = meta ?? (await fetchMeta(true)); - return blockedHosts.some( - (blockedHost) => host === blockedHost || host.endsWith(`.${blockedHost}`), - ); -} - -/** - * Returns whether a specific host (punycoded) should be limited. - * - * @param host punycoded instance host - * @param meta a resolved Meta table - * @returns whether the given host should be limited - */ -export async function shouldSilenceInstance( - host: Instance["host"], - meta?: Meta, -): Promise { - const { silencedHosts } = meta ?? (await fetchMeta(true)); - return silencedHosts.some( - (silencedHost) => - host === silencedHost || host.endsWith(`.${silencedHost}`), - ); -} diff --git a/packages/backend/src/misc/skipped-instances.ts b/packages/backend/src/misc/skipped-instances.ts index 14b26a3032..0c87a524f6 100644 --- a/packages/backend/src/misc/skipped-instances.ts +++ b/packages/backend/src/misc/skipped-instances.ts @@ -1,9 +1,8 @@ import { Brackets } from "typeorm"; -import { fetchMeta } from "backend-rs"; +import { isBlockedServer } from "backend-rs"; import { Instances } from "@/models/index.js"; import type { Instance } from "@/models/entities/instance.js"; import { DAY } from "@/const.js"; -import { shouldBlockInstance } from "./should-block-instance.js"; // Threshold from last contact after which an instance will be considered // "dead" and should no longer get activities delivered to it. @@ -19,16 +18,16 @@ export async function skippedInstances( hosts: Instance["host"][], ): Promise { // first check for blocked instances since that info may already be in memory - const meta = await fetchMeta(true); const shouldSkip = await Promise.all( - hosts.map((host) => shouldBlockInstance(host, meta)), + hosts.map((host) => isBlockedServer(host)), ); const skipped = hosts.filter((_, i) => shouldSkip[i]); // if possible return early and skip accessing the database if (skipped.length === hosts.length) return hosts; - const deadTime = new Date(Date.now() - deadThreshold); + // FIXME: Use or remove this + // const deadTime = new Date(Date.now() - deadThreshold); return skipped.concat( await Instances.createQueryBuilder("instance") diff --git a/packages/backend/src/models/repositories/instance.ts b/packages/backend/src/models/repositories/instance.ts index 667ec948de..8f479e8ea4 100644 --- a/packages/backend/src/models/repositories/instance.ts +++ b/packages/backend/src/models/repositories/instance.ts @@ -1,10 +1,7 @@ import { db } from "@/db/postgre.js"; import { Instance } from "@/models/entities/instance.js"; import type { Packed } from "@/misc/schema.js"; -import { - shouldBlockInstance, - shouldSilenceInstance, -} from "@/misc/should-block-instance.js"; +import { isBlockedServer, isSilencedServer } from "backend-rs"; export const InstanceRepository = db.getRepository(Instance).extend({ async pack(instance: Instance): Promise> { @@ -22,8 +19,8 @@ export const InstanceRepository = db.getRepository(Instance).extend({ lastCommunicatedAt: instance.lastCommunicatedAt.toISOString(), isNotResponding: instance.isNotResponding, isSuspended: instance.isSuspended, - isBlocked: await shouldBlockInstance(instance.host), - isSilenced: await shouldSilenceInstance(instance.host), + isBlocked: await isBlockedServer(instance.host), + isSilenced: await isSilencedServer(instance.host), softwareName: instance.softwareName, softwareVersion: instance.softwareVersion, openRegistrations: instance.openRegistrations, diff --git a/packages/backend/src/queue/processors/inbox.ts b/packages/backend/src/queue/processors/inbox.ts index 0ea72306b6..898c68cff3 100644 --- a/packages/backend/src/queue/processors/inbox.ts +++ b/packages/backend/src/queue/processors/inbox.ts @@ -5,7 +5,7 @@ import perform from "@/remote/activitypub/perform.js"; import Logger from "@/services/logger.js"; import { registerOrFetchInstanceDoc } from "@/services/register-or-fetch-instance-doc.js"; import { Instances } from "@/models/index.js"; -import { fetchMeta } from "backend-rs"; +import { isAllowedServer, isBlockedServer } from "backend-rs"; import { toPuny, extractHost } from "backend-rs"; import { getApId } from "@/remote/activitypub/type.js"; import { fetchInstanceMetadata } from "@/services/fetch-instance-metadata.js"; @@ -16,7 +16,6 @@ import { LdSignature } from "@/remote/activitypub/misc/ld-signature.js"; import { StatusError } from "@/misc/fetch.js"; import type { CacheableRemoteUser } from "@/models/entities/user.js"; import type { UserPublickey } from "@/models/entities/user-publickey.js"; -import { shouldBlockInstance } from "@/misc/should-block-instance.js"; import { verifySignature } from "@/remote/activitypub/check-fetch.js"; import { inspect } from "node:util"; @@ -41,13 +40,12 @@ export default async (job: Bull.Job): Promise => { const host = toPuny(new URL(signature.keyId).hostname); // interrupt if blocked - const meta = await fetchMeta(true); - if (await shouldBlockInstance(host, meta)) { + if (await isBlockedServer(host)) { return `Blocked request: ${host}`; } // only whitelisted instances in private mode - if (meta.privateMode && !meta.allowedHosts.includes(host)) { + if (!isAllowedServer(host)) { return `Blocked request: ${host}`; } @@ -158,7 +156,7 @@ export default async (job: Bull.Job): Promise => { // ブロックしてたら中断 const ldHost = extractHost(authUser.user.uri); - if (await shouldBlockInstance(ldHost, meta)) { + if (await isBlockedServer(ldHost)) { return `Blocked request: ${ldHost}`; } } else { diff --git a/packages/backend/src/remote/activitypub/check-fetch.ts b/packages/backend/src/remote/activitypub/check-fetch.ts index 04d989064f..726d996ad8 100644 --- a/packages/backend/src/remote/activitypub/check-fetch.ts +++ b/packages/backend/src/remote/activitypub/check-fetch.ts @@ -1,11 +1,10 @@ import { URL } from "url"; -import httpSignature, { IParsedSignature } from "@peertube/http-signature"; +import httpSignature, { type IParsedSignature } from "@peertube/http-signature"; import { config } from "@/config.js"; -import { fetchMeta } from "backend-rs"; +import { fetchMeta, isAllowedServer, isBlockedServer } from "backend-rs"; import { toPuny } from "backend-rs"; import DbResolver from "@/remote/activitypub/db-resolver.js"; import { getApId } from "@/remote/activitypub/type.js"; -import { shouldBlockInstance } from "@/misc/should-block-instance.js"; import type { IncomingMessage } from "http"; import type { CacheableRemoteUser } from "@/models/entities/user.js"; import type { UserPublickey } from "@/models/entities/user-publickey.js"; @@ -44,15 +43,11 @@ export async function checkFetch(req: IncomingMessage): Promise { const keyId = new URL(signature.keyId); const host = toPuny(keyId.hostname); - if (await shouldBlockInstance(host, meta)) { + if (await isBlockedServer(host)) { return 403; } - if ( - meta.privateMode && - host !== config.host && - !meta.allowedHosts.includes(host) - ) { + if (host !== config.host && !isAllowedServer(host)) { return 403; } diff --git a/packages/backend/src/remote/activitypub/kernel/announce/note.ts b/packages/backend/src/remote/activitypub/kernel/announce/note.ts index ae16c77dbd..41d1319dbd 100644 --- a/packages/backend/src/remote/activitypub/kernel/announce/note.ts +++ b/packages/backend/src/remote/activitypub/kernel/announce/note.ts @@ -10,7 +10,7 @@ import { getApLock } from "@/misc/app-lock.js"; import { parseAudience } from "../../audience.js"; import { StatusError } from "@/misc/fetch.js"; import { Notes } from "@/models/index.js"; -import { shouldBlockInstance } from "@/misc/should-block-instance.js"; +import { isBlockedServer } from "backend-rs"; import { inspect } from "node:util"; const logger = apLogger; @@ -31,7 +31,7 @@ export default async function ( } // Interrupt if you block the announcement destination - if (await shouldBlockInstance(extractHost(uri))) return; + if (await isBlockedServer(extractHost(uri))) return; const lock = await getApLock(uri); diff --git a/packages/backend/src/remote/activitypub/kernel/index.ts b/packages/backend/src/remote/activitypub/kernel/index.ts index f64a0e2ee8..b556550c5f 100644 --- a/packages/backend/src/remote/activitypub/kernel/index.ts +++ b/packages/backend/src/remote/activitypub/kernel/index.ts @@ -38,8 +38,7 @@ import block from "./block/index.js"; import flag from "./flag/index.js"; import move from "./move/index.js"; import type { IObject, IActivity } from "../type.js"; -import { extractHost } from "backend-rs"; -import { shouldBlockInstance } from "@/misc/should-block-instance.js"; +import { extractHost, isBlockedServer } from "backend-rs"; import { inspect } from "node:util"; export async function performActivity( @@ -71,7 +70,7 @@ async function performOneActivity( if (typeof activity.id !== "undefined") { const host = extractHost(getApId(activity)); - if (await shouldBlockInstance(host)) return; + if (await isBlockedServer(host)) return; } if (isCreate(activity)) { diff --git a/packages/backend/src/remote/activitypub/models/note.ts b/packages/backend/src/remote/activitypub/models/note.ts index b2fd67288c..4b685747ba 100644 --- a/packages/backend/src/remote/activitypub/models/note.ts +++ b/packages/backend/src/remote/activitypub/models/note.ts @@ -12,7 +12,7 @@ import { unique, toArray, toSingle } from "@/prelude/array.js"; import { extractPollFromQuestion } from "./question.js"; import vote from "@/services/note/polls/vote.js"; import { apLogger } from "../logger.js"; -import { DriveFile } from "@/models/entities/drive-file.js"; +import type { DriveFile } from "@/models/entities/drive-file.js"; import { extractHost, isSameOrigin, toPuny } from "backend-rs"; import { Emojis, @@ -33,14 +33,13 @@ import { getApType, } from "../type.js"; import type { Emoji } from "@/models/entities/emoji.js"; -import { genId } from "backend-rs"; +import { genId, isBlockedServer } from "backend-rs"; import { getApLock } from "@/misc/app-lock.js"; import { createMessage } from "@/services/messages/create.js"; import { parseAudience } from "../audience.js"; import { extractApMentions } from "./mention.js"; import DbResolver from "../db-resolver.js"; import { StatusError } from "@/misc/fetch.js"; -import { shouldBlockInstance } from "@/misc/should-block-instance.js"; import { publishNoteStream } from "@/services/stream.js"; import { extractHashtags } from "@/misc/extract-hashtags.js"; import { UserProfiles } from "@/models/index.js"; @@ -421,7 +420,7 @@ export async function resolveNote( if (uri == null) throw new Error("missing uri"); // Abort if origin host is blocked - if (await shouldBlockInstance(extractHost(uri))) + if (await isBlockedServer(extractHost(uri))) throw new StatusError( "host blocked", 451, diff --git a/packages/backend/src/remote/activitypub/resolver.ts b/packages/backend/src/remote/activitypub/resolver.ts index 65e6f1d635..51419deecf 100644 --- a/packages/backend/src/remote/activitypub/resolver.ts +++ b/packages/backend/src/remote/activitypub/resolver.ts @@ -1,8 +1,12 @@ import { config } from "@/config.js"; import type { ILocalUser } from "@/models/entities/user.js"; import { getInstanceActor } from "@/services/instance-actor.js"; -import { fetchMeta } from "backend-rs"; -import { extractHost, isSelfHost } from "backend-rs"; +import { + extractHost, + isAllowedServer, + isBlockedServer, + isSelfHost, +} from "backend-rs"; import { apGet } from "./request.js"; import type { IObject, ICollection, IOrderedCollection } from "./type.js"; import { isCollectionOrOrderedCollection, getApId } from "./type.js"; @@ -21,7 +25,6 @@ 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 { shouldBlockInstance } from "@/misc/should-block-instance.js"; import { apLogger } from "@/remote/activitypub/logger.js"; import { IsNull, Not } from "typeorm"; @@ -69,7 +72,7 @@ export default class Resolver { apLogger.debug("Object to resolve is not a string"); if (typeof value.id !== "undefined") { const host = extractHost(getApId(value)); - if (await shouldBlockInstance(host)) { + if (await isBlockedServer(host)) { throw new Error("instance is blocked"); } } @@ -100,17 +103,12 @@ export default class Resolver { return await this.resolveLocal(value); } - const meta = await fetchMeta(true); - if (await shouldBlockInstance(host, meta)) { - throw new Error("Instance is blocked"); + if (await isBlockedServer(host)) { + throw new Error("This instance is blocked"); } - if ( - meta.privateMode && - config.host !== host && - !meta.allowedHosts.includes(host) - ) { - throw new Error("Instance is not allowed"); + if (config.host !== host && !isAllowedServer(host)) { + throw new Error("This instance is not allowed"); } if (!this.user) { diff --git a/packages/backend/src/server/api/endpoints/ap/show.ts b/packages/backend/src/server/api/endpoints/ap/show.ts index f1d42d8d93..56307311b2 100644 --- a/packages/backend/src/server/api/endpoints/ap/show.ts +++ b/packages/backend/src/server/api/endpoints/ap/show.ts @@ -4,14 +4,13 @@ import { createNote } from "@/remote/activitypub/models/note.js"; import DbResolver from "@/remote/activitypub/db-resolver.js"; import Resolver from "@/remote/activitypub/resolver.js"; import { ApiError } from "@/server/api/error.js"; -import { extractHost } from "backend-rs"; +import { extractHost, isBlockedServer } from "backend-rs"; import { Users, Notes } from "@/models/index.js"; import type { Note } from "@/models/entities/note.js"; import type { CacheableLocalUser, User } from "@/models/entities/user.js"; import { isActor, isPost, getApId } from "@/remote/activitypub/type.js"; import type { SchemaType } from "@/misc/schema.js"; import { MINUTE } from "@/const.js"; -import { shouldBlockInstance } from "@/misc/should-block-instance.js"; import { updateQuestion } from "@/remote/activitypub/models/question.js"; import { populatePoll } from "@/models/repositories/note.js"; import { redisClient } from "@/db/redis.js"; @@ -101,7 +100,7 @@ async function fetchAny( me: CacheableLocalUser | null | undefined, ): Promise | null> { // Wait if blocked. - if (await shouldBlockInstance(extractHost(uri))) return null; + if (await isBlockedServer(extractHost(uri))) return null; const dbResolver = new DbResolver(); diff --git a/packages/backend/src/services/create-notification.ts b/packages/backend/src/services/create-notification.ts index a108d4f5de..93fec126d3 100644 --- a/packages/backend/src/services/create-notification.ts +++ b/packages/backend/src/services/create-notification.ts @@ -8,11 +8,10 @@ import { Users, Followings, } from "@/models/index.js"; -import { genId } from "backend-rs"; +import { genId, isSilencedServer } from "backend-rs"; import type { User } from "@/models/entities/user.js"; import type { Notification } from "@/models/entities/notification.js"; import { sendEmailNotification } from "./send-email-notification.js"; -import { shouldSilenceInstance } from "@/misc/should-block-instance.js"; export async function createNotification( notifieeId: User["id"], @@ -35,8 +34,8 @@ export async function createNotification( if ( (notifier.isSilenced || (Users.isRemoteUser(notifier) && - (await shouldSilenceInstance(notifier.host)))) && - !(await Followings.exist({ + (await isSilencedServer(notifier.host)))) && + !(await Followings.exists({ where: { followerId: notifieeId, followeeId: data.notifierId }, })) ) diff --git a/packages/backend/src/services/following/create.ts b/packages/backend/src/services/following/create.ts index 7387346d1a..49852ee9ef 100644 --- a/packages/backend/src/services/following/create.ts +++ b/packages/backend/src/services/following/create.ts @@ -17,13 +17,12 @@ import { Instances, UserProfiles, } from "@/models/index.js"; -import { genId } from "backend-rs"; +import { genId, isSilencedServer } from "backend-rs"; import { createNotification } from "@/services/create-notification.js"; import { isDuplicateKeyValueError } from "@/misc/is-duplicate-key-value-error.js"; import type { Packed } from "@/misc/schema.js"; import { getActiveWebhooks } from "@/misc/webhook-cache.js"; import { webhookDeliver } from "@/queue/index.js"; -import { shouldSilenceInstance } from "@/misc/should-block-instance.js"; const logger = new Logger("following/create"); @@ -231,7 +230,7 @@ export default async function ( (Users.isLocalUser(follower) && Users.isRemoteUser(followee)) || (Users.isRemoteUser(follower) && Users.isLocalUser(followee) && - (await shouldSilenceInstance(follower.host))) + (await isSilencedServer(follower.host))) ) { let autoAccept = false; diff --git a/packages/backend/src/services/note/create.ts b/packages/backend/src/services/note/create.ts index 206f6a50ad..2135847a17 100644 --- a/packages/backend/src/services/note/create.ts +++ b/packages/backend/src/services/note/create.ts @@ -37,14 +37,18 @@ import type { DriveFile } from "@/models/entities/drive-file.js"; import type { App } from "@/models/entities/app.js"; import { Not, In } from "typeorm"; import type { User, ILocalUser, IRemoteUser } from "@/models/entities/user.js"; -import { genId } from "backend-rs"; import { activeUsersChart } from "@/services/chart/index.js"; import type { IPoll } from "@/models/entities/poll.js"; import { Poll } from "@/models/entities/poll.js"; import { createNotification } from "@/services/create-notification.js"; import { isDuplicateKeyValueError } from "@/misc/is-duplicate-key-value-error.js"; import { checkHitAntenna } from "@/misc/check-hit-antenna.js"; -import { addNoteToAntenna, checkWordMute } from "backend-rs"; +import { + addNoteToAntenna, + checkWordMute, + genId, + isSilencedServer, +} from "backend-rs"; import { countSameRenotes } from "@/misc/count-same-renotes.js"; import { deliverToRelays, getCachedRelays } from "../relay.js"; import type { Channel } from "@/models/entities/channel.js"; @@ -56,7 +60,6 @@ import { Cache } from "@/misc/cache.js"; import type { UserProfile } from "@/models/entities/user-profile.js"; import { db } from "@/db/postgre.js"; import { getActiveWebhooks } from "@/misc/webhook-cache.js"; -import { shouldSilenceInstance } from "@/misc/should-block-instance.js"; import { redisClient } from "@/db/redis.js"; import { Mutex } from "redis-semaphore"; import { langmap } from "@/misc/langmap.js"; @@ -225,7 +228,7 @@ export default async ( if ( data.visibility === "public" && Users.isRemoteUser(user) && - (await shouldSilenceInstance(user.host)) + (await isSilencedServer(user.host)) ) { data.visibility = "home"; } From 9acd130a22bb4eb0eaf5cde44e1c6b4adfc48d7f Mon Sep 17 00:00:00 2001 From: naskya Date: Mon, 22 Apr 2024 08:57:00 +0900 Subject: [PATCH 46/52] chore (backend): update meta cache every 5 mins --- packages/backend/src/boot/master.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/backend/src/boot/master.ts b/packages/backend/src/boot/master.ts index 090a84f6ea..f254aaea17 100644 --- a/packages/backend/src/boot/master.ts +++ b/packages/backend/src/boot/master.ts @@ -9,6 +9,7 @@ import semver from "semver"; import Logger from "@/services/logger.js"; import type { Config } from "backend-rs"; +import { fetchMeta } from "backend-rs"; import { config, envOption } from "@/config.js"; import { showMachineInfo } from "@/misc/show-machine-info.js"; import { db, initDb } from "@/db/postgre.js"; @@ -123,6 +124,9 @@ export async function masterMain() { import("../daemons/queue-stats.js").then((x) => x.default()); import("../daemons/janitor.js").then((x) => x.default()); } + + // Update meta cache every 5 minitues + setInterval(() => fetchMeta(false), 1000 * 60 * 5); } function showEnvironment(): void { From c5a344c2a035bc06ee6637491f3a11747a5958b4 Mon Sep 17 00:00:00 2001 From: Lhcfl Date: Mon, 22 Apr 2024 10:32:41 +0800 Subject: [PATCH 47/52] refactor: make isSignedIn a function --- .../client/src/components/MkFollowButton.vue | 2 +- packages/client/src/components/MkMention.vue | 2 +- packages/client/src/components/MkNote.vue | 4 ++-- packages/client/src/components/MkNoteSub.vue | 2 +- .../components/MkPushNotificationAllowButton.vue | 8 ++++---- .../components/MkReactionsViewer.reaction.vue | 8 +++++--- .../client/src/components/MkReactionsViewer.vue | 2 +- .../client/src/components/MkRenoteButton.vue | 2 +- packages/client/src/components/MkTimeline.vue | 4 ++-- packages/client/src/components/MkUserInfo.vue | 4 ++-- packages/client/src/init.ts | 4 ++-- packages/client/src/me.ts | 2 +- packages/client/src/navbar.ts | 14 +++++++------- packages/client/src/pages/announcements.vue | 6 +++--- packages/client/src/pages/auth.vue | 8 ++++---- packages/client/src/pages/clip.vue | 2 +- packages/client/src/pages/explore.users.vue | 10 +++++----- packages/client/src/pages/gallery/post.vue | 4 ++-- packages/client/src/pages/page.vue | 4 ++-- packages/client/src/pages/settings/drive.vue | 2 +- .../src/pages/settings/preferences-backups.vue | 4 ++-- packages/client/src/pages/timeline.vue | 16 ++++++++-------- packages/client/src/pages/user/home.vue | 6 +++--- packages/client/src/pages/user/index.vue | 2 +- packages/client/src/pizzax.ts | 14 +++++++------- packages/client/src/scripts/get-note-menu.ts | 2 +- packages/client/src/scripts/get-user-menu.ts | 4 ++-- packages/client/src/scripts/please-login.ts | 4 ++-- packages/client/src/scripts/use-note-capture.ts | 8 ++++---- packages/client/src/store.ts | 4 ++-- packages/client/src/theme-store.ts | 4 ++-- packages/client/src/ui/_common_/common.vue | 2 +- packages/client/src/ui/deck.vue | 2 +- packages/client/src/ui/deck/tl-column.vue | 4 ++-- 34 files changed, 86 insertions(+), 84 deletions(-) diff --git a/packages/client/src/components/MkFollowButton.vue b/packages/client/src/components/MkFollowButton.vue index 0920001c7b..a018c47b55 100644 --- a/packages/client/src/components/MkFollowButton.vue +++ b/packages/client/src/components/MkFollowButton.vue @@ -8,7 +8,7 @@