Rewrite README + use lettre crate to validate email address instead of regex
authorGreg Burri <greg.burri@gmail.com>
Thu, 16 Jan 2025 22:09:06 +0000 (23:09 +0100)
committerGreg Burri <greg.burri@gmail.com>
Thu, 16 Jan 2025 22:09:06 +0000 (23:09 +0100)
Cargo.lock
README.md
TODO.md
backend/src/services/user.rs
common/Cargo.toml
common/src/utils.rs
frontend/Cargo.toml
frontend/src/recipe_edit.rs

index 24c22c1..c9a4177 100644 (file)
@@ -440,7 +440,6 @@ checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990"
 name = "common"
 version = "0.1.0"
 dependencies = [
- "regex",
  "ron",
  "serde",
 ]
index 63d7f80..04bd2ca 100644 (file)
--- a/README.md
+++ b/README.md
@@ -1,59 +1,59 @@
-# Use cases
-
-## Create a recipe
-
-To create a recipe the user must have an account.
+# Technical
 
-* The user
-(A group is automatically created)
+## Backend
 
-## Create a groupe
+### Launch Axum
 
-## Move a group
+In directory '/backend' type:
+    $> cargo run
 
-## Delete a group
+Then browse http://127.0.0.1:8082 (You need to compile the wasm file first, see section 'Frontend')
 
-## Create a step
+At first launch the configuration file '/backend/conf.ron' is created. It contains the port the server will listen to and information about the SMTP server which will be used to send email when a user sign up or change its password.
 
-## Move a step
+### Autoreload
 
-## Delete a step
+First install cargo watch:
+    $> cargo install cargo-watch
 
-# Technical
+In directory '/backend' type:
+    $> cargo watch -x run
 
-## Cross-compilation on Windows 11
 
-The toolchain for Raspberry Pi 64 bits is available here: https://gnutoolchains.com/raspberry64/
+## Frontend
 
-## How to install service on RPI Zero
+### Tools needed
 
-1. Copy doc/recipes.service to /lib/systemd/system
-2. Enabled it: #> systemctl enable recipes
+nushell: https://www.nushell.sh/
+wasm-pack: https://github.com/rustwasm/wasm-pack
+wasm-opt: $> cargo install wasm-opt
 
-## Backend
+### Compilation
 
-Autoreload: https://actix.rs/docs/autoreload/
+In directory '/frontend' type:
+    $> nu deploy.nu
 
-### Frontend
+It will create the '/frontend/pkg' directory and copy the wasm file into '/backend/static'.
+You can now refresh your browser to reload the wasm file.
 
-## WebAssembly
+# How-to
 
-'frontend' project needs some tools to generate the WebAssembly stuff. Everything is explained here: https://rustwasm.github.io/wasm-bindgen/examples/hello-world.html
-TODO MVC Example:
-    https://github.com/rustwasm/wasm-bindgen/tree/main/examples/todomvc -> https://rustwasm.github.io/wasm-bindgen/exbuild/todomvc/#/
+## How to install service on a Linux server
 
-Javascript bundler: https://rspack.dev/
+As root:
 
-To compile run 'wasm-pack build' in 'frontend' directory
-To launch node run 'npm run start' in 'frontend/www' directory
+1. Copy '/doc/recipes.service' to '/lib/systemd/system/'
+2. Enabled it: #> systemctl enable recipes
+3. Launch it: #> systemctl start recipes
 
-## Useful URLs
+# Useful URLs
 
-* Rust patterns : https://github.com/rust-unofficial/patterns/tree/master/patterns
-* Node install: https://nodejs.org/en/download/
+* Rust patterns : https://github.com/rust-unofficial/patterns
+* Rust cheat Sheet: https://cheats.rs/
 
 
-# Tools
+# Useful tools
 
 Benchmarking: https://crates.io/crates/oha
-HTTP API tool: https://www.usebruno.com/
\ No newline at end of file
+HTTP API tool: https://www.usebruno.com/
+GUI Database client: https://dbeaver.io/
diff --git a/TODO.md b/TODO.md
index a8fc10d..4f59ace 100644 (file)
--- a/TODO.md
+++ b/TODO.md
@@ -1,14 +1,22 @@
+* FIX: when the event blur is triggered when changing page, the async process doesn't finish all the time
 * Check position of message error in profile/sign in/sign up with flex grid layout
 * Define the UI (mockups).
     * Two CSS: one for desktop and one for mobile
     * Use CSS flex/grid to define a good design/layout
