diff --git a/migrations/0_create-table.sql b/migrations/0_create-table.sql index 39386cb..6e81813 100644 --- a/migrations/0_create-table.sql +++ b/migrations/0_create-table.sql @@ -18,29 +18,6 @@ CREATE TABLE IF NOT EXISTS `users_passwords` ( `hashed_pass` VARCHAR(255) NOT NULL ); -CREATE TABLE IF NOT EXISTS `mail_verifications` ( - `request_id` INT AUTO_INCREMENT PRIMARY KEY, - `email` VARCHAR(255) NOT NULL, - `token` VARCHAR(255) NOT NULL, - `created_at` DATETIME DEFAULT CURRENT_TIMESTAMP -); - -CREATE TABLE IF NOT EXISTS `put_mail_varifications` ( - `request_id` INT AUTO_INCREMENT PRIMARY KEY, - `user_id` INT NOT NULL, - `email` VARCHAR(255) NOT NULL, - `token` VARCHAR(255) NOT NULL, - `created_at` DATETIME DEFAULT CURRENT_TIMESTAMP -); - -CREATE TABLE IF NOT EXISTS `reset_passwords` ( - `request_id` INT AUTO_INCREMENT PRIMARY KEY, - `email` VARCHAR(255) NOT NULL, - `token` VARCHAR(255) NOT NULL, - `created_at` DATETIME DEFAULT CURRENT_TIMESTAMP -); - - CREATE TABLE IF NOT EXISTS `normal_problems` ( `problem_id` INT AUTO_INCREMENT PRIMARY KEY, `auther_id` INT NOT NULL, diff --git a/src/handler/authentication.rs b/src/handler/authentication.rs index 3637b13..f51ae42 100644 --- a/src/handler/authentication.rs +++ b/src/handler/authentication.rs @@ -20,7 +20,7 @@ pub async fn sign_up_request( .map_err(|_| StatusCode::BAD_REQUEST)?; let jwt = state - .save_email_varifications(&body.email) + .encode_email_signup_jwt(&body.email) .await .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?; diff --git a/src/repository.rs b/src/repository.rs index b8f4156..a7536bb 100644 --- a/src/repository.rs +++ b/src/repository.rs @@ -4,9 +4,8 @@ use sqlx::{ MySqlPool, }; -mod signup_jwt; +mod jwt; pub mod users; -mod users_jwt; mod users_session; #[derive(Clone)] diff --git a/src/repository/jwt.rs b/src/repository/jwt.rs new file mode 100644 index 0000000..49ca0c3 --- /dev/null +++ b/src/repository/jwt.rs @@ -0,0 +1,77 @@ +use anyhow::Ok; +use async_session::chrono::{Duration, Utc}; +use serde::{Deserialize, Serialize}; + +use super::Repository; + +#[allow(non_camel_case_types)] +#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)] +enum Action { + reset_password, + change_email, + register_email, +} + +#[derive(Serialize, Deserialize)] +struct EmailToken { + exp: i64, + iat: i64, + nbf: i64, + user_id: Option, + email: String, + action: Action, +} + +impl EmailToken { + fn to_jwt(&self) -> anyhow::Result { + let encode_key: String = std::env::var("JWT_SECRET")?; + + let jwt = jsonwebtoken::encode( + &jsonwebtoken::Header::default(), + &self, + &jsonwebtoken::EncodingKey::from_secret(encode_key.as_ref()), + )?; + + Ok(jwt) + } +} + +impl Repository { + pub async fn encode_email_update_jwt( + &self, + user_id: i64, + email: &str, + ) -> anyhow::Result { + let exp = (Utc::now() + Duration::minutes(60)).timestamp(); + let iat = Utc::now().timestamp(); + let nbf = Utc::now().timestamp(); + + let claims = EmailToken { + exp, + iat, + nbf, + user_id: Some(user_id), + email: email.to_owned(), + action: Action::change_email, + }; + + claims.to_jwt() + } + + pub async fn encode_email_signup_jwt(&self, email: &str) -> anyhow::Result { + let exp = (Utc::now() + Duration::minutes(60)).timestamp(); + let iat = Utc::now().timestamp(); + let nbf = Utc::now().timestamp(); + + let claims = EmailToken { + exp, + iat, + nbf, + user_id: None, + email: email.to_owned(), + action: Action::register_email, + }; + + claims.to_jwt() + } +} diff --git a/src/repository/signup_jwt.rs b/src/repository/signup_jwt.rs deleted file mode 100644 index e1c275b..0000000 --- a/src/repository/signup_jwt.rs +++ /dev/null @@ -1,42 +0,0 @@ -use async_session::chrono::{Duration, Utc}; -use serde::{Deserialize, Serialize}; - -use super::Repository; - -impl Repository { - pub async fn save_email_varifications(&self, email: &str) -> anyhow::Result { - let jwt = encode_jwt_from_email(email)?; - - sqlx::query("INSERT INTO mail_verifications (email, token) VALUES (?, ?)") - .bind(email) - .bind(&jwt) - .execute(&self.pool) - .await?; - - Ok(jwt) - } -} - -#[derive(Serialize, Deserialize)] -struct SignupClaims { - email: String, - exp: i64, -} - -fn encode_jwt_from_email(email: &str) -> anyhow::Result { - let exp = (Utc::now() + Duration::minutes(60)).timestamp(); - let claims = SignupClaims { - email: email.to_owned(), - exp, - }; - - let encode_key = std::env::var("JWT_SECRET")?; - - let jwt = jsonwebtoken::encode( - &jsonwebtoken::Header::default(), - &claims, - &jsonwebtoken::EncodingKey::from_secret(encode_key.as_ref()), - )?; - - Ok(jwt) -} diff --git a/src/repository/users_jwt.rs b/src/repository/users_jwt.rs deleted file mode 100644 index 74a515d..0000000 --- a/src/repository/users_jwt.rs +++ /dev/null @@ -1,36 +0,0 @@ -use async_session::chrono::{Duration, Utc}; -use serde::{Deserialize, Serialize}; - -use super::Repository; - -#[derive(Serialize, Deserialize)] -struct SignupClaims { - user_id: i64, - email: String, - exp: i64, -} - -impl Repository { - pub async fn encode_email_update_jwt( - &self, - user_id: i64, - email: &str, - ) -> anyhow::Result { - let exp = (Utc::now() + Duration::minutes(60)).timestamp(); - let claims = SignupClaims { - user_id, - email: email.to_owned(), - exp, - }; - - let encode_key: String = std::env::var("JWT_SECRET")?; - - let jwt = jsonwebtoken::encode( - &jsonwebtoken::Header::default(), - &claims, - &jsonwebtoken::EncodingKey::from_secret(encode_key.as_ref()), - )?; - - Ok(jwt) - } -}