Compare commits
2 Commits
7d9d0b4d2e
...
058dc383f8
| Author | SHA1 | Date | |
|---|---|---|---|
| 058dc383f8 | |||
| e74d794d08 |
1995
moneymgr_backend/Cargo.lock
generated
1995
moneymgr_backend/Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -4,36 +4,35 @@ version = "0.1.0"
|
|||||||
edition = "2024"
|
edition = "2024"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
env_logger = "0.11.8"
|
env_logger = "0.11.9"
|
||||||
log = "0.4.29"
|
log = "0.4.29"
|
||||||
diesel = { version = "2.2.12", features = ["postgres", "r2d2"] }
|
diesel = { version = "2.3.6", features = ["postgres", "r2d2"] }
|
||||||
diesel_migrations = "2.2.0"
|
diesel_migrations = "2.2.0"
|
||||||
clap = { version = "4.5.59", features = ["env", "derive"] }
|
clap = { version = "4.5.59", features = ["env", "derive"] }
|
||||||
actix-web = "4.11.0"
|
actix-web = "4.13.0"
|
||||||
actix-cors = "0.7.1"
|
actix-cors = "0.7.1"
|
||||||
actix-multipart = "0.7.2"
|
actix-multipart = "0.7.2"
|
||||||
actix-remote-ip = "0.1.0"
|
actix-remote-ip = "0.1.0"
|
||||||
actix-session = { version = "0.10.1", features = ["redis-session"] }
|
actix-session = { version = "0.11.0", features = ["redis-session"] }
|
||||||
actix-files = "0.6.10"
|
actix-files = "0.6.10"
|
||||||
lazy_static = "1.5.0"
|
|
||||||
anyhow = "1.0.101"
|
anyhow = "1.0.101"
|
||||||
serde = { version = "1.0.228", features = ["derive"] }
|
serde = { version = "1.0.228", features = ["derive"] }
|
||||||
rust-s3 = "0.36.0-beta.2"
|
rust-s3 = "0.37.1"
|
||||||
thiserror = "2.0.18"
|
thiserror = "2.0.18"
|
||||||
tokio = "1.45.1"
|
tokio = "1.49.0"
|
||||||
futures-util = "0.3.31"
|
futures-util = "0.3.32"
|
||||||
serde_json = "1.0.149"
|
serde_json = "1.0.149"
|
||||||
light-openid = "1.0.4"
|
light-openid = "1.1.0"
|
||||||
rand = "0.9.2"
|
rand = "0.10.0"
|
||||||
ipnet = { version = "2.11.0", features = ["serde"] }
|
ipnet = { version = "2.11.0", features = ["serde"] }
|
||||||
lazy-regex = "3.4.2"
|
lazy-regex = "3.6.0"
|
||||||
jwt-simple = { version = "0.12.14", default-features = false, features = ["pure-rust"] }
|
jwt-simple = { version = "0.12.14", default-features = false, features = ["pure-rust"] }
|
||||||
mime_guess = "2.0.5"
|
mime_guess = "2.0.5"
|
||||||
rust-embed = { version = "8.7.2" }
|
rust-embed = { version = "8.11.0" }
|
||||||
sha2 = "0.11.0-rc.4"
|
sha2 = "0.11.0-rc.5"
|
||||||
base16ct = "0.2.0"
|
base16ct = { version = "1.0.0", features = ["alloc"] }
|
||||||
httpdate = "1.0.3"
|
httpdate = "1.0.3"
|
||||||
chrono = "0.4.43"
|
chrono = "0.4.43"
|
||||||
tempfile = "3.20.0"
|
tempfile = "3.25.0"
|
||||||
zip = "3.0.0"
|
zip = "8.1.0"
|
||||||
rust_xlsxwriter = "0.87.0"
|
rust_xlsxwriter = "0.93.0"
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use s3::creds::Credentials;
|
use s3::creds::Credentials;
|
||||||
use s3::{Bucket, Region};
|
use s3::{Bucket, Region};
|
||||||
|
use std::sync::OnceLock;
|
||||||
|
|
||||||
/// Money Manager backend API
|
/// Money Manager backend API
|
||||||
#[derive(Parser, Debug, Clone)]
|
#[derive(Parser, Debug, Clone)]
|
||||||
@@ -132,16 +133,13 @@ pub struct AppConfig {
|
|||||||
pub apk_download_url: String,
|
pub apk_download_url: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
lazy_static::lazy_static! {
|
/// Cached application config
|
||||||
static ref ARGS: AppConfig = {
|
static ARGS: OnceLock<AppConfig> = OnceLock::new();
|
||||||
AppConfig::parse()
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
impl AppConfig {
|
impl AppConfig {
|
||||||
/// Get parsed command line arguments
|
/// Get parsed command line arguments
|
||||||
pub fn get() -> &'static AppConfig {
|
pub fn get() -> &'static AppConfig {
|
||||||
&ARGS
|
ARGS.get_or_init(AppConfig::parse)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get auto login email (if not empty)
|
/// Get auto login email (if not empty)
|
||||||
|
|||||||
@@ -2,8 +2,7 @@ use crate::app_config::AppConfig;
|
|||||||
use diesel::PgConnection;
|
use diesel::PgConnection;
|
||||||
use diesel::r2d2::{ConnectionManager, Pool, PooledConnection};
|
use diesel::r2d2::{ConnectionManager, Pool, PooledConnection};
|
||||||
use diesel_migrations::{EmbeddedMigrations, MigrationHarness, embed_migrations};
|
use diesel_migrations::{EmbeddedMigrations, MigrationHarness, embed_migrations};
|
||||||
use lazy_static::lazy_static;
|
use std::sync::{Arc, OnceLock};
|
||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
const MIGRATIONS: EmbeddedMigrations = embed_migrations!();
|
const MIGRATIONS: EmbeddedMigrations = embed_migrations!();
|
||||||
|
|
||||||
@@ -20,12 +19,13 @@ fn get_db_connection_pool() -> anyhow::Result<DBConn> {
|
|||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
lazy_static! {
|
static DB_POOL: OnceLock<DBConn> = OnceLock::new();
|
||||||
static ref DB_POOL: DBConn = get_db_connection_pool().expect("Failed to connect to database");
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn db() -> anyhow::Result<PooledConnection<ConnectionManager<PgConnection>>> {
|
pub fn db() -> anyhow::Result<PooledConnection<ConnectionManager<PgConnection>>> {
|
||||||
Ok(DB_POOL.clone().get()?)
|
Ok(DB_POOL
|
||||||
|
.get_or_init(|| get_db_connection_pool().expect("Failed to connect to database"))
|
||||||
|
.clone()
|
||||||
|
.get()?)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn initialize_conn() -> anyhow::Result<()> {
|
pub fn initialize_conn() -> anyhow::Result<()> {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
use crate::app_config::AppConfig;
|
use crate::app_config::AppConfig;
|
||||||
use crate::controllers::{HttpFailure, HttpResult};
|
use crate::controllers::HttpResult;
|
||||||
use crate::extractors::auth_extractor::{AuthExtractor, AuthenticatedMethod};
|
use crate::extractors::auth_extractor::{AuthExtractor, AuthenticatedMethod};
|
||||||
use crate::extractors::money_session::MoneySession;
|
use crate::extractors::money_session::MoneySession;
|
||||||
use crate::services::{tokens_service, users_service};
|
use crate::services::{tokens_service, users_service};
|
||||||
@@ -61,9 +61,7 @@ pub async fn finish_oidc(
|
|||||||
|
|
||||||
let prov = AppConfig::get().openid_provider();
|
let prov = AppConfig::get().openid_provider();
|
||||||
|
|
||||||
let conf = OpenIDConfig::load_from_url(prov.configuration_url)
|
let conf = OpenIDConfig::load_from_url(prov.configuration_url).await?;
|
||||||
.await
|
|
||||||
.map_err(HttpFailure::OpenID)?;
|
|
||||||
|
|
||||||
let (token, _) = conf
|
let (token, _) = conf
|
||||||
.request_token(
|
.request_token(
|
||||||
@@ -72,12 +70,8 @@ pub async fn finish_oidc(
|
|||||||
&req.code,
|
&req.code,
|
||||||
&AppConfig::get().oidc_redirect_url(),
|
&AppConfig::get().oidc_redirect_url(),
|
||||||
)
|
)
|
||||||
.await
|
.await?;
|
||||||
.map_err(HttpFailure::OpenID)?;
|
let (user_info, _) = conf.request_user_info(&token).await?;
|
||||||
let (user_info, _) = conf
|
|
||||||
.request_user_info(&token)
|
|
||||||
.await
|
|
||||||
.map_err(HttpFailure::OpenID)?;
|
|
||||||
|
|
||||||
if user_info.email_verified != Some(true) {
|
if user_info.email_verified != Some(true) {
|
||||||
log::error!("Email is not verified!");
|
log::error!("Email is not verified!");
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use crate::controllers::backup_controller::BackupControllerError;
|
use crate::controllers::backup_controller::BackupControllerError;
|
||||||
use actix_web::http::StatusCode;
|
use actix_web::http::StatusCode;
|
||||||
use actix_web::{HttpResponse, ResponseError};
|
use actix_web::{HttpResponse, ResponseError};
|
||||||
use std::error::Error;
|
use light_openid::errors::OpenIdError;
|
||||||
use zip::result::ZipError;
|
use zip::result::ZipError;
|
||||||
|
|
||||||
pub mod accounts_controller;
|
pub mod accounts_controller;
|
||||||
@@ -28,7 +28,7 @@ pub enum HttpFailure {
|
|||||||
#[error("an unhandled session error occurred")]
|
#[error("an unhandled session error occurred")]
|
||||||
SessionError(#[from] actix_session::SessionGetError),
|
SessionError(#[from] actix_session::SessionGetError),
|
||||||
#[error("an unspecified open id error occurred: {0}")]
|
#[error("an unspecified open id error occurred: {0}")]
|
||||||
OpenID(Box<dyn Error>),
|
OpenID(#[from] OpenIdError),
|
||||||
#[error("an unspecified internal error occurred: {0}")]
|
#[error("an unspecified internal error occurred: {0}")]
|
||||||
InternalError(#[from] anyhow::Error),
|
InternalError(#[from] anyhow::Error),
|
||||||
#[error("a serde_json error occurred: {0}")]
|
#[error("a serde_json error occurred: {0}")]
|
||||||
|
|||||||
@@ -7,3 +7,20 @@ pub fn sha512(bytes: &[u8]) -> String {
|
|||||||
let h = hasher.finalize();
|
let h = hasher.finalize();
|
||||||
base16ct::lower::encode_string(h.as_slice())
|
base16ct::lower::encode_string(h.as_slice())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use crate::utils::crypt_utils::sha512;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_sha512() {
|
||||||
|
assert_eq!(
|
||||||
|
sha512(&[]),
|
||||||
|
"cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e"
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
sha512("hello".as_bytes()),
|
||||||
|
"9b71d224bd62f3785d96d46ad3ea3d73319bfbc2890caadae2dff72519673ca72323c3d99ba5c11d7c7acc6e14b8c5da0c4663475c2e5c3adef46f73bcdec043"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
32
moneymgr_web/package-lock.json
generated
32
moneymgr_web/package-lock.json
generated
@@ -17,7 +17,7 @@
|
|||||||
"@mui/icons-material": "^7.1.2",
|
"@mui/icons-material": "^7.1.2",
|
||||||
"@mui/material": "^7.1.2",
|
"@mui/material": "^7.1.2",
|
||||||
"@mui/x-charts": "^8.27.0",
|
"@mui/x-charts": "^8.27.0",
|
||||||
"@mui/x-data-grid": "^8.18.0",
|
"@mui/x-data-grid": "^8.27.1",
|
||||||
"@mui/x-date-pickers": "^8.23.0",
|
"@mui/x-date-pickers": "^8.23.0",
|
||||||
"date-and-time": "^3.6.0",
|
"date-and-time": "^3.6.0",
|
||||||
"dayjs": "^1.11.19",
|
"dayjs": "^1.11.19",
|
||||||
@@ -2378,15 +2378,15 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@mui/x-data-grid": {
|
"node_modules/@mui/x-data-grid": {
|
||||||
"version": "8.18.0",
|
"version": "8.27.1",
|
||||||
"resolved": "https://registry.npmjs.org/@mui/x-data-grid/-/x-data-grid-8.18.0.tgz",
|
"resolved": "https://registry.npmjs.org/@mui/x-data-grid/-/x-data-grid-8.27.1.tgz",
|
||||||
"integrity": "sha512-g8y5EI3TNqrimHpH/Hv6u6i04cbvsqh39Tg4bZEhGq+SDxWp42iABlUvB7p+gtXfyd+IbmpfzUQ1hOCsHlTMZw==",
|
"integrity": "sha512-Xje197cUzmch33vLip5KR44SQ0CB49iutBTaoIMSxIVSfNqI8BadEh8PpPCacuTeSty06tJKpBMe66NNYWfHFw==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/runtime": "^7.28.4",
|
"@babel/runtime": "^7.28.4",
|
||||||
"@mui/utils": "^7.3.5",
|
"@mui/utils": "^7.3.5",
|
||||||
"@mui/x-internals": "8.18.0",
|
"@mui/x-internals": "8.26.0",
|
||||||
"@mui/x-virtualizer": "0.2.8",
|
"@mui/x-virtualizer": "0.3.3",
|
||||||
"clsx": "^2.1.1",
|
"clsx": "^2.1.1",
|
||||||
"prop-types": "^15.8.1",
|
"prop-types": "^15.8.1",
|
||||||
"use-sync-external-store": "^1.6.0"
|
"use-sync-external-store": "^1.6.0"
|
||||||
@@ -2416,9 +2416,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@mui/x-data-grid/node_modules/@mui/x-internals": {
|
"node_modules/@mui/x-data-grid/node_modules/@mui/x-internals": {
|
||||||
"version": "8.18.0",
|
"version": "8.26.0",
|
||||||
"resolved": "https://registry.npmjs.org/@mui/x-internals/-/x-internals-8.18.0.tgz",
|
"resolved": "https://registry.npmjs.org/@mui/x-internals/-/x-internals-8.26.0.tgz",
|
||||||
"integrity": "sha512-iM2SJALLo4kNqxTel8lfjIymYV9MgTa6021/rAlfdh/vwPMglaKyXQHrxkkWs2Eu/JFKkCKr5Fd34Gsdp63wIg==",
|
"integrity": "sha512-B9OZau5IQUvIxwpJZhoFJKqRpmWf5r0yMmSXjQuqb5WuqM755EuzWJOenY48denGoENzMLT8hQpA0hRTeU2IPA==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/runtime": "^7.28.4",
|
"@babel/runtime": "^7.28.4",
|
||||||
@@ -2535,14 +2535,14 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@mui/x-virtualizer": {
|
"node_modules/@mui/x-virtualizer": {
|
||||||
"version": "0.2.8",
|
"version": "0.3.3",
|
||||||
"resolved": "https://registry.npmjs.org/@mui/x-virtualizer/-/x-virtualizer-0.2.8.tgz",
|
"resolved": "https://registry.npmjs.org/@mui/x-virtualizer/-/x-virtualizer-0.3.3.tgz",
|
||||||
"integrity": "sha512-hCkhTg3BLLbf0SIw9Cx/NHTCUmbna+P5F2V+Bcv/9XiYhfzzmhYnm68+V6vOOhKVbV3j8JKsUEqcTC9K2Jpu8A==",
|
"integrity": "sha512-6ugUh7UAhQYdgPgHLu181zqufh3Y8IqEU9Pe6Huzj0xkRi3NwMx/ZzvrHf2WazNOh2uLhQ5ZM2wFqDu3mxBWZA==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/runtime": "^7.28.4",
|
"@babel/runtime": "^7.28.4",
|
||||||
"@mui/utils": "^7.3.5",
|
"@mui/utils": "^7.3.5",
|
||||||
"@mui/x-internals": "8.18.0"
|
"@mui/x-internals": "8.26.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=14.0.0"
|
"node": ">=14.0.0"
|
||||||
@@ -2557,9 +2557,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@mui/x-virtualizer/node_modules/@mui/x-internals": {
|
"node_modules/@mui/x-virtualizer/node_modules/@mui/x-internals": {
|
||||||
"version": "8.18.0",
|
"version": "8.26.0",
|
||||||
"resolved": "https://registry.npmjs.org/@mui/x-internals/-/x-internals-8.18.0.tgz",
|
"resolved": "https://registry.npmjs.org/@mui/x-internals/-/x-internals-8.26.0.tgz",
|
||||||
"integrity": "sha512-iM2SJALLo4kNqxTel8lfjIymYV9MgTa6021/rAlfdh/vwPMglaKyXQHrxkkWs2Eu/JFKkCKr5Fd34Gsdp63wIg==",
|
"integrity": "sha512-B9OZau5IQUvIxwpJZhoFJKqRpmWf5r0yMmSXjQuqb5WuqM755EuzWJOenY48denGoENzMLT8hQpA0hRTeU2IPA==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/runtime": "^7.28.4",
|
"@babel/runtime": "^7.28.4",
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
"@mui/icons-material": "^7.1.2",
|
"@mui/icons-material": "^7.1.2",
|
||||||
"@mui/material": "^7.1.2",
|
"@mui/material": "^7.1.2",
|
||||||
"@mui/x-charts": "^8.27.0",
|
"@mui/x-charts": "^8.27.0",
|
||||||
"@mui/x-data-grid": "^8.18.0",
|
"@mui/x-data-grid": "^8.27.1",
|
||||||
"@mui/x-date-pickers": "^8.23.0",
|
"@mui/x-date-pickers": "^8.23.0",
|
||||||
"date-and-time": "^3.6.0",
|
"date-and-time": "^3.6.0",
|
||||||
"dayjs": "^1.11.19",
|
"dayjs": "^1.11.19",
|
||||||
|
|||||||
Reference in New Issue
Block a user