-* Drag and drop of steps and groups to define their order
+* CSS for toast and modal dialog
 * Make a search page
+    Use FTS5:
+        https://sqlite.org/fts5.html
+        https://www.sqlitetutorial.net/sqlite-full-text-search/
 * Use of markdown for some field (how to add markdown as rinja filter?)
 * Quick search left panel by tags ?
 * Make the home page: Define what to display to the user
 * Show existing tags when editing a recipe
 
+[ok] Drag and drop of steps and groups to define their order
+[ok] Force tags in lowercase
+[ok] Remove the given language to recipe_edit and replace it by tr (like the header)
+    [ok] List only recipe of current language
 [ok] Add support to translations.
     * Make a Text database (a bit like d-lan.net) and think about translation.
     * The language is stored in cookie or in user profile if the user is connected
index 6695676..d01a422 100644 (file)
@@ -13,6 +13,7 @@ use axum_extra::extract::{
     Host,
 };
 use chrono::Duration;
+use lettre::Address;
 use rinja::Template;
 use serde::Deserialize;
 use tracing::{event, Level};
@@ -109,9 +110,7 @@ pub async fn sign_up_post(
     }
 
     // Validation of email and password.
-    if let common::utils::EmailValidation::NotValid =
-        common::utils::validate_email(&form_data.email)
-    {
+    if form_data.email.parse::<Address>().is_err() {
         return error_response(SignUpError::InvalidEmail, &form_data, user, tr);
     }
 
@@ -431,9 +430,7 @@ pub async fn ask_reset_password_post(
     }
 
     // Validation of email.
-    if let common::utils::EmailValidation::NotValid =
-        common::utils::validate_email(&form_data.email)
-    {
+    if form_data.email.parse::<Address>().is_err() {
         return error_response(
             AskResetPasswordError::InvalidEmail,
             &form_data.email,
@@ -721,9 +718,7 @@ pub async fn edit_user_post(
             .into_response())
         }
 
-        if let common::utils::EmailValidation::NotValid =
-            common::utils::validate_email(&form_data.email)
-        {
+        if form_data.email.parse::<Address>().is_err() {
             return error_response(ProfileUpdateError::InvalidEmail, &form_data, user, tr);
         }
 
index 871cd85..efb39b9 100644 (file)
@@ -5,7 +5,5 @@ authors = ["GrĂ©gory Burri <greg.burri@gmail.com>"]
 edition = "2021"
 
 [dependencies]
-regex = "1"
-
 ron = "0.8"
 serde = { version = "1.0", features = ["derive"] }
index 0b598cf..8b24810 100644 (file)
@@ -1,29 +1,5 @@
-use std::sync::LazyLock;
-
-use regex::Regex;
-
 use crate::consts;
 
-pub enum EmailValidation {
-    Ok,
-    NotValid,
-}
-
-static EMAIL_REGEX: LazyLock<Regex> = LazyLock::new(|| {
-    Regex::new(
-        r"^([a-z0-9_+]([a-z0-9_+.]*[a-z0-9_+])?)@([a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,6})",
-    )
-    .expect("Error parsing email regex")
-});
-
-pub fn validate_email(email: &str) -> EmailValidation {
-    if EMAIL_REGEX.is_match(email) {
-        EmailValidation::Ok
-    } else {
-        EmailValidation::NotValid
-    }
-}
-
 pub enum PasswordValidation {
     Ok,
     TooShort,
index affb787..7c9f8b8 100644 (file)
@@ -51,5 +51,7 @@ gloo = "0.11"
 # code size when deploying.
 console_error_panic_hook = { version = "0.1", optional = true }
 
-[package.metadata.wasm-pack.profile.release]
-wasm-opt = false
+# wasm-opt is used by default: https://docs.rs/wasm-opt/latest/wasm_opt/
+# Uncomment the following lines to disable it.
+# [package.metadata.wasm-pack.profile.release]
+# wasm-opt = false
index de4b26f..5fe5d13 100644 (file)
@@ -1,7 +1,6 @@
 use std::{cell::RefCell, rc, sync::Mutex};
 
 use gloo::{
-    console::log,
     events::{EventListener, EventListenerOptions},
     net::http::Request,
     utils::{document, window},