Skip to content

Commit

Permalink
feat(db): Implement password reset DAO (#1456)
Browse files Browse the repository at this point in the history
* feat(db, webserver): Implement password reset flow

* [autofix.ci] apply automated fixes

* Remove webserver logic from this PR

* Use ID instead of email

* Create delete_expired_password_reset

* Rename id to user_id

* Add rowid

* Rename parameters

* Rename db methods

* Unrename one db method

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
  • Loading branch information
boxbeam and autofix-ci[bot] authored Feb 15, 2024
1 parent 904ebbe commit 76f733b
Show file tree
Hide file tree
Showing 7 changed files with 86 additions and 0 deletions.
1 change: 1 addition & 0 deletions ee/tabby-db/migrations/0014_password-reset.down.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
DROP TABLE password_reset;
6 changes: 6 additions & 0 deletions ee/tabby-db/migrations/0014_password-reset.up.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
CREATE TABLE password_reset(
id INTEGER PRIMARY KEY AUTOINCREMENT,
user_id INTEGER NOT NULL UNIQUE,
code VARCHAR(36) NOT NULL,
created_at TIMESTAMP NOT NULL DEFAULT (DATETIME('now'))
);
Binary file modified ee/tabby-db/schema.sqlite
Binary file not shown.
1 change: 1 addition & 0 deletions ee/tabby-db/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ mod github_oauth_credential;
mod google_oauth_credential;
mod invitations;
mod job_runs;
mod password_reset;
mod path;
mod refresh_tokens;
mod repositories;
Expand Down
58 changes: 58 additions & 0 deletions ee/tabby-db/src/password_reset.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
use anyhow::Result;
use chrono::{DateTime, Duration, Utc};
use sqlx::{prelude::FromRow, query};
use uuid::Uuid;

use crate::DbConn;

#[derive(FromRow)]
pub struct PasswordResetDAO {
pub user_id: i32,
pub code: String,
pub created_at: DateTime<Utc>,
}

impl DbConn {
pub async fn create_password_reset(&self, user_id: i32) -> Result<String> {
let code = Uuid::new_v4().to_string();
let time = Utc::now();
query!(
"INSERT INTO password_reset (user_id, code, created_at) VALUES ($1, $2, $3)
ON CONFLICT(user_id) DO UPDATE SET code= $2, created_at = $3;",
user_id,
code,
time
)
.execute(&self.pool)
.await?;
Ok(code)
}

pub async fn delete_password_reset_by_user_id(&self, user_id: i32) -> Result<()> {
query!("DELETE FROM password_reset WHERE user_id = ?", user_id)
.execute(&self.pool)
.await?;
Ok(())
}

pub async fn get_password_reset_by_user_id(
&self,
user_id: i32,
) -> Result<Option<PasswordResetDAO>> {
let password_reset = sqlx::query_as(
"SELECT user_id, code, created_at FROM password_reset WHERE user_id = ?;",
)
.bind(user_id)
.fetch_optional(&self.pool)
.await?;
Ok(password_reset)
}

pub async fn delete_expired_password_resets(&self) -> Result<()> {
let time = Utc::now() - Duration::hours(1);
query!("DELETE FROM password_reset WHERE created_at < ?", time)
.execute(&self.pool)
.await?;
Ok(())
}
}
11 changes: 11 additions & 0 deletions ee/tabby-db/src/users.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,17 @@ impl DbConn {
Ok(())
}
}

pub async fn update_user_password(&self, id: i32, password_encrypted: String) -> Result<()> {
query!(
"UPDATE users SET password_encrypted = ? WHERE id = ?",
password_encrypted,
id
)
.execute(&self.pool)
.await?;
Ok(())
}
}

fn generate_auth_token() -> String {
Expand Down
9 changes: 9 additions & 0 deletions ee/tabby-webserver/email_templates/password_reset.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
Reset your Tabby password
---
You recently requested a password reset for your TabbyML account {{EMAIL}}. Please click the link below to reset your password.

{{EXTERNAL_URL}}/passwordReset?code={{CODE}}

Best regards,

The Tabby Team

0 comments on commit 76f733b

Please sign in to comment.