Rewrite README + use lettre crate to validate email address instead of regex

This commit is contained in:
Greg Burri 2025-01-16 23:09:06 +01:00
parent 67e13d9074
commit 65489e7692
8 changed files with 62 additions and 85 deletions

1
Cargo.lock generated
View file

@ -440,7 +440,6 @@ checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990"
name = "common"
version = "0.1.0"
dependencies = [
"regex",
"ron",
"serde",
]

View file

@ -1,59 +1,59 @@
# Use cases
## Create a recipe
To create a recipe the user must have an account.
* The user
(A group is automatically created)
## Create a groupe
## Move a group
## Delete a group
## Create a step
## Move a step
## Delete a step
# Technical
## Cross-compilation on Windows 11
The toolchain for Raspberry Pi 64 bits is available here: https://gnutoolchains.com/raspberry64/
## How to install service on RPI Zero
1. Copy doc/recipes.service to /lib/systemd/system
2. Enabled it: #> systemctl enable recipes
## Backend
Autoreload: https://actix.rs/docs/autoreload/
### Launch Axum
### Frontend
In directory '/backend' type:
$> cargo run
## WebAssembly
Then browse http://127.0.0.1:8082 (You need to compile the wasm file first, see section 'Frontend')
'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/#/
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.
Javascript bundler: https://rspack.dev/
### Autoreload
To compile run 'wasm-pack build' in 'frontend' directory
To launch node run 'npm run start' in 'frontend/www' directory
First install cargo watch:
$> cargo install cargo-watch
## Useful URLs
* Rust patterns : https://github.com/rust-unofficial/patterns/tree/master/patterns
* Node install: https://nodejs.org/en/download/
In directory '/backend' type:
$> cargo watch -x run
# Tools
## Frontend
### Tools needed
nushell: https://www.nushell.sh/
wasm-pack: https://github.com/rustwasm/wasm-pack
wasm-opt: $> cargo install wasm-opt
### Compilation
In directory '/frontend' type:
$> nu deploy.nu
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.
# How-to
## How to install service on a Linux server
As root:
1. Copy '/doc/recipes.service' to '/lib/systemd/system/'
2. Enabled it: #> systemctl enable recipes
3. Launch it: #> systemctl start recipes
# Useful URLs
* Rust patterns : https://github.com/rust-unofficial/patterns
* Rust cheat Sheet: https://cheats.rs/
# Useful tools
Benchmarking: https://crates.io/crates/oha
HTTP API tool: https://www.usebruno.com/
HTTP API tool: https://www.usebruno.com/
GUI Database client: https://dbeaver.io/

10
TODO.md
View file

@ -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

View 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);
}

View 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"] }

View 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,

View 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

View 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},