Compare commits
5 commits
0365d2d337
...
d63c42612e
Author | SHA1 | Date | |
---|---|---|---|
d63c42612e | |||
9374e4ef93 | |||
0db57bd423 | |||
9cc05e565b | |||
fe051e8207 |
37 changed files with 327 additions and 197 deletions
|
@ -295,7 +295,7 @@ if (!nativeBinding) {
|
|||
throw new Error(`Failed to load native binding`)
|
||||
}
|
||||
|
||||
const { EnvConfig, readEnvironmentConfig, readServerConfig, JsDbConn, connectToDatabase, AntennaSrcEnum, MutedNoteReasonEnum, NoteVisibilityEnum, NotificationTypeEnum, PageVisibilityEnum, PollNotevisibilityEnum, RelayStatusEnum, UserEmojimodpermEnum, UserProfileFfvisibilityEnum, UserProfileMutingnotificationtypesEnum, stringToAcct, acctToString, getFullApAccount, isSelfHost, extractHost, toPuny, toPunyOptional, convertToHiddenPost, sqlLikeEscape, safeForSql, formatMilliseconds, nativeInitIdGenerator, nativeCreateId, nativeGetTimestamp, fetchMeta, metaToPugArgs, hasOtherRenoteOfThisNote, genString, IdConvertType, convertId } = nativeBinding
|
||||
const { EnvConfig, readEnvironmentConfig, readServerConfig, JsDbConn, connectToDatabase, AntennaSrcEnum, MutedNoteReasonEnum, NoteVisibilityEnum, NotificationTypeEnum, PageVisibilityEnum, PollNotevisibilityEnum, RelayStatusEnum, UserEmojimodpermEnum, UserProfileFfvisibilityEnum, UserProfileMutingnotificationtypesEnum, stringToAcct, acctToString, getFullApAccount, isSelfHost, extractHost, toPuny, toPunyOptional, convertToHiddenPost, sqlLikeEscape, safeForSql, formatMilliseconds, nativeInitIdGenerator, nativeCreateId, nativeGetTimestamp, fetchMeta, metaToPugArgs, hasOtherRenoteOfThisNote, nyaify, hashPassword, verifyPassword, isOldPasswordAlgorithm, genString, IdConvertType, convertId } = nativeBinding
|
||||
|
||||
module.exports.EnvConfig = EnvConfig
|
||||
module.exports.readEnvironmentConfig = readEnvironmentConfig
|
||||
|
@ -329,6 +329,10 @@ module.exports.nativeGetTimestamp = nativeGetTimestamp
|
|||
module.exports.fetchMeta = fetchMeta
|
||||
module.exports.metaToPugArgs = metaToPugArgs
|
||||
module.exports.hasOtherRenoteOfThisNote = hasOtherRenoteOfThisNote
|
||||
module.exports.nyaify = nyaify
|
||||
module.exports.hashPassword = hashPassword
|
||||
module.exports.verifyPassword = verifyPassword
|
||||
module.exports.isOldPasswordAlgorithm = isOldPasswordAlgorithm
|
||||
module.exports.genString = genString
|
||||
module.exports.IdConvertType = IdConvertType
|
||||
module.exports.convertId = convertId
|
||||
|
|
113
packages/backend-rs/Cargo.lock
generated
113
packages/backend-rs/Cargo.lock
generated
|
@ -132,6 +132,18 @@ version = "1.0.79"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca"
|
||||
|
||||
[[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"
|
||||
|
@ -200,8 +212,10 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
|||
name = "backend-rs"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"argon2",
|
||||
"async-trait",
|
||||
"basen",
|
||||
"bcrypt",
|
||||
"cfg-if",
|
||||
"chrono",
|
||||
"cuid2",
|
||||
|
@ -214,6 +228,7 @@ dependencies = [
|
|||
"parse-display",
|
||||
"pretty_assertions",
|
||||
"rand",
|
||||
"regex",
|
||||
"schemars",
|
||||
"sea-orm",
|
||||
"serde",
|
||||
|
@ -258,6 +273,19 @@ version = "0.1.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1dbe4bb73fd931c4d1aaf53b35d1286c8a948ad00ec92c8e3c856f15fd027f43"
|
||||
|
||||
[[package]]
|
||||
name = "bcrypt"
|
||||
version = "0.15.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "28d1c9c15093eb224f0baa400f38fcd713fc1391a6f1c389d886beef146d60a3"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"blowfish",
|
||||
"getrandom",
|
||||
"subtle",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bigdecimal"
|
||||
version = "0.3.1"
|
||||
|
@ -311,6 +339,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"
|
||||
|
@ -320,6 +357,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.3.1"
|
||||
|
@ -413,9 +460,9 @@ checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e"
|
|||
|
||||
[[package]]
|
||||
name = "chrono"
|
||||
version = "0.4.32"
|
||||
version = "0.4.33"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "41daef31d7a747c5c847246f36de49ced6f7403b4cdabc807a97b5cc184cda7a"
|
||||
checksum = "9f13690e35a5e4ace198e7beea2895d29f3a9cc55015fcebe6336bd2010af9eb"
|
||||
dependencies = [
|
||||
"android-tzdata",
|
||||
"iana-time-zone",
|
||||
|
@ -426,6 +473,16 @@ dependencies = [
|
|||
"windows-targets 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cipher"
|
||||
version = "0.4.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad"
|
||||
dependencies = [
|
||||
"crypto-common",
|
||||
"inout",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "4.4.18"
|
||||
|
@ -1080,6 +1137,15 @@ dependencies = [
|
|||
"syn 2.0.48",
|
||||
]
|
||||
|
||||
[[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"
|
||||
|
@ -1272,9 +1338,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "napi"
|
||||
version = "2.14.4"
|
||||
version = "2.15.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "902495f6b80f53f8435aefbbd2241c9c675fa239cd7e5f8e28fb57f3b69ecd09"
|
||||
checksum = "efbf98e1bcb85cc441bbf7cdfb11070d2537a100e2697d75397b2584c32492d1"
|
||||
dependencies = [
|
||||
"bitflags 2.4.2",
|
||||
"chrono",
|
||||
|
@ -1295,9 +1361,9 @@ checksum = "d4b4532cf86bfef556348ac65e561e3123879f0e7566cca6d43a6ff5326f13df"
|
|||
|
||||
[[package]]
|
||||
name = "napi-derive"
|
||||
version = "2.14.6"
|
||||
version = "2.15.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e61bec1ee990ae3e9a5f443484c65fb38e571a898437f0ad283ed69c82fc59c0"
|
||||
checksum = "7622f0dbe0968af2dacdd64870eee6dee94f93c989c841f1ad8f300cf1abd514"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"convert_case",
|
||||
|
@ -1309,9 +1375,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "napi-derive-backend"
|
||||
version = "1.0.58"
|
||||
version = "1.0.59"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2314f777bc9cde51705d991c44466cee4de4a3f41c6d3d019fcbbebb5cdd47c4"
|
||||
checksum = "8ec514d65fce18a959be55e7f683ac89c6cb850fb59b09e25ab777fd5a4a8d9e"
|
||||
dependencies = [
|
||||
"convert_case",
|
||||
"once_cell",
|
||||
|
@ -1559,6 +1625,17 @@ dependencies = [
|
|||
"syn 2.0.48",
|
||||
]
|
||||
|
||||
[[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"
|
||||
|
@ -1771,9 +1848,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "regex-automata"
|
||||
version = "0.4.4"
|
||||
version = "0.4.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3b7fa1134405e2ec9353fd416b17f8dacd46c473d7d3fd1cf202706a14eb792a"
|
||||
checksum = "5bb987efffd3c6d0d8f5f89510bb458559eab11e4f869acb20bf845e016259cd"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
|
@ -2113,18 +2190,18 @@ checksum = "b97ed7a9823b74f99c7742f5336af7be5ecd3eeafcb1507d1fa93347b1d589b0"
|
|||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.195"
|
||||
version = "1.0.196"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "63261df402c67811e9ac6def069e4786148c4563f4b50fd4bf30aa370d626b02"
|
||||
checksum = "870026e60fa08c69f064aa766c10f10b1d62db9ccd4d0abb206472bee0ce3b32"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.195"
|
||||
version = "1.0.196"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "46fe8f8603d81ba86327b23a2e9cdf49e1255fb94a4c5f297f6ee0547178ea2c"
|
||||
checksum = "33c85360c95e7d137454dc81d9a4ed2b8efd8fbe19cee57357b32b9771fccb67"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -2144,9 +2221,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.111"
|
||||
version = "1.0.112"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "176e46fa42316f18edd598015a5166857fc835ec732f5215eac6b7bdbf0a84f4"
|
||||
checksum = "4d1bd37ce2324cf3bf85e5a25f96eb4baf0d5aa6eba43e7ae8958870c4ec48ed"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
|
@ -3168,9 +3245,9 @@ checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04"
|
|||
|
||||
[[package]]
|
||||
name = "winnow"
|
||||
version = "0.5.34"
|
||||
version = "0.5.35"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b7cf47b659b318dccbd69cc4797a39ae128f533dce7902a1096044d1967b9c16"
|
||||
checksum = "1931d78a9c73861da0134f453bb1f790ce49b2e30eba8410b4b79bac72b46a2d"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
|
|
@ -20,6 +20,7 @@ jsonschema = "0.17.1"
|
|||
once_cell = "1.19.0"
|
||||
parse-display = "0.8.2"
|
||||
rand = "0.8.5"
|
||||
regex = "1.10.3"
|
||||
schemars = { version = "0.8.16", features = ["chrono"] }
|
||||
sea-orm = { version = "0.12.12", features = ["sqlx-postgres", "runtime-tokio-rustls"] }
|
||||
serde = { version = "1.0.195", features = ["derive"] }
|
||||
|
@ -34,6 +35,8 @@ napi = { version = "2.14.4", default-features = false, features = ["napi9", "tok
|
|||
napi-derive = { version = "2.14.6", optional = true }
|
||||
basen = "0.1.0"
|
||||
urlencoding = "2.1.3"
|
||||
argon2 = "0.5.3"
|
||||
bcrypt = "0.15.0"
|
||||
|
||||
[dev-dependencies]
|
||||
pretty_assertions = "1.4.0"
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#[cfg_attr(feature = "napi", napi_derive::napi)]
|
||||
#[napi_derive::napi]
|
||||
pub struct EnvConfig {
|
||||
pub only_queue: bool,
|
||||
pub only_server: bool,
|
||||
|
@ -10,7 +10,7 @@ pub struct EnvConfig {
|
|||
pub slow: bool,
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "napi", napi_derive::napi)]
|
||||
#[napi_derive::napi]
|
||||
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" || node_env == "testing";
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
use once_cell::sync::Lazy;
|
||||
use serde::Deserialize;
|
||||
use serde_yaml;
|
||||
use std::env;
|
||||
use std::fs;
|
||||
|
||||
#[derive(Debug, PartialEq, Deserialize)]
|
||||
#[derive(Clone, Debug, PartialEq, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[cfg_attr(feature = "napi", napi_derive::napi(object))]
|
||||
#[napi_derive::napi(object)]
|
||||
pub struct ServerConfig {
|
||||
pub url: String,
|
||||
pub db: DbConfig,
|
||||
|
@ -13,8 +14,8 @@ pub struct ServerConfig {
|
|||
pub cache_server: Option<RedisConfig>,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Deserialize)]
|
||||
#[cfg_attr(feature = "napi", napi_derive::napi(object))]
|
||||
#[derive(Clone, Debug, PartialEq, Deserialize)]
|
||||
#[napi_derive::napi(object)]
|
||||
pub struct DbConfig {
|
||||
pub host: String,
|
||||
pub port: u32,
|
||||
|
@ -23,8 +24,8 @@ pub struct DbConfig {
|
|||
pub pass: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Deserialize)]
|
||||
#[cfg_attr(feature = "napi", napi_derive::napi(object))]
|
||||
#[derive(Clone, Debug, PartialEq, Deserialize)]
|
||||
#[napi_derive::napi(object)]
|
||||
pub struct RedisConfig {
|
||||
pub host: String,
|
||||
pub port: u32,
|
||||
|
@ -37,18 +38,20 @@ pub struct RedisConfig {
|
|||
pub prefix: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Deserialize)]
|
||||
#[derive(Clone, Debug, PartialEq, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[cfg_attr(feature = "napi", napi_derive::napi(object))]
|
||||
#[napi_derive::napi(object)]
|
||||
pub struct TlsConfig {
|
||||
pub host: String,
|
||||
pub reject_unauthorized: bool,
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "napi", napi_derive::napi)]
|
||||
#[napi_derive::napi]
|
||||
pub fn read_server_config() -> ServerConfig {
|
||||
let cwd = env::current_dir().unwrap();
|
||||
let yml = fs::File::open(cwd.join("../../.config/default.yml"))
|
||||
.expect("Failed to open '.config/default.yml'");
|
||||
serde_yaml::from_reader(yml).expect("Failed to parse yaml")
|
||||
}
|
||||
|
||||
pub static SERVER_CONFIG: Lazy<ServerConfig> = Lazy::new(read_server_config);
|
||||
|
|
40
packages/backend-rs/src/database/connect.rs
Normal file
40
packages/backend-rs/src/database/connect.rs
Normal file
|
@ -0,0 +1,40 @@
|
|||
use crate::config::server::SERVER_CONFIG;
|
||||
use crate::database::NapiDbErrExt;
|
||||
use sea_orm::{Database, DbConn};
|
||||
use urlencoding::encode;
|
||||
|
||||
#[napi_derive::napi]
|
||||
pub struct JsDbConn {
|
||||
inner: DbConn,
|
||||
}
|
||||
impl JsDbConn {
|
||||
pub fn inner(&self) -> &DbConn {
|
||||
&self.inner
|
||||
}
|
||||
}
|
||||
|
||||
#[napi_derive::napi]
|
||||
pub async fn connect_to_database() -> napi::Result<JsDbConn> {
|
||||
let conn_uri = format!(
|
||||
"postgres://{}:{}@{}:{}/{}",
|
||||
SERVER_CONFIG.db.user,
|
||||
encode(&SERVER_CONFIG.db.pass),
|
||||
SERVER_CONFIG.db.host,
|
||||
SERVER_CONFIG.db.port,
|
||||
SERVER_CONFIG.db.db,
|
||||
);
|
||||
let conn = Database::connect(conn_uri)
|
||||
.await
|
||||
.map_err(NapiDbErrExt::into)?;
|
||||
Ok(JsDbConn { inner: conn })
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod unit_test {
|
||||
use super::connect_to_database;
|
||||
|
||||
#[tokio::test]
|
||||
async fn connect_test() {
|
||||
assert!(connect_to_database().await.is_ok());
|
||||
}
|
||||
}
|
|
@ -1,50 +1,5 @@
|
|||
pub mod connect;
|
||||
pub mod error;
|
||||
|
||||
pub use connect::JsDbConn;
|
||||
pub use error::NapiDbErrExt;
|
||||
|
||||
use crate::config::server::DbConfig;
|
||||
use sea_orm::{Database, DbConn};
|
||||
use urlencoding::encode;
|
||||
|
||||
#[napi_derive::napi]
|
||||
pub struct JsDbConn {
|
||||
inner: DbConn,
|
||||
}
|
||||
impl JsDbConn {
|
||||
pub fn inner(&self) -> &DbConn {
|
||||
&self.inner
|
||||
}
|
||||
}
|
||||
|
||||
#[napi_derive::napi]
|
||||
pub async fn connect_to_database(config: DbConfig) -> napi::Result<JsDbConn> {
|
||||
let conn_uri = format!(
|
||||
"postgres://{}:{}@{}:{}/{}",
|
||||
config.user,
|
||||
encode(&config.pass),
|
||||
config.host,
|
||||
config.port,
|
||||
config.db,
|
||||
);
|
||||
let conn = Database::connect(conn_uri)
|
||||
.await
|
||||
.map_err(NapiDbErrExt::into)?;
|
||||
Ok(JsDbConn { inner: conn })
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod unit_test {
|
||||
use super::connect_to_database;
|
||||
use crate::config::server::read_server_config;
|
||||
|
||||
#[tokio::test]
|
||||
async fn connect_with_server_config() {
|
||||
assert!(connect_to_database(read_server_config().db).await.is_ok());
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn connect_with_incorrect_password() {
|
||||
let mut config = read_server_config().db;
|
||||
config.pass.push('.'); // password should be incorrect now
|
||||
assert!(connect_to_database(config).await.is_err());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ pub mod config;
|
|||
pub mod database;
|
||||
pub mod macros;
|
||||
pub mod model;
|
||||
pub mod prelude;
|
||||
pub mod util;
|
||||
|
||||
// #[cfg(feature = "napi")]
|
||||
|
|
3
packages/backend-rs/src/prelude.rs
Normal file
3
packages/backend-rs/src/prelude.rs
Normal file
|
@ -0,0 +1,3 @@
|
|||
pub fn to_napi_error<E: ToString>(err: E) -> napi::Error {
|
||||
napi::Error::from_reason(err.to_string())
|
||||
}
|
|
@ -1,24 +1,20 @@
|
|||
use crate::config::server::ServerConfig;
|
||||
use crate::config::server::SERVER_CONFIG;
|
||||
use idna;
|
||||
use url::Url;
|
||||
|
||||
#[napi_derive::napi]
|
||||
pub fn get_full_ap_account(
|
||||
server_config: ServerConfig,
|
||||
username: String,
|
||||
host: Option<String>,
|
||||
) -> String {
|
||||
pub fn get_full_ap_account(username: String, host: Option<String>) -> String {
|
||||
if host.is_none() {
|
||||
format!("{}@{}", username, extract_host(server_config.url))
|
||||
format!("{}@{}", username, extract_host(SERVER_CONFIG.url.clone()))
|
||||
} else {
|
||||
format!("{}@{}", username, to_puny(host.unwrap()))
|
||||
}
|
||||
}
|
||||
|
||||
#[napi_derive::napi]
|
||||
pub fn is_self_host(server_config: ServerConfig, host: Option<String>) -> bool {
|
||||
pub fn is_self_host(host: Option<String>) -> bool {
|
||||
if let Some(x) = host {
|
||||
extract_host(server_config.url) == to_puny(x)
|
||||
extract_host(SERVER_CONFIG.url.clone()) == to_puny(x)
|
||||
} else {
|
||||
true
|
||||
}
|
||||
|
|
|
@ -6,4 +6,6 @@ pub mod format_milliseconds;
|
|||
pub mod id;
|
||||
pub mod meta;
|
||||
pub mod note;
|
||||
pub mod nyaify;
|
||||
pub mod password;
|
||||
pub mod random;
|
||||
|
|
84
packages/backend-rs/src/util/nyaify.rs
Normal file
84
packages/backend-rs/src/util/nyaify.rs
Normal file
|
@ -0,0 +1,84 @@
|
|||
use once_cell::sync::Lazy;
|
||||
use regex::{Captures, Regex};
|
||||
|
||||
#[napi_derive::napi]
|
||||
pub fn nyaify(text: String, lang: Option<String>, append_miao: bool) -> String {
|
||||
let mut to_return = text.clone();
|
||||
|
||||
{
|
||||
static RE: Lazy<Regex> =
|
||||
Lazy::new(|| Regex::new(r"(?i-u)(non)([bcdfghjklmnpqrstvwxyz])").unwrap());
|
||||
to_return = RE
|
||||
.replace_all(&to_return, |caps: &Captures<'_>| {
|
||||
format!(
|
||||
"{}{}",
|
||||
match &caps[1] {
|
||||
"non" => "nyan",
|
||||
"Non" => "Nyan",
|
||||
"NON" => "NYAN",
|
||||
_ => &caps[1],
|
||||
},
|
||||
&caps[2]
|
||||
)
|
||||
})
|
||||
.to_string();
|
||||
}
|
||||
|
||||
{
|
||||
static RE: Lazy<Regex> = Lazy::new(|| Regex::new(r"다([..。…??!!\s]|$)").unwrap());
|
||||
to_return = RE.replace_all(&to_return, r"다냥$1").to_string();
|
||||
}
|
||||
|
||||
{
|
||||
static RE: Lazy<Regex> = Lazy::new(|| Regex::new(r"야([??\s]|$)").unwrap());
|
||||
to_return = RE.replace_all(&to_return, r"냥$1").to_string();
|
||||
}
|
||||
|
||||
{
|
||||
static RE: Lazy<Regex> = Lazy::new(|| Regex::new(r"([나-낳])").unwrap());
|
||||
to_return = RE
|
||||
.replace_all(&to_return, |caps: &Captures<'_>| {
|
||||
format!(
|
||||
"{}",
|
||||
char::from_u32(
|
||||
caps[0].chars().next().unwrap() as u32 + 56 /* = '냐' - '나' */
|
||||
)
|
||||
.unwrap()
|
||||
)
|
||||
})
|
||||
.to_string();
|
||||
}
|
||||
|
||||
if lang.is_some() && lang.unwrap().starts_with("zh") {
|
||||
static RE: Lazy<Regex> = Lazy::new(|| Regex::new(r"[妙庙描渺瞄秒苗藐廟]").unwrap());
|
||||
to_return = RE.replace_all(&to_return, "喵").to_string();
|
||||
}
|
||||
|
||||
let simple_rules = [
|
||||
("な", "にゃ"),
|
||||
("ナ", "ニャ"),
|
||||
("ナ", "ニャ"),
|
||||
("na", "nya"),
|
||||
("NA", "NYA"),
|
||||
("Na", "Nya"),
|
||||
("morning", "mornyan"),
|
||||
("Morning", "Mornyan"),
|
||||
("MORNING", "MORNYAN"),
|
||||
("everyone", "everynyan"),
|
||||
("Everyone", "Everynyan"),
|
||||
("EVERYONE", "EVERYNYAN"),
|
||||
("να", "νια"),
|
||||
("ΝΑ", "ΝΙΑ"),
|
||||
("Να", "Νια"),
|
||||
];
|
||||
|
||||
simple_rules.into_iter().for_each(|(from, to)| {
|
||||
to_return = to_return.replace(from, to);
|
||||
});
|
||||
|
||||
if append_miao {
|
||||
to_return.push('喵');
|
||||
}
|
||||
|
||||
to_return
|
||||
}
|
37
packages/backend-rs/src/util/password.rs
Normal file
37
packages/backend-rs/src/util/password.rs
Normal file
|
@ -0,0 +1,37 @@
|
|||
use crate::prelude::to_napi_error;
|
||||
use argon2::{
|
||||
password_hash::{rand_core::OsRng, PasswordHash, PasswordHasher, PasswordVerifier, SaltString},
|
||||
Argon2,
|
||||
};
|
||||
|
||||
#[napi_derive::napi]
|
||||
pub async fn hash_password(password: String) -> napi::Result<String> {
|
||||
let salt = SaltString::generate(&mut OsRng);
|
||||
Argon2::default()
|
||||
.hash_password(password.as_bytes(), &salt)
|
||||
.map(|s| s.to_string())
|
||||
.map_err(to_napi_error)
|
||||
}
|
||||
|
||||
#[napi_derive::napi]
|
||||
pub async fn verify_password(password: String, hash: String) -> napi::Result<bool> {
|
||||
if _is_old_password_algorithm(&hash) {
|
||||
bcrypt::verify(&password, &hash).map_err(to_napi_error)
|
||||
} else {
|
||||
let parsed_hash = PasswordHash::new(&hash).map_err(to_napi_error)?;
|
||||
Ok(Argon2::default()
|
||||
.verify_password(password.as_bytes(), &parsed_hash)
|
||||
.is_ok())
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn _is_old_password_algorithm(hash: &str) -> bool {
|
||||
// bcrypt hashes start with $2[ab]$
|
||||
hash.starts_with("$2")
|
||||
}
|
||||
|
||||
#[napi_derive::napi]
|
||||
pub fn is_old_password_algorithm(hash: String) -> bool {
|
||||
_is_old_password_algorithm(&hash)
|
||||
}
|
|
@ -3,18 +3,16 @@ import {
|
|||
readEnvironmentConfig,
|
||||
connectToDatabase,
|
||||
fetchMeta as fetchMetaImpl,
|
||||
getFullApAccount as getFullApAccountImpl,
|
||||
hasOtherRenoteOfThisNote as hasOtherRenoteOfThisNoteImpl,
|
||||
isSelfHost as isSelfHostImpl,
|
||||
JsDbConn,
|
||||
} from "backend-rs";
|
||||
|
||||
export const serverConfig = readServerConfig();
|
||||
export const envConfig = readEnvironmentConfig();
|
||||
const dbPromise = connectToDatabase(serverConfig.db);
|
||||
|
||||
type Option<T> = T | null | undefined;
|
||||
|
||||
const dbPromise = connectToDatabase();
|
||||
const curryDb =
|
||||
<P extends any[], R>(f: (db: JsDbConn, ...args: P) => Promise<R>) =>
|
||||
(...args: P) =>
|
||||
|
@ -22,14 +20,3 @@ const curryDb =
|
|||
|
||||
export const fetchMeta = curryDb(fetchMetaImpl);
|
||||
export const hasOtherRenoteOfThisNote = curryDb(hasOtherRenoteOfThisNoteImpl);
|
||||
|
||||
export function getFullApAccount(
|
||||
username: string,
|
||||
host: Option<string>,
|
||||
): string {
|
||||
return getFullApAccountImpl(serverConfig, username, host);
|
||||
}
|
||||
|
||||
export function isSelfHost(host: Option<string>): boolean {
|
||||
return isSelfHostImpl(serverConfig, host);
|
||||
}
|
||||
|
|
|
@ -2,8 +2,7 @@ import type { Antenna } from "@/models/entities/antenna.js";
|
|||
import type { Note } from "@/models/entities/note.js";
|
||||
import type { User } from "@/models/entities/user.js";
|
||||
import { Blockings, Followings, UserProfiles } from "@/models/index.js";
|
||||
import { getFullApAccount } from "@/misc/backend-rs.js";
|
||||
import { stringToAcct } from "backend-rs";
|
||||
import { getFullApAccount, stringToAcct } from "backend-rs";
|
||||
import type { Packed } from "@/misc/schema.js";
|
||||
import { Cache } from "@/misc/cache.js";
|
||||
import { getWordHardMute } from "@/misc/check-word-mute.js";
|
||||
|
|
|
@ -1,38 +0,0 @@
|
|||
export default function (
|
||||
text: string,
|
||||
lang: string | undefined,
|
||||
appendMiao: boolean,
|
||||
): string {
|
||||
text = text
|
||||
// ja-JP
|
||||
.replaceAll("な", "にゃ")
|
||||
.replaceAll("ナ", "ニャ")
|
||||
.replaceAll("ナ", "ニャ")
|
||||
// en-US
|
||||
.replaceAll("na", "nya")
|
||||
.replaceAll("Na", "Nya")
|
||||
.replaceAll("NA", "NYA")
|
||||
.replace(/(?<=morn)ing/gi, (x) => (x === "ING" ? "YAN" : "yan"))
|
||||
.replace(/(?<=every)one/gi, (x) => (x === "ONE" ? "NYAN" : "nyan"))
|
||||
.replace(/non(?=[bcdfghjklmnpqrstvwxyz])/gi, (x) =>
|
||||
x === "NON" ? "NYAN" : "nyan",
|
||||
)
|
||||
// ko-KR
|
||||
.replace(/[나-낳]/g, (match) =>
|
||||
String.fromCharCode(
|
||||
match.charCodeAt(0)! + "냐".charCodeAt(0) - "나".charCodeAt(0),
|
||||
),
|
||||
)
|
||||
.replace(/(다$)|(다(?=\.))|(다(?= ))|(다(?=!))|(다(?=\?))/gm, "다냥")
|
||||
.replace(/(야(?=\?))|(야$)|(야(?= ))/gm, "냥")
|
||||
// el-GR
|
||||
.replaceAll("να", "νια")
|
||||
.replaceAll("ΝΑ", "ΝΙΑ")
|
||||
.replaceAll("Να", "Νια");
|
||||
|
||||
// zh-CN, zh-TW
|
||||
if (lang === "zh") text = text.replace(/(妙|庙|描|渺|瞄|秒|苗|藐|廟)/g, "喵");
|
||||
if (appendMiao) text += "喵";
|
||||
|
||||
return text;
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
import bcrypt from "bcryptjs";
|
||||
import * as argon2 from "argon2";
|
||||
|
||||
export async function hashPassword(password: string): Promise<string> {
|
||||
return argon2.hash(password);
|
||||
}
|
||||
|
||||
export async function comparePassword(
|
||||
password: string,
|
||||
hash: string,
|
||||
): Promise<boolean> {
|
||||
if (isOldAlgorithm(hash)) return bcrypt.compare(password, hash);
|
||||
|
||||
return argon2.verify(hash, password);
|
||||
}
|
||||
|
||||
export function isOldAlgorithm(hash: string): boolean {
|
||||
// bcrypt hashes start with $2[ab]$
|
||||
return hash.startsWith("$2");
|
||||
}
|
|
@ -3,8 +3,7 @@ import { Emojis } from "@/models/index.js";
|
|||
import type { Emoji } from "@/models/entities/emoji.js";
|
||||
import type { Note } from "@/models/entities/note.js";
|
||||
import { Cache } from "./cache.js";
|
||||
import { toPunyOptional } from "backend-rs";
|
||||
import { isSelfHost } from "@/misc/backend-rs.js";
|
||||
import { isSelfHost, toPunyOptional } from "backend-rs";
|
||||
import { decodeReaction } from "./reaction-lib.js";
|
||||
import config from "@/config/index.js";
|
||||
import { query } from "@/prelude/url.js";
|
||||
|
|
|
@ -12,7 +12,7 @@ import {
|
|||
Channels,
|
||||
} from "../index.js";
|
||||
import type { Packed } from "@/misc/schema.js";
|
||||
import nyaify from "@/misc/nyaify.js";
|
||||
import { nyaify } from "backend-rs";
|
||||
import { awaitAll } from "@/prelude/await-all.js";
|
||||
import { convertReactions, decodeReaction } from "@/misc/reaction-lib.js";
|
||||
import type { NoteReaction } from "@/models/entities/note-reaction.js";
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
import type { CacheableRemoteUser } from "@/models/entities/user.js";
|
||||
import type { IRead } from "../type.js";
|
||||
import { getApId } from "../type.js";
|
||||
import { extractHost } from "backend-rs";
|
||||
import { isSelfHost } from "@/misc/backend-rs.js";
|
||||
import { extractHost, isSelfHost } from "backend-rs";
|
||||
import { MessagingMessages } from "@/models/index.js";
|
||||
import { readUserMessagingMessage } from "@/server/api/common/read-messaging-message.js";
|
||||
|
||||
|
|
|
@ -3,8 +3,7 @@ import { getJson } from "@/misc/fetch.js";
|
|||
import type { ILocalUser } from "@/models/entities/user.js";
|
||||
import { getInstanceActor } from "@/services/instance-actor.js";
|
||||
import { fetchMeta } from "@/misc/backend-rs.js";
|
||||
import { extractHost } from "backend-rs";
|
||||
import { isSelfHost } from "@/misc/backend-rs.js";
|
||||
import { extractHost, isSelfHost } from "backend-rs";
|
||||
import { signedGet } from "./request.js";
|
||||
import type { IObject, ICollection, IOrderedCollection } from "./type.js";
|
||||
import { isCollectionOrOrderedCollection, getApId } from "./type.js";
|
||||
|
|
|
@ -9,7 +9,7 @@ import renderKey from "@/remote/activitypub/renderer/key.js";
|
|||
import { renderPerson } from "@/remote/activitypub/renderer/person.js";
|
||||
import renderEmoji from "@/remote/activitypub/renderer/emoji.js";
|
||||
import { inbox as processInbox } from "@/queue/index.js";
|
||||
import { isSelfHost } from "@/misc/backend-rs.js";
|
||||
import { isSelfHost } from "backend-rs";
|
||||
import {
|
||||
Notes,
|
||||
Users,
|
||||
|
|
|
@ -10,7 +10,7 @@ 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 { hashPassword } from "@/misc/password.js";
|
||||
import { hashPassword } from "backend-rs";
|
||||
|
||||
export async function signup(opts: {
|
||||
username: User["username"];
|
||||
|
|
|
@ -2,7 +2,7 @@ import define from "@/server/api/define.js";
|
|||
// import bcrypt from "bcryptjs";
|
||||
import rndstr from "rndstr";
|
||||
import { Users, UserProfiles } from "@/models/index.js";
|
||||
import { hashPassword } from "@/misc/password.js";
|
||||
import { hashPassword } from "backend-rs";
|
||||
|
||||
export const meta = {
|
||||
tags: ["admin"],
|
||||
|
|
|
@ -9,7 +9,7 @@ import {
|
|||
import config from "@/config/index.js";
|
||||
import { procedures, hash } from "@/server/api/2fa.js";
|
||||
import { publishMainStream } from "@/services/stream.js";
|
||||
import { comparePassword } from "@/misc/password.js";
|
||||
import { verifyPassword } from "backend-rs";
|
||||
|
||||
const rpIdHashReal = hash(Buffer.from(config.hostname, "utf-8"));
|
||||
|
||||
|
@ -41,7 +41,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
const profile = await UserProfiles.findOneByOrFail({ userId: user.id });
|
||||
|
||||
// Compare password
|
||||
const same = await comparePassword(ps.password, profile.password!);
|
||||
const same = await verifyPassword(ps.password, profile.password!);
|
||||
|
||||
if (!same) {
|
||||
throw new Error("incorrect password");
|
||||
|
|
|
@ -4,7 +4,7 @@ import { promisify } from "node:util";
|
|||
import * as crypto from "node:crypto";
|
||||
import { genId } from "@/misc/gen-id.js";
|
||||
import { hash } from "@/server/api/2fa.js";
|
||||
import { comparePassword } from "@/misc/password.js";
|
||||
import { verifyPassword } from "backend-rs";
|
||||
|
||||
const randomBytes = promisify(crypto.randomBytes);
|
||||
|
||||
|
@ -26,7 +26,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
const profile = await UserProfiles.findOneByOrFail({ userId: user.id });
|
||||
|
||||
// Compare password
|
||||
const same = await comparePassword(ps.password, profile.password!);
|
||||
const same = await verifyPassword(ps.password, profile.password!);
|
||||
|
||||
if (!same) {
|
||||
throw new Error("incorrect password");
|
||||
|
|
|
@ -3,7 +3,7 @@ import * as QRCode from "qrcode";
|
|||
import config from "@/config/index.js";
|
||||
import { UserProfiles } from "@/models/index.js";
|
||||
import define from "@/server/api/define.js";
|
||||
import { comparePassword } from "@/misc/password.js";
|
||||
import { verifyPassword } from "backend-rs";
|
||||
|
||||
export const meta = {
|
||||
requireCredential: true,
|
||||
|
@ -23,7 +23,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
const profile = await UserProfiles.findOneByOrFail({ userId: user.id });
|
||||
|
||||
// Compare password
|
||||
const same = await comparePassword(ps.password, profile.password!);
|
||||
const same = await verifyPassword(ps.password, profile.password!);
|
||||
|
||||
if (!same) {
|
||||
throw new Error("incorrect password");
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { comparePassword } from "@/misc/password.js";
|
||||
import { verifyPassword } from "backend-rs";
|
||||
import define from "@/server/api/define.js";
|
||||
import { UserProfiles, UserSecurityKeys, Users } from "@/models/index.js";
|
||||
import { publishMainStream } from "@/services/stream.js";
|
||||
|
@ -22,7 +22,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
const profile = await UserProfiles.findOneByOrFail({ userId: user.id });
|
||||
|
||||
// Compare password
|
||||
const same = await comparePassword(ps.password, profile.password!);
|
||||
const same = await verifyPassword(ps.password, profile.password!);
|
||||
|
||||
if (!same) {
|
||||
throw new Error("incorrect password");
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { publishMainStream } from "@/services/stream.js";
|
||||
import define from "@/server/api/define.js";
|
||||
import { Users, UserProfiles } from "@/models/index.js";
|
||||
import { comparePassword } from "@/misc/password.js";
|
||||
import { verifyPassword } from "backend-rs";
|
||||
|
||||
export const meta = {
|
||||
requireCredential: true,
|
||||
|
@ -21,7 +21,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
const profile = await UserProfiles.findOneByOrFail({ userId: user.id });
|
||||
|
||||
// Compare password
|
||||
const same = await comparePassword(ps.password, profile.password!);
|
||||
const same = await verifyPassword(ps.password, profile.password!);
|
||||
|
||||
if (!same) {
|
||||
throw new Error("incorrect password");
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import define from "@/server/api/define.js";
|
||||
import { UserProfiles } from "@/models/index.js";
|
||||
import { hashPassword, comparePassword } from "@/misc/password.js";
|
||||
import { hashPassword, verifyPassword } from "backend-rs";
|
||||
|
||||
export const meta = {
|
||||
requireCredential: true,
|
||||
|
@ -21,7 +21,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
const profile = await UserProfiles.findOneByOrFail({ userId: user.id });
|
||||
|
||||
// Compare password
|
||||
const same = await comparePassword(ps.currentPassword, profile.password!);
|
||||
const same = await verifyPassword(ps.currentPassword, profile.password!);
|
||||
|
||||
if (!same) {
|
||||
throw new Error("incorrect password");
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { UserProfiles, Users } from "@/models/index.js";
|
||||
import { deleteAccount } from "@/services/delete-account.js";
|
||||
import define from "@/server/api/define.js";
|
||||
import { comparePassword } from "@/misc/password.js";
|
||||
import { verifyPassword } from "backend-rs";
|
||||
|
||||
export const meta = {
|
||||
requireCredential: true,
|
||||
|
@ -25,7 +25,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
}
|
||||
|
||||
// Compare password
|
||||
const same = await comparePassword(ps.password, profile.password!);
|
||||
const same = await verifyPassword(ps.password, profile.password!);
|
||||
|
||||
if (!same) {
|
||||
throw new Error("incorrect password");
|
||||
|
|
|
@ -6,7 +6,7 @@ import {
|
|||
import generateUserToken from "@/server/api/common/generate-native-user-token.js";
|
||||
import define from "@/server/api/define.js";
|
||||
import { Users, UserProfiles } from "@/models/index.js";
|
||||
import { comparePassword } from "@/misc/password.js";
|
||||
import { verifyPassword } from "backend-rs";
|
||||
|
||||
export const meta = {
|
||||
requireCredential: true,
|
||||
|
@ -29,7 +29,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
const profile = await UserProfiles.findOneByOrFail({ userId: user.id });
|
||||
|
||||
// Compare password
|
||||
const same = await comparePassword(ps.password, profile.password!);
|
||||
const same = await verifyPassword(ps.password, profile.password!);
|
||||
|
||||
if (!same) {
|
||||
throw new Error("incorrect password");
|
||||
|
|
|
@ -7,7 +7,7 @@ import { sendEmail } from "@/services/send-email.js";
|
|||
import { ApiError } from "@/server/api/error.js";
|
||||
import { validateEmailForAccount } from "@/services/validate-email-for-account.js";
|
||||
import { HOUR } from "@/const.js";
|
||||
import { comparePassword } from "@/misc/password.js";
|
||||
import { verifyPassword } from "backend-rs";
|
||||
|
||||
export const meta = {
|
||||
requireCredential: true,
|
||||
|
@ -47,7 +47,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
const profile = await UserProfiles.findOneByOrFail({ userId: user.id });
|
||||
|
||||
// Compare password
|
||||
const same = await comparePassword(ps.password, profile.password!);
|
||||
const same = await verifyPassword(ps.password, profile.password!);
|
||||
|
||||
if (!same) {
|
||||
throw new ApiError(meta.errors.incorrectPassword);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { UserProfiles, PasswordResetRequests } from "@/models/index.js";
|
||||
import define from "@/server/api/define.js";
|
||||
import { hashPassword } from "@/misc/password.js";
|
||||
import { hashPassword } from "backend-rs";
|
||||
|
||||
export const meta = {
|
||||
tags: ["reset password"],
|
||||
|
|
|
@ -12,10 +12,10 @@ import {
|
|||
import type { ILocalUser } from "@/models/entities/user.js";
|
||||
import { genId } from "@/misc/gen-id.js";
|
||||
import {
|
||||
comparePassword,
|
||||
verifyPassword,
|
||||
hashPassword,
|
||||
isOldAlgorithm,
|
||||
} from "@/misc/password.js";
|
||||
isOldPasswordAlgorithm,
|
||||
} from "backend-rs";
|
||||
import { verifyLogin, hash } from "@/server/api/2fa.js";
|
||||
import { randomBytes } from "node:crypto";
|
||||
import { IsNull } from "typeorm";
|
||||
|
@ -92,9 +92,9 @@ export default async (ctx: Koa.Context) => {
|
|||
const profile = await UserProfiles.findOneByOrFail({ userId: user.id });
|
||||
|
||||
// Compare password
|
||||
const same = await comparePassword(password, profile.password!);
|
||||
const same = await verifyPassword(password, profile.password!);
|
||||
|
||||
if (same && isOldAlgorithm(profile.password!)) {
|
||||
if (same && isOldPasswordAlgorithm(profile.password!)) {
|
||||
profile.password = await hashPassword(password);
|
||||
await UserProfiles.save(profile);
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ import config from "@/config/index.js";
|
|||
import { sendEmail } from "@/services/send-email.js";
|
||||
import { genId } from "@/misc/gen-id.js";
|
||||
import { validateEmailForAccount } from "@/services/validate-email-for-account.js";
|
||||
import { hashPassword } from "@/misc/password.js";
|
||||
import { hashPassword } from "backend-rs";
|
||||
|
||||
export default async (ctx: Koa.Context) => {
|
||||
const body = ctx.request.body;
|
||||
|
|
|
@ -8,7 +8,7 @@ import { genId } from "@/misc/gen-id.js";
|
|||
import { UserKeypair } from "@/models/entities/user-keypair.js";
|
||||
import { UsedUsername } from "@/models/entities/used-username.js";
|
||||
import { db } from "@/db/postgre.js";
|
||||
import { hashPassword } from "@/misc/password.js";
|
||||
import { hashPassword } from "backend-rs";
|
||||
|
||||
export async function createSystemUser(username: string) {
|
||||
const password = uuid();
|
||||
|
|
Loading…
Reference in a new issue