refactor code
This commit is contained in:
parent
e6c2e2385f
commit
c25fffa956
|
@ -65,9 +65,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "async-trait"
|
||||
version = "0.1.53"
|
||||
version = "0.1.56"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed6aa3524a2dfcf9fe180c51eae2b58738348d819517ceadf95789c51fff7600"
|
||||
checksum = "96cf8829f67d2eab0b2dfa42c5d0ef737e0724e4a82b01b3e292456202b19716"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -215,9 +215,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.9.1"
|
||||
version = "3.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899"
|
||||
checksum = "37ccbd214614c6783386c1af30caf03192f17891059cecc394b4fb119e363de3"
|
||||
|
||||
[[package]]
|
||||
name = "byte-unit"
|
||||
|
@ -406,13 +406,11 @@ checksum = "77f3309417938f28bf8228fcff79a4a37103981e3e186d2ccd19c74b38f4eb71"
|
|||
|
||||
[[package]]
|
||||
name = "flate2"
|
||||
version = "1.0.23"
|
||||
version = "1.0.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b39522e96686d38f4bc984b9198e3a0613264abaebaff2c5c918bfa6b6da09af"
|
||||
checksum = "f82b0f4c27ad9f8bfd1f3208d882da2b09c301bc1c828fd3a00d0216d2fbbff6"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"crc32fast",
|
||||
"libc",
|
||||
"miniz_oxide",
|
||||
]
|
||||
|
||||
|
@ -636,6 +634,7 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
|
|||
name = "homedisk-core"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"better-panic",
|
||||
"homedisk-database",
|
||||
"homedisk-server",
|
||||
|
@ -655,6 +654,7 @@ dependencies = [
|
|||
"rust_utilities",
|
||||
"serde",
|
||||
"sqlx",
|
||||
"thiserror",
|
||||
"tokio",
|
||||
"uuid",
|
||||
]
|
||||
|
@ -697,9 +697,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "http"
|
||||
version = "0.2.7"
|
||||
version = "0.2.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ff8670570af52249509a86f5e3e18a08c60b177071826898fde8997cf5f6bfbb"
|
||||
checksum = "75f43d41e26995c17e71ee126451dd3941010b0514a81a9d11f3b341debc2399"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"fnv",
|
||||
|
@ -772,9 +772,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "1.8.1"
|
||||
version = "1.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0f647032dfaa1f8b6dc29bd3edb7bbef4861b8b8007ebb118d6db284fd59f6ee"
|
||||
checksum = "e6012d540c5baa3589337a98ce73408de9b5a25ec9fc2c6fd6be8f0d39e0ca5a"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"hashbrown",
|
||||
|
@ -920,9 +920,9 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
|
|||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.5.1"
|
||||
version = "0.5.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2b29bd4bc3f33391105ebee3589c19197c4271e3e5a9ec9bfe8127eeff8f082"
|
||||
checksum = "6f5c75688da582b8ffc1f1799e9db273f32133c49e048f614d22ec3256773ccc"
|
||||
dependencies = [
|
||||
"adler",
|
||||
]
|
||||
|
@ -1044,9 +1044,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "parking_lot"
|
||||
version = "0.12.0"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "87f5ec2493a61ac0506c0f4199f99070cbe83857b0337006a30f3e6719b8ef58"
|
||||
checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f"
|
||||
dependencies = [
|
||||
"lock_api",
|
||||
"parking_lot_core 0.9.3",
|
||||
|
@ -1147,15 +1147,6 @@ dependencies = [
|
|||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quickcheck"
|
||||
version = "1.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "588f6378e4dd99458b60ec275b4477add41ce4fa9f64dcba6f15adccb19b50d6"
|
||||
dependencies = [
|
||||
"rand",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.18"
|
||||
|
@ -1165,24 +1156,6 @@ dependencies = [
|
|||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
|
||||
dependencies = [
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.6.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.2.13"
|
||||
|
@ -1355,9 +1328,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "simple_asn1"
|
||||
version = "0.6.1"
|
||||
version = "0.6.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4a762b1c38b9b990c694b9c2f8abe3372ce6a9ceaae6bca39cfc46e054f45745"
|
||||
checksum = "adc4e5204eb1910f40f9cfa375f6f05b68c3abac4b6fd879c8ff5e7ae8a0a085"
|
||||
dependencies = [
|
||||
"num-bigint",
|
||||
"num-traits",
|
||||
|
@ -1521,9 +1494,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.95"
|
||||
version = "1.0.96"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fbaf6116ab8924f39d52792136fb74fd60a80194cf1b1c6ffa6453eef1c3f942"
|
||||
checksum = "0748dd251e24453cb8717f0354206b91557e4ec8703673a4b30208f2abaf1ebf"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -1607,7 +1580,6 @@ dependencies = [
|
|||
"itoa",
|
||||
"libc",
|
||||
"num_threads",
|
||||
"quickcheck",
|
||||
"time-macros",
|
||||
]
|
||||
|
||||
|
@ -1644,7 +1616,7 @@ dependencies = [
|
|||
"mio",
|
||||
"num_cpus",
|
||||
"once_cell",
|
||||
"parking_lot 0.12.0",
|
||||
"parking_lot 0.12.1",
|
||||
"pin-project-lite",
|
||||
"signal-hook-registry",
|
||||
"socket2",
|
||||
|
@ -1654,9 +1626,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "tokio-macros"
|
||||
version = "1.7.0"
|
||||
version = "1.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b557f72f448c511a979e2564e55d74e6c4432fc96ff4f6241bc6bded342643b7"
|
||||
checksum = "9724f9a975fb987ef7a3cd9be0350edcbe130698af5b8f7a631e23d42d052484"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -1676,9 +1648,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "tokio-stream"
|
||||
version = "0.1.8"
|
||||
version = "0.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "50145484efff8818b5ccd256697f36863f587da82cf8b409c53adf1e840798e3"
|
||||
checksum = "df54d54117d6fdc4e4fea40fe1e4e566b3505700e148a6827e59b34b0d2600d9"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"pin-project-lite",
|
||||
|
@ -1687,9 +1659,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "tokio-util"
|
||||
version = "0.7.2"
|
||||
version = "0.7.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f988a1a1adc2fb21f9c12aa96441da33a1728193ae0b95d2be22dbd17fcb4e5c"
|
||||
checksum = "cc463cd8deddc3770d20f9852143d50bf6094e640b485cb2e189a2099085ff45"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"futures-core",
|
||||
|
@ -1776,21 +1748,9 @@ dependencies = [
|
|||
"cfg-if",
|
||||
"log",
|
||||
"pin-project-lite",
|
||||
"tracing-attributes",
|
||||
"tracing-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-attributes"
|
||||
version = "0.1.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cc6b8ad3567499f98a1db7a752b07a7c8c7c7c34c332ec00effb2b0027974b7c"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-core"
|
||||
version = "0.1.26"
|
||||
|
|
|
@ -14,10 +14,11 @@ name = "cloud"
|
|||
path = "./src/main.rs"
|
||||
|
||||
[dependencies]
|
||||
anyhow = "1.0.57"
|
||||
better-panic = "0.3.0"
|
||||
simplelog = "0.12.0"
|
||||
tokio = { version = "1.19.2", features = ["full"] }
|
||||
log = { version = "0.4.17", features = ["max_level_debug", "release_max_level_warn"] }
|
||||
simplelog = "0.12.0"
|
||||
tokio = { version = "1.19.2", features = ["rt-multi-thread", "macros"] }
|
||||
homedisk-database = { path = "../database" }
|
||||
homedisk-server = { path = "../server" }
|
||||
homedisk-types = { path = "../types", features = ["config"] }
|
||||
|
|
|
@ -3,9 +3,11 @@ use std::fs::File;
|
|||
use log::LevelFilter;
|
||||
use simplelog::{ColorChoice, CombinedLogger, Config, TermLogger, TerminalMode, WriteLogger};
|
||||
|
||||
pub fn init() {
|
||||
pub fn init() -> anyhow::Result<()> {
|
||||
// init better_panic
|
||||
better_panic::install();
|
||||
|
||||
// init logger
|
||||
CombinedLogger::init(vec![
|
||||
TermLogger::new(
|
||||
LevelFilter::Debug,
|
||||
|
@ -18,6 +20,7 @@ pub fn init() {
|
|||
Config::default(),
|
||||
File::create("logs.log").expect("create logs file"),
|
||||
),
|
||||
])
|
||||
.expect("init simplelog");
|
||||
])?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -1,24 +1,25 @@
|
|||
mod init;
|
||||
|
||||
use homedisk_database::Database;
|
||||
use homedisk_server::run_http_server;
|
||||
use homedisk_types::config::types::Config;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
init::init();
|
||||
async fn main() -> anyhow::Result<()> {
|
||||
init::init()?;
|
||||
|
||||
let config = Config::parse().expect("parse configuration file");
|
||||
// parse config
|
||||
let config = Config::parse()?;
|
||||
|
||||
let db = Database::open("homedisk.db")
|
||||
.await
|
||||
.expect("open SQLite database");
|
||||
// open database connection
|
||||
let db = Database::open("homedisk.db").await?;
|
||||
|
||||
// change the type from Vec<String> to Vec<HeaderValue> so that the http server can correctly detect CORS hosts
|
||||
let origins = config
|
||||
.http
|
||||
.cors
|
||||
.iter()
|
||||
.map(|e| e.parse().expect("parse CORS host"))
|
||||
.map(|e| e.parse().expect("parse CORS hosts"))
|
||||
.collect();
|
||||
|
||||
let host = format!(
|
||||
|
@ -27,7 +28,8 @@ async fn main() {
|
|||
port = config.http.port
|
||||
);
|
||||
|
||||
homedisk_server::serve(host, origins, db, config)
|
||||
.await
|
||||
.expect("start http server");
|
||||
// start http server
|
||||
run_http_server(host, origins, db, config).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ version = "0.0.0"
|
|||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
thiserror = "1.0.31"
|
||||
log = "0.4.17"
|
||||
futures-util = "0.3.21"
|
||||
serde = { version = "1.0.137", features = ["derive"] }
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
use std::fmt;
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum Error {
|
||||
#[error("user not found")]
|
||||
UserNotFound,
|
||||
|
||||
#[error("sqlx error - {0}")]
|
||||
SQLx(sqlx::Error),
|
||||
|
||||
#[error("std::io error - {0}")]
|
||||
Io(std::io::Error),
|
||||
}
|
||||
|
||||
|
@ -18,13 +21,3 @@ impl From<std::io::Error> for Error {
|
|||
Error::Io(err)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Error {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
Error::UserNotFound => write!(f, "user not found"),
|
||||
Error::SQLx(err) => write!(f, "kind `sqlx`: {:?}", err),
|
||||
Error::Io(err) => write!(f, "kind `io`: {:?}", err),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
mod error;
|
||||
mod sqlite;
|
||||
|
||||
pub use error::*;
|
||||
pub use homedisk_types::database::User;
|
||||
pub use {error::*, sqlite::*};
|
||||
pub use sqlite::*;
|
||||
|
|
|
@ -6,18 +6,19 @@ use super::{Error, User};
|
|||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Database {
|
||||
/// Sqlite Connection Pool
|
||||
pub conn: SqlitePool,
|
||||
}
|
||||
|
||||
impl Database {
|
||||
/// Open SQLite Database file
|
||||
/// ```ignore
|
||||
/// ```ignore,rust
|
||||
/// use homedisk_database::Database;
|
||||
///
|
||||
/// Database::open("sqlite::memory:").await?;
|
||||
/// ```
|
||||
pub async fn open(path: &str) -> Result<Self, Error> {
|
||||
debug!("opening SQLite database");
|
||||
debug!("Opening SQLite database");
|
||||
|
||||
let conn = SqlitePool::connect(path).await?;
|
||||
|
||||
|
@ -25,14 +26,14 @@ impl Database {
|
|||
}
|
||||
|
||||
/// Create new User
|
||||
/// ```ignore
|
||||
/// ```ignore,rust
|
||||
/// use homedisk_database::{Database, User};
|
||||
///
|
||||
/// let user = User::new("username", "password");
|
||||
/// db.create_user(&user).await?;
|
||||
/// ```
|
||||
pub async fn create_user(&self, user: &User) -> Result<SqliteQueryResult, Error> {
|
||||
debug!("creating user - {}", user.username);
|
||||
debug!("Creating user - {}", user.username);
|
||||
|
||||
let query = sqlx::query("INSERT INTO user (id, username, password) VALUES (?, ?, ?)")
|
||||
.bind(&user.id)
|
||||
|
@ -43,7 +44,7 @@ impl Database {
|
|||
}
|
||||
|
||||
/// Find user
|
||||
/// ```ignore
|
||||
/// ```ignore,rust
|
||||
/// use homedisk_database::{Database, User};
|
||||
///
|
||||
/// let user = User::new("username", "password");
|
||||
|
@ -51,7 +52,7 @@ impl Database {
|
|||
/// db.find_user(&user.username, &user.password).await?;
|
||||
/// ```
|
||||
pub async fn find_user(&self, username: &str, password: &str) -> Result<User, Error> {
|
||||
debug!("searching for user - {}", username);
|
||||
debug!("Searching for user - {}", username);
|
||||
|
||||
let query =
|
||||
sqlx::query_as::<_, User>("SELECT * FROM user WHERE username = ? AND password = ?")
|
||||
|
@ -74,7 +75,7 @@ impl Database {
|
|||
}
|
||||
|
||||
/// Find user by UUID
|
||||
/// ```ignore
|
||||
/// ```ignore,rust
|
||||
/// use homedisk_database::{Database, User};
|
||||
///
|
||||
/// let user = User::new("username", "password");
|
||||
|
@ -82,7 +83,7 @@ impl Database {
|
|||
/// db.find_user_by_id(&user.id).await?;
|
||||
/// ```
|
||||
pub async fn find_user_by_id(&self, id: String) -> Result<User, Error> {
|
||||
debug!("searching for a user by UUID - {}", id);
|
||||
debug!("Searching for a user by UUID - {}", id);
|
||||
|
||||
let query = sqlx::query_as::<_, User>("SELECT * FROM user WHERE id = ?").bind(id);
|
||||
|
||||
|
|
|
@ -5,16 +5,16 @@ edition = "2021"
|
|||
|
||||
[dependencies]
|
||||
axum = { version = "0.5.6", features = ["multipart"] }
|
||||
log = "0.4.17"
|
||||
thiserror = "1.0.31"
|
||||
serde = { version = "1.0.137", features = ["derive"] }
|
||||
tower-http = { version = "0.3.4", features = ["full"] }
|
||||
hyper = { version = "0.14.19", features = ["full"] }
|
||||
rust_utilities = { version = "0.2.0", features = ["jsonwebtoken"] }
|
||||
homedisk-database = { path = "../database" }
|
||||
homedisk-types = { path = "../types", features = ["axum"] }
|
||||
axum-auth = "0.2.0"
|
||||
jsonwebtoken = "8.1.0"
|
||||
base64 = "0.13.0"
|
||||
byte-unit = "4.0.14"
|
||||
futures = "0.3.21"
|
||||
hyper = { version = "0.14.19", features = ["full"] }
|
||||
jsonwebtoken = "8.1.0"
|
||||
log = "0.4.17"
|
||||
rust_utilities = { version = "0.2.0", features = ["jsonwebtoken"] }
|
||||
serde = { version = "1.0.137", features = ["derive"] }
|
||||
thiserror = "1.0.31"
|
||||
tower-http = { version = "0.3.4", features = ["full"] }
|
||||
homedisk-database = { path = "../database" }
|
||||
homedisk-types = { path = "../types", features = ["axum"] }
|
||||
|
|
|
@ -13,6 +13,7 @@ pub async fn handle(
|
|||
Extension(config): Extension<Config>,
|
||||
request: Result<Json<Request>, JsonRejection>,
|
||||
) -> Result<Json<Response>, ServerError> {
|
||||
// validate json request
|
||||
let request = validate_json::<Request>(request)?;
|
||||
|
||||
let user = User::new(&request.username, &request.password);
|
||||
|
|
|
@ -15,6 +15,7 @@ pub async fn handle(
|
|||
Extension(config): Extension<Config>,
|
||||
request: Result<Json<Request>, JsonRejection>,
|
||||
) -> Result<Json<Response>, ServerError> {
|
||||
// validate json request
|
||||
let request = validate_json::<Request>(request)?;
|
||||
|
||||
// username must contain at least 4 characters
|
||||
|
|
|
@ -14,6 +14,7 @@ pub async fn handle(
|
|||
config: Extension<Config>,
|
||||
AuthBearer(token): AuthBearer,
|
||||
) -> Result<Json<Response>, ServerError> {
|
||||
// validate user token
|
||||
let token = validate_jwt(config.jwt.secret.as_bytes(), &token)?;
|
||||
|
||||
let response = match db.find_user_by_id(token.claims.sub).await {
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
use std::fmt;
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum Error {
|
||||
#[error("axum error - {0}")]
|
||||
Axum(axum::Error),
|
||||
|
||||
#[error("hyper error - {0}")]
|
||||
Hyper(hyper::Error),
|
||||
|
||||
#[error("std::net::AddrParseError - {0}")]
|
||||
AddrParseError(std::net::AddrParseError),
|
||||
}
|
||||
|
||||
|
@ -26,13 +29,3 @@ impl From<std::net::AddrParseError> for Error {
|
|||
Error::AddrParseError(err)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Error {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
Error::Axum(err) => write!(f, "axum error: {}", err),
|
||||
Error::Hyper(err) => write!(f, "hyper error: {}", err),
|
||||
Error::AddrParseError(err) => write!(f, "std::net::AddrParseError: {}", err),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,7 +18,10 @@ pub async fn handle(
|
|||
AuthBearer(token): AuthBearer,
|
||||
request: Result<Json<Request>, JsonRejection>,
|
||||
) -> Result<Json<Response>, ServerError> {
|
||||
// validate json request
|
||||
let Json(request) = validate_json::<Request>(request)?;
|
||||
|
||||
// validate user token
|
||||
let token = validate_jwt(config.jwt.secret.as_bytes(), &token)?;
|
||||
|
||||
// validate the `path` can be used
|
||||
|
@ -34,6 +37,7 @@ pub async fn handle(
|
|||
req_dir = request.path
|
||||
);
|
||||
|
||||
// create dirs
|
||||
fs::create_dir_all(path)
|
||||
.map_err(|err| ServerError::FsError(FsError::CreateDirectory(err.to_string())))?;
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ pub async fn handle(
|
|||
AuthBearer(token): AuthBearer,
|
||||
query: Query<Pagination>,
|
||||
) -> Result<Vec<u8>, ServerError> {
|
||||
// validate token
|
||||
// validate user token
|
||||
let token = validate_jwt(config.jwt.secret.as_bytes(), &token)?;
|
||||
|
||||
// validate the `path` can be used
|
||||
|
|
|
@ -15,6 +15,7 @@ use homedisk_types::{
|
|||
|
||||
use crate::middleware::{find_user, validate_json, validate_jwt};
|
||||
|
||||
/// Get directory size on disk (size of all files in directory).
|
||||
fn dir_size(path: impl Into<PathBuf>) -> io::Result<u64> {
|
||||
fn dir_size(mut dir: fs::ReadDir) -> io::Result<u64> {
|
||||
dir.try_fold(0, |acc, file| {
|
||||
|
@ -36,7 +37,10 @@ pub async fn handle(
|
|||
AuthBearer(token): AuthBearer,
|
||||
request: Result<Json<Request>, JsonRejection>,
|
||||
) -> Result<Json<Response>, ServerError> {
|
||||
// validate json request
|
||||
let Json(request) = validate_json::<Request>(request)?;
|
||||
|
||||
// validate user token
|
||||
let token = validate_jwt(config.jwt.secret.as_bytes(), &token)?;
|
||||
|
||||
// validate the `path` can be used
|
||||
|
@ -52,6 +56,7 @@ pub async fn handle(
|
|||
req_dir = request.path
|
||||
);
|
||||
|
||||
// get paths from dir
|
||||
let paths = fs::read_dir(&path)
|
||||
.map_err(|err| ServerError::FsError(FsError::ReadDir(err.to_string())))?;
|
||||
|
||||
|
@ -59,24 +64,37 @@ pub async fn handle(
|
|||
let mut dirs = vec![];
|
||||
|
||||
for f in paths {
|
||||
// handle Error
|
||||
let f = f.map_err(|err| ServerError::FsError(FsError::UnknownError(err.to_string())))?;
|
||||
|
||||
// get path metadata
|
||||
let metadata = f
|
||||
.metadata()
|
||||
.map_err(|err| ServerError::FsError(FsError::UnknownError(err.to_string())))?;
|
||||
|
||||
// get name of the path
|
||||
let name = f.path().display().to_string().replace(&path, "");
|
||||
|
||||
// if path is directory
|
||||
if metadata.is_dir() {
|
||||
let size = Byte::from_bytes(dir_size(f.path().display().to_string()).unwrap() as u128)
|
||||
.get_appropriate_unit(true)
|
||||
.to_string();
|
||||
let size = Byte::from_bytes(
|
||||
dir_size(f.path().display().to_string())
|
||||
.map_err(|err| ServerError::FsError(FsError::UnknownError(err.to_string())))?
|
||||
.into(),
|
||||
)
|
||||
.get_appropriate_unit(true)
|
||||
.to_string();
|
||||
|
||||
dirs.push(DirInfo { name, size })
|
||||
} else {
|
||||
}
|
||||
// if path is file
|
||||
else {
|
||||
// get file size in bytes
|
||||
let size = Byte::from_bytes(metadata.len().into())
|
||||
.get_appropriate_unit(true)
|
||||
.to_string();
|
||||
|
||||
// check how long it has been since the file was last modified
|
||||
let elapsed = metadata.modified().unwrap().elapsed().unwrap();
|
||||
|
||||
let seconds = elapsed.as_secs();
|
||||
|
@ -86,6 +104,7 @@ pub async fn handle(
|
|||
|
||||
let modified;
|
||||
|
||||
// format elapsed time
|
||||
if days > 1 {
|
||||
modified = format!("{} day(s)", days)
|
||||
} else if hours > 1 {
|
||||
|
|
|
@ -18,7 +18,7 @@ pub fn app() -> axum::Router {
|
|||
pub fn validate_path(path: &str) -> Result<(), homedisk_types::errors::ServerError> {
|
||||
use homedisk_types::errors::{FsError, ServerError};
|
||||
|
||||
// `path` cannot contain `..`
|
||||
// `path` can't contain `..`
|
||||
// to prevent attack attempts because by using a `..` you can access the previous folder
|
||||
if path.contains("..") {
|
||||
return Err(ServerError::FsError(FsError::ReadDir(
|
||||
|
@ -26,5 +26,13 @@ pub fn validate_path(path: &str) -> Result<(), homedisk_types::errors::ServerErr
|
|||
)));
|
||||
}
|
||||
|
||||
// `path` can't contain `~`
|
||||
// to prevent attack attempts because `~` can get up a directory on `$HOME`
|
||||
if path.contains('~') {
|
||||
return Err(ServerError::FsError(FsError::ReadDir(
|
||||
"the `path` must not contain `~`".to_string(),
|
||||
)));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ pub async fn handle(
|
|||
mut multipart: Multipart,
|
||||
query: Query<Pagination>,
|
||||
) -> Result<Json<Response>, ServerError> {
|
||||
// validate user token
|
||||
let token = validate_jwt(config.jwt.secret.as_bytes(), &token)?;
|
||||
|
||||
// validate the `path` can be used
|
||||
|
|
|
@ -14,15 +14,16 @@ async fn health_check() -> &'static str {
|
|||
"I'm alive!"
|
||||
}
|
||||
|
||||
pub async fn serve(
|
||||
pub async fn run_http_server(
|
||||
host: String,
|
||||
origins: Vec<HeaderValue>,
|
||||
db: Database,
|
||||
config: Config,
|
||||
) -> error::Result<()> {
|
||||
debug!("starting http server");
|
||||
debug!("Starting http server");
|
||||
info!("Website available at: http://{host}");
|
||||
|
||||
// create http Router
|
||||
let app = Router::new()
|
||||
.route("/health-check", get(health_check))
|
||||
.nest("/auth", auth::app())
|
||||
|
@ -31,6 +32,7 @@ pub async fn serve(
|
|||
.layer(Extension(db))
|
||||
.layer(Extension(config));
|
||||
|
||||
// bind the provided address and serve Router
|
||||
Server::bind(&host.parse()?)
|
||||
.serve(app.into_make_service())
|
||||
.await?;
|
||||
|
|
|
@ -3,7 +3,6 @@ use zeroize::{Zeroize, ZeroizeOnDrop};
|
|||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone, Zeroize, ZeroizeOnDrop)]
|
||||
pub struct Request {
|
||||
#[zeroize(skip)]
|
||||
pub username: String,
|
||||
pub password: String,
|
||||
}
|
||||
|
|
|
@ -7,14 +7,16 @@ use crate::option_return;
|
|||
use super::types::Config;
|
||||
|
||||
impl Config {
|
||||
/// parse configuration file
|
||||
/// Parse configuration file
|
||||
pub fn parse() -> Result<Config> {
|
||||
// configuration file path
|
||||
let config_dir = option_return!(dirs::config_dir(), "get config dir")?;
|
||||
|
||||
let config_path = format!("{}/homedisk/config.toml", config_dir.to_string_lossy());
|
||||
|
||||
// read file
|
||||
let config = fs::read_to_string(config_path)?;
|
||||
|
||||
// parse config and return it
|
||||
Ok(toml::from_str(&config)?)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,18 +9,24 @@ pub struct Config {
|
|||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct ConfigHTTP {
|
||||
/// HTTP Host
|
||||
pub host: String,
|
||||
/// Port HTTP Port
|
||||
pub port: u16,
|
||||
/// CORS Domaing (e.g ["site1.example.com", "site2.example.com"])
|
||||
pub cors: Vec<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct ConfigJWT {
|
||||
/// JWT Secret string
|
||||
pub secret: String,
|
||||
/// Token expiers time in seconds
|
||||
pub expires: i64,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct ConfigStorage {
|
||||
/// Directory where user files will be stored
|
||||
pub path: String,
|
||||
}
|
||||
|
|
|
@ -67,6 +67,7 @@ impl User {
|
|||
mod tests {
|
||||
use super::User;
|
||||
|
||||
/// Check if the username has been changed to lowercase
|
||||
#[test]
|
||||
fn check_username_is_in_lowercase() {
|
||||
let user = User::new("MEdzIk", "SuperSecretPassword123!");
|
||||
|
@ -74,6 +75,7 @@ mod tests {
|
|||
assert_eq!(user.username, "medzik")
|
||||
}
|
||||
|
||||
/// Check that the password is a checksum
|
||||
#[test]
|
||||
fn check_if_password_is_hashed() {
|
||||
let password = "password";
|
||||
|
|
|
@ -23,6 +23,6 @@ pub enum Error {
|
|||
#[error("invalid jwt token")]
|
||||
InvalidToken,
|
||||
|
||||
#[error("unknown error")]
|
||||
#[error("unknown error - {0}")]
|
||||
UnknownError(String),
|
||||
}
|
||||
|
|
|
@ -81,10 +81,10 @@ packages:
|
|||
'@babel/helper-compilation-targets': 7.18.2_@babel+core@7.18.2
|
||||
'@babel/helper-module-transforms': 7.18.0
|
||||
'@babel/helpers': 7.18.2
|
||||
'@babel/parser': 7.18.3
|
||||
'@babel/parser': 7.18.4
|
||||
'@babel/template': 7.16.7
|
||||
'@babel/traverse': 7.18.2
|
||||
'@babel/types': 7.18.2
|
||||
'@babel/types': 7.18.4
|
||||
convert-source-map: 1.8.0
|
||||
debug: 4.3.4
|
||||
gensync: 1.0.0-beta.2
|
||||
|
@ -97,7 +97,7 @@ packages:
|
|||
resolution: {integrity: sha512-W1lG5vUwFvfMd8HVXqdfbuG7RuaSrTCCD8cl8fP8wOivdbtbIg2Db3IWUcgvfxKbbn6ZBGYRW/Zk1MIwK49mgw==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
dependencies:
|
||||
'@babel/types': 7.18.2
|
||||
'@babel/types': 7.18.4
|
||||
'@jridgewell/gen-mapping': 0.3.1
|
||||
jsesc: 2.5.2
|
||||
|
||||
|
@ -105,7 +105,7 @@ packages:
|
|||
resolution: {integrity: sha512-s6t2w/IPQVTAET1HitoowRGXooX8mCgtuP5195wD/QJPV6wYjpujCGF7JuMODVX2ZAJOf1GT6DT9MHEZvLOFSw==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
dependencies:
|
||||
'@babel/types': 7.18.2
|
||||
'@babel/types': 7.18.4
|
||||
dev: false
|
||||
|
||||
/@babel/helper-compilation-targets/7.18.2_@babel+core@7.18.2:
|
||||
|
@ -117,7 +117,7 @@ packages:
|
|||
'@babel/compat-data': 7.17.10
|
||||
'@babel/core': 7.18.2
|
||||
'@babel/helper-validator-option': 7.16.7
|
||||
browserslist: 4.20.3
|
||||
browserslist: 4.20.4
|
||||
semver: 6.3.0
|
||||
|
||||
/@babel/helper-environment-visitor/7.18.2:
|
||||
|
@ -129,19 +129,19 @@ packages:
|
|||
engines: {node: '>=6.9.0'}
|
||||
dependencies:
|
||||
'@babel/template': 7.16.7
|
||||
'@babel/types': 7.18.2
|
||||
'@babel/types': 7.18.4
|
||||
|
||||
/@babel/helper-hoist-variables/7.16.7:
|
||||
resolution: {integrity: sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
dependencies:
|
||||
'@babel/types': 7.18.2
|
||||
'@babel/types': 7.18.4
|
||||
|
||||
/@babel/helper-module-imports/7.16.7:
|
||||
resolution: {integrity: sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
dependencies:
|
||||
'@babel/types': 7.18.2
|
||||
'@babel/types': 7.18.4
|
||||
|
||||
/@babel/helper-module-transforms/7.18.0:
|
||||
resolution: {integrity: sha512-kclUYSUBIjlvnzN2++K9f2qzYKFgjmnmjwL4zlmU5f8ZtzgWe8s0rUPSTGy2HmK4P8T52MQsS+HTQAgZd3dMEA==}
|
||||
|
@ -154,7 +154,7 @@ packages:
|
|||
'@babel/helper-validator-identifier': 7.16.7
|
||||
'@babel/template': 7.16.7
|
||||
'@babel/traverse': 7.18.2
|
||||
'@babel/types': 7.18.2
|
||||
'@babel/types': 7.18.4
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
|
@ -167,13 +167,13 @@ packages:
|
|||
resolution: {integrity: sha512-7LIrjYzndorDY88MycupkpQLKS1AFfsVRm2k/9PtKScSy5tZq0McZTj+DiMRynboZfIqOKvo03pmhTaUgiD6fQ==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
dependencies:
|
||||
'@babel/types': 7.18.2
|
||||
'@babel/types': 7.18.4
|
||||
|
||||
/@babel/helper-split-export-declaration/7.16.7:
|
||||
resolution: {integrity: sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
dependencies:
|
||||
'@babel/types': 7.18.2
|
||||
'@babel/types': 7.18.4
|
||||
|
||||
/@babel/helper-validator-identifier/7.16.7:
|
||||
resolution: {integrity: sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==}
|
||||
|
@ -189,7 +189,7 @@ packages:
|
|||
dependencies:
|
||||
'@babel/template': 7.16.7
|
||||
'@babel/traverse': 7.18.2
|
||||
'@babel/types': 7.18.2
|
||||
'@babel/types': 7.18.4
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
|
@ -201,12 +201,12 @@ packages:
|
|||
chalk: 2.4.2
|
||||
js-tokens: 4.0.0
|
||||
|
||||
/@babel/parser/7.18.3:
|
||||
resolution: {integrity: sha512-rL50YcEuHbbauAFAysNsJA4/f89fGTOBRNs9P81sniKnKAr4xULe5AecolcsKbi88xu0ByWYDj/S1AJ3FSFuSQ==}
|
||||
/@babel/parser/7.18.4:
|
||||
resolution: {integrity: sha512-FDge0dFazETFcxGw/EXzOkN8uJp0PC7Qbm+Pe9T+av2zlBpOgunFHkQPPn+eRuClU73JF+98D531UgayY89tow==}
|
||||
engines: {node: '>=6.0.0'}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
'@babel/types': 7.18.2
|
||||
'@babel/types': 7.18.4
|
||||
|
||||
/@babel/plugin-syntax-jsx/7.17.12_@babel+core@7.18.2:
|
||||
resolution: {integrity: sha512-spyY3E3AURfxh/RHtjx5j6hs8am5NbUBGfcZ2vB3uShSpZdQyXSf5rR5Mk76vbtlAZOelyVQ71Fg0x9SG4fsog==}
|
||||
|
@ -222,7 +222,7 @@ packages:
|
|||
resolution: {integrity: sha512-l4ddFwrc9rnR+EJsHsh+TJ4A35YqQz/UqcjtlX2ov53hlJYG5CxtQmNZxyajwDVmCxwy++rtvGU5HazCK4W41Q==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
dependencies:
|
||||
core-js-pure: 3.22.7
|
||||
core-js-pure: 3.22.8
|
||||
regenerator-runtime: 0.13.9
|
||||
dev: true
|
||||
|
||||
|
@ -237,8 +237,8 @@ packages:
|
|||
engines: {node: '>=6.9.0'}
|
||||
dependencies:
|
||||
'@babel/code-frame': 7.16.7
|
||||
'@babel/parser': 7.18.3
|
||||
'@babel/types': 7.18.2
|
||||
'@babel/parser': 7.18.4
|
||||
'@babel/types': 7.18.4
|
||||
|
||||
/@babel/traverse/7.18.2:
|
||||
resolution: {integrity: sha512-9eNwoeovJ6KH9zcCNnENY7DMFwTU9JdGCFtqNLfUAqtUHRCOsTOqWoffosP8vKmNYeSBUv3yVJXjfd8ucwOjUA==}
|
||||
|
@ -250,8 +250,8 @@ packages:
|
|||
'@babel/helper-function-name': 7.17.9
|
||||
'@babel/helper-hoist-variables': 7.16.7
|
||||
'@babel/helper-split-export-declaration': 7.16.7
|
||||
'@babel/parser': 7.18.3
|
||||
'@babel/types': 7.18.2
|
||||
'@babel/parser': 7.18.4
|
||||
'@babel/types': 7.18.4
|
||||
debug: 4.3.4
|
||||
globals: 11.12.0
|
||||
transitivePeerDependencies:
|
||||
|
@ -267,16 +267,16 @@ packages:
|
|||
'@babel/helper-function-name': 7.17.9
|
||||
'@babel/helper-hoist-variables': 7.16.7
|
||||
'@babel/helper-split-export-declaration': 7.16.7
|
||||
'@babel/parser': 7.18.3
|
||||
'@babel/types': 7.18.2
|
||||
'@babel/parser': 7.18.4
|
||||
'@babel/types': 7.18.4
|
||||
debug: 4.3.4_supports-color@5.5.0
|
||||
globals: 11.12.0
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: false
|
||||
|
||||
/@babel/types/7.18.2:
|
||||
resolution: {integrity: sha512-0On6B8A4/+mFUto5WERt3EEuG1NznDirvwca1O8UwXQHVY8g3R7OzYgxXdOfMwLO08UrpUD/2+3Bclyq+/C94Q==}
|
||||
/@babel/types/7.18.4:
|
||||
resolution: {integrity: sha512-ThN1mBcMq5pG/Vm2IcBmPPfyPXbd8S02rS+OBIDENdufvqC7Z/jHPCv9IcP01277aKtDI8g/2XysBN4hA8niiw==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
dependencies:
|
||||
'@babel/helper-validator-identifier': 7.16.7
|
||||
|
@ -563,7 +563,7 @@ packages:
|
|||
'@emotion/react': 11.9.0_mojt4vfvzjgczlgs4u436xt75u
|
||||
'@emotion/styled': 11.8.1_ev7eaohrznmneepri7xttmcb7i
|
||||
'@mui/base': 5.0.0-alpha.83_eurjwfem4ie5nnznw6gmhlbswe
|
||||
'@mui/system': 5.8.2_mmveigglvfulwfhs2gmh6qegum
|
||||
'@mui/system': 5.8.3_mmveigglvfulwfhs2gmh6qegum
|
||||
'@mui/types': 7.1.3_@types+react@18.0.12
|
||||
'@mui/utils': 5.8.0_react@18.1.0
|
||||
'@types/react': 18.0.12
|
||||
|
@ -631,8 +631,8 @@ packages:
|
|||
react: 18.1.0
|
||||
dev: false
|
||||
|
||||
/@mui/system/5.8.2_mmveigglvfulwfhs2gmh6qegum:
|
||||
resolution: {integrity: sha512-N74gDNKM+MnWvKTMmCPvCVLH4f0ZzakP1bcMDaPctrHwcyxNcEmtTGNpIiVk0Iu7vtThZAFL3DjHpINPGF7+cg==}
|
||||
/@mui/system/5.8.3_mmveigglvfulwfhs2gmh6qegum:
|
||||
resolution: {integrity: sha512-/tyGQcYqZT0nl98qV9XnGiedTO+V7VHc28k4POfhMJNedB1CRrwWRm767DeEdc5f/8CU2See3WD16ikP6pYiOA==}
|
||||
engines: {node: '>=12.0.0'}
|
||||
peerDependencies:
|
||||
'@emotion/react': ^11.5.0
|
||||
|
@ -874,8 +874,8 @@ packages:
|
|||
'@types/react': 18.0.12
|
||||
csstype: 3.1.0
|
||||
|
||||
/@typescript-eslint/parser/5.26.0_ud6rd4xtew5bv4yhvkvu24pzm4:
|
||||
resolution: {integrity: sha512-n/IzU87ttzIdnAH5vQ4BBDnLPly7rC5VnjN3m0xBG82HK6rhRxnCb3w/GyWbNDghPd+NktJqB/wl6+YkzZ5T5Q==}
|
||||
/@typescript-eslint/parser/5.27.1_ud6rd4xtew5bv4yhvkvu24pzm4:
|
||||
resolution: {integrity: sha512-7Va2ZOkHi5NP+AZwb5ReLgNF6nWLGTeUJfxdkVUAPPSaAdbWNnFZzLZ4EGGmmiCTg+AwlbE1KyUYTBglosSLHQ==}
|
||||
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
||||
peerDependencies:
|
||||
eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
|
||||
|
@ -884,9 +884,9 @@ packages:
|
|||
typescript:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@typescript-eslint/scope-manager': 5.26.0
|
||||
'@typescript-eslint/types': 5.26.0
|
||||
'@typescript-eslint/typescript-estree': 5.26.0_typescript@4.7.3
|
||||
'@typescript-eslint/scope-manager': 5.27.1
|
||||
'@typescript-eslint/types': 5.27.1
|
||||
'@typescript-eslint/typescript-estree': 5.27.1_typescript@4.7.3
|
||||
debug: 4.3.4
|
||||
eslint: 8.17.0
|
||||
typescript: 4.7.3
|
||||
|
@ -894,21 +894,21 @@ packages:
|
|||
- supports-color
|
||||
dev: true
|
||||
|
||||
/@typescript-eslint/scope-manager/5.26.0:
|
||||
resolution: {integrity: sha512-gVzTJUESuTwiju/7NiTb4c5oqod8xt5GhMbExKsCTp6adU3mya6AGJ4Pl9xC7x2DX9UYFsjImC0mA62BCY22Iw==}
|
||||
/@typescript-eslint/scope-manager/5.27.1:
|
||||
resolution: {integrity: sha512-fQEOSa/QroWE6fAEg+bJxtRZJTH8NTskggybogHt4H9Da8zd4cJji76gA5SBlR0MgtwF7rebxTbDKB49YUCpAg==}
|
||||
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
||||
dependencies:
|
||||
'@typescript-eslint/types': 5.26.0
|
||||
'@typescript-eslint/visitor-keys': 5.26.0
|
||||
'@typescript-eslint/types': 5.27.1
|
||||
'@typescript-eslint/visitor-keys': 5.27.1
|
||||
dev: true
|
||||
|
||||
/@typescript-eslint/types/5.26.0:
|
||||
resolution: {integrity: sha512-8794JZFE1RN4XaExLWLI2oSXsVImNkl79PzTOOWt9h0UHROwJedNOD2IJyfL0NbddFllcktGIO2aOu10avQQyA==}
|
||||
/@typescript-eslint/types/5.27.1:
|
||||
resolution: {integrity: sha512-LgogNVkBhCTZU/m8XgEYIWICD6m4dmEDbKXESCbqOXfKZxRKeqpiJXQIErv66sdopRKZPo5l32ymNqibYEH/xg==}
|
||||
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
||||
dev: true
|
||||
|
||||
/@typescript-eslint/typescript-estree/5.26.0_typescript@4.7.3:
|
||||
resolution: {integrity: sha512-EyGpw6eQDsfD6jIqmXP3rU5oHScZ51tL/cZgFbFBvWuCwrIptl+oueUZzSmLtxFuSOQ9vDcJIs+279gnJkfd1w==}
|
||||
/@typescript-eslint/typescript-estree/5.27.1_typescript@4.7.3:
|
||||
resolution: {integrity: sha512-DnZvvq3TAJ5ke+hk0LklvxwYsnXpRdqUY5gaVS0D4raKtbznPz71UJGnPTHEFo0GDxqLOLdMkkmVZjSpET1hFw==}
|
||||
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
||||
peerDependencies:
|
||||
typescript: '*'
|
||||
|
@ -916,8 +916,8 @@ packages:
|
|||
typescript:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@typescript-eslint/types': 5.26.0
|
||||
'@typescript-eslint/visitor-keys': 5.26.0
|
||||
'@typescript-eslint/types': 5.27.1
|
||||
'@typescript-eslint/visitor-keys': 5.27.1
|
||||
debug: 4.3.4
|
||||
globby: 11.1.0
|
||||
is-glob: 4.0.3
|
||||
|
@ -928,11 +928,11 @@ packages:
|
|||
- supports-color
|
||||
dev: true
|
||||
|
||||
/@typescript-eslint/visitor-keys/5.26.0:
|
||||
resolution: {integrity: sha512-wei+ffqHanYDOQgg/fS6Hcar6wAWv0CUPQ3TZzOWd2BLfgP539rb49bwua8WRAs7R6kOSLn82rfEu2ro6Llt8Q==}
|
||||
/@typescript-eslint/visitor-keys/5.27.1:
|
||||
resolution: {integrity: sha512-xYs6ffo01nhdJgPieyk7HAOpjhTsx7r/oB9LWEhwAXgwn33tkr+W8DI2ChboqhZlC4q3TC6geDYPoiX8ROqyOQ==}
|
||||
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
||||
dependencies:
|
||||
'@typescript-eslint/types': 5.26.0
|
||||
'@typescript-eslint/types': 5.27.1
|
||||
eslint-visitor-keys: 3.3.0
|
||||
dev: true
|
||||
|
||||
|
@ -1094,13 +1094,13 @@ packages:
|
|||
fill-range: 7.0.1
|
||||
dev: true
|
||||
|
||||
/browserslist/4.20.3:
|
||||
resolution: {integrity: sha512-NBhymBQl1zM0Y5dQT/O+xiLP9/rzOIQdKM/eMJBAq7yBgaB6krIYLGejrwVYnSHZdqjscB1SPuAjHwxjvN6Wdg==}
|
||||
/browserslist/4.20.4:
|
||||
resolution: {integrity: sha512-ok1d+1WpnU24XYN7oC3QWgTyMhY/avPJ/r9T00xxvUOIparA/gc+UPUMaod3i+G6s+nI2nUb9xZ5k794uIwShw==}
|
||||
engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
caniuse-lite: 1.0.30001344
|
||||
electron-to-chromium: 1.4.140
|
||||
caniuse-lite: 1.0.30001349
|
||||
electron-to-chromium: 1.4.147
|
||||
escalade: 3.1.1
|
||||
node-releases: 2.0.5
|
||||
picocolors: 1.0.0
|
||||
|
@ -1120,8 +1120,8 @@ packages:
|
|||
resolution: {integrity: sha512-W2lPwkBkMZwFlPCXhIlYgxu+7gC/NUlCtdK652DAJ1JdgV0sTrvuPFshNPrFa1TY2JOkLhgdeEBplB4ezEa+xg==}
|
||||
dev: false
|
||||
|
||||
/caniuse-lite/1.0.30001344:
|
||||
resolution: {integrity: sha512-0ZFjnlCaXNOAYcV7i+TtdKBp0L/3XEU2MF/x6Du1lrh+SRX4IfzIVL4HNJg5pB2PmFb8rszIGyOvsZnqqRoc2g==}
|
||||
/caniuse-lite/1.0.30001349:
|
||||
resolution: {integrity: sha512-VFaWW3jeo6DLU5rwdiasosxhYSduJgSGil4cSyX3/85fbctlE58pXAkWyuRmVA0r2RxsOSVYUTZcySJ8WpbTxw==}
|
||||
|
||||
/chalk/2.4.2:
|
||||
resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==}
|
||||
|
@ -1171,7 +1171,7 @@ packages:
|
|||
dev: false
|
||||
|
||||
/concat-map/0.0.1:
|
||||
resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
|
||||
resolution: {integrity: sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=}
|
||||
dev: true
|
||||
|
||||
/convert-source-map/1.8.0:
|
||||
|
@ -1184,8 +1184,8 @@ packages:
|
|||
engines: {node: '>= 0.6'}
|
||||
dev: false
|
||||
|
||||
/core-js-pure/3.22.7:
|
||||
resolution: {integrity: sha512-wTriFxiZI+C8msGeh7fJcbC/a0V8fdInN1oS2eK79DMBGs8iIJiXhtFJCiT3rBa8w6zroHWW3p8ArlujZ/Mz+w==}
|
||||
/core-js-pure/3.22.8:
|
||||
resolution: {integrity: sha512-bOxbZIy9S5n4OVH63XaLVXZ49QKicjowDx/UELyJ68vxfCRpYsbyh/WNZNfEfAk+ekA8vSjt+gCDpvh672bc3w==}
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
|
||||
|
@ -1210,7 +1210,7 @@ packages:
|
|||
dev: true
|
||||
|
||||
/css-color-keywords/1.0.0:
|
||||
resolution: {integrity: sha1-/qJhbcZ2spYmhrOvjb2+GAskTgU=}
|
||||
resolution: {integrity: sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==}
|
||||
engines: {node: '>=4'}
|
||||
dev: false
|
||||
|
||||
|
@ -1288,7 +1288,7 @@ packages:
|
|||
dev: true
|
||||
|
||||
/delayed-stream/1.0.0:
|
||||
resolution: {integrity: sha1-3zrhmayt+31ECqrgsp4icrJOxhk=}
|
||||
resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==}
|
||||
engines: {node: '>=0.4.0'}
|
||||
dev: false
|
||||
|
||||
|
@ -1320,8 +1320,8 @@ packages:
|
|||
csstype: 3.1.0
|
||||
dev: false
|
||||
|
||||
/electron-to-chromium/1.4.140:
|
||||
resolution: {integrity: sha512-NLz5va823QfJBYOO/hLV4AfU4Crmkl/6Hl2pH3qdJcmi0ySZ3YTWHxOlDm3uJOFBEPy3pIhu8gKQo6prQTWKKA==}
|
||||
/electron-to-chromium/1.4.147:
|
||||
resolution: {integrity: sha512-czclPqxLMPqPMkahKcske4TaS5lcznsc26ByBlEFDU8grTBVK9C5W6K9I6oEEhm4Ai4jTihGnys90xY1yjXcRg==}
|
||||
|
||||
/emoji-regex/9.2.2:
|
||||
resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==}
|
||||
|
@ -1401,11 +1401,11 @@ packages:
|
|||
dependencies:
|
||||
'@next/eslint-plugin-next': 12.1.6
|
||||
'@rushstack/eslint-patch': 1.1.3
|
||||
'@typescript-eslint/parser': 5.26.0_ud6rd4xtew5bv4yhvkvu24pzm4
|
||||
'@typescript-eslint/parser': 5.27.1_ud6rd4xtew5bv4yhvkvu24pzm4
|
||||
eslint: 8.17.0
|
||||
eslint-import-resolver-node: 0.3.6
|
||||
eslint-import-resolver-typescript: 2.7.1_3yxiwxzsqipdmy4jwrlv6vgfmy
|
||||
eslint-plugin-import: 2.26.0_ws6ck2gdxspv6ngtwevulm53da
|
||||
eslint-plugin-import: 2.26.0_xzp3xuu5l2v5skncvl5a2je5s4
|
||||
eslint-plugin-jsx-a11y: 6.5.1_eslint@8.17.0
|
||||
eslint-plugin-react: 7.30.0_eslint@8.17.0
|
||||
eslint-plugin-react-hooks: 4.5.0_eslint@8.17.0
|
||||
|
@ -1434,7 +1434,7 @@ packages:
|
|||
dependencies:
|
||||
debug: 4.3.4
|
||||
eslint: 8.17.0
|
||||
eslint-plugin-import: 2.26.0_ws6ck2gdxspv6ngtwevulm53da
|
||||
eslint-plugin-import: 2.26.0_xzp3xuu5l2v5skncvl5a2je5s4
|
||||
glob: 7.2.3
|
||||
is-glob: 4.0.3
|
||||
resolve: 1.22.0
|
||||
|
@ -1443,7 +1443,7 @@ packages:
|
|||
- supports-color
|
||||
dev: true
|
||||
|
||||
/eslint-module-utils/2.7.3_yxrttxwxgn5axzfjkhhzgts2eq:
|
||||
/eslint-module-utils/2.7.3_4wf6ctbofaywkfx7kzk32kp7ge:
|
||||
resolution: {integrity: sha512-088JEC7O3lDZM9xGe0RerkOMd0EjFl+Yvd1jPWIkMT5u3H9+HC34mWWPnqPrN13gieT9pBOO+Qt07Nb/6TresQ==}
|
||||
engines: {node: '>=4'}
|
||||
peerDependencies:
|
||||
|
@ -1461,7 +1461,7 @@ packages:
|
|||
eslint-import-resolver-webpack:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@typescript-eslint/parser': 5.26.0_ud6rd4xtew5bv4yhvkvu24pzm4
|
||||
'@typescript-eslint/parser': 5.27.1_ud6rd4xtew5bv4yhvkvu24pzm4
|
||||
debug: 3.2.7
|
||||
eslint-import-resolver-node: 0.3.6
|
||||
eslint-import-resolver-typescript: 2.7.1_3yxiwxzsqipdmy4jwrlv6vgfmy
|
||||
|
@ -1470,7 +1470,7 @@ packages:
|
|||
- supports-color
|
||||
dev: true
|
||||
|
||||
/eslint-plugin-import/2.26.0_ws6ck2gdxspv6ngtwevulm53da:
|
||||
/eslint-plugin-import/2.26.0_xzp3xuu5l2v5skncvl5a2je5s4:
|
||||
resolution: {integrity: sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==}
|
||||
engines: {node: '>=4'}
|
||||
peerDependencies:
|
||||
|
@ -1480,14 +1480,14 @@ packages:
|
|||
'@typescript-eslint/parser':
|
||||
optional: true
|
||||
dependencies:
|
||||
'@typescript-eslint/parser': 5.26.0_ud6rd4xtew5bv4yhvkvu24pzm4
|
||||
'@typescript-eslint/parser': 5.27.1_ud6rd4xtew5bv4yhvkvu24pzm4
|
||||
array-includes: 3.1.5
|
||||
array.prototype.flat: 1.3.0
|
||||
debug: 2.6.9
|
||||
doctrine: 2.1.0
|
||||
eslint: 8.17.0
|
||||
eslint-import-resolver-node: 0.3.6
|
||||
eslint-module-utils: 2.7.3_yxrttxwxgn5axzfjkhhzgts2eq
|
||||
eslint-module-utils: 2.7.3_4wf6ctbofaywkfx7kzk32kp7ge
|
||||
has: 1.0.3
|
||||
is-core-module: 2.9.0
|
||||
is-glob: 4.0.3
|
||||
|
@ -1707,7 +1707,7 @@ packages:
|
|||
dev: false
|
||||
|
||||
/find-up/2.1.0:
|
||||
resolution: {integrity: sha1-RdG35QbHF93UgndaK3eSCjwMV6c=}
|
||||
resolution: {integrity: sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==}
|
||||
engines: {node: '>=4'}
|
||||
dependencies:
|
||||
locate-path: 2.0.0
|
||||
|
@ -1928,7 +1928,7 @@ packages:
|
|||
dev: true
|
||||
|
||||
/is-arrayish/0.2.1:
|
||||
resolution: {integrity: sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=}
|
||||
resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==}
|
||||
dev: false
|
||||
|
||||
/is-bigint/1.0.4:
|
||||
|
@ -2081,7 +2081,7 @@ packages:
|
|||
dev: true
|
||||
|
||||
/language-tags/1.0.5:
|
||||
resolution: {integrity: sha1-0yHbxNowuovzAk4ED6XBRmH5GTo=}
|
||||
resolution: {integrity: sha512-qJhlO9cGXi6hBGKoxEG/sKZDAHD5Hnu9Hs4WbOY3pCWXDhw0N8x1NenNzm2EnNLkLkk7J2SdxAkDSbb6ftT+UQ==}
|
||||
dependencies:
|
||||
language-subtag-registry: 0.3.21
|
||||
dev: true
|
||||
|
@ -2099,7 +2099,7 @@ packages:
|
|||
dev: false
|
||||
|
||||
/locate-path/2.0.0:
|
||||
resolution: {integrity: sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=}
|
||||
resolution: {integrity: sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==}
|
||||
engines: {node: '>=4'}
|
||||
dependencies:
|
||||
p-locate: 2.0.0
|
||||
|
@ -2201,7 +2201,7 @@ packages:
|
|||
optional: true
|
||||
dependencies:
|
||||
'@next/env': 12.1.6
|
||||
caniuse-lite: 1.0.30001344
|
||||
caniuse-lite: 1.0.30001349
|
||||
postcss: 8.4.5
|
||||
react: 18.1.0
|
||||
react-dom: 18.1.0_react@18.1.0
|
||||
|
@ -2227,7 +2227,7 @@ packages:
|
|||
resolution: {integrity: sha512-U9h1NLROZTq9uE1SNffn6WuPDg8icmi3ns4rEl/oTfIle4iLjTliCzgTsbaIFMq/Xn078/lfY/BL0GWZ+psK4Q==}
|
||||
|
||||
/object-assign/4.1.1:
|
||||
resolution: {integrity: sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=}
|
||||
resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
/object-inspect/1.12.2:
|
||||
|
@ -2309,14 +2309,14 @@ packages:
|
|||
dev: true
|
||||
|
||||
/p-locate/2.0.0:
|
||||
resolution: {integrity: sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=}
|
||||
resolution: {integrity: sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==}
|
||||
engines: {node: '>=4'}
|
||||
dependencies:
|
||||
p-limit: 1.3.0
|
||||
dev: true
|
||||
|
||||
/p-try/1.0.0:
|
||||
resolution: {integrity: sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=}
|
||||
resolution: {integrity: sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==}
|
||||
engines: {node: '>=4'}
|
||||
dev: true
|
||||
|
||||
|
@ -2337,12 +2337,12 @@ packages:
|
|||
dev: false
|
||||
|
||||
/path-exists/3.0.0:
|
||||
resolution: {integrity: sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=}
|
||||
resolution: {integrity: sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==}
|
||||
engines: {node: '>=4'}
|
||||
dev: true
|
||||
|
||||
/path-is-absolute/1.0.1:
|
||||
resolution: {integrity: sha1-F0uSaHNVNP+8es5r9TpanhtcX18=}
|
||||
resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
dev: true
|
||||
|
||||
|
|
Loading…
Reference in New Issue