diff --git a/.config/example.yml b/.config/example.yml
index 9082dfb868..17149f6c3a 100644
--- a/.config/example.yml
+++ b/.config/example.yml
@@ -178,19 +178,13 @@ logLevel: [
# Media Proxy
#mediaProxy: https://example.com/proxy
-# Proxy remote files (default: false)
+# Proxy remote files (default: true)
#proxyRemoteFiles: true
#allowedPrivateNetworks: [
# '127.0.0.1/32'
#]
-# TWA
-#twa:
-# nameSpace: android_app
-# packageName: tld.domain.twa
-# sha256CertFingerprints: ['AB:CD:EF']
-
# Upload or download file size limits (bytes)
#maxFileSize: 262144000
diff --git a/.gitlab/issue_templates/bug.md b/.gitlab/issue_templates/bug.md
index 3bffa21cde..a94fae0f0d 100644
--- a/.gitlab/issue_templates/bug.md
+++ b/.gitlab/issue_templates/bug.md
@@ -3,30 +3,38 @@
🔒 Found a security vulnerability? [Please disclose it responsibly.](https://firefish.dev/firefish/firefish/-/blob/develop/SECURITY.md)
🤝 By submitting this issue, you agree to follow our [Contribution Guidelines.](https://firefish.dev/firefish/firefish/-/blob/develop/CONTRIBUTING.md) -->
-**What happened?** _(Please give us a brief description of what happened.)_
+## What happened?
-**What did you expect to happen?** _(Please give us a brief description of what you expected to happen.)_
+## What did you expect to happen?
-**Version** _(What version of firefish is your instance running? You can find this by clicking your instance's logo at the bottom left and then clicking instance information.)_
+## Version
-**Instance** _(What instance of firefish are you using?)_
+## What type of issue is this?
-**What type of issue is this?** _(If this happens on your device and has to do with the user interface, it's client-side. If this happens on either with the API or the backend, or you got a server-side error in the client, it's server-side.)_
+- [] server-side
+- [] client-side
+- [] not sure
-**What browser are you using? (Client-side issues only)**
+
-**What operating system are you using? (Client-side issues only)**
+### Instance
-**How do you deploy Firefish on your server? (Server-side issues only)**
+### What browser are you using? (client-side issues only)
-**What operating system are you using? (Server-side issues only)**
+### What operating system are you using? (client-side issues only)
-**Relevant log output** _(Please copy and paste any relevant log output. You can find your log by inspecting the page, and going to the "console" tab. This will be automatically formatted into code, so no need for backticks.)_
+### How do you deploy Firefish on your server? (server-side issues only)
-**Contribution Guidelines**
+### What operating system are you using? (Server-side issues only)
+
+### Relevant log output
+
+
+
+## Contribution Guidelines
By submitting this issue, you agree to follow our [Contribution Guidelines](https://firefish.dev/firefish/firefish/-/blob/develop/CONTRIBUTING.md)
- [ ] I agree to follow this project's Contribution Guidelines
- [ ] I have searched the issue tracker for similar issues, and this is not a duplicate.
-**Are you willing to fix this bug?** (optional)
+## Are you willing to fix this bug? (optional)
- [ ] Yes. I will fix this bug and open a merge request if the change is agreed upon.
diff --git a/.gitlab/issue_templates/feature.md b/.gitlab/issue_templates/feature.md
index b4af4884b7..7b4917ecb3 100644
--- a/.gitlab/issue_templates/feature.md
+++ b/.gitlab/issue_templates/feature.md
@@ -3,18 +3,18 @@
🔒 Found a security vulnerability? [Please disclose it responsibly.](https://firefish.dev/firefish/firefish/-/blob/develop/SECURITY.md)
🤝 By submitting this feature request, you agree to follow our [Contribution Guidelines.](https://firefish.dev/firefish/firefish/-/blob/develop/CONTRIBUTING.md) -->
-**What feature would you like implemented?** _(Please give us a brief description of what you'd like.)_
+## What feature would you like implemented?
-**Why should we add this feature?** _(Please give us a brief description of why your feature is important.)_
+## Why should we add this feature?
-**Version** _(What version of firefish is your instance running? You can find this by clicking your instance's logo at the bottom left and then clicking instance information.)_
+## Version
-**Instance** _(What instance of firefish are you using?)_
+## Instance
-**Contribution Guidelines**
+## Contribution Guidelines
By submitting this issue, you agree to follow our [Contribution Guidelines](https://firefish.dev/firefish/firefish/-/blob/develop/CONTRIBUTING.md)
- [ ] I agree to follow this project's Contribution Guidelines
- [ ] I have searched the issue tracker for similar requests, and this is not a duplicate.
-**Are you willing to implement this feature?** (optional)
+## Are you willing to implement this feature? (optional)
- [ ] Yes. I will implement this feature and open a merge request if the change is agreed upon.
diff --git a/.gitlab/merge_request_templates/default.md b/.gitlab/merge_request_templates/default.md
index 2a1c926223..c2382481e3 100644
--- a/.gitlab/merge_request_templates/default.md
+++ b/.gitlab/merge_request_templates/default.md
@@ -1,8 +1,8 @@
-**What does this PR do?** _(Please give us a brief description of what this PR does.)_
+## What does this PR do?
-**Contribution Guidelines**
+## Contribution Guidelines
By submitting this merge request, you agree to follow our [Contribution Guidelines](https://firefish.dev/firefish/firefish/-/blob/develop/CONTRIBUTING.md)
- [ ] This change is reviewed in an issue / This is a minor bug fix
- [ ] I agree to follow this project's Contribution Guidelines
diff --git a/.vscode/extensions.json b/.vscode/extensions.json
index 0083604d44..de0385be2a 100644
--- a/.vscode/extensions.json
+++ b/.vscode/extensions.json
@@ -12,6 +12,7 @@
"esbenp.prettier-vscode",
"redhat.vscode-yaml",
"yoavbls.pretty-ts-errors",
- "biomejs.biome"
+ "biomejs.biome",
+ "rust-lang.rust-analyzer"
]
}
diff --git a/Cargo.lock b/Cargo.lock
index 93c475fa0b..c6ba96e683 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -59,9 +59,9 @@ checksum = "250f629c0161ad8107cf89319e990051fae62832fd343083bea452d93e2205fd"
[[package]]
name = "allocator-api2"
-version = "0.2.16"
+version = "0.2.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5"
+checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f"
[[package]]
name = "android-tzdata"
@@ -132,6 +132,18 @@ version = "1.0.82"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f538837af36e6f6a9be0faa67f9a314f8119e4e4b5867c6ab40ed60360142519"
+[[package]]
+name = "argon2"
+version = "0.5.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3c3610892ee6e0cbce8ae2700349fcf8f98adb0dbfbee85aec3c9179d29cc072"
+dependencies = [
+ "base64ct",
+ "blake2",
+ "cpufeatures",
+ "password-hash",
+]
+
[[package]]
name = "arrayvec"
version = "0.7.4"
@@ -190,11 +202,14 @@ checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80"
name = "backend-rs"
version = "0.0.0"
dependencies = [
+ "argon2",
"async-trait",
"basen",
+ "bcrypt",
"cfg-if",
"chrono",
"cuid2",
+ "emojis",
"idna",
"jsonschema",
"macro_rs",
@@ -238,6 +253,12 @@ version = "0.21.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567"
+[[package]]
+name = "base64"
+version = "0.22.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9475866fec1451be56a3c2400fd081ff546538961565ccb5b7142cbd22bc7a51"
+
[[package]]
name = "base64ct"
version = "1.6.0"
@@ -250,6 +271,19 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1dbe4bb73fd931c4d1aaf53b35d1286c8a948ad00ec92c8e3c856f15fd027f43"
+[[package]]
+name = "bcrypt"
+version = "0.15.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e65938ed058ef47d92cf8b346cc76ef48984572ade631927e9937b5ffc7662c7"
+dependencies = [
+ "base64 0.22.0",
+ "blowfish",
+ "getrandom",
+ "subtle",
+ "zeroize",
+]
+
[[package]]
name = "bigdecimal"
version = "0.3.1"
@@ -303,6 +337,15 @@ dependencies = [
"wyz",
]
+[[package]]
+name = "blake2"
+version = "0.10.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe"
+dependencies = [
+ "digest",
+]
+
[[package]]
name = "block-buffer"
version = "0.10.4"
@@ -312,6 +355,16 @@ dependencies = [
"generic-array",
]
+[[package]]
+name = "blowfish"
+version = "0.9.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e412e2cd0f2b2d93e02543ceae7917b3c70331573df19ee046bcbc35e45e87d7"
+dependencies = [
+ "byteorder",
+ "cipher",
+]
+
[[package]]
name = "borsh"
version = "1.4.0"
@@ -384,9 +437,9 @@ checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9"
[[package]]
name = "cc"
-version = "1.0.92"
+version = "1.0.94"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2678b2e3449475e95b0aa6f9b506a28e61b3dc8996592b983695e8ebb58a8b41"
+checksum = "17f6e324229dc011159fcc089755d1e2e216a90d43a7dea6853ca740b84f35e7"
[[package]]
name = "cfg-if"
@@ -412,7 +465,17 @@ dependencies = [
"num-traits",
"serde",
"wasm-bindgen",
- "windows-targets 0.52.4",
+ "windows-targets 0.52.5",
+]
+
+[[package]]
+name = "cipher"
+version = "0.4.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad"
+dependencies = [
+ "crypto-common",
+ "inout",
]
[[package]]
@@ -633,13 +696,22 @@ checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125"
[[package]]
name = "either"
-version = "1.10.0"
+version = "1.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a"
+checksum = "a47c1c47d2f5964e29c61246e81db715514cd532db6b5116a25ea3c03d6780a2"
dependencies = [
"serde",
]
+[[package]]
+name = "emojis"
+version = "0.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4ee61eb945bff65ee7d19d157d39c67c33290ff0742907413fd5eefd29edc979"
+dependencies = [
+ "phf",
+]
+
[[package]]
name = "encoding_rs"
version = "0.8.34"
@@ -1075,6 +1147,15 @@ dependencies = [
"syn 2.0.58",
]
+[[package]]
+name = "inout"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5"
+dependencies = [
+ "generic-array",
+]
+
[[package]]
name = "ipnet"
version = "2.9.0"
@@ -1122,7 +1203,7 @@ checksum = "2a071f4f7efc9a9118dfb627a0a94ef247986e1ab8606a4c806ae2b3aa3b6978"
dependencies = [
"ahash 0.8.11",
"anyhow",
- "base64",
+ "base64 0.21.7",
"bytecount",
"clap",
"fancy-regex",
@@ -1175,7 +1256,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c2a198fb6b0eada2a8df47933734e6d35d350665a33a3593d7164fa52c75c19"
dependencies = [
"cfg-if",
- "windows-targets 0.52.4",
+ "windows-targets 0.52.5",
]
[[package]]
@@ -1296,9 +1377,9 @@ dependencies = [
[[package]]
name = "napi-build"
-version = "2.1.2"
+version = "2.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2f9130fccc5f763cf2069b34a089a18f0d0883c66aceb81f2fad541a3d823c43"
+checksum = "e1c0f5d67ee408a4685b61f5ab7e58605c8ae3f2b4189f0127d804ff13d5560a"
[[package]]
name = "napi-derive"
@@ -1350,9 +1431,9 @@ dependencies = [
[[package]]
name = "num"
-version = "0.4.1"
+version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b05180d69e3da0e530ba2a1dae5110317e49e3b7f3d41be227dc5f92e49ee7af"
+checksum = "3135b08af27d103b0a51f2ae0f8632117b7b185ccf931445affa8df530576a41"
dependencies = [
"num-bigint",
"num-complex",
@@ -1559,6 +1640,17 @@ dependencies = [
"syn 2.0.58",
]
+[[package]]
+name = "password-hash"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "346f04948ba92c43e8469c1ee6736c7563d71012b17d40745260fe106aac2166"
+dependencies = [
+ "base64ct",
+ "rand_core",
+ "subtle",
+]
+
[[package]]
name = "paste"
version = "1.0.14"
@@ -1580,6 +1672,24 @@ version = "2.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
+[[package]]
+name = "phf"
+version = "0.11.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc"
+dependencies = [
+ "phf_shared",
+]
+
+[[package]]
+name = "phf_shared"
+version = "0.11.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b"
+dependencies = [
+ "siphasher",
+]
+
[[package]]
name = "pin-project-lite"
version = "0.2.14"
@@ -1801,7 +1911,7 @@ version = "0.11.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62"
dependencies = [
- "base64",
+ "base64 0.21.7",
"bytes",
"encoding_rs",
"futures-core",
@@ -1947,7 +2057,7 @@ version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c"
dependencies = [
- "base64",
+ "base64 0.21.7",
]
[[package]]
@@ -2231,6 +2341,12 @@ version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f27f6278552951f1f2b8cf9da965d10969b2efdea95a6ec47987ab46edfe263a"
+[[package]]
+name = "siphasher"
+version = "0.3.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d"
+
[[package]]
name = "slab"
version = "0.4.9"
@@ -2398,7 +2514,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ed31390216d20e538e447a7a9b959e06ed9fc51c37b514b46eb758016ecd418"
dependencies = [
"atoi",
- "base64",
+ "base64 0.21.7",
"bigdecimal",
"bitflags 2.5.0",
"byteorder",
@@ -2445,7 +2561,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7c824eb80b894f926f89a0b9da0c7f435d27cdd35b8c655b114e58223918577e"
dependencies = [
"atoi",
- "base64",
+ "base64 0.21.7",
"bigdecimal",
"bitflags 2.5.0",
"byteorder",
@@ -3041,7 +3157,7 @@ version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9"
dependencies = [
- "windows-targets 0.52.4",
+ "windows-targets 0.52.5",
]
[[package]]
@@ -3059,7 +3175,7 @@ version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
dependencies = [
- "windows-targets 0.52.4",
+ "windows-targets 0.52.5",
]
[[package]]
@@ -3079,17 +3195,18 @@ dependencies = [
[[package]]
name = "windows-targets"
-version = "0.52.4"
+version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b"
+checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb"
dependencies = [
- "windows_aarch64_gnullvm 0.52.4",
- "windows_aarch64_msvc 0.52.4",
- "windows_i686_gnu 0.52.4",
- "windows_i686_msvc 0.52.4",
- "windows_x86_64_gnu 0.52.4",
- "windows_x86_64_gnullvm 0.52.4",
- "windows_x86_64_msvc 0.52.4",
+ "windows_aarch64_gnullvm 0.52.5",
+ "windows_aarch64_msvc 0.52.5",
+ "windows_i686_gnu 0.52.5",
+ "windows_i686_gnullvm",
+ "windows_i686_msvc 0.52.5",
+ "windows_x86_64_gnu 0.52.5",
+ "windows_x86_64_gnullvm 0.52.5",
+ "windows_x86_64_msvc 0.52.5",
]
[[package]]
@@ -3100,9 +3217,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
[[package]]
name = "windows_aarch64_gnullvm"
-version = "0.52.4"
+version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9"
+checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263"
[[package]]
name = "windows_aarch64_msvc"
@@ -3112,9 +3229,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
[[package]]
name = "windows_aarch64_msvc"
-version = "0.52.4"
+version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675"
+checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6"
[[package]]
name = "windows_i686_gnu"
@@ -3124,9 +3241,15 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
[[package]]
name = "windows_i686_gnu"
-version = "0.52.4"
+version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3"
+checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670"
+
+[[package]]
+name = "windows_i686_gnullvm"
+version = "0.52.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9"
[[package]]
name = "windows_i686_msvc"
@@ -3136,9 +3259,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
[[package]]
name = "windows_i686_msvc"
-version = "0.52.4"
+version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02"
+checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf"
[[package]]
name = "windows_x86_64_gnu"
@@ -3148,9 +3271,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
[[package]]
name = "windows_x86_64_gnu"
-version = "0.52.4"
+version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03"
+checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9"
[[package]]
name = "windows_x86_64_gnullvm"
@@ -3160,9 +3283,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
[[package]]
name = "windows_x86_64_gnullvm"
-version = "0.52.4"
+version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177"
+checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596"
[[package]]
name = "windows_x86_64_msvc"
@@ -3172,9 +3295,9 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
[[package]]
name = "windows_x86_64_msvc"
-version = "0.52.4"
+version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8"
+checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0"
[[package]]
name = "winnow"
diff --git a/Cargo.toml b/Cargo.toml
index f7ba12d884..7ca43c960b 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -7,14 +7,17 @@ macro_rs = { path = "packages/macro-rs" }
napi = { version = "2.16.2", default-features = false }
napi-derive = "2.16.2"
-napi-build = "2.1.2"
+napi-build = "2.1.3"
+argon2 = "0.5.3"
async-trait = "0.1.80"
basen = "0.1.0"
+bcrypt = "0.15.1"
cfg-if = "1.0.0"
chrono = "0.4.37"
convert_case = "0.6.0"
cuid2 = "0.1.2"
+emojis = "0.6.1"
idna = "0.5.0"
jsonschema = "0.17.1"
once_cell = "1.19.0"
diff --git a/docs/api-change.md b/docs/api-change.md
index e788b3d637..f3ed584c32 100644
--- a/docs/api-change.md
+++ b/docs/api-change.md
@@ -2,7 +2,7 @@
Breaking changes are indicated by the :warning: icon.
-## Unreleased
+## v20240413
- :warning: Removed `patrons` endpoint.
diff --git a/docs/changelog.md b/docs/changelog.md
index f0076197bc..a818e09835 100644
--- a/docs/changelog.md
+++ b/docs/changelog.md
@@ -5,9 +5,12 @@ Critical security updates are indicated by the :warning: icon.
- Server administrators should check [notice-for-admins.md](./notice-for-admins.md) as well.
- Third-party client/bot developers may want to check [api-change.md](./api-change.md) as well.
-## Unreleased
+## [v20240413](https://firefish.dev/firefish/firefish/-/merge_requests/10741/commits)
- Add "Media" tab to user page
+- Improve federation and rendering of mathematical expressions
+- Remove donor information from the web client
+ - See also: https://info.firefish.dev/notes/9s1n283sb10rh869
- Fix bugs
## [v20240405](https://firefish.dev/firefish/firefish/-/merge_requests/10733/commits)
diff --git a/docs/notice-for-admins.md b/docs/notice-for-admins.md
index c22b1da0aa..9bff40a65c 100644
--- a/docs/notice-for-admins.md
+++ b/docs/notice-for-admins.md
@@ -2,7 +2,7 @@
You can skip intermediate versions when upgrading from an old version, but please read the notices and follow the instructions for each intermediate version before [upgrading](./upgrade.md).
-## Unreleased
+## v20240413
### For all users
diff --git a/locales/fr-FR.yml b/locales/fr-FR.yml
index 9dff23f110..6367dda9f4 100644
--- a/locales/fr-FR.yml
+++ b/locales/fr-FR.yml
@@ -2318,3 +2318,4 @@ markLocalFilesNsfwByDefaultDescription: Indépendamment de ce réglage, les util
peuvent supprimer le drapeau « sensible » (NSFW) eux-mêmes. Les fichiers existants
ne sont pas affectés.
noteEditHistory: Historique des publications
+media: Multimédia
diff --git a/package.json b/package.json
index bff235df6e..dd0766bc7b 100644
--- a/package.json
+++ b/package.json
@@ -1,11 +1,11 @@
{
"name": "firefish",
- "version": "20240405",
+ "version": "20240413",
"repository": {
"type": "git",
"url": "https://firefish.dev/firefish/firefish.git"
},
- "packageManager": "pnpm@8.15.6",
+ "packageManager": "pnpm@8.15.7",
"private": true,
"scripts": {
"rebuild": "pnpm run clean && pnpm run build",
@@ -36,11 +36,11 @@
"clean-all": "pnpm run clean && pnpm run clean-cargo && pnpm run clean-npm"
},
"dependencies": {
- "js-yaml": "4.1.0",
"gulp": "4.0.2",
"gulp-cssnano": "2.1.3",
"gulp-replace": "1.1.4",
- "gulp-terser": "2.1.0"
+ "gulp-terser": "2.1.0",
+ "js-yaml": "4.1.0"
},
"devDependencies": {
"@biomejs/biome": "1.6.4",
@@ -50,7 +50,7 @@
"@biomejs/cli-linux-x64": "^1.6.4",
"@types/node": "20.12.7",
"execa": "8.0.1",
- "pnpm": "8.15.6",
+ "pnpm": "8.15.7",
"typescript": "5.4.5"
}
}
diff --git a/packages/README.md b/packages/README.md
index 56356ec2d0..6637462910 100644
--- a/packages/README.md
+++ b/packages/README.md
@@ -4,6 +4,7 @@ This directory contains all of the packages Firefish uses.
- `backend`: Main backend code written in TypeScript for NodeJS
- `backend-rs`: Backend code written in Rust, bound to NodeJS by [NAPI-RS](https://napi.rs/)
+- `macro-rs`: Procedural macros for backend-rs
- `client`: Web interface written in Vue3 and TypeScript
- `sw`: Web [Service Worker](https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API) written in TypeScript
- `firefish-js`: TypeScript SDK for both backend and client
diff --git a/packages/backend-rs/Cargo.toml b/packages/backend-rs/Cargo.toml
index 783f630942..af9e10cdc1 100644
--- a/packages/backend-rs/Cargo.toml
+++ b/packages/backend-rs/Cargo.toml
@@ -17,11 +17,14 @@ macro_rs = { workspace = true }
napi = { workspace = true, optional = true, default-features = false, features = ["napi9", "tokio_rt", "chrono_date", "serde-json"] }
napi-derive = { workspace = true, optional = true }
+argon2 = { workspace = true, features = ["std"] }
async-trait = { workspace = true }
basen = { workspace = true }
+bcrypt = { workspace = true }
cfg-if = { workspace = true }
chrono = { workspace = true }
cuid2 = { workspace = true }
+emojis = { workspace = true }
idna = { workspace = true }
jsonschema = { workspace = true }
once_cell = { workspace = true }
diff --git a/packages/backend-rs/index.d.ts b/packages/backend-rs/index.d.ts
index 617bedf5b9..ae050e01d8 100644
--- a/packages/backend-rs/index.d.ts
+++ b/packages/backend-rs/index.d.ts
@@ -3,6 +3,16 @@
/* auto-generated by NAPI-RS */
+export interface EnvConfig {
+ onlyQueue: boolean
+ onlyServer: boolean
+ noDaemons: boolean
+ disableClustering: boolean
+ verbose: boolean
+ withLogTime: boolean
+ slow: boolean
+}
+export function readEnvironmentConfig(): EnvConfig
export interface ServerConfig {
url: string
port: number
@@ -132,9 +142,38 @@ export function isSelfHost(host?: string | undefined | null): boolean
export function isSameOrigin(uri: string): boolean
export function extractHost(uri: string): string
export function toPuny(host: string): string
+export function isUnicodeEmoji(s: string): boolean
+export function sqlLikeEscape(src: string): string
+export function safeForSql(src: string): boolean
+/** Convert milliseconds to a human readable string */
+export function formatMilliseconds(milliseconds: number): string
export function toMastodonId(firefishId: string): string | null
export function fromMastodonId(mastodonId: string): string | null
+export function fetchMeta(useCache: boolean): Promise
+export interface PugArgs {
+ img: string | null
+ title: string
+ instanceName: string
+ desc: string | null
+ icon: string | null
+ splashIcon: string | null
+ themeColor: string | null
+ randomMotd: string
+ privateMode: boolean | null
+}
+export function metaToPugArgs(meta: Meta): PugArgs
export function nyaify(text: string, lang?: string | undefined | null): string
+export function hashPassword(password: string): string
+export function verifyPassword(password: string, hash: string): boolean
+export function isOldPasswordAlgorithm(hash: string): boolean
+export interface DecodedReaction {
+ reaction: string
+ name: string | null
+ host: string | null
+}
+export function decodeReaction(reaction: string): DecodedReaction
+export function countReactions(reactions: Record): Record
+export function toDbReaction(reaction?: string | undefined | null, host?: string | undefined | null): Promise
export interface AbuseUserReport {
id: string
createdAt: Date
diff --git a/packages/backend-rs/index.js b/packages/backend-rs/index.js
index f2942a9aa5..6acd3ca68d 100644
--- a/packages/backend-rs/index.js
+++ b/packages/backend-rs/index.js
@@ -310,8 +310,9 @@ if (!nativeBinding) {
throw new Error(`Failed to load native binding`)
}
-const { readServerConfig, stringToAcct, acctToString, checkWordMute, getFullApAccount, isSelfHost, isSameOrigin, extractHost, toPuny, toMastodonId, fromMastodonId, nyaify, AntennaSrcEnum, MutedNoteReasonEnum, NoteVisibilityEnum, NotificationTypeEnum, PageVisibilityEnum, PollNotevisibilityEnum, RelayStatusEnum, UserEmojimodpermEnum, UserProfileFfvisibilityEnum, UserProfileMutingnotificationtypesEnum, initIdGenerator, getTimestamp, genId, secureRndstr } = nativeBinding
+const { readEnvironmentConfig, readServerConfig, stringToAcct, acctToString, checkWordMute, getFullApAccount, isSelfHost, isSameOrigin, extractHost, toPuny, isUnicodeEmoji, sqlLikeEscape, safeForSql, formatMilliseconds, 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.stringToAcct = stringToAcct
module.exports.acctToString = acctToString
@@ -321,9 +322,21 @@ module.exports.isSelfHost = isSelfHost
module.exports.isSameOrigin = isSameOrigin
module.exports.extractHost = extractHost
module.exports.toPuny = toPuny
+module.exports.isUnicodeEmoji = isUnicodeEmoji
+module.exports.sqlLikeEscape = sqlLikeEscape
+module.exports.safeForSql = safeForSql
+module.exports.formatMilliseconds = formatMilliseconds
module.exports.toMastodonId = toMastodonId
module.exports.fromMastodonId = fromMastodonId
+module.exports.fetchMeta = fetchMeta
+module.exports.metaToPugArgs = metaToPugArgs
module.exports.nyaify = nyaify
+module.exports.hashPassword = hashPassword
+module.exports.verifyPassword = verifyPassword
+module.exports.isOldPasswordAlgorithm = isOldPasswordAlgorithm
+module.exports.decodeReaction = decodeReaction
+module.exports.countReactions = countReactions
+module.exports.toDbReaction = toDbReaction
module.exports.AntennaSrcEnum = AntennaSrcEnum
module.exports.MutedNoteReasonEnum = MutedNoteReasonEnum
module.exports.NoteVisibilityEnum = NoteVisibilityEnum
diff --git a/packages/backend-rs/src/config/environment.rs b/packages/backend-rs/src/config/environment.rs
new file mode 100644
index 0000000000..7d66aec7ba
--- /dev/null
+++ b/packages/backend-rs/src/config/environment.rs
@@ -0,0 +1,27 @@
+// FIXME: Are these options used?
+#[crate::export(object)]
+pub struct EnvConfig {
+ pub only_queue: bool,
+ pub only_server: bool,
+ pub no_daemons: bool,
+ pub disable_clustering: bool,
+ pub verbose: bool,
+ pub with_log_time: bool,
+ pub slow: bool,
+}
+
+#[crate::export]
+pub fn read_environment_config() -> EnvConfig {
+ let node_env = std::env::var("NODE_ENV").unwrap_or_default().to_lowercase();
+ let is_testing = node_env == "test";
+
+ EnvConfig {
+ only_queue: std::env::var("MK_ONLY_QUEUE").is_ok(),
+ only_server: std::env::var("MK_ONLY_SERVER").is_ok(),
+ no_daemons: is_testing || std::env::var("MK_NO_DAEMONS").is_ok(),
+ disable_clustering: is_testing || std::env::var("MK_DISABLE_CLUSTERING").is_ok(),
+ verbose: std::env::var("MK_VERBOSE").is_ok(),
+ with_log_time: std::env::var("MK_WITH_LOG_TIME").is_ok(),
+ slow: std::env::var("MK_SLOW").is_ok(),
+ }
+}
diff --git a/packages/backend-rs/src/config/mod.rs b/packages/backend-rs/src/config/mod.rs
index 74f47ad347..b708f2b265 100644
--- a/packages/backend-rs/src/config/mod.rs
+++ b/packages/backend-rs/src/config/mod.rs
@@ -1 +1,2 @@
+pub mod environment;
pub mod server;
diff --git a/packages/backend-rs/src/misc/emoji.rs b/packages/backend-rs/src/misc/emoji.rs
new file mode 100644
index 0000000000..df7d33848c
--- /dev/null
+++ b/packages/backend-rs/src/misc/emoji.rs
@@ -0,0 +1,31 @@
+#[inline]
+#[crate::export]
+pub fn is_unicode_emoji(s: &str) -> bool {
+ emojis::get(s).is_some()
+}
+
+#[cfg(test)]
+mod unit_test {
+ use super::is_unicode_emoji;
+
+ #[test]
+ fn test_unicode_emoji_check() {
+ assert!(is_unicode_emoji("⭐"));
+ assert!(is_unicode_emoji("👍"));
+ assert!(is_unicode_emoji("❤"));
+ assert!(is_unicode_emoji("♥️"));
+ assert!(is_unicode_emoji("❤️"));
+ assert!(is_unicode_emoji("💙"));
+ assert!(is_unicode_emoji("🩷"));
+ assert!(is_unicode_emoji("🖖🏿"));
+ assert!(is_unicode_emoji("🏃➡️"));
+ assert!(is_unicode_emoji("👩❤️👨"));
+ assert!(is_unicode_emoji("👩👦👦"));
+ assert!(is_unicode_emoji("🏳️🌈"));
+
+ assert!(!is_unicode_emoji("⭐⭐"));
+ assert!(!is_unicode_emoji("x"));
+ assert!(!is_unicode_emoji("\t"));
+ assert!(!is_unicode_emoji(":meow_aww:"));
+ }
+}
diff --git a/packages/backend-rs/src/misc/escape_sql.rs b/packages/backend-rs/src/misc/escape_sql.rs
new file mode 100644
index 0000000000..c575e088ce
--- /dev/null
+++ b/packages/backend-rs/src/misc/escape_sql.rs
@@ -0,0 +1,36 @@
+#[crate::export]
+pub fn sql_like_escape(src: &str) -> String {
+ src.replace('%', r"\%").replace('_', r"\_")
+}
+
+#[crate::export]
+pub fn safe_for_sql(src: &str) -> bool {
+ !src.contains([
+ '\0', '\x08', '\x09', '\x1a', '\n', '\r', '"', '\'', '\\', '%',
+ ])
+}
+
+#[cfg(test)]
+mod unit_test {
+ use super::{safe_for_sql, sql_like_escape};
+ use pretty_assertions::assert_eq;
+
+ #[test]
+ fn sql_like_escape_test() {
+ assert_eq!(sql_like_escape(""), "");
+ assert_eq!(sql_like_escape("abc"), "abc");
+ assert_eq!(sql_like_escape("a%bc"), r"a\%bc");
+ assert_eq!(sql_like_escape("a呼%吸bc"), r"a呼\%吸bc");
+ assert_eq!(sql_like_escape("a呼%吸b%_c"), r"a呼\%吸b\%\_c");
+ assert_eq!(sql_like_escape("_اللغة العربية"), r"\_اللغة العربية");
+ }
+
+ #[test]
+ fn safe_for_sql_test() {
+ assert!(safe_for_sql("123"));
+ assert!(safe_for_sql("人間"));
+ assert!(!safe_for_sql("人間\x09"));
+ assert!(!safe_for_sql("abc\ndef"));
+ assert!(!safe_for_sql("%something%"));
+ }
+}
diff --git a/packages/backend-rs/src/misc/format_milliseconds.rs b/packages/backend-rs/src/misc/format_milliseconds.rs
new file mode 100644
index 0000000000..dfa8df6f62
--- /dev/null
+++ b/packages/backend-rs/src/misc/format_milliseconds.rs
@@ -0,0 +1,46 @@
+/// Convert milliseconds to a human readable string
+#[crate::export]
+pub fn format_milliseconds(milliseconds: u32) -> String {
+ let mut seconds = milliseconds / 1000;
+ let mut minutes = seconds / 60;
+ let mut hours = minutes / 60;
+ let days = hours / 24;
+
+ seconds %= 60;
+ minutes %= 60;
+ hours %= 24;
+
+ let mut buf: Vec = vec![];
+
+ if days > 0 {
+ buf.push(format!("{} day(s)", days));
+ }
+ if hours > 0 {
+ buf.push(format!("{} hour(s)", hours));
+ }
+ if minutes > 0 {
+ buf.push(format!("{} minute(s)", minutes));
+ }
+ if seconds > 0 {
+ buf.push(format!("{} second(s)", seconds));
+ }
+
+ buf.join(", ")
+}
+
+#[cfg(test)]
+mod unit_test {
+ use super::format_milliseconds;
+ use pretty_assertions::assert_eq;
+
+ #[test]
+ fn format_milliseconds_test() {
+ assert_eq!(format_milliseconds(1000), "1 second(s)");
+ assert_eq!(format_milliseconds(1387938), "23 minute(s), 7 second(s)");
+ assert_eq!(format_milliseconds(34200457), "9 hour(s), 30 minute(s)");
+ assert_eq!(
+ format_milliseconds(998244353),
+ "11 day(s), 13 hour(s), 17 minute(s), 24 second(s)"
+ );
+ }
+}
diff --git a/packages/backend-rs/src/misc/meta.rs b/packages/backend-rs/src/misc/meta.rs
new file mode 100644
index 0000000000..5aed617038
--- /dev/null
+++ b/packages/backend-rs/src/misc/meta.rs
@@ -0,0 +1,83 @@
+use crate::database::db_conn;
+use crate::model::entity::meta;
+use rand::prelude::*;
+use sea_orm::{prelude::*, ActiveValue};
+use std::sync::Mutex;
+
+type Meta = meta::Model;
+
+static CACHE: Mutex