From 840ceb4d8ad6190a1b17fd9b9a9db4fa7e234535 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 30 Jul 2025 07:53:41 +0200 Subject: [PATCH 01/78] Update softprops/action-gh-release digest to f2352b9 (#41) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Xodium Dependencies Updater This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | softprops/action-gh-release | action | digest | `f37a2f9` -> `f2352b9` | --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/XodiumSoftware/xbim). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/ci_cd.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci_cd.yml b/.github/workflows/ci_cd.yml index 90fec3e5..f2335c96 100644 --- a/.github/workflows/ci_cd.yml +++ b/.github/workflows/ci_cd.yml @@ -85,7 +85,7 @@ jobs: - id: create_release name: Create Release - uses: softprops/action-gh-release@f37a2f9143791b88da06f2c143d376e00fce81dc + uses: softprops/action-gh-release@f2352b97da0095b4dbbd885a81023e3deabf4fef env: { GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" } with: draft: ${{ contains(github.event.head_commit.message, '.draft') }} From 4ddf97ed57f0b739204fb4f9f4d25304fc3fad01 Mon Sep 17 00:00:00 2001 From: Illyrius <28700752+illyrius666@users.noreply.github.com> Date: Wed, 30 Jul 2025 13:44:55 +0200 Subject: [PATCH 02/78] feat/auto_gen_certs (#42) Signed-off-by: illyrius666 --- .idea/dictionaries/project.xml | 1 + Cargo.toml | 2 + scripts/gen_certs_for_dev_LINUX.sh | 18 ------ scripts/gen_certs_for_dev_WINDOWS.ps1 | 30 --------- src/config.rs | 49 ++++++++++---- src/main.rs | 30 ++++++++- src/tls.rs | 92 +++++++++++++++++++++++++++ src/utils.rs | 17 +++-- 8 files changed, 171 insertions(+), 68 deletions(-) delete mode 100644 scripts/gen_certs_for_dev_LINUX.sh delete mode 100644 scripts/gen_certs_for_dev_WINDOWS.ps1 create mode 100644 src/tls.rs diff --git a/.idea/dictionaries/project.xml b/.idea/dictionaries/project.xml index 9a3472c3..4e36e3cf 100644 --- a/.idea/dictionaries/project.xml +++ b/.idea/dictionaries/project.xml @@ -4,6 +4,7 @@ authguard ratelimitguard testuser + xodium \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml index e775b510..34938216 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,3 +33,5 @@ surrealdb = { version = "2.2.1", features = ["http"] } figment = { version = "0.10.19", features = ["toml"] } toml = "0.9.0" serde_json = "1.0.140" +rcgen = "0.14.3" +rand = "0.9.2" diff --git a/scripts/gen_certs_for_dev_LINUX.sh b/scripts/gen_certs_for_dev_LINUX.sh deleted file mode 100644 index b3a07a57..00000000 --- a/scripts/gen_certs_for_dev_LINUX.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/bash - -# Gen Certs for Dev - Shell Script Version - -# Create certs directory -mkdir -p ../target/debug/certs - -# Generate private key -openssl genrsa -out ../target/debug/certs/key.pem 2048 - -# Generate self-signed certificate -openssl req -new -x509 -key ../target/debug/certs/key.pem -out ../target/debug/certs/cert.pem -days 365 -subj "/CN=localhost" - -# Set appropriate permissions -chmod 600 ../target/debug/certs/key.pem -chmod 644 ../target/debug/certs/cert.pem - -echo "Self-signed certificates generated in target/debug/certs/" \ No newline at end of file diff --git a/scripts/gen_certs_for_dev_WINDOWS.ps1 b/scripts/gen_certs_for_dev_WINDOWS.ps1 deleted file mode 100644 index ee527a12..00000000 --- a/scripts/gen_certs_for_dev_WINDOWS.ps1 +++ /dev/null @@ -1,30 +0,0 @@ -# Gen Certs for Dev - PowerShell Version - -# Create certs directory -$certsDir = "..\target\debug\certs" -New-Item -ItemType Directory -Force -Path $certsDir | Out-Null - -# Generate self-signed certificate -$cert = New-SelfSignedCertificate ` - -Subject "CN=localhost" ` - -KeyAlgorithm RSA ` - -KeyLength 2048 ` - -CertStoreLocation "Cert:\CurrentUser\My" ` - -NotAfter (Get-Date).AddDays(365) - -# Export certificate and private key -Export-PfxCertificate ` - -Cert $cert ` - -FilePath "$certsDir\cert.pfx" ` - -Password (ConvertTo-SecureString -String "password" -Force -AsPlainText) | Out-Null - -# Export just the public key -Export-Certificate ` - -Cert $cert ` - -FilePath "$certsDir\cert.pem" -Type CERT | Out-Null - -# Clean up - remove from certificate store -Remove-Item -Path $cert.PSPath - -Write-Host "Self-signed certificates generated in $certsDir" -Write-Host "Note: The PFX file contains both certificate and private key (password: 'password')" \ No newline at end of file diff --git a/src/config.rs b/src/config.rs index 6cf7eefa..84f11aa7 100644 --- a/src/config.rs +++ b/src/config.rs @@ -4,6 +4,8 @@ use crate::utils::Utils; use figment::Figment; use figment::providers::{Format, Serialized, Toml}; +use rand::Rng; +use rand::distr::Alphanumeric; use rocket::serde::{Deserialize, Serialize}; use std::fs; use std::fs::File; @@ -26,7 +28,7 @@ pub struct Config { } impl Config { - /// Creates a new instance of `AppConfig` with default values. + /// Creates a new instance of `Config` with default values. /// /// # Returns /// A `Self` instance containing the default configuration. @@ -42,20 +44,45 @@ impl Config { /// # Returns /// A `Self` instance containing the loaded or default configuration. pub fn load_or_create(path: &PathBuf) -> Self { - if !path.exists() { + let mut config = if path.exists() { + Figment::from(Serialized::defaults(Self::default())) + .merge(Toml::file(path)) + .extract::() + .unwrap_or_else(|err| { + eprintln!("Configuration error (using defaults): {err}"); + Self::default() + }) + } else { println!("Creating default config at: {}", path.display()); Self::default() - .save_to_file(path) - .unwrap_or_else(|err| eprintln!("Failed to create config: {err}")); + }; + + if config.secret_key.is_empty() { + config.generate_secret_key(); + config.save_to_file(path).unwrap_or_else(|err| { + eprintln!("Failed to update config with new secret key: {err}") + }); } - Figment::from(Serialized::defaults(Self::default())) - .merge(Toml::file(path)) - .extract::() - .unwrap_or_else(|err| { - eprintln!("Configuration error (using defaults): {err}"); - Self::default() - }) + config + } + + /// Generates a new random secret key if the current one is empty. + /// # Note + /// - This only generates a key if `secret_key` is currently empty + /// - The generated key is printed to stdout for visibility + /// - For production use, consider: + /// - Storing the key securely (not in plaintext in config files) + /// - Using a dedicated secrets management system + fn generate_secret_key(&mut self) { + if self.secret_key.is_empty() { + self.secret_key = rand::rng() + .sample_iter(&Alphanumeric) + .take(64) + .map(char::from) + .collect(); + println!("Generated new secret key"); + } } /// Saves the current configuration to a file. diff --git a/src/main.rs b/src/main.rs index 28b8a630..70ab56e3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -20,12 +20,15 @@ pub mod routes { pub mod config; pub mod database; pub mod errors; +mod tls; mod utils; use crate::config::Config; use crate::routes::data::{data_delete, data_get, data_update, data_upload}; use crate::routes::github::{GitHubUser, github_callback, github_login}; use crate::routes::health::health; +use crate::tls::Tls; +use crate::utils::Utils; use database::Database; use errors::catchers; use rocket::config::SecretKey; @@ -38,10 +41,33 @@ use rocket::{ use rocket_async_compression::{Compression, Level as CompressionLevel}; use rocket_cors::{AllowedOrigins, CorsOptions}; use rocket_oauth2::{HyperRustlsAdapter, OAuth2, OAuthConfig, StaticProvider}; +use std::path::PathBuf; #[launch] async fn rocket() -> Rocket { - let config = Config::new(); + let config_path = Utils::get_exec_path("config.toml"); + let mut config = Config::new(); + + if config.tls_cert_path.is_empty() || config.tls_key_path.is_empty() { + let cert_path = Utils::get_exec_path(PathBuf::from("certs").join("cert.pem")); + let key_path = Utils::get_exec_path(PathBuf::from("certs").join("key.pem")); + + Tls::new(cert_path.clone(), key_path.clone()).expect("Failed to generate TLS certificates"); + + config.tls_cert_path = cert_path.to_string_lossy().into_owned(); + config.tls_key_path = key_path.to_string_lossy().into_owned(); + config + .save_to_file(&config_path) + .expect("Failed to save updated config with TLS paths"); + + println!("Auto-generated TLS certificates for development at:"); + println!(" Config: {}", config_path.display()); + println!(" Cert: {}", cert_path.display()); + println!(" Key: {}", key_path.display()); + } + + let config_clone = config.clone(); + build() .configure(rocket::Config { tls: (!config.tls_cert_path.is_empty() && !config.tls_key_path.is_empty()) @@ -50,7 +76,7 @@ async fn rocket() -> Rocket { ..rocket::Config::default() }) .manage(config.clone()) - .manage(Database::new(&config).await) + .manage(Database::new(&config_clone).await) .mount( "/", routes![ diff --git a/src/tls.rs b/src/tls.rs new file mode 100644 index 00000000..bae14d97 --- /dev/null +++ b/src/tls.rs @@ -0,0 +1,92 @@ +#![warn(clippy::all)] +#![forbid(unsafe_code)] + +use rcgen::{CertificateParams, DistinguishedName, DnType, KeyPair, SanType, date_time_ymd}; +use std::path::PathBuf; +use std::{fs, io}; + +/// TLS Certificate Management & Generation. +#[derive(Debug)] +pub struct Tls { + cert_path: PathBuf, + key_path: PathBuf, +} + +impl Tls { + /// Creates a new instance of `Tls` with default values. + /// + /// # Returns + /// A `Self` instance containing the default configuration. + pub fn new(cert_path: PathBuf, key_path: PathBuf) -> io::Result { + let tls = Self { + cert_path, + key_path, + }; + + if !tls.cert_path.exists() || !tls.key_path.exists() { + tls.generate_certificates()?; + println!( + "WARNING: Auto-generated self-signed TLS certificates are for development only." + ); + println!("For production use, provide CA-signed certificates at the specified paths:"); + println!(" Certificate: {}", tls.cert_path.display()); + println!(" Private Key: {}", tls.key_path.display()); + } + + Ok(tls) + } + + /// Generates self-signed TLS certificates and writes them to disk. + /// + /// This function will: + /// 1. Create parent directories if they don't exist + /// 2. Generate certificate parameters with: + /// - Long validity period (1975-4096) + /// - Organization name "Xodium Software" + /// - Subject Alternative Name for "localhost" + /// 3. Generate a new cryptographic key pair + /// 4. Create a self-signed certificate + /// 5. Write both certificate and private key to specified paths + /// + /// # Errors + /// Returns `io::Result` with detailed error messages if any step fails, including: + /// - Directory creation failures + /// - Invalid DNS name format + /// - Key generation failures + /// - Certificate signing failures + /// - File writing failures + /// + /// # Security Note + /// The generated certificates are self-signed and should only be used for development. + /// Production environments should use properly signed certificates from a Certificate Authority. + fn generate_certificates(&self) -> io::Result<()> { + for path in [&self.cert_path, &self.key_path] { + if let Some(parent) = path.parent() { + fs::create_dir_all(parent)?; + } + } + + let mut params: CertificateParams = Default::default(); + params.not_before = date_time_ymd(1975, 1, 1); + params.not_after = date_time_ymd(4096, 1, 1); + params.distinguished_name = DistinguishedName::new(); + params + .distinguished_name + .push(DnType::OrganizationName, "Xodium Software"); + params.subject_alt_names = + vec![SanType::DnsName("localhost".try_into().map_err(|e| { + io::Error::other(format!("Invalid DNS name: {e}")) + })?)]; + + let key_pair = KeyPair::generate() + .map_err(|e| io::Error::other(format!("Key generation failed: {e}")))?; + let cert = params + .self_signed(&key_pair) + .map_err(|e| io::Error::other(format!("Certificate generation failed: {e}")))?; + + fs::write(&self.cert_path, cert.pem().as_bytes())?; + fs::write(&self.key_path, key_pair.serialize_pem().as_bytes())?; + + Ok(()) + } +} diff --git a/src/utils.rs b/src/utils.rs index 30d26121..44b48161 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -3,27 +3,30 @@ use crate::config::Config; use colored::*; -use std::env; use std::path::PathBuf; +use std::{env, path}; use surrealdb::Error; /// A utility struct for common helper functions. pub struct Utils; impl Utils { - /// Returns a path to a file in the same directory as the current executable. + /// Returns a path to a file relative to the current executable's directory. /// /// # Arguments - /// * `filename` - The name of the file to locate (e.g., "config.toml") + /// * `path_components` - One or more path components (folders and/or filename) /// /// # Returns - /// A `PathBuf` pointing to the specified file in the executable's directory - pub fn get_exec_path(filename: &str) -> PathBuf { - env::current_exe() + /// A `PathBuf` pointing to the specified path relative to the executable's directory + pub fn get_exec_path>(path_components: P) -> PathBuf { + let mut path = env::current_exe() .expect("Failed to get executable path") .parent() .expect("Failed to get executable directory") - .join(filename) + .to_path_buf(); + + path.push(path_components); + path } /// Displays a formatted error message for database connection issues. From 1cc16d3494c62d2935f8a9ee33287004b3d594a7 Mon Sep 17 00:00:00 2001 From: illyrius666 Date: Wed, 30 Jul 2025 13:50:52 +0200 Subject: [PATCH 03/78] refactor Signed-off-by: illyrius666 --- src/config.rs | 29 +++++++++++++++++++++++++++++ src/main.rs | 29 ++--------------------------- 2 files changed, 31 insertions(+), 27 deletions(-) diff --git a/src/config.rs b/src/config.rs index 84f11aa7..c997994c 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,6 +1,7 @@ #![warn(clippy::all)] #![forbid(unsafe_code)] +use crate::tls::Tls; use crate::utils::Utils; use figment::Figment; use figment::providers::{Format, Serialized, Toml}; @@ -64,6 +65,34 @@ impl Config { }); } + if config.tls_cert_path.is_empty() + || config.tls_key_path.is_empty() + || !PathBuf::from(&config.tls_cert_path).exists() + || !PathBuf::from(&config.tls_key_path).exists() + { + let cert_path = if config.tls_cert_path.is_empty() { + Utils::get_exec_path("cert.pem") + } else { + PathBuf::from(&config.tls_cert_path) + }; + + let key_path = if config.tls_key_path.is_empty() { + Utils::get_exec_path("key.pem") + } else { + PathBuf::from(&config.tls_key_path) + }; + + if let Err(e) = Tls::new(cert_path.clone(), key_path.clone()) { + eprintln!("Failed to generate TLS certificates: {e}"); + } else { + config.tls_cert_path = cert_path.to_string_lossy().into_owned(); + config.tls_key_path = key_path.to_string_lossy().into_owned(); + config.save_to_file(path).unwrap_or_else(|err| { + eprintln!("Failed to update config with TLS paths: {err}") + }); + } + } + config } diff --git a/src/main.rs b/src/main.rs index 70ab56e3..8f20a0af 100644 --- a/src/main.rs +++ b/src/main.rs @@ -27,8 +27,6 @@ use crate::config::Config; use crate::routes::data::{data_delete, data_get, data_update, data_upload}; use crate::routes::github::{GitHubUser, github_callback, github_login}; use crate::routes::health::health; -use crate::tls::Tls; -use crate::utils::Utils; use database::Database; use errors::catchers; use rocket::config::SecretKey; @@ -41,33 +39,10 @@ use rocket::{ use rocket_async_compression::{Compression, Level as CompressionLevel}; use rocket_cors::{AllowedOrigins, CorsOptions}; use rocket_oauth2::{HyperRustlsAdapter, OAuth2, OAuthConfig, StaticProvider}; -use std::path::PathBuf; #[launch] async fn rocket() -> Rocket { - let config_path = Utils::get_exec_path("config.toml"); - let mut config = Config::new(); - - if config.tls_cert_path.is_empty() || config.tls_key_path.is_empty() { - let cert_path = Utils::get_exec_path(PathBuf::from("certs").join("cert.pem")); - let key_path = Utils::get_exec_path(PathBuf::from("certs").join("key.pem")); - - Tls::new(cert_path.clone(), key_path.clone()).expect("Failed to generate TLS certificates"); - - config.tls_cert_path = cert_path.to_string_lossy().into_owned(); - config.tls_key_path = key_path.to_string_lossy().into_owned(); - config - .save_to_file(&config_path) - .expect("Failed to save updated config with TLS paths"); - - println!("Auto-generated TLS certificates for development at:"); - println!(" Config: {}", config_path.display()); - println!(" Cert: {}", cert_path.display()); - println!(" Key: {}", key_path.display()); - } - - let config_clone = config.clone(); - + let config = Config::new(); build() .configure(rocket::Config { tls: (!config.tls_cert_path.is_empty() && !config.tls_key_path.is_empty()) @@ -76,7 +51,7 @@ async fn rocket() -> Rocket { ..rocket::Config::default() }) .manage(config.clone()) - .manage(Database::new(&config_clone).await) + .manage(Database::new(&config).await) .mount( "/", routes![ From f37d2ff5415923003b0c4b66b0e4182bfc6a1859 Mon Sep 17 00:00:00 2001 From: illyrius666 Date: Wed, 30 Jul 2025 14:04:28 +0200 Subject: [PATCH 04/78] refactor utils get exec path Signed-off-by: illyrius666 --- src/config.rs | 4 ++-- src/utils.rs | 13 +++++-------- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/src/config.rs b/src/config.rs index c997994c..58bdef11 100644 --- a/src/config.rs +++ b/src/config.rs @@ -71,13 +71,13 @@ impl Config { || !PathBuf::from(&config.tls_key_path).exists() { let cert_path = if config.tls_cert_path.is_empty() { - Utils::get_exec_path("cert.pem") + Utils::get_exec_path("certs/cert.pem") } else { PathBuf::from(&config.tls_cert_path) }; let key_path = if config.tls_key_path.is_empty() { - Utils::get_exec_path("key.pem") + Utils::get_exec_path("certs/key.pem") } else { PathBuf::from(&config.tls_key_path) }; diff --git a/src/utils.rs b/src/utils.rs index 44b48161..61e3a067 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -14,19 +14,16 @@ impl Utils { /// Returns a path to a file relative to the current executable's directory. /// /// # Arguments - /// * `path_components` - One or more path components (folders and/or filename) + /// * `path` - A path component to append to the executable's directory. /// /// # Returns /// A `PathBuf` pointing to the specified path relative to the executable's directory - pub fn get_exec_path>(path_components: P) -> PathBuf { - let mut path = env::current_exe() + pub fn get_exec_path>(path: P) -> PathBuf { + env::current_exe() .expect("Failed to get executable path") .parent() - .expect("Failed to get executable directory") - .to_path_buf(); - - path.push(path_components); - path + .expect("Executable has no parent directory") + .join(path) } /// Displays a formatted error message for database connection issues. From ad1e4c05e2dd1046d6962298bc9516859590191d Mon Sep 17 00:00:00 2001 From: illyrius666 Date: Wed, 30 Jul 2025 14:22:16 +0200 Subject: [PATCH 05/78] workflow cleanup Signed-off-by: illyrius666 --- .github/workflows/ci_cd.yml | 14 +++++++------- .idea/dictionaries/project.xml | 2 ++ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci_cd.yml b/.github/workflows/ci_cd.yml index f2335c96..fdb22f14 100644 --- a/.github/workflows/ci_cd.yml +++ b/.github/workflows/ci_cd.yml @@ -23,11 +23,11 @@ jobs: steps: - id: checkout name: Checkout - uses: actions/checkout@main + uses: actions/checkout@v4.2.2 - id: setup_rust name: Setup Rust - uses: actions-rust-lang/setup-rust-toolchain@fb51252c7ba57d633bc668f941da052e410add48 + uses: actions-rust-lang/setup-rust-toolchain@v1.13.0 with: { toolchain: stable } - id: build_artifact @@ -44,7 +44,7 @@ jobs: - id: upload_artifact name: Upload Artifact - uses: actions/upload-artifact@main + uses: actions/upload-artifact@v4.6.2 with: { name: xbim, path: target/release/xBIM } test: @@ -58,11 +58,11 @@ jobs: steps: - id: checkout name: Checkout - uses: actions/checkout@main + uses: actions/checkout@v4.2.2 - id: setup_rust name: Setup Rust - uses: actions-rust-lang/setup-rust-toolchain@fb51252c7ba57d633bc668f941da052e410add48 + uses: actions-rust-lang/setup-rust-toolchain@v1.13.0 with: { toolchain: stable } - id: run_tests @@ -80,12 +80,12 @@ jobs: steps: - id: download_artifact name: Download Artefact - uses: actions/download-artifact@main + uses: actions/download-artifact@v4.3.0 with: { name: xbim } - id: create_release name: Create Release - uses: softprops/action-gh-release@f2352b97da0095b4dbbd885a81023e3deabf4fef + uses: softprops/action-gh-release@v2.3.2 env: { GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" } with: draft: ${{ contains(github.event.head_commit.message, '.draft') }} diff --git a/.idea/dictionaries/project.xml b/.idea/dictionaries/project.xml index 4e36e3cf..bf05375f 100644 --- a/.idea/dictionaries/project.xml +++ b/.idea/dictionaries/project.xml @@ -3,7 +3,9 @@ authguard ratelimitguard + softprops testuser + xbim xodium From 3be3e664171b442f60e09ff343800c2b0ca3bcfd Mon Sep 17 00:00:00 2001 From: illyrius666 Date: Wed, 30 Jul 2025 14:29:58 +0200 Subject: [PATCH 06/78] improve ci_cd Signed-off-by: illyrius666 --- .github/workflows/ci_cd.yml | 58 +++++++++++++++++++++++++--------- .idea/dictionaries/project.xml | 3 ++ 2 files changed, 46 insertions(+), 15 deletions(-) diff --git a/.github/workflows/ci_cd.yml b/.github/workflows/ci_cd.yml index fdb22f14..67655ef7 100644 --- a/.github/workflows/ci_cd.yml +++ b/.github/workflows/ci_cd.yml @@ -1,15 +1,17 @@ name: Xodium CI/CD -run-name: "Xodium CI/CD" -on: { push: { branches: [ main ], paths: [ "../../server/src/**" ] }, workflow_dispatch } +on: + push: + branches: [ main ] + paths: [ "src/**" ] -permissions: { contents: write, packages: write } +permissions: + contents: read + packages: write concurrency: - { - group: "${{ github.workflow }}-${{ github.ref }}", - cancel-in-progress: true, - } + group: "${{ github.workflow }}-${{ github.ref }}" + cancel-in-progress: true jobs: build: @@ -25,14 +27,27 @@ jobs: name: Checkout uses: actions/checkout@v4.2.2 + - id: cache_deps + name: Cache dependencies + uses: actions/cache@v4.2.3 + with: + path: | + ~/.cargo/registry + ~/.cargo/git + target + key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} + + - id: setup_rust name: Setup Rust uses: actions-rust-lang/setup-rust-toolchain@v1.13.0 - with: { toolchain: stable } + with: + toolchain: stable + components: rustfmt, clippy - id: build_artifact name: Build Artefact - run: cargo build --release + run: cargo build --release --locked --timings - id: install_toml_cli name: Install toml-cli @@ -45,7 +60,10 @@ jobs: - id: upload_artifact name: Upload Artifact uses: actions/upload-artifact@v4.6.2 - with: { name: xbim, path: target/release/xBIM } + with: + name: xbim + path: target/release/xbim + retention-days: 7 test: needs: [ build ] @@ -63,11 +81,15 @@ jobs: - id: setup_rust name: Setup Rust uses: actions-rust-lang/setup-rust-toolchain@v1.13.0 - with: { toolchain: stable } + with: + toolchain: stable - id: run_tests name: Run Tests - run: cargo test --all + run: | + cargo test --all --no-fail-fast + cargo clippy --all-targets --all-features -- -D warnings + cargo fmt --all -- --check release: needs: [ build, test ] @@ -81,15 +103,21 @@ jobs: - id: download_artifact name: Download Artefact uses: actions/download-artifact@v4.3.0 - with: { name: xbim } + with: + name: xbim + + - id: verify_binary + name: Verify Binary + run: ./xbim --version - id: create_release name: Create Release uses: softprops/action-gh-release@v2.3.2 - env: { GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" } + env: + GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" with: draft: ${{ contains(github.event.head_commit.message, '.draft') }} generate_release_notes: true prerelease: ${{ contains(github.event.head_commit.message, '.pre') }} tag_name: v${{ needs.build.outputs.VERSION }} - files: xBIM + files: xbim diff --git a/.idea/dictionaries/project.xml b/.idea/dictionaries/project.xml index bf05375f..c13c299d 100644 --- a/.idea/dictionaries/project.xml +++ b/.idea/dictionaries/project.xml @@ -2,7 +2,10 @@ authguard + clippy + deps ratelimitguard + rustfmt softprops testuser xbim From e80e505250261ebc639124c9c503a1140a3d4afa Mon Sep 17 00:00:00 2001 From: illyrius666 Date: Wed, 30 Jul 2025 14:32:15 +0200 Subject: [PATCH 07/78] more improvements Signed-off-by: illyrius666 --- .github/workflows/ci_cd.yml | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/.github/workflows/ci_cd.yml b/.github/workflows/ci_cd.yml index 67655ef7..a4668863 100644 --- a/.github/workflows/ci_cd.yml +++ b/.github/workflows/ci_cd.yml @@ -17,10 +17,8 @@ jobs: build: runs-on: ubuntu-latest environment: - { - name: "${{ github.ref_name }}", - url: "${{ steps.upload_artifact.outputs.artifact-url }}", - } + name: "${{ github.ref_name }}" + url: "${{ steps.upload_artifact.outputs.artifact-url }}" outputs: { VERSION: "${{ steps.get_version.outputs.VERSION }}" } steps: - id: checkout @@ -48,6 +46,7 @@ jobs: - id: build_artifact name: Build Artefact run: cargo build --release --locked --timings + shell: bash - id: install_toml_cli name: Install toml-cli @@ -56,6 +55,7 @@ jobs: - id: get_version name: Get Version run: echo "VERSION=$(toml get Cargo.toml package.version | tr -d '\"')" >> $GITHUB_OUTPUT + shell: bash - id: upload_artifact name: Upload Artifact @@ -69,10 +69,7 @@ jobs: needs: [ build ] runs-on: ubuntu-latest environment: - { - name: "${{ github.ref_name }}", - url: "${{ steps.upload_artifact.outputs.artifact-url }}", - } + name: "${{ github.ref_name }}" steps: - id: checkout name: Checkout @@ -90,15 +87,14 @@ jobs: cargo test --all --no-fail-fast cargo clippy --all-targets --all-features -- -D warnings cargo fmt --all -- --check + shell: bash release: needs: [ build, test ] runs-on: ubuntu-latest environment: - { - name: "${{ github.ref_name }}", - url: "${{ steps.create_release.outputs.url }}", - } + name: "${{ github.ref_name }}" + url: "${{ steps.create_release.outputs.url }}" steps: - id: download_artifact name: Download Artefact @@ -109,6 +105,7 @@ jobs: - id: verify_binary name: Verify Binary run: ./xbim --version + shell: bash - id: create_release name: Create Release From 2ebca7ff8a2ae5af58212887a5ca71fe81c2e488 Mon Sep 17 00:00:00 2001 From: illyrius666 Date: Wed, 30 Jul 2025 14:36:09 +0200 Subject: [PATCH 08/78] added check branch to so we dont push to pr to main (only dev is allowed to do that) Signed-off-by: illyrius666 --- .github/workflows/check.yml | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 .github/workflows/check.yml diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml new file mode 100644 index 00000000..18ebc402 --- /dev/null +++ b/.github/workflows/check.yml @@ -0,0 +1,28 @@ +name: Xodium CI/CD - Check Branches + +on: + pull_request_target: + types: [ opened, reopened, synchronize, edited, ready_for_review ] + +concurrency: + group: "${{ github.workflow }}-${{ github.ref }}" + cancel-in-progress: true + +permissions: + contents: read + +jobs: + check-branches: + runs-on: ubuntu-latest + steps: + - id: check_branches + name: Check Branches + env: + HEAD_REF: ${{ github.head_ref }} + BASE_REF: ${{ github.base_ref }} + run: | + if [ "$HEAD_REF" != "dev" ] && [ "$BASE_REF" == "main" ]; then + echo "Merge requests to main branch are only allowed from dev branch." + exit 1 + fi + shell: bash \ No newline at end of file From 66146a98d33a65953d305a6fa1e116b2250c8fbd Mon Sep 17 00:00:00 2001 From: illyrius666 Date: Wed, 30 Jul 2025 17:50:43 +0200 Subject: [PATCH 09/78] woops Signed-off-by: illyrius666 --- SECURITY.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/SECURITY.md b/SECURITY.md index 34199a08..233bed7e 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -2,7 +2,8 @@ ## Reporting a Vulnerability -We take security vulnerabilities seriously. If you discover a security issue, please report it to us responsibly through GitHub's private vulnerability reporting system. +We take security vulnerabilities seriously. If you discover a security issue, +please report it to us responsibly through GitHub's private vulnerability reporting system. ### How to Report From c0eacba29986b958458d4760b9efc8b00380d8ae Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 6 Aug 2025 04:50:14 +0000 Subject: [PATCH 10/78] Update actions/download-artifact action to v5 (#44) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Xodium Dependencies Updater This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [actions/download-artifact](https://redirect.github.com/actions/download-artifact) | action | major | `v4.3.0` -> `v5.0.0` | --- ### Release Notes
actions/download-artifact (actions/download-artifact) ### [`v5.0.0`](https://redirect.github.com/actions/download-artifact/releases/tag/v5.0.0) [Compare Source](https://redirect.github.com/actions/download-artifact/compare/v4.3.0...v5.0.0) #### What's Changed - Update README.md by [@​nebuk89](https://redirect.github.com/nebuk89) in [https://github.com/actions/download-artifact/pull/407](https://redirect.github.com/actions/download-artifact/pull/407) - BREAKING fix: inconsistent path behavior for single artifact downloads by ID by [@​GrantBirki](https://redirect.github.com/GrantBirki) in [https://github.com/actions/download-artifact/pull/416](https://redirect.github.com/actions/download-artifact/pull/416) #### v5.0.0 ##### 🚨 Breaking Change This release fixes an inconsistency in path behavior for single artifact downloads by ID. **If you're downloading single artifacts by ID, the output path may change.** ##### What Changed Previously, **single artifact downloads** behaved differently depending on how you specified the artifact: - **By name**: `name: my-artifact` → extracted to `path/` (direct) - **By ID**: `artifact-ids: 12345` → extracted to `path/my-artifact/` (nested) Now both methods are consistent: - **By name**: `name: my-artifact` → extracted to `path/` (unchanged) - **By ID**: `artifact-ids: 12345` → extracted to `path/` (fixed - now direct) ##### Migration Guide ##### ✅ No Action Needed If: - You download artifacts by **name** - You download **multiple** artifacts by ID - You already use `merge-multiple: true` as a workaround ##### ⚠️ Action Required If: You download **single artifacts by ID** and your workflows expect the nested directory structure. **Before v5 (nested structure):** ```yaml - uses: actions/download-artifact@v4 with: artifact-ids: 12345 path: dist ### Files were in: dist/my-artifact/ ``` > Where `my-artifact` is the name of the artifact you previously uploaded **To maintain old behavior (if needed):** ```yaml - uses: actions/download-artifact@v5 with: artifact-ids: 12345 path: dist/my-artifact # Explicitly specify the nested path ``` #### New Contributors - [@​nebuk89](https://redirect.github.com/nebuk89) made their first contribution in [https://github.com/actions/download-artifact/pull/407](https://redirect.github.com/actions/download-artifact/pull/407) **Full Changelog**: https://github.com/actions/download-artifact/compare/v4...v5.0.0
--- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/XodiumSoftware/xbim). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/ci_cd.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci_cd.yml b/.github/workflows/ci_cd.yml index a4668863..1393048e 100644 --- a/.github/workflows/ci_cd.yml +++ b/.github/workflows/ci_cd.yml @@ -98,7 +98,7 @@ jobs: steps: - id: download_artifact name: Download Artefact - uses: actions/download-artifact@v4.3.0 + uses: actions/download-artifact@v5.0.0 with: name: xbim From f680a0fe0fcd17446eab9778f25fcd2e1a2324f3 Mon Sep 17 00:00:00 2001 From: illyrius666 Date: Wed, 6 Aug 2025 11:16:51 +0200 Subject: [PATCH 11/78] fix security stuff Signed-off-by: illyrius666 --- .github/workflows/ci_cd.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci_cd.yml b/.github/workflows/ci_cd.yml index 1393048e..b917e0ce 100644 --- a/.github/workflows/ci_cd.yml +++ b/.github/workflows/ci_cd.yml @@ -38,7 +38,7 @@ jobs: - id: setup_rust name: Setup Rust - uses: actions-rust-lang/setup-rust-toolchain@v1.13.0 + uses: actions-rust-lang/setup-rust-toolchain@fb51252c7ba57d633bc668f941da052e410add48 with: toolchain: stable components: rustfmt, clippy @@ -77,7 +77,7 @@ jobs: - id: setup_rust name: Setup Rust - uses: actions-rust-lang/setup-rust-toolchain@v1.13.0 + uses: actions-rust-lang/setup-rust-toolchain@fb51252c7ba57d633bc668f941da052e410add48 with: toolchain: stable @@ -109,7 +109,7 @@ jobs: - id: create_release name: Create Release - uses: softprops/action-gh-release@v2.3.2 + uses: softprops/action-gh-release@72f2c25fcb47643c292f7107632f7a47c1df5cd8 env: GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" with: From 9cfb02ad3d68db302117e2293f21ecf3839c1ef2 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 6 Aug 2025 20:41:46 +0000 Subject: [PATCH 12/78] Update softprops/action-gh-release digest to f82d31e (#45) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Xodium Dependencies Updater This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | softprops/action-gh-release | action | digest | `72f2c25` -> `f82d31e` | --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/XodiumSoftware/xbim). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/ci_cd.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci_cd.yml b/.github/workflows/ci_cd.yml index b917e0ce..365631b2 100644 --- a/.github/workflows/ci_cd.yml +++ b/.github/workflows/ci_cd.yml @@ -109,7 +109,7 @@ jobs: - id: create_release name: Create Release - uses: softprops/action-gh-release@72f2c25fcb47643c292f7107632f7a47c1df5cd8 + uses: softprops/action-gh-release@f82d31e53e61a962573dd0c5fcd6b446ca78871f env: GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" with: From c51ffebe8ae85b728520adf3d87904e81db37d6b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 7 Aug 2025 16:47:09 +0000 Subject: [PATCH 13/78] Update actions/cache action to v4.2.4 (#46) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Xodium Dependencies Updater This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [actions/cache](https://redirect.github.com/actions/cache) | action | patch | `v4.2.3` -> `v4.2.4` | --- ### Release Notes
actions/cache (actions/cache) ### [`v4.2.4`](https://redirect.github.com/actions/cache/releases/tag/v4.2.4) [Compare Source](https://redirect.github.com/actions/cache/compare/v4.2.3...v4.2.4) #### What's Changed - Update README.md by [@​nebuk89](https://redirect.github.com/nebuk89) in [https://github.com/actions/cache/pull/1620](https://redirect.github.com/actions/cache/pull/1620) - Upgrade `@actions/cache` to `4.0.4` and move `@protobuf-ts/plugin` to dev depdencies by [@​Link-](https://redirect.github.com/Link-) in [https://github.com/actions/cache/pull/1634](https://redirect.github.com/actions/cache/pull/1634) - Prepare release `4.2.4` by [@​Link-](https://redirect.github.com/Link-) in [https://github.com/actions/cache/pull/1636](https://redirect.github.com/actions/cache/pull/1636) #### New Contributors - [@​nebuk89](https://redirect.github.com/nebuk89) made their first contribution in [https://github.com/actions/cache/pull/1620](https://redirect.github.com/actions/cache/pull/1620) **Full Changelog**: https://github.com/actions/cache/compare/v4...v4.2.4
--- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/XodiumSoftware/xbim). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/ci_cd.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci_cd.yml b/.github/workflows/ci_cd.yml index 365631b2..d648d50f 100644 --- a/.github/workflows/ci_cd.yml +++ b/.github/workflows/ci_cd.yml @@ -27,7 +27,7 @@ jobs: - id: cache_deps name: Cache dependencies - uses: actions/cache@v4.2.3 + uses: actions/cache@v4.2.4 with: path: | ~/.cargo/registry From 0c59f30e6da88b74da2f0c3dab205ac654f2af3d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 11 Aug 2025 17:48:21 +0000 Subject: [PATCH 14/78] Update actions/checkout action to v4.3.0 (#47) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Xodium Dependencies Updater This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [actions/checkout](https://redirect.github.com/actions/checkout) | action | minor | `v4.2.2` -> `v4.3.0` | --- ### Release Notes
actions/checkout (actions/checkout) ### [`v4.3.0`](https://redirect.github.com/actions/checkout/releases/tag/v4.3.0) [Compare Source](https://redirect.github.com/actions/checkout/compare/v4.2.2...v4.3.0) ##### What's Changed - docs: update README.md by [@​motss](https://redirect.github.com/motss) in [https://github.com/actions/checkout/pull/1971](https://redirect.github.com/actions/checkout/pull/1971) - Add internal repos for checking out multiple repositories by [@​mouismail](https://redirect.github.com/mouismail) in [https://github.com/actions/checkout/pull/1977](https://redirect.github.com/actions/checkout/pull/1977) - Documentation update - add recommended permissions to Readme by [@​benwells](https://redirect.github.com/benwells) in [https://github.com/actions/checkout/pull/2043](https://redirect.github.com/actions/checkout/pull/2043) - Adjust positioning of user email note and permissions heading by [@​joshmgross](https://redirect.github.com/joshmgross) in [https://github.com/actions/checkout/pull/2044](https://redirect.github.com/actions/checkout/pull/2044) - Update README.md by [@​nebuk89](https://redirect.github.com/nebuk89) in [https://github.com/actions/checkout/pull/2194](https://redirect.github.com/actions/checkout/pull/2194) - Update CODEOWNERS for actions by [@​TingluoHuang](https://redirect.github.com/TingluoHuang) in [https://github.com/actions/checkout/pull/2224](https://redirect.github.com/actions/checkout/pull/2224) - Update package dependencies by [@​salmanmkc](https://redirect.github.com/salmanmkc) in [https://github.com/actions/checkout/pull/2236](https://redirect.github.com/actions/checkout/pull/2236) - Prepare release v4.3.0 by [@​salmanmkc](https://redirect.github.com/salmanmkc) in [https://github.com/actions/checkout/pull/2237](https://redirect.github.com/actions/checkout/pull/2237) ##### New Contributors - [@​motss](https://redirect.github.com/motss) made their first contribution in [https://github.com/actions/checkout/pull/1971](https://redirect.github.com/actions/checkout/pull/1971) - [@​mouismail](https://redirect.github.com/mouismail) made their first contribution in [https://github.com/actions/checkout/pull/1977](https://redirect.github.com/actions/checkout/pull/1977) - [@​benwells](https://redirect.github.com/benwells) made their first contribution in [https://github.com/actions/checkout/pull/2043](https://redirect.github.com/actions/checkout/pull/2043) - [@​nebuk89](https://redirect.github.com/nebuk89) made their first contribution in [https://github.com/actions/checkout/pull/2194](https://redirect.github.com/actions/checkout/pull/2194) - [@​salmanmkc](https://redirect.github.com/salmanmkc) made their first contribution in [https://github.com/actions/checkout/pull/2236](https://redirect.github.com/actions/checkout/pull/2236) **Full Changelog**: https://github.com/actions/checkout/compare/v4...v4.3.0
--- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/XodiumSoftware/xbim). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/ci_cd.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci_cd.yml b/.github/workflows/ci_cd.yml index d648d50f..ecbeb08d 100644 --- a/.github/workflows/ci_cd.yml +++ b/.github/workflows/ci_cd.yml @@ -23,7 +23,7 @@ jobs: steps: - id: checkout name: Checkout - uses: actions/checkout@v4.2.2 + uses: actions/checkout@v4.3.0 - id: cache_deps name: Cache dependencies @@ -73,7 +73,7 @@ jobs: steps: - id: checkout name: Checkout - uses: actions/checkout@v4.2.2 + uses: actions/checkout@v4.3.0 - id: setup_rust name: Setup Rust From 534405e9157709ac51e7f0b2d69e252648cd7277 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 18 Aug 2025 04:54:05 +0000 Subject: [PATCH 15/78] Update softprops/action-gh-release digest to 126b1e7 (#49) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Xodium Dependencies Updater This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | softprops/action-gh-release | action | digest | `f82d31e` -> `126b1e7` | --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/XodiumSoftware/xbim). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/ci_cd.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci_cd.yml b/.github/workflows/ci_cd.yml index ecbeb08d..bc840549 100644 --- a/.github/workflows/ci_cd.yml +++ b/.github/workflows/ci_cd.yml @@ -109,7 +109,7 @@ jobs: - id: create_release name: Create Release - uses: softprops/action-gh-release@f82d31e53e61a962573dd0c5fcd6b446ca78871f + uses: softprops/action-gh-release@126b1e70939461ae1dc0252ce412cabf99778520 env: GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" with: From c4240373cf3af024d08677532de0685eb42e3c67 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 18 Aug 2025 08:46:17 +0000 Subject: [PATCH 16/78] Update actions/checkout action to v5 (#48) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Xodium Dependencies Updater This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [actions/checkout](https://redirect.github.com/actions/checkout) | action | major | `v4.3.0` -> `v5.0.0` | --- ### Release Notes
actions/checkout (actions/checkout) ### [`v5.0.0`](https://redirect.github.com/actions/checkout/releases/tag/v5.0.0) [Compare Source](https://redirect.github.com/actions/checkout/compare/v4.3.0...v5.0.0) ##### What's Changed - Update actions checkout to use node 24 by [@​salmanmkc](https://redirect.github.com/salmanmkc) in [https://github.com/actions/checkout/pull/2226](https://redirect.github.com/actions/checkout/pull/2226) - Prepare v5.0.0 release by [@​salmanmkc](https://redirect.github.com/salmanmkc) in [https://github.com/actions/checkout/pull/2238](https://redirect.github.com/actions/checkout/pull/2238) ##### ⚠️ Minimum Compatible Runner Version **v2.327.1**\ [Release Notes](https://redirect.github.com/actions/runner/releases/tag/v2.327.1) Make sure your runner is updated to this version or newer to use this release. **Full Changelog**: https://github.com/actions/checkout/compare/v4...v5.0.0
--- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/XodiumSoftware/xbim). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/ci_cd.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci_cd.yml b/.github/workflows/ci_cd.yml index bc840549..3e055d06 100644 --- a/.github/workflows/ci_cd.yml +++ b/.github/workflows/ci_cd.yml @@ -23,7 +23,7 @@ jobs: steps: - id: checkout name: Checkout - uses: actions/checkout@v4.3.0 + uses: actions/checkout@v5.0.0 - id: cache_deps name: Cache dependencies @@ -73,7 +73,7 @@ jobs: steps: - id: checkout name: Checkout - uses: actions/checkout@v4.3.0 + uses: actions/checkout@v5.0.0 - id: setup_rust name: Setup Rust From dd7fe6b35121c50f7969eee3823157876e0f92dd Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 23 Aug 2025 21:09:30 +0000 Subject: [PATCH 17/78] Update actions-rust-lang/setup-rust-toolchain digest to ab68452 (#50) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Xodium Dependencies Updater This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | actions-rust-lang/setup-rust-toolchain | action | digest | `fb51252` -> `ab68452` | --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/XodiumSoftware/xbim). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/ci_cd.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci_cd.yml b/.github/workflows/ci_cd.yml index 3e055d06..1587b79c 100644 --- a/.github/workflows/ci_cd.yml +++ b/.github/workflows/ci_cd.yml @@ -38,7 +38,7 @@ jobs: - id: setup_rust name: Setup Rust - uses: actions-rust-lang/setup-rust-toolchain@fb51252c7ba57d633bc668f941da052e410add48 + uses: actions-rust-lang/setup-rust-toolchain@ab6845274e2ff01cd4462007e1a9d9df1ab49f42 with: toolchain: stable components: rustfmt, clippy @@ -77,7 +77,7 @@ jobs: - id: setup_rust name: Setup Rust - uses: actions-rust-lang/setup-rust-toolchain@fb51252c7ba57d633bc668f941da052e410add48 + uses: actions-rust-lang/setup-rust-toolchain@ab6845274e2ff01cd4462007e1a9d9df1ab49f42 with: toolchain: stable From 93139aabc7462339db345e02f94969293303c670 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 24 Aug 2025 01:25:52 +0000 Subject: [PATCH 18/78] Update softprops/action-gh-release digest to fbadcc9 (#51) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Xodium Dependencies Updater This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | softprops/action-gh-release | action | digest | `126b1e7` -> `fbadcc9` | --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/XodiumSoftware/xbim). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/ci_cd.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci_cd.yml b/.github/workflows/ci_cd.yml index 1587b79c..520aa1bf 100644 --- a/.github/workflows/ci_cd.yml +++ b/.github/workflows/ci_cd.yml @@ -109,7 +109,7 @@ jobs: - id: create_release name: Create Release - uses: softprops/action-gh-release@126b1e70939461ae1dc0252ce412cabf99778520 + uses: softprops/action-gh-release@fbadcc90e88ecface60a0a0d123795b784ceb239 env: GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" with: From 5fa1e4e699030175eaf9bc68325b115d10fda443 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 28 Aug 2025 03:38:05 +0000 Subject: [PATCH 19/78] Update actions-rust-lang/setup-rust-toolchain digest to ac90e63 (#53) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Xodium Dependencies Updater This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | actions-rust-lang/setup-rust-toolchain | action | digest | `ab68452` -> `ac90e63` | --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/XodiumSoftware/xbim). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/ci_cd.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci_cd.yml b/.github/workflows/ci_cd.yml index 520aa1bf..fc2bb10a 100644 --- a/.github/workflows/ci_cd.yml +++ b/.github/workflows/ci_cd.yml @@ -38,7 +38,7 @@ jobs: - id: setup_rust name: Setup Rust - uses: actions-rust-lang/setup-rust-toolchain@ab6845274e2ff01cd4462007e1a9d9df1ab49f42 + uses: actions-rust-lang/setup-rust-toolchain@ac90e63697ac2784f4ecfe2964e1a285c304003a with: toolchain: stable components: rustfmt, clippy @@ -77,7 +77,7 @@ jobs: - id: setup_rust name: Setup Rust - uses: actions-rust-lang/setup-rust-toolchain@ab6845274e2ff01cd4462007e1a9d9df1ab49f42 + uses: actions-rust-lang/setup-rust-toolchain@ac90e63697ac2784f4ecfe2964e1a285c304003a with: toolchain: stable From bd17dd86faba6f4a7f614c956fbe03bdab96c9cd Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 31 Aug 2025 12:59:34 +0000 Subject: [PATCH 20/78] Update actions-rust-lang/setup-rust-toolchain digest to 7659442 (#54) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Xodium Dependencies Updater This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | actions-rust-lang/setup-rust-toolchain | action | digest | `ac90e63` -> `7659442` | --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/XodiumSoftware/xbim). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/ci_cd.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci_cd.yml b/.github/workflows/ci_cd.yml index fc2bb10a..fdd5297d 100644 --- a/.github/workflows/ci_cd.yml +++ b/.github/workflows/ci_cd.yml @@ -38,7 +38,7 @@ jobs: - id: setup_rust name: Setup Rust - uses: actions-rust-lang/setup-rust-toolchain@ac90e63697ac2784f4ecfe2964e1a285c304003a + uses: actions-rust-lang/setup-rust-toolchain@7659442a2cec41defbcdc4837c1ff43bf5bf6299 with: toolchain: stable components: rustfmt, clippy @@ -77,7 +77,7 @@ jobs: - id: setup_rust name: Setup Rust - uses: actions-rust-lang/setup-rust-toolchain@ac90e63697ac2784f4ecfe2964e1a285c304003a + uses: actions-rust-lang/setup-rust-toolchain@7659442a2cec41defbcdc4837c1ff43bf5bf6299 with: toolchain: stable From 25af52581d65a86ff6f7c84769816aa4352c18d0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 8 Sep 2025 01:50:07 +0000 Subject: [PATCH 21/78] Update softprops/action-gh-release digest to 6cbd405 (#56) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Xodium Dependencies Updater This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | softprops/action-gh-release | action | digest | `fbadcc9` -> `6cbd405` | --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/XodiumSoftware/xbim). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/ci_cd.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci_cd.yml b/.github/workflows/ci_cd.yml index fdd5297d..b294a106 100644 --- a/.github/workflows/ci_cd.yml +++ b/.github/workflows/ci_cd.yml @@ -109,7 +109,7 @@ jobs: - id: create_release name: Create Release - uses: softprops/action-gh-release@fbadcc90e88ecface60a0a0d123795b784ceb239 + uses: softprops/action-gh-release@6cbd405e2c4e67a21c47fa9e383d020e4e28b836 env: GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" with: From 0246aaf82a49790ac0760f5a4d1ecaa4d896666d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 8 Sep 2025 06:47:25 +0000 Subject: [PATCH 22/78] Update actions-rust-lang/setup-rust-toolchain digest to 1812c7d (#55) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Xodium Dependencies Updater This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | actions-rust-lang/setup-rust-toolchain | action | digest | `7659442` -> `1812c7d` | --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/XodiumSoftware/xbim). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/ci_cd.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci_cd.yml b/.github/workflows/ci_cd.yml index b294a106..7298d804 100644 --- a/.github/workflows/ci_cd.yml +++ b/.github/workflows/ci_cd.yml @@ -38,7 +38,7 @@ jobs: - id: setup_rust name: Setup Rust - uses: actions-rust-lang/setup-rust-toolchain@7659442a2cec41defbcdc4837c1ff43bf5bf6299 + uses: actions-rust-lang/setup-rust-toolchain@1812c7dfe1e025cc663298d3e33214f534505838 with: toolchain: stable components: rustfmt, clippy @@ -77,7 +77,7 @@ jobs: - id: setup_rust name: Setup Rust - uses: actions-rust-lang/setup-rust-toolchain@7659442a2cec41defbcdc4837c1ff43bf5bf6299 + uses: actions-rust-lang/setup-rust-toolchain@1812c7dfe1e025cc663298d3e33214f534505838 with: toolchain: stable From 4f2220c6187fcb7c9a383cfb57d62c1470b34b06 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 9 Sep 2025 09:28:55 +0000 Subject: [PATCH 23/78] Update softprops/action-gh-release digest to 5d1b0b1 (#57) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Xodium Dependencies Updater This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | softprops/action-gh-release | action | digest | `6cbd405` -> `5d1b0b1` | --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/XodiumSoftware/xbim). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/ci_cd.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci_cd.yml b/.github/workflows/ci_cd.yml index 7298d804..451fa2a6 100644 --- a/.github/workflows/ci_cd.yml +++ b/.github/workflows/ci_cd.yml @@ -109,7 +109,7 @@ jobs: - id: create_release name: Create Release - uses: softprops/action-gh-release@6cbd405e2c4e67a21c47fa9e383d020e4e28b836 + uses: softprops/action-gh-release@5d1b0b11643723aa24b0a5f8cef9618f9c2ed69b env: GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" with: From 5e20ccb936926763e2e61cbb137b5062cd4d5149 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 11 Sep 2025 10:44:05 +0000 Subject: [PATCH 24/78] Update softprops/action-gh-release digest to 19cd0bc (#58) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Xodium Dependencies Updater This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | softprops/action-gh-release | action | digest | `5d1b0b1` -> `19cd0bc` | --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/XodiumSoftware/xbim). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/ci_cd.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci_cd.yml b/.github/workflows/ci_cd.yml index 451fa2a6..62d9ac5e 100644 --- a/.github/workflows/ci_cd.yml +++ b/.github/workflows/ci_cd.yml @@ -109,7 +109,7 @@ jobs: - id: create_release name: Create Release - uses: softprops/action-gh-release@5d1b0b11643723aa24b0a5f8cef9618f9c2ed69b + uses: softprops/action-gh-release@19cd0bcd2b95a5f9e0aab8377b3cae33e51c2234 env: GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" with: From a91655c0255fa21430ac524a03e1d35a5edcffb4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 15 Sep 2025 01:03:50 +0000 Subject: [PATCH 25/78] Update actions-rust-lang/setup-rust-toolchain digest to 2fcdc49 (#59) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Xodium Dependencies Updater This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | actions-rust-lang/setup-rust-toolchain | action | digest | `1812c7d` -> `2fcdc49` | --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/XodiumSoftware/xbim). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/ci_cd.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci_cd.yml b/.github/workflows/ci_cd.yml index 62d9ac5e..ae5dbc24 100644 --- a/.github/workflows/ci_cd.yml +++ b/.github/workflows/ci_cd.yml @@ -38,7 +38,7 @@ jobs: - id: setup_rust name: Setup Rust - uses: actions-rust-lang/setup-rust-toolchain@1812c7dfe1e025cc663298d3e33214f534505838 + uses: actions-rust-lang/setup-rust-toolchain@2fcdc490d667999e01ddbbf0f2823181beef6b39 with: toolchain: stable components: rustfmt, clippy @@ -77,7 +77,7 @@ jobs: - id: setup_rust name: Setup Rust - uses: actions-rust-lang/setup-rust-toolchain@1812c7dfe1e025cc663298d3e33214f534505838 + uses: actions-rust-lang/setup-rust-toolchain@2fcdc490d667999e01ddbbf0f2823181beef6b39 with: toolchain: stable From 28902be50ff4bdb19a4306fce61b28017521ef4b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 19 Sep 2025 10:24:15 +0000 Subject: [PATCH 26/78] Update softprops/action-gh-release digest to 97d42c1 (#60) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Xodium Dependencies Updater This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | softprops/action-gh-release | action | digest | `19cd0bc` -> `97d42c1` | --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/XodiumSoftware/xbim). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/ci_cd.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci_cd.yml b/.github/workflows/ci_cd.yml index ae5dbc24..9900df0b 100644 --- a/.github/workflows/ci_cd.yml +++ b/.github/workflows/ci_cd.yml @@ -109,7 +109,7 @@ jobs: - id: create_release name: Create Release - uses: softprops/action-gh-release@19cd0bcd2b95a5f9e0aab8377b3cae33e51c2234 + uses: softprops/action-gh-release@97d42c1b50f585f357413698aa1b779307aa0d52 env: GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" with: From 18e36eba3c73bf555142953d1bd31ca11b64de10 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 22 Sep 2025 16:38:17 +0000 Subject: [PATCH 27/78] Update actions-rust-lang/setup-rust-toolchain digest to 69e4802 (#61) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Xodium Dependencies Updater This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | actions-rust-lang/setup-rust-toolchain | action | digest | `2fcdc49` -> `69e4802` | --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/XodiumSoftware/xbim). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/ci_cd.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci_cd.yml b/.github/workflows/ci_cd.yml index 9900df0b..eeee0631 100644 --- a/.github/workflows/ci_cd.yml +++ b/.github/workflows/ci_cd.yml @@ -38,7 +38,7 @@ jobs: - id: setup_rust name: Setup Rust - uses: actions-rust-lang/setup-rust-toolchain@2fcdc490d667999e01ddbbf0f2823181beef6b39 + uses: actions-rust-lang/setup-rust-toolchain@69e48024603c91b996af4004a08116c7b9bf95c1 with: toolchain: stable components: rustfmt, clippy @@ -77,7 +77,7 @@ jobs: - id: setup_rust name: Setup Rust - uses: actions-rust-lang/setup-rust-toolchain@2fcdc490d667999e01ddbbf0f2823181beef6b39 + uses: actions-rust-lang/setup-rust-toolchain@69e48024603c91b996af4004a08116c7b9bf95c1 with: toolchain: stable From 002ba0961aa9f00c626ca71ebec95b97eac87d23 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 24 Sep 2025 01:55:37 +0000 Subject: [PATCH 28/78] Update actions-rust-lang/setup-rust-toolchain digest to 02be93d (#62) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Xodium Dependencies Updater This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | actions-rust-lang/setup-rust-toolchain | action | digest | `69e4802` -> `02be93d` | --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/XodiumSoftware/xbim). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/ci_cd.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci_cd.yml b/.github/workflows/ci_cd.yml index eeee0631..9eb9f0ee 100644 --- a/.github/workflows/ci_cd.yml +++ b/.github/workflows/ci_cd.yml @@ -38,7 +38,7 @@ jobs: - id: setup_rust name: Setup Rust - uses: actions-rust-lang/setup-rust-toolchain@69e48024603c91b996af4004a08116c7b9bf95c1 + uses: actions-rust-lang/setup-rust-toolchain@02be93da58aa71fb456aa9c43b301149248829d8 with: toolchain: stable components: rustfmt, clippy @@ -77,7 +77,7 @@ jobs: - id: setup_rust name: Setup Rust - uses: actions-rust-lang/setup-rust-toolchain@69e48024603c91b996af4004a08116c7b9bf95c1 + uses: actions-rust-lang/setup-rust-toolchain@02be93da58aa71fb456aa9c43b301149248829d8 with: toolchain: stable From 743f11d4045a6d956d64b56860ddfe47d521f5a0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 24 Sep 2025 18:25:48 +0000 Subject: [PATCH 29/78] Update actions/cache action to v4.3.0 (#63) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Xodium Dependencies Updater This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [actions/cache](https://redirect.github.com/actions/cache) | action | minor | `v4.2.4` -> `v4.3.0` | --- ### Release Notes
actions/cache (actions/cache) ### [`v4.3.0`](https://redirect.github.com/actions/cache/compare/v4.2.4...v4.3.0) [Compare Source](https://redirect.github.com/actions/cache/compare/v4.2.4...v4.3.0)
--- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/XodiumSoftware/xbim). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/ci_cd.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci_cd.yml b/.github/workflows/ci_cd.yml index 9eb9f0ee..010f52a0 100644 --- a/.github/workflows/ci_cd.yml +++ b/.github/workflows/ci_cd.yml @@ -27,7 +27,7 @@ jobs: - id: cache_deps name: Cache dependencies - uses: actions/cache@v4.2.4 + uses: actions/cache@v4.3.0 with: path: | ~/.cargo/registry From a82d2e9278fff93be7189dc27b12bc525304301e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 4 Oct 2025 00:43:47 +0000 Subject: [PATCH 30/78] Update softprops/action-gh-release digest to 62c96d0 (#64) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Xodium Dependencies Updater This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | softprops/action-gh-release | action | digest | `97d42c1` -> `62c96d0` | --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/XodiumSoftware/xbim). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/ci_cd.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci_cd.yml b/.github/workflows/ci_cd.yml index 010f52a0..027b54e8 100644 --- a/.github/workflows/ci_cd.yml +++ b/.github/workflows/ci_cd.yml @@ -109,7 +109,7 @@ jobs: - id: create_release name: Create Release - uses: softprops/action-gh-release@97d42c1b50f585f357413698aa1b779307aa0d52 + uses: softprops/action-gh-release@62c96d0c4e8a889135c1f3a25910db8dbe0e85f7 env: GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" with: From f60d09f74fd4a3498d61ec379756affa9f6dcb86 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 7 Oct 2025 08:50:48 +0000 Subject: [PATCH 31/78] Update softprops/action-gh-release digest to f38efde (#66) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Xodium Dependencies Updater This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | softprops/action-gh-release | action | digest | `62c96d0` -> `f38efde` | --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/XodiumSoftware/xbim). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/ci_cd.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci_cd.yml b/.github/workflows/ci_cd.yml index 027b54e8..c16a07c3 100644 --- a/.github/workflows/ci_cd.yml +++ b/.github/workflows/ci_cd.yml @@ -109,7 +109,7 @@ jobs: - id: create_release name: Create Release - uses: softprops/action-gh-release@62c96d0c4e8a889135c1f3a25910db8dbe0e85f7 + uses: softprops/action-gh-release@f38efdea4c5ffe13e9424b0aa2833bee28f1e34c env: GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" with: From 8c7916f6fa05a011681a06006e79f3579880f497 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 7 Oct 2025 16:45:03 +0000 Subject: [PATCH 32/78] Update actions-rust-lang/setup-rust-toolchain digest to 1780873 (#65) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Xodium Dependencies Updater This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | actions-rust-lang/setup-rust-toolchain | action | digest | `02be93d` -> `1780873` | --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/XodiumSoftware/xbim). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/ci_cd.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci_cd.yml b/.github/workflows/ci_cd.yml index c16a07c3..5d48e953 100644 --- a/.github/workflows/ci_cd.yml +++ b/.github/workflows/ci_cd.yml @@ -38,7 +38,7 @@ jobs: - id: setup_rust name: Setup Rust - uses: actions-rust-lang/setup-rust-toolchain@02be93da58aa71fb456aa9c43b301149248829d8 + uses: actions-rust-lang/setup-rust-toolchain@1780873c7b576612439a134613cc4cc74ce5538c with: toolchain: stable components: rustfmt, clippy @@ -77,7 +77,7 @@ jobs: - id: setup_rust name: Setup Rust - uses: actions-rust-lang/setup-rust-toolchain@02be93da58aa71fb456aa9c43b301149248829d8 + uses: actions-rust-lang/setup-rust-toolchain@1780873c7b576612439a134613cc4cc74ce5538c with: toolchain: stable From 977baa8cc58f048a1ad2901de13f102b6d0b61f7 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 11 Oct 2025 21:27:30 +0000 Subject: [PATCH 33/78] Update softprops/action-gh-release digest to 6da8fa9 (#67) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Xodium Dependencies Updater This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | softprops/action-gh-release | action | digest | `f38efde` -> `6da8fa9` | --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/XodiumSoftware/xbim). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/ci_cd.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci_cd.yml b/.github/workflows/ci_cd.yml index 5d48e953..e5a233b7 100644 --- a/.github/workflows/ci_cd.yml +++ b/.github/workflows/ci_cd.yml @@ -109,7 +109,7 @@ jobs: - id: create_release name: Create Release - uses: softprops/action-gh-release@f38efdea4c5ffe13e9424b0aa2833bee28f1e34c + uses: softprops/action-gh-release@6da8fa9354ddfdc4aeace5fc48d7f679b5214090 env: GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" with: From d0145ccedd31d814d964bc9605fddaf1eb892d87 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 17 Oct 2025 04:26:28 +0000 Subject: [PATCH 34/78] Update softprops/action-gh-release digest to 5434409 (#68) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Xodium Dependencies Updater This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | softprops/action-gh-release | action | digest | `6da8fa9` -> `5434409` | --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/XodiumSoftware/xbim). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/ci_cd.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci_cd.yml b/.github/workflows/ci_cd.yml index e5a233b7..1afedd4f 100644 --- a/.github/workflows/ci_cd.yml +++ b/.github/workflows/ci_cd.yml @@ -109,7 +109,7 @@ jobs: - id: create_release name: Create Release - uses: softprops/action-gh-release@6da8fa9354ddfdc4aeace5fc48d7f679b5214090 + uses: softprops/action-gh-release@5434409c2b6457c050f109d68b2547fcbf1db07b env: GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" with: From c17fece244df5e65b0b0d9a0d25e1d451a0af707 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 24 Oct 2025 14:46:17 +0000 Subject: [PATCH 35/78] Update softprops/action-gh-release digest to aa05f9d (#69) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Xodium Dependencies Updater This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | softprops/action-gh-release | action | digest | `5434409` -> `aa05f9d` | --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/XodiumSoftware/xbim). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/ci_cd.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci_cd.yml b/.github/workflows/ci_cd.yml index 1afedd4f..148074a4 100644 --- a/.github/workflows/ci_cd.yml +++ b/.github/workflows/ci_cd.yml @@ -109,7 +109,7 @@ jobs: - id: create_release name: Create Release - uses: softprops/action-gh-release@5434409c2b6457c050f109d68b2547fcbf1db07b + uses: softprops/action-gh-release@aa05f9d77940d1a6b7a495c3264de51fabbf36d9 env: GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" with: From 42f03d5958b7dda60ce3fae66693806f9c1ff5fd Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 25 Oct 2025 00:58:15 +0000 Subject: [PATCH 36/78] Update GitHub Artifact Actions (major) (#70) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Xodium Dependencies Updater This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [actions/download-artifact](https://redirect.github.com/actions/download-artifact) | action | major | `v5.0.0` -> `v6.0.0` | | [actions/upload-artifact](https://redirect.github.com/actions/upload-artifact) | action | major | `v4.6.2` -> `v5.0.0` | --- ### Release Notes
actions/download-artifact (actions/download-artifact) ### [`v6.0.0`](https://redirect.github.com/actions/download-artifact/releases/tag/v6.0.0) [Compare Source](https://redirect.github.com/actions/download-artifact/compare/v5.0.0...v6.0.0) #### What's Changed **BREAKING CHANGE:** this update supports Node `v24.x`. This is not a breaking change per-se but we're treating it as such. - Update README for download-artifact v5 changes by [@​yacaovsnc](https://redirect.github.com/yacaovsnc) in [#​417](https://redirect.github.com/actions/download-artifact/pull/417) - Update README with artifact extraction details by [@​yacaovsnc](https://redirect.github.com/yacaovsnc) in [#​424](https://redirect.github.com/actions/download-artifact/pull/424) - Readme: spell out the first use of GHES by [@​danwkennedy](https://redirect.github.com/danwkennedy) in [#​431](https://redirect.github.com/actions/download-artifact/pull/431) - Bump `@actions/artifact` to `v4.0.0` - Prepare `v6.0.0` by [@​danwkennedy](https://redirect.github.com/danwkennedy) in [#​438](https://redirect.github.com/actions/download-artifact/pull/438) #### New Contributors - [@​danwkennedy](https://redirect.github.com/danwkennedy) made their first contribution in [#​431](https://redirect.github.com/actions/download-artifact/pull/431) **Full Changelog**:
actions/upload-artifact (actions/upload-artifact) ### [`v5.0.0`](https://redirect.github.com/actions/upload-artifact/compare/v4.6.2...v5.0.0) [Compare Source](https://redirect.github.com/actions/upload-artifact/compare/v4.6.2...v5.0.0)
--- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 👻 **Immortal**: This PR will be recreated if closed unmerged. Get [config help](https://redirect.github.com/renovatebot/renovate/discussions) if that's undesired. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/XodiumSoftware/xbim). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/ci_cd.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci_cd.yml b/.github/workflows/ci_cd.yml index 148074a4..01b1d1dc 100644 --- a/.github/workflows/ci_cd.yml +++ b/.github/workflows/ci_cd.yml @@ -59,7 +59,7 @@ jobs: - id: upload_artifact name: Upload Artifact - uses: actions/upload-artifact@v4.6.2 + uses: actions/upload-artifact@v5.0.0 with: name: xbim path: target/release/xbim @@ -98,7 +98,7 @@ jobs: steps: - id: download_artifact name: Download Artefact - uses: actions/download-artifact@v5.0.0 + uses: actions/download-artifact@v6.0.0 with: name: xbim From 056a931beb657b0546b993f8a407614250a0d58a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 31 Oct 2025 00:09:30 +0000 Subject: [PATCH 37/78] Update softprops/action-gh-release digest to 0adea5a (#71) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Xodium Dependencies Updater This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | softprops/action-gh-release | action | digest | `aa05f9d` -> `0adea5a` | --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/XodiumSoftware/xbim). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/ci_cd.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci_cd.yml b/.github/workflows/ci_cd.yml index 01b1d1dc..86c5a42a 100644 --- a/.github/workflows/ci_cd.yml +++ b/.github/workflows/ci_cd.yml @@ -109,7 +109,7 @@ jobs: - id: create_release name: Create Release - uses: softprops/action-gh-release@aa05f9d77940d1a6b7a495c3264de51fabbf36d9 + uses: softprops/action-gh-release@0adea5aa98b89355a3ff602e3f2d18bc4d77e7aa env: GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" with: From 85f0cc432ae93b6980d6b430e094c2f087b023b9 Mon Sep 17 00:00:00 2001 From: Illyrius <28700752+illyrius666@users.noreply.github.com> Date: Fri, 31 Oct 2025 10:45:09 +0100 Subject: [PATCH 38/78] Add files via upload Signed-off-by: Illyrius <28700752+illyrius666@users.noreply.github.com> --- .github/workflows/enforce_branch.yml | 50 ++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 .github/workflows/enforce_branch.yml diff --git a/.github/workflows/enforce_branch.yml b/.github/workflows/enforce_branch.yml new file mode 100644 index 00000000..4f8190ce --- /dev/null +++ b/.github/workflows/enforce_branch.yml @@ -0,0 +1,50 @@ +name: Xodium CI/CD - Enforce Target Branch + +on: + pull_request_target: + types: [ opened, reopened, synchronize, edited, ready_for_review ] + +concurrency: + group: "${{ github.workflow }}-${{ github.ref }}" + cancel-in-progress: true + +permissions: + contents: read + pull-requests: write + +jobs: + enforce-branch: + runs-on: ubuntu-latest + steps: + - id: enforce_branch + name: Enforce and Auto-fix Target Branch + env: + HEAD_REF: ${{ github.head_ref }} + BASE_REF: ${{ github.base_ref }} + GH_TOKEN: ${{ github.token }} + PR_NUMBER: ${{ github.event.pull_request.number }} + REPO: ${{ github.repository }} + run: | + if [ "$BASE_REF" == "main" ] && [ "$HEAD_REF" != "dev" ]; then + echo "❌ PR is targeting 'main' but not from 'dev'. Changing target to 'dev'..." + + gh pr edit "$PR_NUMBER" --repo "$REPO" --base dev + + echo "changed=true" >> $GITHUB_OUTPUT + echo "✅ Target branch automatically changed to 'dev'" + echo "⚠️ To merge to 'main', please create a PR from 'dev' branch" + else + echo "changed=false" >> $GITHUB_OUTPUT + echo "✅ Target branch is correct" + fi + + - id: notify_user + name: Notify User + if: steps.enforce_branch.outputs.changed == true + env: + GH_TOKEN: ${{ github.token }} + PR_NUMBER: ${{ github.event.pull_request.number }} + REPO: ${{ github.repository }} + run: | + gh pr comment "$PR_NUMBER" --repo "$REPO" --body \ + "🤖 The target branch has been automatically changed from \`main\` to \`dev\`.\n\nPRs to \`main\` are only allowed from the \`dev\` branch. Please merge to \`dev\` first." \ No newline at end of file From 85a900e23c232fc232489732148bb6d54bdc2421 Mon Sep 17 00:00:00 2001 From: Illyrius <28700752+illyrius666@users.noreply.github.com> Date: Fri, 31 Oct 2025 10:45:24 +0100 Subject: [PATCH 39/78] Delete .github/workflows/check.yml Signed-off-by: Illyrius <28700752+illyrius666@users.noreply.github.com> --- .github/workflows/check.yml | 28 ---------------------------- 1 file changed, 28 deletions(-) delete mode 100644 .github/workflows/check.yml diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml deleted file mode 100644 index 18ebc402..00000000 --- a/.github/workflows/check.yml +++ /dev/null @@ -1,28 +0,0 @@ -name: Xodium CI/CD - Check Branches - -on: - pull_request_target: - types: [ opened, reopened, synchronize, edited, ready_for_review ] - -concurrency: - group: "${{ github.workflow }}-${{ github.ref }}" - cancel-in-progress: true - -permissions: - contents: read - -jobs: - check-branches: - runs-on: ubuntu-latest - steps: - - id: check_branches - name: Check Branches - env: - HEAD_REF: ${{ github.head_ref }} - BASE_REF: ${{ github.base_ref }} - run: | - if [ "$HEAD_REF" != "dev" ] && [ "$BASE_REF" == "main" ]; then - echo "Merge requests to main branch are only allowed from dev branch." - exit 1 - fi - shell: bash \ No newline at end of file From 4c9c353c8d65e0cb65328306ff4c9b9b4ee6cb4f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 8 Nov 2025 08:49:43 +0000 Subject: [PATCH 40/78] Update softprops/action-gh-release digest to 00362be (#72) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Xodium Dependencies Updater This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | softprops/action-gh-release | action | digest | `0adea5a` -> `00362be` | --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/XodiumSoftware/xbim). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/ci_cd.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci_cd.yml b/.github/workflows/ci_cd.yml index 86c5a42a..88202339 100644 --- a/.github/workflows/ci_cd.yml +++ b/.github/workflows/ci_cd.yml @@ -109,7 +109,7 @@ jobs: - id: create_release name: Create Release - uses: softprops/action-gh-release@0adea5aa98b89355a3ff602e3f2d18bc4d77e7aa + uses: softprops/action-gh-release@00362bea6fa45e7091e03f6bd4ccd5cb6a17eb5e env: GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" with: From 0f95934537ed82dfe97c47280cf78c64803cb0a4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 9 Nov 2025 01:36:35 +0000 Subject: [PATCH 41/78] Update softprops/action-gh-release digest to 5be0e66 (#73) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Xodium Dependencies Updater This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | softprops/action-gh-release | action | digest | `00362be` -> `5be0e66` | --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/XodiumSoftware/xbim). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/ci_cd.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci_cd.yml b/.github/workflows/ci_cd.yml index 88202339..3eaed23c 100644 --- a/.github/workflows/ci_cd.yml +++ b/.github/workflows/ci_cd.yml @@ -109,7 +109,7 @@ jobs: - id: create_release name: Create Release - uses: softprops/action-gh-release@00362bea6fa45e7091e03f6bd4ccd5cb6a17eb5e + uses: softprops/action-gh-release@5be0e66d93ac7ed76da52eca8bb058f665c3a5fe env: GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" with: From d72d427b39c890b0477976cc05dcc8db122dded3 Mon Sep 17 00:00:00 2001 From: Illyrius Date: Wed, 12 Nov 2025 19:05:44 +0100 Subject: [PATCH 42/78] Refactor issue templates to improve structure and clarity Signed-off-by: Illyrius --- .github/ISSUE_TEMPLATE/bug.yml | 7 ++----- .github/ISSUE_TEMPLATE/config.yml | 8 ++++---- .github/ISSUE_TEMPLATE/feature.yml | 18 ++++-------------- .github/pull_request_template.md | 22 ++++++++++------------ .github/renovate.json | 6 ++---- .idea/copilot.data.migration.agent.xml | 6 ++++++ .idea/copilot.data.migration.ask.xml | 6 ++++++ .idea/copilot.data.migration.ask2agent.xml | 6 ++++++ .idea/copilot.data.migration.edit.xml | 6 ++++++ 9 files changed, 46 insertions(+), 39 deletions(-) create mode 100644 .idea/copilot.data.migration.agent.xml create mode 100644 .idea/copilot.data.migration.ask.xml create mode 100644 .idea/copilot.data.migration.ask2agent.xml create mode 100644 .idea/copilot.data.migration.edit.xml diff --git a/.github/ISSUE_TEMPLATE/bug.yml b/.github/ISSUE_TEMPLATE/bug.yml index 305f0e6a..e2c4b46c 100644 --- a/.github/ISSUE_TEMPLATE/bug.yml +++ b/.github/ISSUE_TEMPLATE/bug.yml @@ -1,13 +1,13 @@ name: Bug Report description: File a bug report -labels: [ Bug ] +type: "Bug" +assignees: [ "illyrius666" ] body: - type: markdown attributes: value: | Thank you for taking the time to fill this out! - type: textarea - id: how attributes: label: Problem description: Please give a text description of how you reached the problem @@ -19,7 +19,6 @@ body: validations: required: true - type: textarea - id: what attributes: label: Solution (if any) description: Explain where you think the problem comes from (optional) @@ -27,7 +26,6 @@ body: validations: required: false - type: input - id: version attributes: label: Version description: What version are you running? @@ -35,7 +33,6 @@ body: validations: required: true - type: input - id: logs attributes: label: Log description: Paste a full log. Always use [Pastebin](https://pastebin.com/). Must not be a crash report. Must be a full log. Must not be a screenshot of a log. diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 9888262e..6300bb34 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -1,5 +1,5 @@ blank_issues_enabled: false -contact_links: - - name: Community Support - url: https://discord.gg/CWy6JxNXP4 - about: Please ask and answer questions here. +# contact_links: +# - name: Community Support +# url: https://discord.gg/CWy6JxNXP4 +# about: Please ask and answer questions here. diff --git a/.github/ISSUE_TEMPLATE/feature.yml b/.github/ISSUE_TEMPLATE/feature.yml index 1198e89e..1475a79a 100644 --- a/.github/ISSUE_TEMPLATE/feature.yml +++ b/.github/ISSUE_TEMPLATE/feature.yml @@ -1,32 +1,23 @@ name: Feature Request description: File a feature request. -labels: [ Feature ] +type: "Feature" +assignees: [ "illyrius666" ] body: - type: markdown attributes: value: | Thank you for taking the time to fill this out! - type: dropdown - id: arc attributes: - label: Adding, Removing, or Changing - description: What are you doing + label: Type of Modification + description: What are you doing? options: - Adding - Removing - Changing validations: required: true - - type: input - id: type - attributes: - label: Type of Modification - description: What is it for? - placeholder: I want to ... - validations: - required: true - type: textarea - id: desc attributes: label: What are you trying to modify description: Give as detailed of a description as you can for the skill that you want (include pictures/Videos if applicable) @@ -34,7 +25,6 @@ body: validations: required: true - type: textarea - id: alternative attributes: label: Alternatives description: What alternatives have you considered? diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 6e23bab6..7424ad4c 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,14 +1,12 @@ ## Description -Please include a summary of the changes and the related issue. Explain the motivation behind these changes. - -## Checklist: - -- [ ] My code follows the style guidelines of this project -- [ ] I have performed a self-review of my own code -- [ ] I have commented my code, particularly in hard-to-understand areas -- [ ] I have made corresponding changes to the documentation -- [ ] My changes generate no new warnings -- [ ] I have added tests that prove my fix is effective or that my feature works -- [ ] New and existing unit tests pass locally with my changes -- [ ] Any dependent changes have been merged and published in downstream modules + + +## How Has This Been Tested? + + + +- [ ] Unit tests +- [ ] Integration tests +- [ ] Manual testing +- [ ] Other (please describe) diff --git a/.github/renovate.json b/.github/renovate.json index ceb699b7..24c5eaa8 100644 --- a/.github/renovate.json +++ b/.github/renovate.json @@ -10,8 +10,6 @@ "extends": [ "config:recommended" ], - "labels": [ - "Dependencies" - ], - "prHeader": "Xodium Dependencies Updater" + "prHeader": "Dependencies Updater", + "commitMessagePrefix": "[ci-skip]" } diff --git a/.idea/copilot.data.migration.agent.xml b/.idea/copilot.data.migration.agent.xml new file mode 100644 index 00000000..4ea72a91 --- /dev/null +++ b/.idea/copilot.data.migration.agent.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/copilot.data.migration.ask.xml b/.idea/copilot.data.migration.ask.xml new file mode 100644 index 00000000..7ef04e2e --- /dev/null +++ b/.idea/copilot.data.migration.ask.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/copilot.data.migration.ask2agent.xml b/.idea/copilot.data.migration.ask2agent.xml new file mode 100644 index 00000000..1f2ea11e --- /dev/null +++ b/.idea/copilot.data.migration.ask2agent.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/copilot.data.migration.edit.xml b/.idea/copilot.data.migration.edit.xml new file mode 100644 index 00000000..8648f940 --- /dev/null +++ b/.idea/copilot.data.migration.edit.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file From 4a0bf786195e342fcc127d92e9478378ddd970cb Mon Sep 17 00:00:00 2001 From: Illyrius Date: Wed, 12 Nov 2025 19:16:18 +0100 Subject: [PATCH 43/78] Update documentation to use em dashes for argument descriptions Signed-off-by: Illyrius --- README.md | 6 +++--- src/config.rs | 4 ++-- src/database.rs | 24 ++++++++++++------------ src/routes/data.rs | 34 +++++++++++++++++----------------- src/routes/health.rs | 2 +- src/utils.rs | 8 ++++---- 6 files changed, 39 insertions(+), 39 deletions(-) diff --git a/README.md b/README.md index 37865069..c9a79894 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ ## About The Project -xbim is a project aimed to provide a complete solution for working with BIM models. It is written in Rust, which +`xbim` is a project aimed to provide a complete solution for working with BIM models. It is written in Rust, which provides a high level of performance and safety. The project is still in its early stages, but it is already capable of reading and writing IFC files. @@ -42,9 +42,9 @@ reading and writing IFC files. 1. Download the latest version of xbim from the [release][release_latest] page. 2. Place it in a directory of your choice. 3. Run the executable. It will return an error that it cannot connect to the database. This is expected, as the - database is not yet set up in the config.toml which will generate on first time run. + database is not yet set up in the `config.toml` which will generate on first time run. 4. Replace the default values in the config with yours. -5. Rerun the executable and voila! +5. Rerun the executable and voilà! ## Built With diff --git a/src/config.rs b/src/config.rs index 58bdef11..bb003149 100644 --- a/src/config.rs +++ b/src/config.rs @@ -40,7 +40,7 @@ impl Config { /// Loads the configuration from a file, creating a default one if it doesn't exist. /// /// # Arguments - /// * `path` - The path to the configuration file. + /// * `path` — The path to the configuration file. /// /// # Returns /// A `Self` instance containing the loaded or default configuration. @@ -117,7 +117,7 @@ impl Config { /// Saves the current configuration to a file. /// /// # Arguments - /// * `path` - The path to the configuration file. + /// * `path` — The path to the configuration file. /// /// # Returns /// A `std::io::Result<()>` indicating success or failure. diff --git a/src/database.rs b/src/database.rs index 0730f513..b2ae7174 100644 --- a/src/database.rs +++ b/src/database.rs @@ -21,7 +21,7 @@ impl Database { /// Creates a new `Database` instance. /// /// # Arguments - /// * `config` - The application configuration. + /// * `config` — The application configuration. /// /// # Returns /// A new `Database` instance. @@ -38,7 +38,7 @@ impl Database { /// Connects to the database using the provided configuration. /// /// # Arguments - /// * `config` - The application configuration. + /// * `config` — The application configuration. /// /// # Returns /// A `Result` containing the connected `Database` instance. @@ -58,11 +58,11 @@ impl Database { }) } - /// Creates a new record in the specified table. + /// Creates a record in the specified table. /// /// # Arguments - /// * `table` - The table name to create the record in. - /// * `data` - The data to create. + /// * `table` — The table name to create the record in. + /// * `data` — The data to create. /// /// # Returns /// A `Result` containing the created record with its ID. @@ -81,8 +81,8 @@ impl Database { /// Retrieves a record from the specified table by its ID. /// /// # Arguments - /// * `table` - The table name to retrieve from. - /// * `id` - The ID of the record to retrieve. + /// * `table` — The table name to retrieve from. + /// * `id` — The ID of the record to retrieve. /// /// # Returns /// A `Result` containing the retrieved record. @@ -100,9 +100,9 @@ impl Database { /// Updates a record in the specified table. /// /// # Arguments - /// * `table` - The table name where the record is stored. - /// * `id` - The ID of the record to update. - /// * `data` - The updated data. + /// * `table` — The table name where the record is stored. + /// * `id` — The ID of the record to update. + /// * `data` — The updated data. /// /// # Returns /// A `Result` containing the updated record. @@ -121,8 +121,8 @@ impl Database { /// Deletes a record from the specified table. /// /// # Arguments - /// * `table` - The table name where the record is stored. - /// * `id` - The ID of the record to delete. + /// * `table` — The table name where the record is stored. + /// * `id` — The ID of the record to delete. /// /// # Returns /// A `Result` indicating whether the deletion was successful. diff --git a/src/routes/data.rs b/src/routes/data.rs index 1f9956eb..a06acfe7 100644 --- a/src/routes/data.rs +++ b/src/routes/data.rs @@ -30,10 +30,10 @@ pub struct StoredIFC { /// Upload a new IFC model to the database. /// /// # Arguments -/// * `database` - The database instance. -/// * `_authguard` - Authentication Guard. -/// * `_ratelimitguard` - Rate Limit Guard. -/// * `model` - The IFC model to upload. +/// * `database` — The database instance. +/// * `_authguard` — Authentication Guard. +/// * `_ratelimitguard` — Rate Limit Guard. +/// * `model` — The IFC model to upload. /// /// # Returns /// The saved IFC model with its ID. @@ -60,10 +60,10 @@ pub async fn data_upload( /// Get an IFC model by ID. /// /// # Arguments -/// * `database` - The database instance. -/// * `_authguard` - Authentication Guard. -/// * `_ratelimitguard` - Rate Limit Guard. -/// * `id` - The ID of the IFC model to retrieve. +/// * `database` — The database instance. +/// * `_authguard` — Authentication Guard. +/// * `_ratelimitguard` — Rate Limit Guard. +/// * `id` — The ID of the IFC model to retrieve. /// /// # Returns /// The retrieved IFC model. @@ -90,11 +90,11 @@ pub async fn data_get( /// Update an existing IFC model. /// /// # Arguments -/// * `database` - The database instance. -/// * `_authguard` - Authentication Guard. -/// * `_ratelimitguard` - Rate Limit Guard. -/// * `id` - The ID of the IFC model to update. -/// * `model` - The updated IFC model data. +/// * `database` — The database instance. +/// * `_authguard` — Authentication Guard. +/// * `_ratelimitguard` — Rate Limit Guard. +/// * `id` — The ID of the IFC model to update. +/// * `model` — The updated IFC model data. /// /// # Returns /// The updated IFC model. @@ -122,10 +122,10 @@ pub async fn data_update( /// Delete an IFC model by ID. /// /// # Arguments -/// * `database` - The database instance. -/// * `_authguard` - Authentication Guard. -/// * `_ratelimitguard` - Rate Limit Guard. -/// * `id` - The ID of the IFC model to delete. +/// * `database` — The database instance. +/// * `_authguard` — Authentication Guard. +/// * `_ratelimitguard` — Rate Limit Guard. +/// * `id` — The ID of the IFC model to delete. /// /// # Returns /// 204 No Content on success, error status otherwise. diff --git a/src/routes/health.rs b/src/routes/health.rs index 93045767..af114024 100644 --- a/src/routes/health.rs +++ b/src/routes/health.rs @@ -21,7 +21,7 @@ pub struct Response { /// * `_ratelimitguard`: An instance of `RateLimitGuard` to handle rate limiting. /// /// # Returns -/// A JSON response with the status, request ID, version, and timestamp. +/// A JSON response with the status, request ID, version and timestamp. #[get("/health")] pub fn health( _authguard: AuthGuard, diff --git a/src/utils.rs b/src/utils.rs index 61e3a067..89db4587 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -14,10 +14,10 @@ impl Utils { /// Returns a path to a file relative to the current executable's directory. /// /// # Arguments - /// * `path` - A path component to append to the executable's directory. + /// * `path` — A path component to append to the executable's directory. /// /// # Returns - /// A `PathBuf` pointing to the specified path relative to the executable's directory + /// A `PathBuf` pointing to the specified path relative to the executable's directory. pub fn get_exec_path>(path: P) -> PathBuf { env::current_exe() .expect("Failed to get executable path") @@ -29,8 +29,8 @@ impl Utils { /// Displays a formatted error message for database connection issues. /// /// # Arguments - /// * `error` - The error encountered during database connection. - /// * `config` - The application configuration containing the database URL. + /// * `error` — The error encountered during database connection. + /// * `config` — The application configuration containing the database URL. pub fn database_err_msg(error: &Error, config: &Config) { const ERROR_TITLE: &str = "DATABASE ERROR"; const PADDING: usize = 6; From 0578ce82bdc2b9294798ef5ff913054b378af58f Mon Sep 17 00:00:00 2001 From: Illyrius Date: Wed, 12 Nov 2025 19:23:29 +0100 Subject: [PATCH 44/78] Update dependencies in Cargo.toml to latest versions Signed-off-by: Illyrius --- Cargo.toml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 34938216..b5198c10 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,17 +21,17 @@ publish = false all-features = true [dependencies] -chrono = "0.4.40" +chrono = "0.4.42" colored = "3.0.0" -reqwest = { version = "0.12.15", features = ["json"] } +reqwest = { version = "0.12.24", features = ["json"] } rocket = { version = "0.5.1", features = ["json", "uuid", "tls"] } rocket_async_compression = "0.6.1" rocket_cors = "0.6.0" rocket-governor = "0.2.0-rc.4" rocket_oauth2 = "0.5.0" -surrealdb = { version = "2.2.1", features = ["http"] } +surrealdb = { version = "3.0.0-alpha.13", features = ["http"] } figment = { version = "0.10.19", features = ["toml"] } toml = "0.9.0" -serde_json = "1.0.140" -rcgen = "0.14.3" -rand = "0.9.2" +serde_json = "1.0.145" +rcgen = "0.14.5" +rand = "0.10.0-rc.5" From b4c1e5da7bc573bddc32a98b2536aafeee0a8c0d Mon Sep 17 00:00:00 2001 From: Illyrius Date: Wed, 12 Nov 2025 19:29:31 +0100 Subject: [PATCH 45/78] cleanup Signed-off-by: Illyrius --- Cargo.toml | 15 +--- src/config.rs | 134 ---------------------------------- src/database.rs | 136 ----------------------------------- src/errors.rs | 85 ---------------------- src/guards/auth.rs | 101 -------------------------- src/guards/ratelimit.rs | 52 -------------- src/main.rs | 100 -------------------------- src/models/card.rs | 20 ------ src/models/user.rs | 30 -------- src/routes/data.rs | 154 ---------------------------------------- src/routes/github.rs | 73 ------------------- src/routes/health.rs | 35 --------- src/tls.rs | 92 ------------------------ src/utils.rs | 93 ------------------------ 14 files changed, 1 insertion(+), 1119 deletions(-) delete mode 100644 src/config.rs delete mode 100644 src/database.rs delete mode 100644 src/errors.rs delete mode 100644 src/guards/auth.rs delete mode 100644 src/guards/ratelimit.rs delete mode 100644 src/main.rs delete mode 100644 src/models/card.rs delete mode 100644 src/models/user.rs delete mode 100644 src/routes/data.rs delete mode 100644 src/routes/github.rs delete mode 100644 src/routes/health.rs delete mode 100644 src/tls.rs delete mode 100644 src/utils.rs diff --git a/Cargo.toml b/Cargo.toml index b5198c10..8d1631f8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,17 +21,4 @@ publish = false all-features = true [dependencies] -chrono = "0.4.42" -colored = "3.0.0" -reqwest = { version = "0.12.24", features = ["json"] } -rocket = { version = "0.5.1", features = ["json", "uuid", "tls"] } -rocket_async_compression = "0.6.1" -rocket_cors = "0.6.0" -rocket-governor = "0.2.0-rc.4" -rocket_oauth2 = "0.5.0" -surrealdb = { version = "3.0.0-alpha.13", features = ["http"] } -figment = { version = "0.10.19", features = ["toml"] } -toml = "0.9.0" -serde_json = "1.0.145" -rcgen = "0.14.5" -rand = "0.10.0-rc.5" + diff --git a/src/config.rs b/src/config.rs deleted file mode 100644 index bb003149..00000000 --- a/src/config.rs +++ /dev/null @@ -1,134 +0,0 @@ -#![warn(clippy::all)] -#![forbid(unsafe_code)] - -use crate::tls::Tls; -use crate::utils::Utils; -use figment::Figment; -use figment::providers::{Format, Serialized, Toml}; -use rand::Rng; -use rand::distr::Alphanumeric; -use rocket::serde::{Deserialize, Serialize}; -use std::fs; -use std::fs::File; -use std::io::Write; -use std::path::PathBuf; - -/// Configuration settings for the application. -#[derive(Clone, Default, Debug, Serialize, Deserialize)] -#[serde(crate = "rocket::serde")] -pub struct Config { - pub secret_key: String, - pub database_url: String, - pub database_username: String, - pub database_password: String, - pub github_client_id: String, - pub github_client_secret: String, - pub github_redirect_url: String, - pub tls_cert_path: String, - pub tls_key_path: String, -} - -impl Config { - /// Creates a new instance of `Config` with default values. - /// - /// # Returns - /// A `Self` instance containing the default configuration. - pub fn new() -> Self { - Self::load_or_create(&Utils::get_exec_path("config.toml")) - } - - /// Loads the configuration from a file, creating a default one if it doesn't exist. - /// - /// # Arguments - /// * `path` — The path to the configuration file. - /// - /// # Returns - /// A `Self` instance containing the loaded or default configuration. - pub fn load_or_create(path: &PathBuf) -> Self { - let mut config = if path.exists() { - Figment::from(Serialized::defaults(Self::default())) - .merge(Toml::file(path)) - .extract::() - .unwrap_or_else(|err| { - eprintln!("Configuration error (using defaults): {err}"); - Self::default() - }) - } else { - println!("Creating default config at: {}", path.display()); - Self::default() - }; - - if config.secret_key.is_empty() { - config.generate_secret_key(); - config.save_to_file(path).unwrap_or_else(|err| { - eprintln!("Failed to update config with new secret key: {err}") - }); - } - - if config.tls_cert_path.is_empty() - || config.tls_key_path.is_empty() - || !PathBuf::from(&config.tls_cert_path).exists() - || !PathBuf::from(&config.tls_key_path).exists() - { - let cert_path = if config.tls_cert_path.is_empty() { - Utils::get_exec_path("certs/cert.pem") - } else { - PathBuf::from(&config.tls_cert_path) - }; - - let key_path = if config.tls_key_path.is_empty() { - Utils::get_exec_path("certs/key.pem") - } else { - PathBuf::from(&config.tls_key_path) - }; - - if let Err(e) = Tls::new(cert_path.clone(), key_path.clone()) { - eprintln!("Failed to generate TLS certificates: {e}"); - } else { - config.tls_cert_path = cert_path.to_string_lossy().into_owned(); - config.tls_key_path = key_path.to_string_lossy().into_owned(); - config.save_to_file(path).unwrap_or_else(|err| { - eprintln!("Failed to update config with TLS paths: {err}") - }); - } - } - - config - } - - /// Generates a new random secret key if the current one is empty. - /// # Note - /// - This only generates a key if `secret_key` is currently empty - /// - The generated key is printed to stdout for visibility - /// - For production use, consider: - /// - Storing the key securely (not in plaintext in config files) - /// - Using a dedicated secrets management system - fn generate_secret_key(&mut self) { - if self.secret_key.is_empty() { - self.secret_key = rand::rng() - .sample_iter(&Alphanumeric) - .take(64) - .map(char::from) - .collect(); - println!("Generated new secret key"); - } - } - - /// Saves the current configuration to a file. - /// - /// # Arguments - /// * `path` — The path to the configuration file. - /// - /// # Returns - /// A `std::io::Result<()>` indicating success or failure. - pub fn save_to_file(&self, path: &PathBuf) -> std::io::Result<()> { - if let Some(parent) = path.parent() { - fs::create_dir_all(parent)?; - } - File::create(path)?.write_all( - toml::to_string_pretty(self) - .expect("Failed to serialize config to TOML") - .as_bytes(), - ) - } -} diff --git a/src/database.rs b/src/database.rs deleted file mode 100644 index b2ae7174..00000000 --- a/src/database.rs +++ /dev/null @@ -1,136 +0,0 @@ -#![warn(clippy::all)] -#![forbid(unsafe_code)] - -use crate::config::Config; -use crate::utils::Utils; -use rocket::serde::{Deserialize, Serialize}; -use surrealdb::{ - Error, Surreal, - engine::remote::ws::{Client, Ws}, - error::Api, - opt::auth::Root, - sql::Uuid, -}; - -pub struct Database { - pub client: Surreal, - pub session_token: Uuid, -} - -impl Database { - /// Creates a new `Database` instance. - /// - /// # Arguments - /// * `config` — The application configuration. - /// - /// # Returns - /// A new `Database` instance. - pub async fn new(config: &Config) -> Self { - match Self::connect(config).await { - Ok(db) => db, - Err(e) => { - Utils::database_err_msg(&e, config); - std::process::exit(1); - } - } - } - - /// Connects to the database using the provided configuration. - /// - /// # Arguments - /// * `config` — The application configuration. - /// - /// # Returns - /// A `Result` containing the connected `Database` instance. - async fn connect(config: &Config) -> Result { - Ok(Self { - client: { - let client = Surreal::new::(&config.database_url).await?; - client - .signin(Root { - username: &config.database_username, - password: &config.database_password, - }) - .await?; - client - }, - session_token: Uuid::new(), - }) - } - - /// Creates a record in the specified table. - /// - /// # Arguments - /// * `table` — The table name to create the record in. - /// * `data` — The data to create. - /// - /// # Returns - /// A `Result` containing the created record with its ID. - pub async fn create(&self, table: &str, data: T) -> Result - where - T: Serialize + for<'a> Deserialize<'a> + 'static, - { - self.client - .create(table) - .content(data) - .await? - .take() - .ok_or_else(|| Error::Api(Api::ParseError(String::from("Failed to create record")))) - } - - /// Retrieves a record from the specified table by its ID. - /// - /// # Arguments - /// * `table` — The table name to retrieve from. - /// * `id` — The ID of the record to retrieve. - /// - /// # Returns - /// A `Result` containing the retrieved record. - pub async fn read(&self, table: &str, id: &str) -> Result - where - T: for<'a> Deserialize<'a> + 'static, - { - self.client - .select((table, id)) - .await? - .take() - .ok_or_else(|| Error::Api(Api::ParseError(String::from("Failed to retrieve record")))) - } - - /// Updates a record in the specified table. - /// - /// # Arguments - /// * `table` — The table name where the record is stored. - /// * `id` — The ID of the record to update. - /// * `data` — The updated data. - /// - /// # Returns - /// A `Result` containing the updated record. - pub async fn update(&self, table: &str, id: &str, data: T) -> Result - where - T: Serialize + for<'a> Deserialize<'a> + 'static, - { - self.client - .update((table, id)) - .content(data) - .await? - .take() - .ok_or_else(|| Error::Api(Api::ParseError(String::from("Failed to update record")))) - } - - /// Deletes a record from the specified table. - /// - /// # Arguments - /// * `table` — The table name where the record is stored. - /// * `id` — The ID of the record to delete. - /// - /// # Returns - /// A `Result` indicating whether the deletion was successful. - pub async fn delete(&self, table: &str, id: &str) -> Result - where - T: for<'a> Deserialize<'a> + 'static, - { - let result: Option = self.client.delete((table, id)).await?.take(); - Ok(result.is_some()) - } -} diff --git a/src/errors.rs b/src/errors.rs deleted file mode 100644 index a47026e7..00000000 --- a/src/errors.rs +++ /dev/null @@ -1,85 +0,0 @@ -#![warn(clippy::all)] -#![forbid(unsafe_code)] - -use rocket::{Catcher, catch, catchers, http::Status, serde::Serialize, serde::json::Json}; -use rocket_governor::rocket_governor_catcher; - -#[derive(Serialize)] -#[serde(crate = "rocket::serde")] -struct Response { - status: Status, - message: &'static str, -} - -/// Returns a list of catchers for the application. -/// -/// # Returns -/// A vector of catchers. -pub fn catchers() -> Vec { - catchers![ - err_400, - err_401, - err_403, - err_404, - err_405, - rocket_governor_catcher, - err_500, - err_503 - ] -} - -#[catch(400)] -fn err_400() -> Json { - Json(Response { - status: Status::BadRequest, - message: "Bad request format or invalid parameters", - }) -} - -#[catch(401)] -fn err_401() -> Json { - Json(Response { - status: Status::Unauthorized, - message: "Authentication required", - }) -} - -#[catch(403)] -fn err_403() -> Json { - Json(Response { - status: Status::Forbidden, - message: "Access forbidden - You don't have permission to access this resource", - }) -} - -#[catch(404)] -fn err_404() -> Json { - Json(Response { - status: Status::NotFound, - message: "Resource not found", - }) -} - -#[catch(405)] -fn err_405() -> Json { - Json(Response { - status: Status::MethodNotAllowed, - message: "Method not allowed for this resource", - }) -} - -#[catch(500)] -fn err_500() -> Json { - Json(Response { - status: Status::InternalServerError, - message: "Internal server error", - }) -} - -#[catch(503)] -fn err_503() -> Json { - Json(Response { - status: Status::ServiceUnavailable, - message: "Service temporarily unavailable", - }) -} diff --git a/src/guards/auth.rs b/src/guards/auth.rs deleted file mode 100644 index da86622b..00000000 --- a/src/guards/auth.rs +++ /dev/null @@ -1,101 +0,0 @@ -#![warn(clippy::all)] -#![forbid(unsafe_code)] - -use crate::routes::github::GitHubUser; -use rocket::{ - Request, async_trait, - http::Status, - request::{FromRequest, Outcome}, - serde::json::from_str, -}; - -/// Authentication Guard -pub struct AuthGuard; - -#[async_trait] -impl<'r> FromRequest<'r> for AuthGuard { - type Error = (); - - async fn from_request(request: &'r Request<'_>) -> Outcome { - request - .cookies() - .get_private("user_session") - .and_then(|cookie| { - from_str::(cookie.value()) - .map(|_| AuthGuard) - .ok() - }) - .map(Outcome::Success) - .unwrap_or(Outcome::Error((Status::Unauthorized, ()))) - } -} - -#[cfg(test)] -mod tests { - use super::*; - use rocket::http::Cookie; - use rocket::local::asynchronous::Client; - use rocket::{Build, Rocket, get, routes, tokio}; - use serde_json::json; - - #[get("/protected")] - fn test_endpoint(_auth: AuthGuard) -> &'static str { - "Authenticated!" - } - - fn rocket_test() -> Rocket { - rocket::build().mount("/", routes![test_endpoint]) - } - - #[tokio::test] - async fn test_auth_guard_success() { - let client = Client::tracked(rocket_test()) - .await - .expect("valid rocket instance"); - - let user_json = json!({ - "login": "testuser", - "id": 12345, - "name": "Test User" - }) - .to_string(); - - let cookie = Cookie::new("user_session", user_json); - - let response = client - .get("/protected") - .private_cookie(cookie) - .dispatch() - .await; - - assert_eq!(response.status(), Status::Ok); - } - - #[tokio::test] - async fn test_auth_guard_unauthorized_no_cookie() { - let client = Client::tracked(rocket_test()) - .await - .expect("valid rocket instance"); - - let response = client.get("/protected").dispatch().await; - - assert_eq!(response.status(), Status::Unauthorized); - } - - #[tokio::test] - async fn test_auth_guard_invalid_cookie_value() { - let client = Client::tracked(rocket_test()) - .await - .expect("valid rocket instance"); - - let invalid_cookie = Cookie::new("user_session", "not_valid_json"); - - let response = client - .get("/protected") - .private_cookie(invalid_cookie) - .dispatch() - .await; - - assert_eq!(response.status(), Status::Unauthorized); - } -} diff --git a/src/guards/ratelimit.rs b/src/guards/ratelimit.rs deleted file mode 100644 index 3a0f7dd3..00000000 --- a/src/guards/ratelimit.rs +++ /dev/null @@ -1,52 +0,0 @@ -#![warn(clippy::all)] -#![forbid(unsafe_code)] - -use rocket_governor::{Method, Quota, RocketGovernable}; - -/// RateLimit Guard. -pub struct RateLimitGuard; - -impl RocketGovernable<'_> for RateLimitGuard { - fn quota(_method: Method, _route_name: &str) -> Quota { - Quota::per_second(Self::nonzero(1u32)) - } -} - -#[cfg(test)] -mod tests { - use super::*; - use rocket_governor::{Method, Quota}; - use std::num::NonZeroU32; - - #[test] - fn test_rate_limit_quota_get() { - let quota = RateLimitGuard::quota(Method::Get, "test_route"); - let expected = Quota::per_second(NonZeroU32::new(1).unwrap()); - - assert_eq!(quota, expected); - } - - #[test] - fn test_rate_limit_quota_different_methods() { - let get_quota = RateLimitGuard::quota(Method::Get, "test_route"); - let post_quota = RateLimitGuard::quota(Method::Post, "test_route"); - let put_quota = RateLimitGuard::quota(Method::Put, "test_route"); - - assert_eq!(get_quota, post_quota); - assert_eq!(post_quota, put_quota); - } - - #[test] - fn test_rate_limit_quota_different_routes() { - let route1_quota = RateLimitGuard::quota(Method::Get, "route1"); - let route2_quota = RateLimitGuard::quota(Method::Get, "route2"); - - assert_eq!(route1_quota, route2_quota); - } - - #[test] - fn test_nonzero_conversion() { - assert_eq!(RateLimitGuard::nonzero(5u32), NonZeroU32::new(5).unwrap()); - assert_eq!(RateLimitGuard::nonzero(1u32), NonZeroU32::new(1).unwrap()); - } -} diff --git a/src/main.rs b/src/main.rs deleted file mode 100644 index 8f20a0af..00000000 --- a/src/main.rs +++ /dev/null @@ -1,100 +0,0 @@ -#![warn(clippy::all)] -#![forbid(unsafe_code)] - -pub mod guards { - pub mod auth; - pub mod ratelimit; -} - -pub mod models { - pub mod card; - pub mod user; -} - -pub mod routes { - pub mod data; - pub mod github; - pub mod health; -} - -pub mod config; -pub mod database; -pub mod errors; -mod tls; -mod utils; - -use crate::config::Config; -use crate::routes::data::{data_delete, data_get, data_update, data_upload}; -use crate::routes::github::{GitHubUser, github_callback, github_login}; -use crate::routes::health::health; -use database::Database; -use errors::catchers; -use rocket::config::SecretKey; -use rocket::routes; -use rocket::{ - Build, Rocket, build, config::TlsConfig, launch, shield::ExpectCt, shield::Feature, - shield::Frame, shield::Hsts, shield::NoSniff, shield::Permission, shield::Prefetch, - shield::Referrer, shield::Shield, shield::XssFilter, time::Duration, -}; -use rocket_async_compression::{Compression, Level as CompressionLevel}; -use rocket_cors::{AllowedOrigins, CorsOptions}; -use rocket_oauth2::{HyperRustlsAdapter, OAuth2, OAuthConfig, StaticProvider}; - -#[launch] -async fn rocket() -> Rocket { - let config = Config::new(); - build() - .configure(rocket::Config { - tls: (!config.tls_cert_path.is_empty() && !config.tls_key_path.is_empty()) - .then(|| TlsConfig::from_paths(&config.tls_cert_path, &config.tls_key_path)), - secret_key: SecretKey::derive_from(config.secret_key.as_bytes()), - ..rocket::Config::default() - }) - .manage(config.clone()) - .manage(Database::new(&config).await) - .mount( - "/", - routes![ - github_login, - github_callback, - health, - data_upload, - data_get, - data_update, - data_delete, - ], - ) - .attach( - Shield::new() - .enable(ExpectCt::Enforce(Duration::days(30))) - .enable( - Permission::default() - .block(Feature::Camera) - .block(Feature::Geolocation) - .block(Feature::Microphone), - ) - .enable(Frame::SameOrigin) - .enable(Hsts::IncludeSubDomains(Duration::days(365))) - .enable(NoSniff::Enable) - .enable(Prefetch::On) - .enable(Referrer::StrictOriginWhenCrossOrigin) - .enable(XssFilter::EnableBlock), - ) - .attach( - CorsOptions::default() - .allowed_origins(AllowedOrigins::all()) - .to_cors() - .expect("Failed to build CORS"), - ) - .attach(Compression::with_level(CompressionLevel::Default)) - .attach(OAuth2::::custom( - HyperRustlsAdapter::default(), - OAuthConfig::new( - StaticProvider::GitHub, - config.github_client_id.clone(), - config.github_client_secret.clone(), - Some(config.github_redirect_url.clone()), - ), - )) - .register("/", catchers()) -} diff --git a/src/models/card.rs b/src/models/card.rs deleted file mode 100644 index b0d8ce7b..00000000 --- a/src/models/card.rs +++ /dev/null @@ -1,20 +0,0 @@ -#![warn(clippy::all)] -#![forbid(unsafe_code)] - -use crate::models::user::User; -use rocket::serde::{Deserialize, Serialize}; -use surrealdb::sql::Thing; - -#[derive(Clone, Debug, Serialize, Deserialize)] -#[serde(crate = "rocket::serde")] -pub struct Card { - pub id: Option, - pub thumbnail: Option, - pub title: String, - pub author: User, - pub description: String, - pub platform: String, - pub downloads: u32, - pub rating: f32, - pub last_updated: f64, -} diff --git a/src/models/user.rs b/src/models/user.rs deleted file mode 100644 index f9ec7105..00000000 --- a/src/models/user.rs +++ /dev/null @@ -1,30 +0,0 @@ -#![warn(clippy::all)] -#![forbid(unsafe_code)] - -use crate::routes::github::GitHubUser; -use rocket::serde::{Deserialize, Serialize}; -use surrealdb::sql::Thing; - -#[derive(Clone, Debug, Serialize, Deserialize)] -#[serde(crate = "rocket::serde")] -pub struct User { - pub id: Option, - pub github_id: u64, - pub login: String, - pub name: Option, - pub email: Option, - pub avatar_url: Option, -} - -impl From for User { - fn from(github_user: GitHubUser) -> Self { - Self { - id: None, - github_id: github_user.id, - login: github_user.login, - name: github_user.name, - email: github_user.email, - avatar_url: github_user.avatar_url, - } - } -} diff --git a/src/routes/data.rs b/src/routes/data.rs deleted file mode 100644 index a06acfe7..00000000 --- a/src/routes/data.rs +++ /dev/null @@ -1,154 +0,0 @@ -#![warn(clippy::all)] -#![forbid(unsafe_code)] - -use crate::guards::ratelimit::RateLimitGuard; -use crate::{database::Database, guards::auth::AuthGuard}; -use chrono::{DateTime, Utc}; -use rocket::{ - State, delete, get, - http::Status, - post, put, - serde::json::Json, - serde::{Deserialize, Serialize}, -}; -use rocket_governor::RocketGovernor; -use std::collections::HashMap; - -#[derive(Debug, Serialize, Deserialize)] -#[serde(crate = "rocket::serde")] -pub struct StoredIFC { - pub id: Option, - pub name: String, - pub version: String, - pub description: Option, - pub created_at: DateTime, - pub updated_at: DateTime, - pub metadata: HashMap, - pub file_content: Option, -} - -/// Upload a new IFC model to the database. -/// -/// # Arguments -/// * `database` — The database instance. -/// * `_authguard` — Authentication Guard. -/// * `_ratelimitguard` — Rate Limit Guard. -/// * `model` — The IFC model to upload. -/// -/// # Returns -/// The saved IFC model with its ID. -#[post("/ifc", data = "")] -pub async fn data_upload( - database: &State, - _authguard: AuthGuard, - _ratelimitguard: RocketGovernor<'_, RateLimitGuard>, - model: Json, -) -> Result, Status> { - println!("Processing IFC upload"); - match database.create("ifc_models", model.into_inner()).await { - Ok(saved_model) => { - println!("Successfully saved IFC model"); - Ok(Json(saved_model)) - } - Err(e) => { - println!("Error saving IFC model: {e:?}"); - Err(Status::InternalServerError) - } - } -} - -/// Get an IFC model by ID. -/// -/// # Arguments -/// * `database` — The database instance. -/// * `_authguard` — Authentication Guard. -/// * `_ratelimitguard` — Rate Limit Guard. -/// * `id` — The ID of the IFC model to retrieve. -/// -/// # Returns -/// The retrieved IFC model. -#[get("/ifc/")] -pub async fn data_get( - database: &State, - _authguard: AuthGuard, - _ratelimitguard: RocketGovernor<'_, RateLimitGuard>, - id: String, -) -> Result, Status> { - println!("Retrieving IFC model {id}"); - match database.read::("ifc_models", &id).await { - Ok(model) => { - println!("Successfully retrieved IFC model {id}"); - Ok(Json(model)) - } - Err(e) => { - println!("Error retrieving IFC model {id}: {e:?}"); - Err(Status::NotFound) - } - } -} - -/// Update an existing IFC model. -/// -/// # Arguments -/// * `database` — The database instance. -/// * `_authguard` — Authentication Guard. -/// * `_ratelimitguard` — Rate Limit Guard. -/// * `id` — The ID of the IFC model to update. -/// * `model` — The updated IFC model data. -/// -/// # Returns -/// The updated IFC model. -#[put("/ifc/", data = "")] -pub async fn data_update( - database: &State, - _authguard: AuthGuard, - _ratelimitguard: RocketGovernor<'_, RateLimitGuard>, - id: String, - model: Json, -) -> Result, Status> { - println!("Updating IFC model {id}"); - match database.update("ifc_models", &id, model.into_inner()).await { - Ok(updated_model) => { - println!("Successfully updated IFC model {id}"); - Ok(Json(updated_model)) - } - Err(e) => { - println!("Error updating IFC model {id}: {e:?}"); - Err(Status::InternalServerError) - } - } -} - -/// Delete an IFC model by ID. -/// -/// # Arguments -/// * `database` — The database instance. -/// * `_authguard` — Authentication Guard. -/// * `_ratelimitguard` — Rate Limit Guard. -/// * `id` — The ID of the IFC model to delete. -/// -/// # Returns -/// 204 No Content on success, error status otherwise. -#[delete("/ifc/")] -pub async fn data_delete( - database: &State, - _authguard: AuthGuard, - _ratelimitguard: RocketGovernor<'_, RateLimitGuard>, - id: String, -) -> Status { - println!("Deleting IFC model {id}"); - match database.delete::("ifc_models", &id).await { - Ok(true) => { - println!("Successfully deleted IFC model {id}"); - Status::NoContent - } - Ok(false) => { - println!("IFC model {id} not found for deletion"); - Status::NotFound - } - Err(e) => { - println!("Error deleting IFC model {id}: {e:?}"); - Status::InternalServerError - } - } -} diff --git a/src/routes/github.rs b/src/routes/github.rs deleted file mode 100644 index 490192f6..00000000 --- a/src/routes/github.rs +++ /dev/null @@ -1,73 +0,0 @@ -#![warn(clippy::all)] -#![forbid(unsafe_code)] - -use crate::database::Database; -use crate::models::user::User; -use reqwest::Client as HttpClient; -use rocket::http::{Cookie, CookieJar, SameSite}; -use rocket::response::{Flash, Redirect}; -use rocket::serde::{Deserialize, Serialize}; -use rocket::{State, get}; -use rocket_oauth2::{OAuth2, TokenResponse}; -use std::time::Duration; - -#[derive(Debug, Serialize, Deserialize)] -#[serde(crate = "rocket::serde")] -pub struct GitHubUser { - pub id: u64, - pub login: String, - pub name: Option, - pub email: Option, - pub avatar_url: Option, -} - -#[get("/auth/github/login")] -pub fn github_login(oauth2: OAuth2, cookies: &CookieJar<'_>) -> Redirect { - oauth2 - .get_redirect(cookies, &["user:email", "read:user"]) - .unwrap() -} - -#[get("/auth/github/callback")] -pub async fn github_callback( - token: TokenResponse, - cookies: &CookieJar<'_>, - db: &State, -) -> Result> { - // Get GitHub user data - let github_user: GitHubUser = HttpClient::new() - .get("https://api.github.com/user") - .header("User-Agent", "xBIM-App") - .bearer_auth(token.access_token()) - .send() - .await - .map_err(|_| Flash::error(Redirect::to("/"), "Failed to get GitHub user data"))? - .json() - .await - .map_err(|_| Flash::error(Redirect::to("/"), "Failed to parse GitHub user data"))?; - - let github_id = github_user.id; - - // Create or update user record - let user = User::from(github_user); - let user_clone = user.clone(); - let saved_user = match db.create("users", user).await { - Ok(user) => user, - Err(_) => db - .update("users", &format!("github_id:{github_id}"), user_clone) - .await - .map_err(|_| Flash::error(Redirect::to("/"), "Failed to save user data"))?, - }; - - // Store just the session ID in cookie - let user_id = saved_user.id.unwrap().to_string(); - cookies.add_private( - Cookie::build(("user_session", user_id)) - .same_site(SameSite::Lax) - .http_only(true) - .max_age(Duration::from_secs(86400).try_into().unwrap()) - .build(), - ); - - Ok(Redirect::to("/")) -} diff --git a/src/routes/health.rs b/src/routes/health.rs deleted file mode 100644 index af114024..00000000 --- a/src/routes/health.rs +++ /dev/null @@ -1,35 +0,0 @@ -#![warn(clippy::all)] -#![forbid(unsafe_code)] - -use crate::{guards::auth::AuthGuard, guards::ratelimit::RateLimitGuard}; -use chrono::{DateTime, Utc}; -use rocket::{get, http::Status, serde::Serialize, serde::json::Json}; -use rocket_governor::RocketGovernor; - -#[derive(Serialize)] -#[serde(crate = "rocket::serde")] -pub struct Response { - status: Status, - version: &'static str, - timestamp: DateTime, -} - -/// Health check endpoint to confirm the service is running. -/// -/// # Arguments -/// * `_authguard`: An instance of `AuthGuard` to handle authentication. -/// * `_ratelimitguard`: An instance of `RateLimitGuard` to handle rate limiting. -/// -/// # Returns -/// A JSON response with the status, request ID, version and timestamp. -#[get("/health")] -pub fn health( - _authguard: AuthGuard, - _ratelimitguard: RocketGovernor<'_, RateLimitGuard>, -) -> Json { - Json(Response { - status: Status::Ok, - version: env!("CARGO_PKG_VERSION"), - timestamp: Utc::now(), - }) -} diff --git a/src/tls.rs b/src/tls.rs deleted file mode 100644 index bae14d97..00000000 --- a/src/tls.rs +++ /dev/null @@ -1,92 +0,0 @@ -#![warn(clippy::all)] -#![forbid(unsafe_code)] - -use rcgen::{CertificateParams, DistinguishedName, DnType, KeyPair, SanType, date_time_ymd}; -use std::path::PathBuf; -use std::{fs, io}; - -/// TLS Certificate Management & Generation. -#[derive(Debug)] -pub struct Tls { - cert_path: PathBuf, - key_path: PathBuf, -} - -impl Tls { - /// Creates a new instance of `Tls` with default values. - /// - /// # Returns - /// A `Self` instance containing the default configuration. - pub fn new(cert_path: PathBuf, key_path: PathBuf) -> io::Result { - let tls = Self { - cert_path, - key_path, - }; - - if !tls.cert_path.exists() || !tls.key_path.exists() { - tls.generate_certificates()?; - println!( - "WARNING: Auto-generated self-signed TLS certificates are for development only." - ); - println!("For production use, provide CA-signed certificates at the specified paths:"); - println!(" Certificate: {}", tls.cert_path.display()); - println!(" Private Key: {}", tls.key_path.display()); - } - - Ok(tls) - } - - /// Generates self-signed TLS certificates and writes them to disk. - /// - /// This function will: - /// 1. Create parent directories if they don't exist - /// 2. Generate certificate parameters with: - /// - Long validity period (1975-4096) - /// - Organization name "Xodium Software" - /// - Subject Alternative Name for "localhost" - /// 3. Generate a new cryptographic key pair - /// 4. Create a self-signed certificate - /// 5. Write both certificate and private key to specified paths - /// - /// # Errors - /// Returns `io::Result` with detailed error messages if any step fails, including: - /// - Directory creation failures - /// - Invalid DNS name format - /// - Key generation failures - /// - Certificate signing failures - /// - File writing failures - /// - /// # Security Note - /// The generated certificates are self-signed and should only be used for development. - /// Production environments should use properly signed certificates from a Certificate Authority. - fn generate_certificates(&self) -> io::Result<()> { - for path in [&self.cert_path, &self.key_path] { - if let Some(parent) = path.parent() { - fs::create_dir_all(parent)?; - } - } - - let mut params: CertificateParams = Default::default(); - params.not_before = date_time_ymd(1975, 1, 1); - params.not_after = date_time_ymd(4096, 1, 1); - params.distinguished_name = DistinguishedName::new(); - params - .distinguished_name - .push(DnType::OrganizationName, "Xodium Software"); - params.subject_alt_names = - vec![SanType::DnsName("localhost".try_into().map_err(|e| { - io::Error::other(format!("Invalid DNS name: {e}")) - })?)]; - - let key_pair = KeyPair::generate() - .map_err(|e| io::Error::other(format!("Key generation failed: {e}")))?; - let cert = params - .self_signed(&key_pair) - .map_err(|e| io::Error::other(format!("Certificate generation failed: {e}")))?; - - fs::write(&self.cert_path, cert.pem().as_bytes())?; - fs::write(&self.key_path, key_pair.serialize_pem().as_bytes())?; - - Ok(()) - } -} diff --git a/src/utils.rs b/src/utils.rs deleted file mode 100644 index 89db4587..00000000 --- a/src/utils.rs +++ /dev/null @@ -1,93 +0,0 @@ -#![warn(clippy::all)] -#![forbid(unsafe_code)] - -use crate::config::Config; -use colored::*; -use std::path::PathBuf; -use std::{env, path}; -use surrealdb::Error; - -/// A utility struct for common helper functions. -pub struct Utils; - -impl Utils { - /// Returns a path to a file relative to the current executable's directory. - /// - /// # Arguments - /// * `path` — A path component to append to the executable's directory. - /// - /// # Returns - /// A `PathBuf` pointing to the specified path relative to the executable's directory. - pub fn get_exec_path>(path: P) -> PathBuf { - env::current_exe() - .expect("Failed to get executable path") - .parent() - .expect("Executable has no parent directory") - .join(path) - } - - /// Displays a formatted error message for database connection issues. - /// - /// # Arguments - /// * `error` — The error encountered during database connection. - /// * `config` — The application configuration containing the database URL. - pub fn database_err_msg(error: &Error, config: &Config) { - const ERROR_TITLE: &str = "DATABASE ERROR"; - const PADDING: usize = 6; - const BULLET: &str = "● "; - const LABELS: [&str; 3] = ["URL:", "Error:", "Note:"]; - - let total_width = ERROR_TITLE.len() + (PADDING * 2); - let border_line = "─".repeat(total_width); - let box_parts = [ - format!("╭{border_line}╮"), - format!( - "│{}{}{}│", - " ".repeat(PADDING), - ERROR_TITLE, - " ".repeat(PADDING) - ), - format!("╰{border_line}╯"), - ]; - - for (i, part) in box_parts.iter().enumerate() { - eprintln!( - "{}", - if i == 1 { - part.bright_red().bold() - } else { - part.bright_red() - } - ); - } - - eprintln!( - "{} {}", - format!("{BULLET} {}", LABELS[0]).yellow().bold(), - config.database_url - ); - - let (problem, note) = if error.to_string().contains("authentication") { - ( - "Authentication failed", - "Check your database username and password in config.toml", - ) - } else { - ( - "Connection failed", - "Check if SurrealDB is running and network connectivity", - ) - }; - - eprintln!( - "{} {}", - format!("{BULLET} {}", LABELS[1]).yellow().bold(), - problem.red() - ); - eprintln!( - "{} {}", - format!("{BULLET} {}", LABELS[2]).yellow().bold(), - note.bright_white() - ); - } -} From 1551cef1ad7e29faebc5d4b51eeed0d52649c2c8 Mon Sep 17 00:00:00 2001 From: Illyrius Date: Wed, 12 Nov 2025 19:45:03 +0100 Subject: [PATCH 46/78] init Signed-off-by: Illyrius --- Cargo.toml | 11 +++++- src/app.rs | 103 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 4 ++ src/main.rs | 18 +++++++++ 4 files changed, 135 insertions(+), 1 deletion(-) create mode 100644 src/app.rs create mode 100644 src/lib.rs create mode 100644 src/main.rs diff --git a/Cargo.toml b/Cargo.toml index 8d1631f8..0de98de6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,6 +19,15 @@ publish = false [package.metadata.docs.rs] all-features = true +targets = ["x86_64-unknown-linux-gnu"] [dependencies] - +egui = "0.33.0" +eframe = { version = "0.33.0", default-features = false, features = [ + "default_fonts", + "glow", + "persistence", + "wayland", +] } +env_logger = "0.11.8" +serde = { version = "1.0.228", features = ["derive"] } \ No newline at end of file diff --git a/src/app.rs b/src/app.rs new file mode 100644 index 00000000..12c37510 --- /dev/null +++ b/src/app.rs @@ -0,0 +1,103 @@ +#[derive(serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct App { + label: String, + + #[serde(skip)] + value: f32, +} + +impl Default for App { + fn default() -> Self { + Self { + label: "Hello World!".to_owned(), + value: 2.7, + } + } +} + +impl App { + pub fn new(cc: &eframe::CreationContext<'_>) -> Self { + // This is also where you can customize the look and feel of egui using + // `cc.egui_ctx.set_visuals` and `cc.egui_ctx.set_fonts`. + + // Load previous app state (if any). + // Note that you must enable the `persistence` feature for this to work. + if let Some(storage) = cc.storage { + eframe::get_value(storage, eframe::APP_KEY).unwrap_or_default() + } else { + Default::default() + } + } +} + +impl eframe::App for App { + fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) { + // Put your widgets into a `SidePanel`, `TopBottomPanel`, `CentralPanel`, `Window` or `Area`. + // For inspiration and more examples, go to https://emilk.github.io/egui + + egui::TopBottomPanel::top("top_panel").show(ctx, |ui| { + // The top panel is often a good place for a menu bar: + + egui::MenuBar::new().ui(ui, |ui| { + // NOTE: no File->Quit on web pages! + let is_web = cfg!(target_arch = "wasm32"); + if !is_web { + ui.menu_button("File", |ui| { + if ui.button("Quit").clicked() { + ctx.send_viewport_cmd(egui::ViewportCommand::Close); + } + }); + ui.add_space(16.0); + } + + egui::widgets::global_theme_preference_buttons(ui); + }); + }); + + egui::CentralPanel::default().show(ctx, |ui| { + // The central panel the region left after adding TopPanel's and SidePanel's + ui.heading("eframe template"); + + ui.horizontal(|ui| { + ui.label("Write something: "); + ui.text_edit_singleline(&mut self.label); + }); + + ui.add(egui::Slider::new(&mut self.value, 0.0..=10.0).text("value")); + if ui.button("Increment").clicked() { + self.value += 1.0; + } + + ui.separator(); + + ui.add(egui::github_link_file!( + "https://github.com/emilk/eframe_template/blob/main/", + "Source code." + )); + + ui.with_layout(egui::Layout::bottom_up(egui::Align::LEFT), |ui| { + powered_by_egui_and_eframe(ui); + egui::warn_if_debug_build(ui); + }); + }); + } + + fn save(&mut self, storage: &mut dyn eframe::Storage) { + eframe::set_value(storage, eframe::APP_KEY, self); + } +} + +fn powered_by_egui_and_eframe(ui: &mut egui::Ui) { + ui.horizontal(|ui| { + ui.spacing_mut().item_spacing.x = 0.0; + ui.label("Powered by "); + ui.hyperlink_to("egui", "https://github.com/emilk/egui"); + ui.label(" and "); + ui.hyperlink_to( + "eframe", + "https://github.com/emilk/egui/tree/master/crates/eframe", + ); + ui.label("."); + }); +} diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 00000000..7872c141 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,4 @@ +#![warn(clippy::all)] + +mod app; +pub use app::App; diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 00000000..8d4b890b --- /dev/null +++ b/src/main.rs @@ -0,0 +1,18 @@ +#![warn(clippy::all)] + +fn main() -> eframe::Result { + env_logger::init(); + + let native_options = eframe::NativeOptions { + viewport: egui::ViewportBuilder::default() + .with_inner_size([400.0, 300.0]) + .with_min_inner_size([300.0, 220.0]), + ..Default::default() + }; + + eframe::run_native( + "xbim", + native_options, + Box::new(|cc| Ok(Box::new(xbim::App::new(cc)))), + ) +} From 563e799c0082f98d3e59f2275da93a5c121ba534 Mon Sep 17 00:00:00 2001 From: Illyrius Date: Wed, 12 Nov 2025 19:55:42 +0100 Subject: [PATCH 47/78] Refactor app.rs to improve clarity and update footer information Signed-off-by: Illyrius --- .idea/dictionaries/project.xml | 2 ++ src/app.rs | 15 +++++---------- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/.idea/dictionaries/project.xml b/.idea/dictionaries/project.xml index c13c299d..89d7125d 100644 --- a/.idea/dictionaries/project.xml +++ b/.idea/dictionaries/project.xml @@ -4,6 +4,8 @@ authguard clippy deps + eframe + egui ratelimitguard rustfmt softprops diff --git a/src/app.rs b/src/app.rs index 12c37510..38f86a09 100644 --- a/src/app.rs +++ b/src/app.rs @@ -18,11 +18,6 @@ impl Default for App { impl App { pub fn new(cc: &eframe::CreationContext<'_>) -> Self { - // This is also where you can customize the look and feel of egui using - // `cc.egui_ctx.set_visuals` and `cc.egui_ctx.set_fonts`. - - // Load previous app state (if any). - // Note that you must enable the `persistence` feature for this to work. if let Some(storage) = cc.storage { eframe::get_value(storage, eframe::APP_KEY).unwrap_or_default() } else { @@ -40,7 +35,6 @@ impl eframe::App for App { // The top panel is often a good place for a menu bar: egui::MenuBar::new().ui(ui, |ui| { - // NOTE: no File->Quit on web pages! let is_web = cfg!(target_arch = "wasm32"); if !is_web { ui.menu_button("File", |ui| { @@ -56,7 +50,6 @@ impl eframe::App for App { }); egui::CentralPanel::default().show(ctx, |ui| { - // The central panel the region left after adding TopPanel's and SidePanel's ui.heading("eframe template"); ui.horizontal(|ui| { @@ -77,7 +70,7 @@ impl eframe::App for App { )); ui.with_layout(egui::Layout::bottom_up(egui::Align::LEFT), |ui| { - powered_by_egui_and_eframe(ui); + footer(ui); egui::warn_if_debug_build(ui); }); }); @@ -88,10 +81,12 @@ impl eframe::App for App { } } -fn powered_by_egui_and_eframe(ui: &mut egui::Ui) { +fn footer(ui: &mut egui::Ui) { ui.horizontal(|ui| { ui.spacing_mut().item_spacing.x = 0.0; - ui.label("Powered by "); + ui.label("© 2025 "); + ui.hyperlink_to("Xodium", "https://github.com/XodiumSoftware"); + ui.label(". Powered by "); ui.hyperlink_to("egui", "https://github.com/emilk/egui"); ui.label(" and "); ui.hyperlink_to( From 90151afb696c3adf21d4c6ba008fb5639093dc7c Mon Sep 17 00:00:00 2001 From: Illyrius Date: Wed, 12 Nov 2025 20:03:56 +0100 Subject: [PATCH 48/78] Enhance documentation with detailed comments and improve footer rendering Signed-off-by: Illyrius --- src/app.rs | 14 +++++--------- src/main.rs | 20 +++++++++++--------- 2 files changed, 16 insertions(+), 18 deletions(-) diff --git a/src/app.rs b/src/app.rs index 38f86a09..cf8463c9 100644 --- a/src/app.rs +++ b/src/app.rs @@ -28,14 +28,10 @@ impl App { impl eframe::App for App { fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) { - // Put your widgets into a `SidePanel`, `TopBottomPanel`, `CentralPanel`, `Window` or `Area`. - // For inspiration and more examples, go to https://emilk.github.io/egui - egui::TopBottomPanel::top("top_panel").show(ctx, |ui| { - // The top panel is often a good place for a menu bar: - egui::MenuBar::new().ui(ui, |ui| { let is_web = cfg!(target_arch = "wasm32"); + if !is_web { ui.menu_button("File", |ui| { if ui.button("Quit").clicked() { @@ -51,24 +47,21 @@ impl eframe::App for App { egui::CentralPanel::default().show(ctx, |ui| { ui.heading("eframe template"); - ui.horizontal(|ui| { ui.label("Write something: "); ui.text_edit_singleline(&mut self.label); }); - ui.add(egui::Slider::new(&mut self.value, 0.0..=10.0).text("value")); + if ui.button("Increment").clicked() { self.value += 1.0; } ui.separator(); - ui.add(egui::github_link_file!( "https://github.com/emilk/eframe_template/blob/main/", "Source code." )); - ui.with_layout(egui::Layout::bottom_up(egui::Align::LEFT), |ui| { footer(ui); egui::warn_if_debug_build(ui); @@ -81,6 +74,9 @@ impl eframe::App for App { } } +/// Renders the application footer with copyright and attribution links. +/// # Arguments +/// * `ui` — The egui UI context to render the footer into. fn footer(ui: &mut egui::Ui) { ui.horizontal(|ui| { ui.spacing_mut().item_spacing.x = 0.0; diff --git a/src/main.rs b/src/main.rs index 8d4b890b..5095f9c8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,18 +1,20 @@ #![warn(clippy::all)] +/// Entry point for the xbim application. +/// # Returns +/// An `eframe::Result` indicating the success or failure of the application startup. +/// # Errors +/// Returns an error if the application fails to start or encounters a runtime error. fn main() -> eframe::Result { env_logger::init(); - - let native_options = eframe::NativeOptions { - viewport: egui::ViewportBuilder::default() - .with_inner_size([400.0, 300.0]) - .with_min_inner_size([300.0, 220.0]), - ..Default::default() - }; - eframe::run_native( "xbim", - native_options, + eframe::NativeOptions { + viewport: egui::ViewportBuilder::default() + .with_inner_size([400.0, 300.0]) + .with_min_inner_size([300.0, 220.0]), + ..Default::default() + }, Box::new(|cc| Ok(Box::new(xbim::App::new(cc)))), ) } From 7ec4ae84a38656e592374f4ab0e8ac4a429d1ac2 Mon Sep 17 00:00:00 2001 From: Illyrius Date: Wed, 12 Nov 2025 20:06:11 +0100 Subject: [PATCH 49/78] Refactor menu button logic in app.rs for improved readability and functionality Signed-off-by: Illyrius --- src/app.rs | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/src/app.rs b/src/app.rs index cf8463c9..3a3531e9 100644 --- a/src/app.rs +++ b/src/app.rs @@ -30,18 +30,14 @@ impl eframe::App for App { fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) { egui::TopBottomPanel::top("top_panel").show(ctx, |ui| { egui::MenuBar::new().ui(ui, |ui| { - let is_web = cfg!(target_arch = "wasm32"); + ui.menu_button("File", |ui| { + if ui.button("Quit").clicked() { + ctx.send_viewport_cmd(egui::ViewportCommand::Close); + } + }); + ui.add_space(16.0); - if !is_web { - ui.menu_button("File", |ui| { - if ui.button("Quit").clicked() { - ctx.send_viewport_cmd(egui::ViewportCommand::Close); - } - }); - ui.add_space(16.0); - } - - egui::widgets::global_theme_preference_buttons(ui); + egui::widgets::global_theme_preference_switch(ui); }); }); From a47d1b64e74af3eccb1ef9c8d701b022a6ac28b7 Mon Sep 17 00:00:00 2001 From: Illyrius Date: Wed, 12 Nov 2025 20:31:48 +0100 Subject: [PATCH 50/78] Refactor authentication logic in app.rs and move footer rendering to footer.rs Signed-off-by: Illyrius --- src/app.rs | 92 ++++++++++++++++++++-------------------- src/components/footer.rs | 18 ++++++++ src/components/mod.rs | 1 + src/lib.rs | 2 + 4 files changed, 68 insertions(+), 45 deletions(-) create mode 100644 src/components/footer.rs create mode 100644 src/components/mod.rs diff --git a/src/app.rs b/src/app.rs index 3a3531e9..91fe47af 100644 --- a/src/app.rs +++ b/src/app.rs @@ -1,19 +1,16 @@ -#[derive(serde::Deserialize, serde::Serialize)] +use crate::components::footer::footer; + +#[derive(Clone, Default, serde::Deserialize, serde::Serialize)] #[serde(default)] pub struct App { - label: String, - + username: String, #[serde(skip)] - value: f32, -} - -impl Default for App { - fn default() -> Self { - Self { - label: "Hello World!".to_owned(), - value: 2.7, - } - } + password: String, + #[serde(skip)] + is_logged_in: bool, + #[serde(skip)] + login_error: Option, + persist_username: bool, } impl App { @@ -42,22 +39,42 @@ impl eframe::App for App { }); egui::CentralPanel::default().show(ctx, |ui| { - ui.heading("eframe template"); - ui.horizontal(|ui| { - ui.label("Write something: "); - ui.text_edit_singleline(&mut self.label); - }); - ui.add(egui::Slider::new(&mut self.value, 0.0..=10.0).text("value")); + if self.is_logged_in { + ui.colored_label(egui::Color32::GREEN, format!("Welcome, {}!", self.username)); + if ui.button("Log out").clicked() { + self.is_logged_in = false; + self.password.clear(); + } + } else { + ui.heading("Login"); + ui.horizontal(|ui| { + ui.label("Username:"); + ui.add(egui::TextEdit::singleline(&mut self.username).desired_width(200.0)); + }); + ui.horizontal(|ui| { + ui.label("Password:"); + ui.add( + egui::TextEdit::singleline(&mut self.password) + .password(true) + .desired_width(200.0), + ); + }); + ui.checkbox(&mut self.persist_username, "Remember username"); + + if ui.button("Log in").clicked() || ui.input(|i| i.key_pressed(egui::Key::Enter)) { + if self.username == "admin" && self.password == "secret" { + self.is_logged_in = true; + self.login_error = None; + } else { + self.login_error = Some("Invalid Credentials.".to_owned()); + } + } - if ui.button("Increment").clicked() { - self.value += 1.0; + if let Some(error) = &self.login_error { + ui.colored_label(egui::Color32::RED, error); + } } - ui.separator(); - ui.add(egui::github_link_file!( - "https://github.com/emilk/eframe_template/blob/main/", - "Source code." - )); ui.with_layout(egui::Layout::bottom_up(egui::Align::LEFT), |ui| { footer(ui); egui::warn_if_debug_build(ui); @@ -66,25 +83,10 @@ impl eframe::App for App { } fn save(&mut self, storage: &mut dyn eframe::Storage) { + let mut snapshot = self.clone(); + if !snapshot.persist_username { + snapshot.username.clear(); + } eframe::set_value(storage, eframe::APP_KEY, self); } } - -/// Renders the application footer with copyright and attribution links. -/// # Arguments -/// * `ui` — The egui UI context to render the footer into. -fn footer(ui: &mut egui::Ui) { - ui.horizontal(|ui| { - ui.spacing_mut().item_spacing.x = 0.0; - ui.label("© 2025 "); - ui.hyperlink_to("Xodium", "https://github.com/XodiumSoftware"); - ui.label(". Powered by "); - ui.hyperlink_to("egui", "https://github.com/emilk/egui"); - ui.label(" and "); - ui.hyperlink_to( - "eframe", - "https://github.com/emilk/egui/tree/master/crates/eframe", - ); - ui.label("."); - }); -} diff --git a/src/components/footer.rs b/src/components/footer.rs new file mode 100644 index 00000000..dd029ff0 --- /dev/null +++ b/src/components/footer.rs @@ -0,0 +1,18 @@ +/// Renders the application footer with copyright and attribution links. +/// # Arguments +/// * `ui` — The egui UI context to render the footer into. +pub fn footer(ui: &mut egui::Ui) { + ui.horizontal(|ui| { + ui.spacing_mut().item_spacing.x = 0.0; + ui.label("© 2025 "); + ui.hyperlink_to("Xodium", "https://github.com/XodiumSoftware"); + ui.label(". Powered by "); + ui.hyperlink_to("egui", "https://github.com/emilk/egui"); + ui.label(" and "); + ui.hyperlink_to( + "eframe", + "https://github.com/emilk/egui/tree/master/crates/eframe", + ); + ui.label("."); + }); +} diff --git a/src/components/mod.rs b/src/components/mod.rs new file mode 100644 index 00000000..65405b17 --- /dev/null +++ b/src/components/mod.rs @@ -0,0 +1 @@ +pub mod footer; diff --git a/src/lib.rs b/src/lib.rs index 7872c141..40ee4f9a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,6 @@ #![warn(clippy::all)] mod app; +mod components; + pub use app::App; From badfe9f915b3ae10e9eed443ed10a2e4aeca65be Mon Sep 17 00:00:00 2001 From: Illyrius Date: Wed, 12 Nov 2025 20:38:59 +0100 Subject: [PATCH 51/78] Clear username on logout and during app initialization if persist_username is false Signed-off-by: Illyrius --- src/app.rs | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/app.rs b/src/app.rs index 91fe47af..cf00bd50 100644 --- a/src/app.rs +++ b/src/app.rs @@ -15,11 +15,17 @@ pub struct App { impl App { pub fn new(cc: &eframe::CreationContext<'_>) -> Self { - if let Some(storage) = cc.storage { + let mut app: App = if let Some(storage) = cc.storage { eframe::get_value(storage, eframe::APP_KEY).unwrap_or_default() } else { Default::default() + }; + + if !app.persist_username { + app.username.clear(); } + + app } } @@ -44,6 +50,10 @@ impl eframe::App for App { if ui.button("Log out").clicked() { self.is_logged_in = false; self.password.clear(); + + if !self.persist_username { + self.username.clear(); + } } } else { ui.heading("Login"); @@ -87,6 +97,6 @@ impl eframe::App for App { if !snapshot.persist_username { snapshot.username.clear(); } - eframe::set_value(storage, eframe::APP_KEY, self); + eframe::set_value(storage, eframe::APP_KEY, &snapshot); } } From fdc1806bef9207a44f0f29558613320eab8209fa Mon Sep 17 00:00:00 2001 From: Illyrius Date: Wed, 12 Nov 2025 20:50:36 +0100 Subject: [PATCH 52/78] Refactor app.rs to use a separate menu component and improve footer rendering Signed-off-by: Illyrius --- src/app.rs | 17 +++-------------- src/components/footer.rs | 1 + src/components/menu.rs | 13 +++++++++++++ src/components/mod.rs | 1 + 4 files changed, 18 insertions(+), 14 deletions(-) create mode 100644 src/components/menu.rs diff --git a/src/app.rs b/src/app.rs index cf00bd50..87d837c1 100644 --- a/src/app.rs +++ b/src/app.rs @@ -1,4 +1,5 @@ use crate::components::footer::footer; +use crate::components::menu::menu; #[derive(Clone, Default, serde::Deserialize, serde::Serialize)] #[serde(default)] @@ -32,16 +33,7 @@ impl App { impl eframe::App for App { fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) { egui::TopBottomPanel::top("top_panel").show(ctx, |ui| { - egui::MenuBar::new().ui(ui, |ui| { - ui.menu_button("File", |ui| { - if ui.button("Quit").clicked() { - ctx.send_viewport_cmd(egui::ViewportCommand::Close); - } - }); - ui.add_space(16.0); - - egui::widgets::global_theme_preference_switch(ui); - }); + egui::MenuBar::new().ui(ui, menu); }); egui::CentralPanel::default().show(ctx, |ui| { @@ -85,10 +77,7 @@ impl eframe::App for App { } } - ui.with_layout(egui::Layout::bottom_up(egui::Align::LEFT), |ui| { - footer(ui); - egui::warn_if_debug_build(ui); - }); + ui.with_layout(egui::Layout::bottom_up(egui::Align::LEFT), footer); }); } diff --git a/src/components/footer.rs b/src/components/footer.rs index dd029ff0..48787064 100644 --- a/src/components/footer.rs +++ b/src/components/footer.rs @@ -15,4 +15,5 @@ pub fn footer(ui: &mut egui::Ui) { ); ui.label("."); }); + egui::warn_if_debug_build(ui); } diff --git a/src/components/menu.rs b/src/components/menu.rs new file mode 100644 index 00000000..db2a5218 --- /dev/null +++ b/src/components/menu.rs @@ -0,0 +1,13 @@ +/// A simple menu component with a "File" menu, and a "Quit" option, +/// as well as a global theme preference switch. +/// # Arguments +/// * `ui` — The egui UI context to render the menu in. +pub fn menu(ui: &mut egui::Ui) { + ui.menu_button("File", |ui| { + if ui.button("Quit").clicked() { + ui.ctx().send_viewport_cmd(egui::ViewportCommand::Close); + } + }); + ui.add_space(16.0); + egui::widgets::global_theme_preference_switch(ui); +} diff --git a/src/components/mod.rs b/src/components/mod.rs index 65405b17..f836a355 100644 --- a/src/components/mod.rs +++ b/src/components/mod.rs @@ -1 +1,2 @@ pub mod footer; +pub mod menu; From 3f4f2c0a4acc9e6b731812c4ab5f6894a06384b2 Mon Sep 17 00:00:00 2001 From: Illyrius Date: Wed, 12 Nov 2025 21:03:20 +0100 Subject: [PATCH 53/78] Refactor authentication flow by introducing LoginForm and AuthService components Signed-off-by: Illyrius --- src/app.rs | 67 ++++++++++++---------------------- src/components/login_form.rs | 53 +++++++++++++++++++++++++++ src/components/mod.rs | 2 + src/components/user_profile.rs | 14 +++++++ src/lib.rs | 1 + src/services/auth.rs | 7 ++++ src/services/mod.rs | 1 + 7 files changed, 102 insertions(+), 43 deletions(-) create mode 100644 src/components/login_form.rs create mode 100644 src/components/user_profile.rs create mode 100644 src/services/auth.rs create mode 100644 src/services/mod.rs diff --git a/src/app.rs b/src/app.rs index 87d837c1..76f867d2 100644 --- a/src/app.rs +++ b/src/app.rs @@ -1,16 +1,15 @@ use crate::components::footer::footer; +use crate::components::login_form::LoginForm; use crate::components::menu::menu; +use crate::components::user_profile::UserProfile; +use crate::services::auth::AuthService; #[derive(Clone, Default, serde::Deserialize, serde::Serialize)] #[serde(default)] pub struct App { - username: String, - #[serde(skip)] - password: String, + login_form: LoginForm, #[serde(skip)] is_logged_in: bool, - #[serde(skip)] - login_error: Option, persist_username: bool, } @@ -23,11 +22,25 @@ impl App { }; if !app.persist_username { - app.username.clear(); + app.login_form.username.clear(); } app } + + fn handle_login(&mut self) { + if AuthService::validate_credentials(&self.login_form.username, &self.login_form.password) { + self.is_logged_in = true; + self.login_form.clear(); + } else { + self.login_form.set_error("Invalid Credentials.".to_owned()); + } + } + + fn handle_logout(&mut self) { + self.is_logged_in = false; + self.login_form.clear(); + } } impl eframe::App for App { @@ -38,43 +51,11 @@ impl eframe::App for App { egui::CentralPanel::default().show(ctx, |ui| { if self.is_logged_in { - ui.colored_label(egui::Color32::GREEN, format!("Welcome, {}!", self.username)); - if ui.button("Log out").clicked() { - self.is_logged_in = false; - self.password.clear(); - - if !self.persist_username { - self.username.clear(); - } - } - } else { - ui.heading("Login"); - ui.horizontal(|ui| { - ui.label("Username:"); - ui.add(egui::TextEdit::singleline(&mut self.username).desired_width(200.0)); - }); - ui.horizontal(|ui| { - ui.label("Password:"); - ui.add( - egui::TextEdit::singleline(&mut self.password) - .password(true) - .desired_width(200.0), - ); - }); - ui.checkbox(&mut self.persist_username, "Remember username"); - - if ui.button("Log in").clicked() || ui.input(|i| i.key_pressed(egui::Key::Enter)) { - if self.username == "admin" && self.password == "secret" { - self.is_logged_in = true; - self.login_error = None; - } else { - self.login_error = Some("Invalid Credentials.".to_owned()); - } - } - - if let Some(error) = &self.login_error { - ui.colored_label(egui::Color32::RED, error); + if UserProfile::show(ui, &self.login_form.username) { + self.handle_logout(); } + } else if self.login_form.show(ui) { + self.handle_login(); } ui.with_layout(egui::Layout::bottom_up(egui::Align::LEFT), footer); @@ -84,7 +65,7 @@ impl eframe::App for App { fn save(&mut self, storage: &mut dyn eframe::Storage) { let mut snapshot = self.clone(); if !snapshot.persist_username { - snapshot.username.clear(); + snapshot.login_form.username.clear(); } eframe::set_value(storage, eframe::APP_KEY, &snapshot); } diff --git a/src/components/login_form.rs b/src/components/login_form.rs new file mode 100644 index 00000000..738fcb4d --- /dev/null +++ b/src/components/login_form.rs @@ -0,0 +1,53 @@ +#[derive(Clone, Default, serde::Deserialize, serde::Serialize)] +pub struct LoginForm { + pub username: String, + pub password: String, + pub persist_username: bool, + pub error: Option, +} + +impl LoginForm { + pub fn show(&mut self, ui: &mut egui::Ui) -> bool { + let mut login_attempted = false; + + ui.heading("Login"); + + ui.horizontal(|ui| { + ui.label("Username:"); + ui.add(egui::TextEdit::singleline(&mut self.username).desired_width(200.0)); + }); + + ui.horizontal(|ui| { + ui.label("Password:"); + ui.add( + egui::TextEdit::singleline(&mut self.password) + .password(true) + .desired_width(200.0), + ); + }); + + ui.checkbox(&mut self.persist_username, "Remember username"); + + if ui.button("Log in").clicked() || ui.input(|i| i.key_pressed(egui::Key::Enter)) { + login_attempted = true; + } + + if let Some(error) = &self.error { + ui.colored_label(egui::Color32::RED, error); + } + + login_attempted + } + + pub fn clear(&mut self) { + self.password.clear(); + self.error = None; + if !self.persist_username { + self.username.clear(); + } + } + + pub fn set_error(&mut self, error: String) { + self.error = Some(error); + } +} diff --git a/src/components/mod.rs b/src/components/mod.rs index f836a355..a73aef64 100644 --- a/src/components/mod.rs +++ b/src/components/mod.rs @@ -1,2 +1,4 @@ pub mod footer; +pub mod login_form; pub mod menu; +pub mod user_profile; diff --git a/src/components/user_profile.rs b/src/components/user_profile.rs new file mode 100644 index 00000000..6b328547 --- /dev/null +++ b/src/components/user_profile.rs @@ -0,0 +1,14 @@ +pub struct UserProfile; + +impl UserProfile { + pub fn show(ui: &mut egui::Ui, username: &str) -> bool { + let mut logout_clicked = false; + + ui.colored_label(egui::Color32::GREEN, format!("Welcome, {}!", username)); + if ui.button("Log out").clicked() { + logout_clicked = true; + } + + logout_clicked + } +} diff --git a/src/lib.rs b/src/lib.rs index 40ee4f9a..eca5e32d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,5 +2,6 @@ mod app; mod components; +mod services; pub use app::App; diff --git a/src/services/auth.rs b/src/services/auth.rs new file mode 100644 index 00000000..4582746a --- /dev/null +++ b/src/services/auth.rs @@ -0,0 +1,7 @@ +pub struct AuthService; + +impl AuthService { + pub fn validate_credentials(username: &str, password: &str) -> bool { + username == "admin" && password == "secret" + } +} diff --git a/src/services/mod.rs b/src/services/mod.rs new file mode 100644 index 00000000..0e4a05d5 --- /dev/null +++ b/src/services/mod.rs @@ -0,0 +1 @@ +pub mod auth; From bf468a81d2186a3284896698bff8fee892bf3ae7 Mon Sep 17 00:00:00 2001 From: Illyrius Date: Wed, 12 Nov 2025 21:16:08 +0100 Subject: [PATCH 54/78] Enhance authentication and login form components with detailed documentation and clear state management Signed-off-by: Illyrius --- src/components/login_form.rs | 12 ++++++++++++ src/components/user_profile.rs | 7 +++++++ src/lib.rs | 2 -- src/main.rs | 2 -- src/services/auth.rs | 5 +++++ 5 files changed, 24 insertions(+), 4 deletions(-) diff --git a/src/components/login_form.rs b/src/components/login_form.rs index 738fcb4d..10b37bcf 100644 --- a/src/components/login_form.rs +++ b/src/components/login_form.rs @@ -1,3 +1,4 @@ +/// Login form state and UI component. #[derive(Clone, Default, serde::Deserialize, serde::Serialize)] pub struct LoginForm { pub username: String, @@ -7,6 +8,13 @@ pub struct LoginForm { } impl LoginForm { + /// Renders the login form UI. + /// # Parameters + /// * `ui`: Mutable reference to the current `egui::Ui`. + /// # Returns + /// `true` if "Log in" was clicked or Enter was pressed in this frame, otherwise `false`. + /// # Notes + /// If `error` is set, it is shown in red below the controls. pub fn show(&mut self, ui: &mut egui::Ui) -> bool { let mut login_attempted = false; @@ -39,6 +47,7 @@ impl LoginForm { login_attempted } + /// Clears sensitive and transient state. pub fn clear(&mut self) { self.password.clear(); self.error = None; @@ -47,6 +56,9 @@ impl LoginForm { } } + /// Sets the current error message to be displayed below the form. + /// # Parameters + /// * `error`: The message to show in the UI. pub fn set_error(&mut self, error: String) { self.error = Some(error); } diff --git a/src/components/user_profile.rs b/src/components/user_profile.rs index 6b328547..a781a8aa 100644 --- a/src/components/user_profile.rs +++ b/src/components/user_profile.rs @@ -1,6 +1,13 @@ +/// User profile UI component for displaying a greeting, and a logout button. pub struct UserProfile; impl UserProfile { + /// Shows the user profile UI. + /// # Parameters + /// * `ui`: Mutable reference to the current `egui::Ui`. + /// * `username`: The name to display in the greeting. + /// # Returns + /// `true` if the "Log out" button was clicked in this frame, otherwise `false`. pub fn show(ui: &mut egui::Ui, username: &str) -> bool { let mut logout_clicked = false; diff --git a/src/lib.rs b/src/lib.rs index eca5e32d..8abd0ac4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,3 @@ -#![warn(clippy::all)] - mod app; mod components; mod services; diff --git a/src/main.rs b/src/main.rs index 5095f9c8..0ecdef43 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,3 @@ -#![warn(clippy::all)] - /// Entry point for the xbim application. /// # Returns /// An `eframe::Result` indicating the success or failure of the application startup. diff --git a/src/services/auth.rs b/src/services/auth.rs index 4582746a..a95bb056 100644 --- a/src/services/auth.rs +++ b/src/services/auth.rs @@ -1,6 +1,11 @@ +/// Authentication service for validating user credentials. pub struct AuthService; +// TODO: Integrate with a secure password hashing library and user database. impl AuthService { + /// Validates a username/password pair against static test values. + /// # Returns + /// `true` if the credentials match the expected pair, otherwise `false`. pub fn validate_credentials(username: &str, password: &str) -> bool { username == "admin" && password == "secret" } From c8851f20fbf95a1a5ddf708006ada997fbf9f28b Mon Sep 17 00:00:00 2001 From: Illyrius Date: Wed, 12 Nov 2025 21:35:12 +0100 Subject: [PATCH 55/78] Refactor app.rs to use crate-level imports for components and services Signed-off-by: Illyrius --- src/app.rs | 19 ++++++++----------- src/components/mod.rs | 13 +++++++++---- src/lib.rs | 2 ++ src/services/mod.rs | 4 +++- 4 files changed, 22 insertions(+), 16 deletions(-) diff --git a/src/app.rs b/src/app.rs index 76f867d2..e92763d7 100644 --- a/src/app.rs +++ b/src/app.rs @@ -1,13 +1,7 @@ -use crate::components::footer::footer; -use crate::components::login_form::LoginForm; -use crate::components::menu::menu; -use crate::components::user_profile::UserProfile; -use crate::services::auth::AuthService; - #[derive(Clone, Default, serde::Deserialize, serde::Serialize)] #[serde(default)] pub struct App { - login_form: LoginForm, + login_form: crate::LoginForm, #[serde(skip)] is_logged_in: bool, persist_username: bool, @@ -29,7 +23,10 @@ impl App { } fn handle_login(&mut self) { - if AuthService::validate_credentials(&self.login_form.username, &self.login_form.password) { + if crate::AuthService::validate_credentials( + &self.login_form.username, + &self.login_form.password, + ) { self.is_logged_in = true; self.login_form.clear(); } else { @@ -46,19 +43,19 @@ impl App { impl eframe::App for App { fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) { egui::TopBottomPanel::top("top_panel").show(ctx, |ui| { - egui::MenuBar::new().ui(ui, menu); + egui::MenuBar::new().ui(ui, crate::menu); }); egui::CentralPanel::default().show(ctx, |ui| { if self.is_logged_in { - if UserProfile::show(ui, &self.login_form.username) { + if crate::UserProfile::show(ui, &self.login_form.username) { self.handle_logout(); } } else if self.login_form.show(ui) { self.handle_login(); } - ui.with_layout(egui::Layout::bottom_up(egui::Align::LEFT), footer); + ui.with_layout(egui::Layout::bottom_up(egui::Align::LEFT), crate::footer); }); } diff --git a/src/components/mod.rs b/src/components/mod.rs index a73aef64..1a521b27 100644 --- a/src/components/mod.rs +++ b/src/components/mod.rs @@ -1,4 +1,9 @@ -pub mod footer; -pub mod login_form; -pub mod menu; -pub mod user_profile; +mod footer; +mod login_form; +mod menu; +mod user_profile; + +pub use footer::footer; +pub use login_form::LoginForm; +pub use menu::menu; +pub use user_profile::UserProfile; diff --git a/src/lib.rs b/src/lib.rs index 8abd0ac4..1a41c72c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,3 +3,5 @@ mod components; mod services; pub use app::App; +pub use components::{footer, menu, LoginForm, UserProfile}; +pub use services::AuthService; diff --git a/src/services/mod.rs b/src/services/mod.rs index 0e4a05d5..17f642b2 100644 --- a/src/services/mod.rs +++ b/src/services/mod.rs @@ -1 +1,3 @@ -pub mod auth; +mod auth; + +pub use auth::AuthService; From a052dcf2d37935559c245752f81fc6abc377b084 Mon Sep 17 00:00:00 2001 From: Illyrius Date: Wed, 12 Nov 2025 21:41:33 +0100 Subject: [PATCH 56/78] Refactor app.rs and lib.rs to use crate-level imports for components and services Signed-off-by: Illyrius --- src/app.rs | 19 +++++++++++-------- src/components/mod.rs | 9 --------- src/lib.rs | 17 ++++++++++++----- src/services/mod.rs | 3 --- 4 files changed, 23 insertions(+), 25 deletions(-) delete mode 100644 src/components/mod.rs delete mode 100644 src/services/mod.rs diff --git a/src/app.rs b/src/app.rs index e92763d7..5a5ceded 100644 --- a/src/app.rs +++ b/src/app.rs @@ -1,7 +1,13 @@ +use crate::auth::AuthService; +use crate::footer::footer; +use crate::login_form::LoginForm; +use crate::menu::menu; +use crate::user_profile::UserProfile; + #[derive(Clone, Default, serde::Deserialize, serde::Serialize)] #[serde(default)] pub struct App { - login_form: crate::LoginForm, + login_form: LoginForm, #[serde(skip)] is_logged_in: bool, persist_username: bool, @@ -23,10 +29,7 @@ impl App { } fn handle_login(&mut self) { - if crate::AuthService::validate_credentials( - &self.login_form.username, - &self.login_form.password, - ) { + if AuthService::validate_credentials(&self.login_form.username, &self.login_form.password) { self.is_logged_in = true; self.login_form.clear(); } else { @@ -43,19 +46,19 @@ impl App { impl eframe::App for App { fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) { egui::TopBottomPanel::top("top_panel").show(ctx, |ui| { - egui::MenuBar::new().ui(ui, crate::menu); + egui::MenuBar::new().ui(ui, menu); }); egui::CentralPanel::default().show(ctx, |ui| { if self.is_logged_in { - if crate::UserProfile::show(ui, &self.login_form.username) { + if UserProfile::show(ui, &self.login_form.username) { self.handle_logout(); } } else if self.login_form.show(ui) { self.handle_login(); } - ui.with_layout(egui::Layout::bottom_up(egui::Align::LEFT), crate::footer); + ui.with_layout(egui::Layout::bottom_up(egui::Align::LEFT), footer); }); } diff --git a/src/components/mod.rs b/src/components/mod.rs deleted file mode 100644 index 1a521b27..00000000 --- a/src/components/mod.rs +++ /dev/null @@ -1,9 +0,0 @@ -mod footer; -mod login_form; -mod menu; -mod user_profile; - -pub use footer::footer; -pub use login_form::LoginForm; -pub use menu::menu; -pub use user_profile::UserProfile; diff --git a/src/lib.rs b/src/lib.rs index 1a41c72c..5afb483c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,7 +1,14 @@ mod app; -mod components; -mod services; +mod components { + pub mod footer; + pub mod login_form; + pub mod menu; + pub mod user_profile; +} +mod services { + pub mod auth; +} -pub use app::App; -pub use components::{footer, menu, LoginForm, UserProfile}; -pub use services::AuthService; +pub use app::*; +pub use components::*; +pub use services::*; diff --git a/src/services/mod.rs b/src/services/mod.rs deleted file mode 100644 index 17f642b2..00000000 --- a/src/services/mod.rs +++ /dev/null @@ -1,3 +0,0 @@ -mod auth; - -pub use auth::AuthService; From 47ee9fd361be6c3870070449e29738e785eded09 Mon Sep 17 00:00:00 2001 From: Illyrius Date: Wed, 12 Nov 2025 21:48:39 +0100 Subject: [PATCH 57/78] Refactor App struct to replace persist_username with current_username and update login/logout handling Signed-off-by: Illyrius --- src/app.rs | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/app.rs b/src/app.rs index 5a5ceded..a8972d02 100644 --- a/src/app.rs +++ b/src/app.rs @@ -10,7 +10,8 @@ pub struct App { login_form: LoginForm, #[serde(skip)] is_logged_in: bool, - persist_username: bool, + #[serde(skip)] + current_username: String, } impl App { @@ -21,7 +22,7 @@ impl App { Default::default() }; - if !app.persist_username { + if !app.login_form.persist_username { app.login_form.username.clear(); } @@ -31,6 +32,7 @@ impl App { fn handle_login(&mut self) { if AuthService::validate_credentials(&self.login_form.username, &self.login_form.password) { self.is_logged_in = true; + self.current_username = self.login_form.username.clone(); self.login_form.clear(); } else { self.login_form.set_error("Invalid Credentials.".to_owned()); @@ -39,6 +41,7 @@ impl App { fn handle_logout(&mut self) { self.is_logged_in = false; + self.current_username.clear(); self.login_form.clear(); } } @@ -51,7 +54,7 @@ impl eframe::App for App { egui::CentralPanel::default().show(ctx, |ui| { if self.is_logged_in { - if UserProfile::show(ui, &self.login_form.username) { + if UserProfile::show(ui, &self.current_username) { self.handle_logout(); } } else if self.login_form.show(ui) { @@ -64,9 +67,11 @@ impl eframe::App for App { fn save(&mut self, storage: &mut dyn eframe::Storage) { let mut snapshot = self.clone(); - if !snapshot.persist_username { + if !snapshot.login_form.persist_username { snapshot.login_form.username.clear(); } + snapshot.is_logged_in = false; + snapshot.current_username.clear(); eframe::set_value(storage, eframe::APP_KEY, &snapshot); } } From 16785744c595328db927447269581886c8f49a18 Mon Sep 17 00:00:00 2001 From: Illyrius Date: Wed, 12 Nov 2025 22:33:05 +0100 Subject: [PATCH 58/78] setup async oauth Signed-off-by: Illyrius --- .idea/dictionaries/project.xml | 2 + Cargo.toml | 5 +- src/app.rs | 1 + src/lib.rs | 2 +- src/services/auth.rs | 12 ---- src/services/oauth.rs | 109 +++++++++++++++++++++++++++++++++ 6 files changed, 117 insertions(+), 14 deletions(-) delete mode 100644 src/services/auth.rs create mode 100644 src/services/oauth.rs diff --git a/.idea/dictionaries/project.xml b/.idea/dictionaries/project.xml index 89d7125d..211aa6bd 100644 --- a/.idea/dictionaries/project.xml +++ b/.idea/dictionaries/project.xml @@ -6,9 +6,11 @@ deps eframe egui + pkce ratelimitguard rustfmt softprops + ssrf testuser xbim xodium diff --git a/Cargo.toml b/Cargo.toml index 0de98de6..799ad5d2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,4 +30,7 @@ eframe = { version = "0.33.0", default-features = false, features = [ "wayland", ] } env_logger = "0.11.8" -serde = { version = "1.0.228", features = ["derive"] } \ No newline at end of file +serde = { version = "1.0.228", features = ["derive"] } +url = "2.5.7" +oauth2 = { version = "5.0.0", features = ["reqwest", "reqwest-blocking"] } +tokio = { version = "1.48.0", features = ["rt", "rt-multi-thread", "macros"] } \ No newline at end of file diff --git a/src/app.rs b/src/app.rs index a8972d02..4e656210 100644 --- a/src/app.rs +++ b/src/app.rs @@ -30,6 +30,7 @@ impl App { } fn handle_login(&mut self) { + //TODO: Replace with oauth. if AuthService::validate_credentials(&self.login_form.username, &self.login_form.password) { self.is_logged_in = true; self.current_username = self.login_form.username.clone(); diff --git a/src/lib.rs b/src/lib.rs index 5afb483c..30b02ba7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -6,7 +6,7 @@ mod components { pub mod user_profile; } mod services { - pub mod auth; + pub mod oauth; } pub use app::*; diff --git a/src/services/auth.rs b/src/services/auth.rs deleted file mode 100644 index a95bb056..00000000 --- a/src/services/auth.rs +++ /dev/null @@ -1,12 +0,0 @@ -/// Authentication service for validating user credentials. -pub struct AuthService; - -// TODO: Integrate with a secure password hashing library and user database. -impl AuthService { - /// Validates a username/password pair against static test values. - /// # Returns - /// `true` if the credentials match the expected pair, otherwise `false`. - pub fn validate_credentials(username: &str, password: &str) -> bool { - username == "admin" && password == "secret" - } -} diff --git a/src/services/oauth.rs b/src/services/oauth.rs new file mode 100644 index 00000000..bf6f43d8 --- /dev/null +++ b/src/services/oauth.rs @@ -0,0 +1,109 @@ +use oauth2::basic::BasicClient; +use oauth2::reqwest; +use oauth2::{ + AuthUrl, AuthorizationCode, ClientId, ClientSecret, CsrfToken, RedirectUrl, Scope, + TokenResponse, TokenUrl, +}; +use tokio::io::{AsyncBufReadExt, AsyncWriteExt, BufReader}; +use tokio::net::TcpListener; +use url::Url; + +use std::env; + +//TODO: refactor this file. +#[tokio::main] +async fn main() { + let github_client_id = ClientId::new( + env::var("GITHUB_CLIENT_ID").expect("Missing the GITHUB_CLIENT_ID environment variable."), + ); + let github_client_secret = ClientSecret::new( + env::var("GITHUB_CLIENT_SECRET") + .expect("Missing the GITHUB_CLIENT_SECRET environment variable."), + ); + let auth_url = AuthUrl::new("https://github.com/login/oauth/authorize".to_string()) + .expect("Invalid authorization endpoint URL"); + let token_url = TokenUrl::new("https://github.com/login/oauth/access_token".to_string()) + .expect("Invalid token endpoint URL"); + + let client = BasicClient::new(github_client_id) + .set_client_secret(github_client_secret) + .set_auth_uri(auth_url) + .set_token_uri(token_url) + .set_redirect_uri( + RedirectUrl::new("http://localhost:8080".to_string()).expect("Invalid redirect URL"), + ); + + let http_client = reqwest::ClientBuilder::new() + .redirect(reqwest::redirect::Policy::none()) + .build() + .expect("Client should build"); + + let (authorize_url, csrf_state) = client + .authorize_url(CsrfToken::new_random) + .add_scope(Scope::new("public_repo".to_string())) + .add_scope(Scope::new("user:email".to_string())) + .url(); + + println!("Open this URL in your browser:\n{authorize_url}\n"); + + let (code, state) = { + let listener = TcpListener::bind("127.0.0.1:8080").await.unwrap(); + + loop { + if let Ok((mut stream, _)) = listener.accept().await { + let mut reader = BufReader::new(&mut stream); + + let mut request_line = String::new(); + reader.read_line(&mut request_line).await.unwrap(); + + let redirect_url = request_line.split_whitespace().nth(1).unwrap(); + let url = Url::parse(&("http://localhost".to_string() + redirect_url)).unwrap(); + + let code = url + .query_pairs() + .find(|(key, _)| key == "code") + .map(|(_, code)| AuthorizationCode::new(code.into_owned())) + .unwrap(); + + let state = url + .query_pairs() + .find(|(key, _)| key == "state") + .map(|(_, state)| CsrfToken::new(state.into_owned())) + .unwrap(); + + let message = "Go back to your terminal :)"; + let response = format!( + "HTTP/1.1 200 OK\r\ncontent-length: {}\r\n\r\n{}", + message.len(), + message + ); + stream.write_all(response.as_bytes()).await.unwrap(); + + break (code, state); + } + } + }; + + println!("Github returned the following code:\n{}\n", code.secret()); + println!( + "Github returned the following state:\n{} (expected `{}`)\n", + state.secret(), + csrf_state.secret() + ); + + let token_res = client.exchange_code(code).request_async(&http_client).await; + + println!("Github returned the following token:\n{token_res:?}\n"); + + if let Ok(token) = token_res { + let scopes = if let Some(scopes_vec) = token.scopes() { + scopes_vec + .iter() + .flat_map(|comma_separated| comma_separated.split(',')) + .collect::>() + } else { + Vec::new() + }; + println!("Github returned the following scopes:\n{scopes:?}\n"); + } +} From f2024450c95367655a1cc0091297d07d589b6332 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 18 Nov 2025 12:04:24 +0000 Subject: [PATCH 59/78] Update actions/checkout action to v5.0.1 (#74) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Xodium Dependencies Updater This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [actions/checkout](https://redirect.github.com/actions/checkout) | action | patch | `v5.0.0` -> `v5.0.1` | --- ### Release Notes
actions/checkout (actions/checkout) ### [`v5.0.1`](https://redirect.github.com/actions/checkout/compare/v5.0.0...v5.0.1) [Compare Source](https://redirect.github.com/actions/checkout/compare/v5.0.0...v5.0.1)
--- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/XodiumSoftware/xbim). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/ci_cd.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci_cd.yml b/.github/workflows/ci_cd.yml index 3eaed23c..4ebb31a1 100644 --- a/.github/workflows/ci_cd.yml +++ b/.github/workflows/ci_cd.yml @@ -23,7 +23,7 @@ jobs: steps: - id: checkout name: Checkout - uses: actions/checkout@v5.0.0 + uses: actions/checkout@v5.0.1 - id: cache_deps name: Cache dependencies @@ -73,7 +73,7 @@ jobs: steps: - id: checkout name: Checkout - uses: actions/checkout@v5.0.0 + uses: actions/checkout@v5.0.1 - id: setup_rust name: Setup Rust From c29d94a3c7132a153c1657eb4d64f6376459599d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 20 Nov 2025 22:06:24 +0000 Subject: [PATCH 60/78] Update actions/checkout action to v6 (#75) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Xodium Dependencies Updater This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [actions/checkout](https://redirect.github.com/actions/checkout) | action | major | `v5.0.1` -> `v6.0.0` | --- ### Release Notes
actions/checkout (actions/checkout) ### [`v6.0.0`](https://redirect.github.com/actions/checkout/compare/v5.0.1...v6.0.0) [Compare Source](https://redirect.github.com/actions/checkout/compare/v5.0.1...v6.0.0)
--- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/XodiumSoftware/xbim). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/ci_cd.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci_cd.yml b/.github/workflows/ci_cd.yml index 4ebb31a1..d30cc595 100644 --- a/.github/workflows/ci_cd.yml +++ b/.github/workflows/ci_cd.yml @@ -23,7 +23,7 @@ jobs: steps: - id: checkout name: Checkout - uses: actions/checkout@v5.0.1 + uses: actions/checkout@v6.0.0 - id: cache_deps name: Cache dependencies @@ -73,7 +73,7 @@ jobs: steps: - id: checkout name: Checkout - uses: actions/checkout@v5.0.1 + uses: actions/checkout@v6.0.0 - id: setup_rust name: Setup Rust From bc404f4835e57f5672e900b4e08aff1d99db6016 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 24 Nov 2025 18:49:47 +0000 Subject: [PATCH 61/78] Update actions-rust-lang/setup-rust-toolchain digest to ca4a643 (#76) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Xodium Dependencies Updater This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | actions-rust-lang/setup-rust-toolchain | action | digest | `1780873` -> `ca4a643` | --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/XodiumSoftware/xbim). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/ci_cd.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci_cd.yml b/.github/workflows/ci_cd.yml index d30cc595..45da3e63 100644 --- a/.github/workflows/ci_cd.yml +++ b/.github/workflows/ci_cd.yml @@ -38,7 +38,7 @@ jobs: - id: setup_rust name: Setup Rust - uses: actions-rust-lang/setup-rust-toolchain@1780873c7b576612439a134613cc4cc74ce5538c + uses: actions-rust-lang/setup-rust-toolchain@ca4a6432af353637602348dec3df861ef02ed8a6 with: toolchain: stable components: rustfmt, clippy @@ -77,7 +77,7 @@ jobs: - id: setup_rust name: Setup Rust - uses: actions-rust-lang/setup-rust-toolchain@1780873c7b576612439a134613cc4cc74ce5538c + uses: actions-rust-lang/setup-rust-toolchain@ca4a6432af353637602348dec3df861ef02ed8a6 with: toolchain: stable From 2e15555ed6f45e9e3f1ac7b9a9b14516dbe7a4e4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 1 Dec 2025 13:41:55 +0000 Subject: [PATCH 62/78] Update softprops/action-gh-release digest to a06a81a (#77) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Xodium Dependencies Updater This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | softprops/action-gh-release | action | digest | `5be0e66` -> `a06a81a` | --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/XodiumSoftware/xbim). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/ci_cd.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci_cd.yml b/.github/workflows/ci_cd.yml index 45da3e63..4ccc94ea 100644 --- a/.github/workflows/ci_cd.yml +++ b/.github/workflows/ci_cd.yml @@ -109,7 +109,7 @@ jobs: - id: create_release name: Create Release - uses: softprops/action-gh-release@5be0e66d93ac7ed76da52eca8bb058f665c3a5fe + uses: softprops/action-gh-release@a06a81a03ee405af7f2048a818ed3f03bbf83c7b env: GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" with: From d7b835d509d16aa0a93edfa3ffb03f2b6395e50b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 1 Dec 2025 15:23:38 +0000 Subject: [PATCH 63/78] Update actions-rust-lang/setup-rust-toolchain digest to b598bed (#78) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Xodium Dependencies Updater This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | actions-rust-lang/setup-rust-toolchain | action | digest | `ca4a643` -> `b598bed` | --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/XodiumSoftware/xbim). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/ci_cd.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci_cd.yml b/.github/workflows/ci_cd.yml index 4ccc94ea..56073252 100644 --- a/.github/workflows/ci_cd.yml +++ b/.github/workflows/ci_cd.yml @@ -38,7 +38,7 @@ jobs: - id: setup_rust name: Setup Rust - uses: actions-rust-lang/setup-rust-toolchain@ca4a6432af353637602348dec3df861ef02ed8a6 + uses: actions-rust-lang/setup-rust-toolchain@b598bed351cb8d159adfaa2ea4989c797082620f with: toolchain: stable components: rustfmt, clippy @@ -77,7 +77,7 @@ jobs: - id: setup_rust name: Setup Rust - uses: actions-rust-lang/setup-rust-toolchain@ca4a6432af353637602348dec3df861ef02ed8a6 + uses: actions-rust-lang/setup-rust-toolchain@b598bed351cb8d159adfaa2ea4989c797082620f with: toolchain: stable From 614ee8abbca8ebc98384d1730d18df88c4cf86fe Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 3 Dec 2025 03:05:32 +0000 Subject: [PATCH 64/78] Update actions/checkout action to v6.0.1 (#79) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Xodium Dependencies Updater This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [actions/checkout](https://redirect.github.com/actions/checkout) | action | patch | `v6.0.0` -> `v6.0.1` | --- ### Release Notes
actions/checkout (actions/checkout) ### [`v6.0.1`](https://redirect.github.com/actions/checkout/compare/v6.0.0...v6.0.1) [Compare Source](https://redirect.github.com/actions/checkout/compare/v6.0.0...v6.0.1)
--- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/XodiumSoftware/xbim). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/ci_cd.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci_cd.yml b/.github/workflows/ci_cd.yml index 56073252..73bbeac5 100644 --- a/.github/workflows/ci_cd.yml +++ b/.github/workflows/ci_cd.yml @@ -23,7 +23,7 @@ jobs: steps: - id: checkout name: Checkout - uses: actions/checkout@v6.0.0 + uses: actions/checkout@v6.0.1 - id: cache_deps name: Cache dependencies @@ -73,7 +73,7 @@ jobs: steps: - id: checkout name: Checkout - uses: actions/checkout@v6.0.0 + uses: actions/checkout@v6.0.1 - id: setup_rust name: Setup Rust From 47014e1179645c548d214fb56561438117ecf4eb Mon Sep 17 00:00:00 2001 From: Illyrius Date: Fri, 5 Dec 2025 09:41:28 +0100 Subject: [PATCH 65/78] Implement OAuth2 authentication flow with OAuthService struct Signed-off-by: Illyrius --- Cargo.toml | 5 +- src/app.rs | 29 ++++++--- src/services/oauth.rs | 148 ++++++++++++++++++++++++++++-------------- 3 files changed, 123 insertions(+), 59 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 799ad5d2..bdfa4751 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,6 +31,5 @@ eframe = { version = "0.33.0", default-features = false, features = [ ] } env_logger = "0.11.8" serde = { version = "1.0.228", features = ["derive"] } -url = "2.5.7" -oauth2 = { version = "5.0.0", features = ["reqwest", "reqwest-blocking"] } -tokio = { version = "1.48.0", features = ["rt", "rt-multi-thread", "macros"] } \ No newline at end of file +oauth2 = { version = "5.0.0", features = ["reqwest"] } +reqwest = "0.12.24" diff --git a/src/app.rs b/src/app.rs index 4e656210..1a53162c 100644 --- a/src/app.rs +++ b/src/app.rs @@ -1,7 +1,7 @@ -use crate::auth::AuthService; use crate::footer::footer; use crate::login_form::LoginForm; use crate::menu::menu; +use crate::oauth::OAuthService; use crate::user_profile::UserProfile; #[derive(Clone, Default, serde::Deserialize, serde::Serialize)] @@ -12,6 +12,8 @@ pub struct App { is_logged_in: bool, #[serde(skip)] current_username: String, + #[serde(skip)] + oauth_service: Option, } impl App { @@ -26,17 +28,28 @@ impl App { app.login_form.username.clear(); } + app.oauth_service = Some(OAuthService::new( + "client_id", + "client_secret", + "https://github.com/login/oauth/authorize", + "https://github.com/login/oauth/access_token", + "http://127.0.0.1:8080", + )); + app } fn handle_login(&mut self) { - //TODO: Replace with oauth. - if AuthService::validate_credentials(&self.login_form.username, &self.login_form.password) { - self.is_logged_in = true; - self.current_username = self.login_form.username.clone(); - self.login_form.clear(); - } else { - self.login_form.set_error("Invalid Credentials.".to_owned()); + if let Some(service) = &self.oauth_service { + let service = service.clone(); + eframe::glow::winit::platform::run_in_background(async move { + let http_client = HttpClient::builder() + .redirect(reqwest::redirect::Policy::none()) + .build() + .unwrap(); + + oauth(&service).await; + }); } } diff --git a/src/services/oauth.rs b/src/services/oauth.rs index bf6f43d8..97b52661 100644 --- a/src/services/oauth.rs +++ b/src/services/oauth.rs @@ -1,60 +1,115 @@ -use oauth2::basic::BasicClient; -use oauth2::reqwest; +use oauth2::basic::{ + BasicClient, BasicErrorResponse, BasicRevocationErrorResponse, BasicTokenIntrospectionResponse, + BasicTokenResponse, +}; +use oauth2::url::Url; use oauth2::{ - AuthUrl, AuthorizationCode, ClientId, ClientSecret, CsrfToken, RedirectUrl, Scope, - TokenResponse, TokenUrl, + AuthUrl, AuthorizationCode, Client, ClientId, ClientSecret, CsrfToken, EndpointNotSet, + EndpointSet, HttpClientError, RedirectUrl, Scope, StandardRevocableToken, TokenResponse, + TokenUrl, }; -use tokio::io::{AsyncBufReadExt, AsyncWriteExt, BufReader}; -use tokio::net::TcpListener; -use url::Url; +use std::io::{BufRead, BufReader, Write}; +use std::net::TcpListener; + +/// OAuthService handles OAuth2 authentication flow. +/// It uses the `oauth2` crate to manage the OAuth2 process. +#[derive(Clone, Debug)] +pub struct OAuthService { + pub client: Client< + BasicErrorResponse, + BasicTokenResponse, + BasicTokenIntrospectionResponse, + StandardRevocableToken, + BasicRevocationErrorResponse, + EndpointSet, + EndpointNotSet, + EndpointNotSet, + EndpointNotSet, + EndpointSet, + >, +} -use std::env; +impl OAuthService { + /// Creates a new OAuthService instance. + /// # Arguments + /// * `client_id` - The OAuth2 client ID. + /// * `client_secret` - The OAuth2 client secret. + /// * `auth_url` - The authorization endpoint URL. + /// * `token_url` - The token endpoint URL. + /// * `redirect_url` - The redirect URL after authorization. + /// # Returns + /// A new instance of OAuthService. + pub fn new( + client_id: impl Into, + client_secret: impl Into, + auth_url: impl Into, + token_url: impl Into, + redirect_url: impl Into, + ) -> Self { + Self { + client: BasicClient::new(ClientId::new(client_id.into())) + .set_client_secret(ClientSecret::new(client_secret.into())) + .set_auth_uri( + AuthUrl::new(auth_url.into()).expect("Invalid authorization endpoint URL"), + ) + .set_token_uri(TokenUrl::new(token_url.into()).expect("Invalid token endpoint URL")) + .set_redirect_uri( + RedirectUrl::new(redirect_url.into()).expect("Invalid redirect URL"), + ), + } + } -//TODO: refactor this file. -#[tokio::main] -async fn main() { - let github_client_id = ClientId::new( - env::var("GITHUB_CLIENT_ID").expect("Missing the GITHUB_CLIENT_ID environment variable."), - ); - let github_client_secret = ClientSecret::new( - env::var("GITHUB_CLIENT_SECRET") - .expect("Missing the GITHUB_CLIENT_SECRET environment variable."), - ); - let auth_url = AuthUrl::new("https://github.com/login/oauth/authorize".to_string()) - .expect("Invalid authorization endpoint URL"); - let token_url = TokenUrl::new("https://github.com/login/oauth/access_token".to_string()) - .expect("Invalid token endpoint URL"); - - let client = BasicClient::new(github_client_id) - .set_client_secret(github_client_secret) - .set_auth_uri(auth_url) - .set_token_uri(token_url) - .set_redirect_uri( - RedirectUrl::new("http://localhost:8080".to_string()).expect("Invalid redirect URL"), - ); + /// Builds the authorization URL to redirect the user to. + /// # Returns + /// A tuple containing the authorization URL and the CSRF token. + pub fn build_authorize_url(&self) -> (Url, CsrfToken) { + self.client + .authorize_url(CsrfToken::new_random) + .add_scope(Scope::new("public_repo".to_string())) + .add_scope(Scope::new("user:email".to_string())) + .url() + } + /// Exchanges the authorization code for an access token. + /// # Arguments + /// * `code` - The authorization code received from the OAuth2 provider. + /// * `http_client` - The HTTP client to use for the request. + /// # Returns + /// A result containing the token response or an error. + pub async fn exchange_code( + &self, + code: AuthorizationCode, + http_client: &reqwest::Client, + ) -> Result< + BasicTokenResponse, + oauth2::RequestTokenError, BasicErrorResponse>, + > { + self.client + .exchange_code(code) + .request_async(http_client) + .await + } +} + +async fn oauth(service: &OAuthService) { let http_client = reqwest::ClientBuilder::new() .redirect(reqwest::redirect::Policy::none()) .build() .expect("Client should build"); - let (authorize_url, csrf_state) = client - .authorize_url(CsrfToken::new_random) - .add_scope(Scope::new("public_repo".to_string())) - .add_scope(Scope::new("user:email".to_string())) - .url(); + let (authorize_url, csrf_state) = service.build_authorize_url(); println!("Open this URL in your browser:\n{authorize_url}\n"); let (code, state) = { - let listener = TcpListener::bind("127.0.0.1:8080").await.unwrap(); + let listener = TcpListener::bind("127.0.0.1:8080").unwrap(); loop { - if let Ok((mut stream, _)) = listener.accept().await { + if let Ok((mut stream, _)) = listener.accept() { let mut reader = BufReader::new(&mut stream); let mut request_line = String::new(); - reader.read_line(&mut request_line).await.unwrap(); + reader.read_line(&mut request_line).unwrap(); let redirect_url = request_line.split_whitespace().nth(1).unwrap(); let url = Url::parse(&("http://localhost".to_string() + redirect_url)).unwrap(); @@ -77,7 +132,7 @@ async fn main() { message.len(), message ); - stream.write_all(response.as_bytes()).await.unwrap(); + stream.write_all(response.as_bytes()).unwrap(); break (code, state); } @@ -91,19 +146,16 @@ async fn main() { csrf_state.secret() ); - let token_res = client.exchange_code(code).request_async(&http_client).await; + let token_res = service.exchange_code(code, &http_client).await; println!("Github returned the following token:\n{token_res:?}\n"); if let Ok(token) = token_res { - let scopes = if let Some(scopes_vec) = token.scopes() { - scopes_vec - .iter() - .flat_map(|comma_separated| comma_separated.split(',')) - .collect::>() - } else { - Vec::new() - }; + let scopes = token + .scopes() + .map(|v| v.iter().flat_map(|s| s.split(',')).collect::>()) + .unwrap_or_default(); + println!("Github returned the following scopes:\n{scopes:?}\n"); } } From 3f46d56d648c66595bad6bcaa0e4a1ad13ba9f25 Mon Sep 17 00:00:00 2001 From: Illyrius Date: Fri, 5 Dec 2025 09:42:22 +0100 Subject: [PATCH 66/78] Remove unused code and clean up oauth.rs Signed-off-by: Illyrius --- src/services/oauth.rs | 74 +------------------------------------------ 1 file changed, 1 insertion(+), 73 deletions(-) diff --git a/src/services/oauth.rs b/src/services/oauth.rs index 97b52661..6cbfd0f2 100644 --- a/src/services/oauth.rs +++ b/src/services/oauth.rs @@ -5,11 +5,8 @@ use oauth2::basic::{ use oauth2::url::Url; use oauth2::{ AuthUrl, AuthorizationCode, Client, ClientId, ClientSecret, CsrfToken, EndpointNotSet, - EndpointSet, HttpClientError, RedirectUrl, Scope, StandardRevocableToken, TokenResponse, - TokenUrl, + EndpointSet, HttpClientError, RedirectUrl, Scope, StandardRevocableToken, TokenUrl, }; -use std::io::{BufRead, BufReader, Write}; -use std::net::TcpListener; /// OAuthService handles OAuth2 authentication flow. /// It uses the `oauth2` crate to manage the OAuth2 process. @@ -90,72 +87,3 @@ impl OAuthService { .await } } - -async fn oauth(service: &OAuthService) { - let http_client = reqwest::ClientBuilder::new() - .redirect(reqwest::redirect::Policy::none()) - .build() - .expect("Client should build"); - - let (authorize_url, csrf_state) = service.build_authorize_url(); - - println!("Open this URL in your browser:\n{authorize_url}\n"); - - let (code, state) = { - let listener = TcpListener::bind("127.0.0.1:8080").unwrap(); - - loop { - if let Ok((mut stream, _)) = listener.accept() { - let mut reader = BufReader::new(&mut stream); - - let mut request_line = String::new(); - reader.read_line(&mut request_line).unwrap(); - - let redirect_url = request_line.split_whitespace().nth(1).unwrap(); - let url = Url::parse(&("http://localhost".to_string() + redirect_url)).unwrap(); - - let code = url - .query_pairs() - .find(|(key, _)| key == "code") - .map(|(_, code)| AuthorizationCode::new(code.into_owned())) - .unwrap(); - - let state = url - .query_pairs() - .find(|(key, _)| key == "state") - .map(|(_, state)| CsrfToken::new(state.into_owned())) - .unwrap(); - - let message = "Go back to your terminal :)"; - let response = format!( - "HTTP/1.1 200 OK\r\ncontent-length: {}\r\n\r\n{}", - message.len(), - message - ); - stream.write_all(response.as_bytes()).unwrap(); - - break (code, state); - } - } - }; - - println!("Github returned the following code:\n{}\n", code.secret()); - println!( - "Github returned the following state:\n{} (expected `{}`)\n", - state.secret(), - csrf_state.secret() - ); - - let token_res = service.exchange_code(code, &http_client).await; - - println!("Github returned the following token:\n{token_res:?}\n"); - - if let Ok(token) = token_res { - let scopes = token - .scopes() - .map(|v| v.iter().flat_map(|s| s.split(',')).collect::>()) - .unwrap_or_default(); - - println!("Github returned the following scopes:\n{scopes:?}\n"); - } -} From a81f30814af49e645c18e65560e82205caf45b50 Mon Sep 17 00:00:00 2001 From: Illyrius Date: Fri, 5 Dec 2025 09:47:17 +0100 Subject: [PATCH 67/78] Update dependencies and add user info fetching to OAuthService Signed-off-by: Illyrius --- Cargo.toml | 6 +++--- src/services/oauth.rs | 26 ++++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index bdfa4751..7173d3cb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,8 +22,8 @@ all-features = true targets = ["x86_64-unknown-linux-gnu"] [dependencies] -egui = "0.33.0" -eframe = { version = "0.33.0", default-features = false, features = [ +egui = "0.33.2" +eframe = { version = "0.33.2", default-features = false, features = [ "default_fonts", "glow", "persistence", @@ -32,4 +32,4 @@ eframe = { version = "0.33.0", default-features = false, features = [ env_logger = "0.11.8" serde = { version = "1.0.228", features = ["derive"] } oauth2 = { version = "5.0.0", features = ["reqwest"] } -reqwest = "0.12.24" +reqwest = { version = "0.12.24", features = ["json"] } diff --git a/src/services/oauth.rs b/src/services/oauth.rs index 6cbfd0f2..79a630b0 100644 --- a/src/services/oauth.rs +++ b/src/services/oauth.rs @@ -2,11 +2,13 @@ use oauth2::basic::{ BasicClient, BasicErrorResponse, BasicRevocationErrorResponse, BasicTokenIntrospectionResponse, BasicTokenResponse, }; +use oauth2::http::header::{AUTHORIZATION, USER_AGENT}; use oauth2::url::Url; use oauth2::{ AuthUrl, AuthorizationCode, Client, ClientId, ClientSecret, CsrfToken, EndpointNotSet, EndpointSet, HttpClientError, RedirectUrl, Scope, StandardRevocableToken, TokenUrl, }; +use serde::de::DeserializeOwned; /// OAuthService handles OAuth2 authentication flow. /// It uses the `oauth2` crate to manage the OAuth2 process. @@ -86,4 +88,28 @@ impl OAuthService { .request_async(http_client) .await } + + /// Fetches user info from a generic OAuth2 provider. + /// # Arguments + /// * `access_token` - The OAuth2 access token. + /// * `http_client` - The HTTP client to use for the request. + /// * `user_info_url` - The endpoint returning the user's info (e.g., `/me`). + /// # Returns + /// A result containing the deserialized user info. + pub async fn get_user_info( + &self, + access_token: &str, + http_client: &reqwest::Client, + user_info_url: &str, + ) -> Result { + let user: T = http_client + .get(user_info_url) + .header(USER_AGENT, "rust-oauth2-client") + .header(AUTHORIZATION, format!("Bearer {}", access_token)) + .send() + .await? + .json() + .await?; + Ok(user) + } } From b16825c144701960bb4be9c90ebb2da731c7be8f Mon Sep 17 00:00:00 2001 From: Illyrius Date: Fri, 5 Dec 2025 10:01:58 +0100 Subject: [PATCH 68/78] Refactor handle_login function to remove async implementation and add webbrowser and tokio dependencies Signed-off-by: Illyrius --- Cargo.toml | 2 ++ src/app.rs | 14 +------------- 2 files changed, 3 insertions(+), 13 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 7173d3cb..227f8abb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,3 +33,5 @@ env_logger = "0.11.8" serde = { version = "1.0.228", features = ["derive"] } oauth2 = { version = "5.0.0", features = ["reqwest"] } reqwest = { version = "0.12.24", features = ["json"] } +webbrowser = "1.0.6" +tokio = "1.48.0" diff --git a/src/app.rs b/src/app.rs index 1a53162c..eb055000 100644 --- a/src/app.rs +++ b/src/app.rs @@ -39,19 +39,7 @@ impl App { app } - fn handle_login(&mut self) { - if let Some(service) = &self.oauth_service { - let service = service.clone(); - eframe::glow::winit::platform::run_in_background(async move { - let http_client = HttpClient::builder() - .redirect(reqwest::redirect::Policy::none()) - .build() - .unwrap(); - - oauth(&service).await; - }); - } - } + fn handle_login(&mut self) {} fn handle_logout(&mut self) { self.is_logged_in = false; From 74b662b10839826d700e772a71c9c7bd30a2479b Mon Sep 17 00:00:00 2001 From: Illyrius Date: Fri, 5 Dec 2025 10:02:32 +0100 Subject: [PATCH 69/78] Remove webbrowser and tokio dependencies from Cargo.toml Signed-off-by: Illyrius --- Cargo.toml | 2 -- 1 file changed, 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 227f8abb..7173d3cb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,5 +33,3 @@ env_logger = "0.11.8" serde = { version = "1.0.228", features = ["derive"] } oauth2 = { version = "5.0.0", features = ["reqwest"] } reqwest = { version = "0.12.24", features = ["json"] } -webbrowser = "1.0.6" -tokio = "1.48.0" From 01ba785ad89419a157dde6f5c35db4140cc8029a Mon Sep 17 00:00:00 2001 From: Illyrius Date: Fri, 5 Dec 2025 11:53:28 +0100 Subject: [PATCH 70/78] + Signed-off-by: Illyrius --- Cargo.toml | 1 + src/app.rs | 3 +++ src/database.rs | 42 ++++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 2 ++ 4 files changed, 48 insertions(+) create mode 100644 src/database.rs diff --git a/Cargo.toml b/Cargo.toml index 7173d3cb..ba95a009 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,3 +33,4 @@ env_logger = "0.11.8" serde = { version = "1.0.228", features = ["derive"] } oauth2 = { version = "5.0.0", features = ["reqwest"] } reqwest = { version = "0.12.24", features = ["json"] } +surrealdb = "2.4.0" diff --git a/src/app.rs b/src/app.rs index eb055000..e9cd8919 100644 --- a/src/app.rs +++ b/src/app.rs @@ -1,3 +1,4 @@ +use crate::Database; use crate::footer::footer; use crate::login_form::LoginForm; use crate::menu::menu; @@ -14,6 +15,8 @@ pub struct App { current_username: String, #[serde(skip)] oauth_service: Option, + #[serde(skip)] + database: Option, } impl App { diff --git a/src/database.rs b/src/database.rs new file mode 100644 index 00000000..3e27b1cb --- /dev/null +++ b/src/database.rs @@ -0,0 +1,42 @@ +use surrealdb::Surreal; + +#[derive(Clone)] +pub struct Database { + db: Surreal, +} + +impl Database { + pub async fn new() -> Result { + let db = Surreal::new::("xbim.db").await?; + db.use_ns("app").use_db("main").await?; + + Ok(Database { db }) + } + + pub async fn save_user(&self, username: &str) -> Result<(), surrealdb::Error> { + let _: Option = self + .db + .create("users") + .content(User { + username: username.to_string(), + }) + .await?; + Ok(()) + } + + pub async fn get_user(&self, username: &str) -> Result, surrealdb::Error> { + let users: Vec = self + .db + .query("SELECT * FROM users WHERE username = $username") + .bind(("username", username)) + .await? + .take(0)?; + + Ok(users.into_iter().next()) + } +} + +#[derive(Debug, serde::Serialize, serde::Deserialize)] +struct User { + username: String, +} diff --git a/src/lib.rs b/src/lib.rs index 30b02ba7..551b31ed 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -8,7 +8,9 @@ mod components { mod services { pub mod oauth; } +mod database; pub use app::*; pub use components::*; +pub use database::*; pub use services::*; From 12fc76be38ba3347b9019bc42cfc54c2d82f53a2 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 7 Dec 2025 01:01:59 +0000 Subject: [PATCH 71/78] Update softprops/action-gh-release digest to 60cfd9a (#80) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Xodium Dependencies Updater This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | softprops/action-gh-release | action | digest | `a06a81a` -> `60cfd9a` | --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/XodiumSoftware/xbim). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/ci_cd.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci_cd.yml b/.github/workflows/ci_cd.yml index 73bbeac5..89b02292 100644 --- a/.github/workflows/ci_cd.yml +++ b/.github/workflows/ci_cd.yml @@ -109,7 +109,7 @@ jobs: - id: create_release name: Create Release - uses: softprops/action-gh-release@a06a81a03ee405af7f2048a818ed3f03bbf83c7b + uses: softprops/action-gh-release@60cfd9a691d814dcf0d094598101c5cb61cd1646 env: GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" with: From 2693af4dd759691f390b2be94c9da8870cc76da6 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 12 Dec 2025 03:33:13 +0000 Subject: [PATCH 72/78] Update actions/cache action to v5 (#81) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Xodium Dependencies Updater This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [actions/cache](https://redirect.github.com/actions/cache) | action | major | `v4.3.0` -> `v5.0.0` | --- ### Release Notes
actions/cache (actions/cache) ### [`v5.0.0`](https://redirect.github.com/actions/cache/compare/v4.3.0...v5.0.0) [Compare Source](https://redirect.github.com/actions/cache/compare/v4.3.0...v5.0.0)
--- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/XodiumSoftware/xbim). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/ci_cd.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci_cd.yml b/.github/workflows/ci_cd.yml index 89b02292..23e5e59b 100644 --- a/.github/workflows/ci_cd.yml +++ b/.github/workflows/ci_cd.yml @@ -27,7 +27,7 @@ jobs: - id: cache_deps name: Cache dependencies - uses: actions/cache@v4.3.0 + uses: actions/cache@v5.0.0 with: path: | ~/.cargo/registry From 4f926a0f72ddd90cd7debb5b9d183f4ce9c5afb6 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 12 Dec 2025 22:25:18 +0000 Subject: [PATCH 73/78] Update actions/cache action to v5.0.1 (#82) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Xodium Dependencies Updater This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [actions/cache](https://redirect.github.com/actions/cache) | action | patch | `v5.0.0` -> `v5.0.1` | --- ### Release Notes
actions/cache (actions/cache) ### [`v5.0.1`](https://redirect.github.com/actions/cache/compare/v5.0.0...v5.0.1) [Compare Source](https://redirect.github.com/actions/cache/compare/v5.0.0...v5.0.1)
--- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/XodiumSoftware/xbim). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/ci_cd.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci_cd.yml b/.github/workflows/ci_cd.yml index 23e5e59b..8734c63d 100644 --- a/.github/workflows/ci_cd.yml +++ b/.github/workflows/ci_cd.yml @@ -27,7 +27,7 @@ jobs: - id: cache_deps name: Cache dependencies - uses: actions/cache@v5.0.0 + uses: actions/cache@v5.0.1 with: path: | ~/.cargo/registry From 27b382e0c7867323a232cc40abfada4984be250d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 13 Dec 2025 01:09:45 +0000 Subject: [PATCH 74/78] Update GitHub Artifact Actions (major) (#83) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Xodium Dependencies Updater This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [actions/download-artifact](https://redirect.github.com/actions/download-artifact) | action | major | `v6.0.0` -> `v7.0.0` | | [actions/upload-artifact](https://redirect.github.com/actions/upload-artifact) | action | major | `v5.0.0` -> `v6.0.0` | --- ### Release Notes
actions/download-artifact (actions/download-artifact) ### [`v7.0.0`](https://redirect.github.com/actions/download-artifact/releases/tag/v7.0.0) [Compare Source](https://redirect.github.com/actions/download-artifact/compare/v6.0.0...v7.0.0) ##### v7 - What's new > \[!IMPORTANT] > actions/download-artifact\@​v7 now runs on Node.js 24 (`runs.using: node24`) and requires a minimum Actions Runner version of 2.327.1. If you are using self-hosted runners, ensure they are updated before upgrading. ##### Node.js 24 This release updates the runtime to Node.js 24. v6 had preliminary support for Node 24, however this action was by default still running on Node.js 20. Now this action by default will run on Node.js 24. ##### What's Changed - Update GHES guidance to include reference to Node 20 version by [@​patrikpolyak](https://redirect.github.com/patrikpolyak) in [#​440](https://redirect.github.com/actions/download-artifact/pull/440) - Download Artifact Node24 support by [@​salmanmkc](https://redirect.github.com/salmanmkc) in [#​415](https://redirect.github.com/actions/download-artifact/pull/415) - fix: update [@​actions/artifact](https://redirect.github.com/actions/artifact) to fix Node.js 24 punycode deprecation by [@​salmanmkc](https://redirect.github.com/salmanmkc) in [#​451](https://redirect.github.com/actions/download-artifact/pull/451) - prepare release v7.0.0 for Node.js 24 support by [@​salmanmkc](https://redirect.github.com/salmanmkc) in [#​452](https://redirect.github.com/actions/download-artifact/pull/452) ##### New Contributors - [@​patrikpolyak](https://redirect.github.com/patrikpolyak) made their first contribution in [#​440](https://redirect.github.com/actions/download-artifact/pull/440) - [@​salmanmkc](https://redirect.github.com/salmanmkc) made their first contribution in [#​415](https://redirect.github.com/actions/download-artifact/pull/415) **Full Changelog**:
actions/upload-artifact (actions/upload-artifact) ### [`v6.0.0`](https://redirect.github.com/actions/upload-artifact/compare/v5.0.0...v6.0.0) [Compare Source](https://redirect.github.com/actions/upload-artifact/compare/v5.0.0...v6.0.0)
--- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 👻 **Immortal**: This PR will be recreated if closed unmerged. Get [config help](https://redirect.github.com/renovatebot/renovate/discussions) if that's undesired. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/XodiumSoftware/xbim). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/ci_cd.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci_cd.yml b/.github/workflows/ci_cd.yml index 8734c63d..30101f59 100644 --- a/.github/workflows/ci_cd.yml +++ b/.github/workflows/ci_cd.yml @@ -59,7 +59,7 @@ jobs: - id: upload_artifact name: Upload Artifact - uses: actions/upload-artifact@v5.0.0 + uses: actions/upload-artifact@v6.0.0 with: name: xbim path: target/release/xbim @@ -98,7 +98,7 @@ jobs: steps: - id: download_artifact name: Download Artefact - uses: actions/download-artifact@v6.0.0 + uses: actions/download-artifact@v7.0.0 with: name: xbim From 535f391f108e3178ea61fccc9bdfeb90644fd681 Mon Sep 17 00:00:00 2001 From: Illyrius Date: Wed, 17 Dec 2025 12:23:59 +0100 Subject: [PATCH 75/78] Remove unused Database module and related references from app.rs and lib.rs Signed-off-by: Illyrius --- src/app.rs | 3 --- src/database.rs | 42 ------------------------------------------ src/lib.rs | 2 -- 3 files changed, 47 deletions(-) delete mode 100644 src/database.rs diff --git a/src/app.rs b/src/app.rs index e9cd8919..eb055000 100644 --- a/src/app.rs +++ b/src/app.rs @@ -1,4 +1,3 @@ -use crate::Database; use crate::footer::footer; use crate::login_form::LoginForm; use crate::menu::menu; @@ -15,8 +14,6 @@ pub struct App { current_username: String, #[serde(skip)] oauth_service: Option, - #[serde(skip)] - database: Option, } impl App { diff --git a/src/database.rs b/src/database.rs deleted file mode 100644 index 3e27b1cb..00000000 --- a/src/database.rs +++ /dev/null @@ -1,42 +0,0 @@ -use surrealdb::Surreal; - -#[derive(Clone)] -pub struct Database { - db: Surreal, -} - -impl Database { - pub async fn new() -> Result { - let db = Surreal::new::("xbim.db").await?; - db.use_ns("app").use_db("main").await?; - - Ok(Database { db }) - } - - pub async fn save_user(&self, username: &str) -> Result<(), surrealdb::Error> { - let _: Option = self - .db - .create("users") - .content(User { - username: username.to_string(), - }) - .await?; - Ok(()) - } - - pub async fn get_user(&self, username: &str) -> Result, surrealdb::Error> { - let users: Vec = self - .db - .query("SELECT * FROM users WHERE username = $username") - .bind(("username", username)) - .await? - .take(0)?; - - Ok(users.into_iter().next()) - } -} - -#[derive(Debug, serde::Serialize, serde::Deserialize)] -struct User { - username: String, -} diff --git a/src/lib.rs b/src/lib.rs index 551b31ed..30b02ba7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -8,9 +8,7 @@ mod components { mod services { pub mod oauth; } -mod database; pub use app::*; pub use components::*; -pub use database::*; pub use services::*; From f51c57092eaff8b1f4277a8fec77df715daf6501 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 20 Dec 2025 21:06:25 +0000 Subject: [PATCH 76/78] Update softprops/action-gh-release digest to 5122b4e (#84) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Xodium Dependencies Updater This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | softprops/action-gh-release | action | digest | `60cfd9a` -> `5122b4e` | --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/XodiumSoftware/xbim). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/ci_cd.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci_cd.yml b/.github/workflows/ci_cd.yml index 30101f59..17fb481a 100644 --- a/.github/workflows/ci_cd.yml +++ b/.github/workflows/ci_cd.yml @@ -109,7 +109,7 @@ jobs: - id: create_release name: Create Release - uses: softprops/action-gh-release@60cfd9a691d814dcf0d094598101c5cb61cd1646 + uses: softprops/action-gh-release@5122b4edc95f85501a71628a57dc180a03ec7588 env: GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" with: From 81032ef36ab80397c0215cabc98f20e26c2c47aa Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 25 Dec 2025 01:08:13 +0000 Subject: [PATCH 77/78] Update actions-rust-lang/setup-rust-toolchain digest to 806aa7d (#85) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Xodium Dependencies Updater This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | actions-rust-lang/setup-rust-toolchain | action | digest | `b598bed` -> `806aa7d` | --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/XodiumSoftware/xbim). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/ci_cd.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci_cd.yml b/.github/workflows/ci_cd.yml index 17fb481a..9be39e93 100644 --- a/.github/workflows/ci_cd.yml +++ b/.github/workflows/ci_cd.yml @@ -38,7 +38,7 @@ jobs: - id: setup_rust name: Setup Rust - uses: actions-rust-lang/setup-rust-toolchain@b598bed351cb8d159adfaa2ea4989c797082620f + uses: actions-rust-lang/setup-rust-toolchain@806aa7ddf5d59f36fb30048411f6bde29364a53f with: toolchain: stable components: rustfmt, clippy @@ -77,7 +77,7 @@ jobs: - id: setup_rust name: Setup Rust - uses: actions-rust-lang/setup-rust-toolchain@b598bed351cb8d159adfaa2ea4989c797082620f + uses: actions-rust-lang/setup-rust-toolchain@806aa7ddf5d59f36fb30048411f6bde29364a53f with: toolchain: stable From 068d6b00dc243c087948676bb3d180a3291231de Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 30 Dec 2025 21:01:00 +0000 Subject: [PATCH 78/78] Update Rust crate reqwest to 0.13.0 (#86) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Xodium Dependencies Updater This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [reqwest](https://redirect.github.com/seanmonstar/reqwest) | dependencies | minor | `0.12.24` → `0.13.0` | --- ### Release Notes
seanmonstar/reqwest (reqwest) ### [`v0.13.1`](https://redirect.github.com/seanmonstar/reqwest/blob/HEAD/CHANGELOG.md#v0131) [Compare Source](https://redirect.github.com/seanmonstar/reqwest/compare/v0.13.0...v0.13.1) - Fixes compiling with rustls on Android targets. ### [`v0.13.0`](https://redirect.github.com/seanmonstar/reqwest/blob/HEAD/CHANGELOG.md#v0130) [Compare Source](https://redirect.github.com/seanmonstar/reqwest/compare/v0.12.28...v0.13.0) - **Breaking changes**: - `rustls` is now the default TLS backend, instead of `native-tls`. - `rustls` crypto provider defaults to aws-lc instead of *ring*. (`rustls-no-provider` exists if you want a different crypto provider) - `rustls-tls` has been renamed to `rustls`. - rustls roots features removed, `rustls-platform-verifier` is used by default. - To use different roots, call `tls_certs_only(your_roots)`. - `native-tls` now includes ALPN. To disable, use `native-tls-no-alpn`. - `query` and `form` are now crate features, disabled by default. - Long-deprecated methods and crate features have been removed (such as `trust-dns`, which was renamed `hickory-dns` a while ago). - Many TLS-related methods renamed to improve autocompletion and discovery, but previous name left in place with a "soft" deprecation. (just documented, no warnings) - For example, prefer `tls_backend_rustls()` over `use_rustls_tls()`. #### v0.12.28 - Fix compiling on Windows if TLS and SOCKS features are not enabled. #### v0.12.27 - Add `ClientBuilder::windows_named_pipe(name)` option that will force all requests over that Windows Named Piper. #### v0.12.26 - Fix sending `Accept-Encoding` header only with values configured with reqwest, regardless of underlying tower-http config. #### v0.12.25 - Add `Error::is_upgrade()` to determine if the error was from an HTTP upgrade. - Fix sending `Proxy-Authorization` if only username is configured. - Fix sending `Proxy-Authorization` to HTTPS proxies when the target is HTTP. - Refactor internal decompression handling to use tower-http. #### v0.12.24 - Refactor cookie handling to an internal middleware. - Refactor internal random generator. - Refactor base64 encoding to reduce a copy. - Documentation updates. #### v0.12.23 - Add `ClientBuilder::unix_socket(path)` option that will force all requests over that Unix Domain Socket. - Add `ClientBuilder::retry(policy)` and `reqwest::retry::Builder` to configure automatic retries. - Add `ClientBuilder::dns_resolver2()` with more ergonomic argument bounds, allowing more resolver implementations. - Add `http3_*` options to `blocking::ClientBuilder`. - Fix default TCP timeout values to enabled and faster. - Fix SOCKS proxies to default to port 1080 - (wasm) Add cache methods to `RequestBuilder`. #### v0.12.22 - Fix socks proxies when resolving IPv6 destinations. #### v0.12.21 - Fix socks proxy to use `socks4a://` instead of `socks4h://`. - Fix `Error::is_timeout()` to check for hyper and IO timeouts too. - Fix request `Error` to again include URLs when possible. - Fix socks connect error to include more context. - (wasm) implement `Default` for `Body`. #### v0.12.20 - Add `ClientBuilder::tcp_user_timeout(Duration)` option to set `TCP_USER_TIMEOUT`. - Fix proxy headers only using the first matched proxy. - (wasm) Fix re-adding `Error::is_status()`. #### v0.12.19 - Fix redirect that changes the method to GET should remove payload headers. - Fix redirect to only check the next scheme if the policy action is to follow. - (wasm) Fix compilation error if `cookies` feature is enabled (by the way, it's a noop feature in wasm). #### v0.12.18 - Fix compilation when `socks` enabled without TLS. #### v0.12.17 - Fix compilation on macOS. #### v0.12.16 - Add `ClientBuilder::http3_congestion_bbr()` to enable BBR congestion control. - Add `ClientBuilder::http3_send_grease()` to configure whether to send use QUIC grease. - Add `ClientBuilder::http3_max_field_section_size()` to configure the maximum response headers. - Add `ClientBuilder::tcp_keepalive_interval()` to configure TCP probe interval. - Add `ClientBuilder::tcp_keepalive_retries()` to configure TCP probe count. - Add `Proxy::headers()` to add extra headers that should be sent to a proxy. - Fix `redirect::Policy::limit()` which had an off-by-1 error, allowing 1 more redirect than specified. - Fix HTTP/3 to support streaming request bodies. - (wasm) Fix null bodies when calling `Response::bytes_stream()`. #### v0.12.15 - Fix Windows to support both `ProxyOverride` and `NO_PROXY`. - Fix http3 to support streaming response bodies. - Fix http3 dependency from public API misuse. #### v0.12.14 - Fix missing `fetch_mode_no_cors()`, marking as deprecated when not on WASM. #### v0.12.13 - Add `Form::into_reader()` for blocking `multipart` forms. - Add `Form::into_stream()` for async `multipart` forms. - Add support for SOCKS4a proxies. - Fix decoding responses with multiple zstd frames. - Fix `RequestBuilder::form()` from overwriting a previously set `Content-Type` header, like the other builder methods. - Fix cloning of request timeout in `blocking::Request`. - Fix http3 synchronization of connection creation, reducing unneccesary extra connections. - Fix Windows system proxy to use `ProxyOverride` as a `NO_PROXY` value. - Fix blocking read to correctly reserve and zero read buffer. - (wasm) Add support for request timeouts. - (wasm) Fix `Error::is_timeout()` to return true when from a request timeout. #### v0.12.12 - (wasm) Fix compilation by not compiler `tokio/time` on WASM. #### v0.12.11 - Fix decompression returning an error when HTTP/2 ends with an empty data frame. #### v0.12.10 - Add `ClientBuilder::connector_layer()` to allow customizing the connector stack. - Add `ClientBuilder::http2_max_header_list_size()` option. - Fix propagating body size hint (`content-length`) information when wrapping bodies. - Fix decompression of chunked bodies so the connections can be reused more often. #### v0.12.9 - Add `tls::CertificateRevocationLists` support. - Add crate features to enable webpki roots without selecting a rustls provider. - Fix `connection_verbose()` to output read logs. - Fix `multipart::Part::file()` to automatically include content-length. - Fix proxy to internally no longer cache system proxy settings. #### v0.12.8 - Add support for SOCKS4 proxies. - Add `multipart::Form::file()` method for adding files easily. - Add `Body::wrap()` to wrap any `http_body::Body` type. - Fix the pool configuration to use a timer to remove expired connections. #### v0.12.7 - Revert adding `impl Service>` for `Client`. #### v0.12.6 - Add support for `danger_accept_invalid_hostnames` for `rustls`. - Add `impl Service>` for `Client` and `&'_ Client`. - Add support for `!Sync` bodies in `Body::wrap_stream()`. - Enable happy eyeballs when `hickory-dns` is used. - Fix `Proxy` so that `HTTP(S)_PROXY` values take precedence over `ALL_PROXY`. - Fix `blocking::RequestBuilder::header()` from unsetting `sensitive` on passed header values. #### v0.12.5 - Add `blocking::ClientBuilder::dns_resolver()` method to change DNS resolver in blocking client. - Add `http3` feature back, still requiring `reqwest_unstable`. - Add `rustls-tls-no-provider` Cargo feature to use rustls without a crypto provider. - Fix `Accept-Encoding` header combinations. - Fix http3 resolving IPv6 addresses. - Internal: upgrade to rustls 0.23. #### v0.12.4 - Add `zstd` support, enabled with `zstd` Cargo feature. - Add `ClientBuilder::read_timeout(Duration)`, which applies the duration for each read operation. The timeout resets after a successful read. #### v0.12.3 - Add `FromStr` for `dns::Name`. - Add `ClientBuilder::built_in_webpki_certs(bool)` to enable them separately. - Add `ClientBuilder::built_in_native_certs(bool)` to enable them separately. - Fix sending `content-length: 0` for GET requests. - Fix response body `content_length()` to return value when timeout is configured. - Fix `ClientBuilder::resolve()` to use lowercase domain names. #### v0.12.2 - Fix missing ALPN when connecting to socks5 proxy with rustls. - Fix TLS version limits with rustls. - Fix not detected ALPN h2 from server with native-tls. #### v0.12.1 - Fix `ClientBuilder::interface()` when no TLS is enabled. - Fix `TlsInfo::peer_certificate()` being truncated with rustls. - Fix panic if `http2` feature disabled but TLS negotiated h2 in ALPN. - Fix `Display` for `Error` to not include its source error.
--- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/XodiumSoftware/xbim). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index ba95a009..347b55aa 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -32,5 +32,5 @@ eframe = { version = "0.33.2", default-features = false, features = [ env_logger = "0.11.8" serde = { version = "1.0.228", features = ["derive"] } oauth2 = { version = "5.0.0", features = ["reqwest"] } -reqwest = { version = "0.12.24", features = ["json"] } +reqwest = { version = "0.13.0", features = ["json"] } surrealdb = "2.4.0"