mirror of https://github.com/LemmyNet/lemmy
Implement email verification (fixes #219)
parent
97b8b9c255
commit
c199215355
@ -0,0 +1,39 @@
|
||||
use crate::{source::email_verification::*, traits::Crud};
|
||||
use diesel::{insert_into, result::Error, ExpressionMethods, PgConnection, QueryDsl, RunQueryDsl};
|
||||
|
||||
impl Crud for EmailVerification {
|
||||
type Form = EmailVerificationForm;
|
||||
type IdType = i32;
|
||||
fn create(conn: &PgConnection, form: &EmailVerificationForm) -> Result<Self, Error> {
|
||||
use crate::schema::email_verification::dsl::*;
|
||||
insert_into(email_verification)
|
||||
.values(form)
|
||||
.get_result::<Self>(conn)
|
||||
}
|
||||
|
||||
fn read(conn: &PgConnection, id_: i32) -> Result<Self, Error> {
|
||||
use crate::schema::email_verification::dsl::*;
|
||||
email_verification.find(id_).first::<Self>(conn)
|
||||
}
|
||||
|
||||
fn update(conn: &PgConnection, id_: i32, form: &EmailVerificationForm) -> Result<Self, Error> {
|
||||
use crate::schema::email_verification::dsl::*;
|
||||
diesel::update(email_verification.find(id_))
|
||||
.set(form)
|
||||
.get_result::<Self>(conn)
|
||||
}
|
||||
|
||||
fn delete(conn: &PgConnection, id_: i32) -> Result<usize, Error> {
|
||||
use crate::schema::email_verification::dsl::*;
|
||||
diesel::delete(email_verification.find(id_)).execute(conn)
|
||||
}
|
||||
}
|
||||
|
||||
impl EmailVerification {
|
||||
pub fn read_for_token(conn: &PgConnection, token: &str) -> Result<Self, Error> {
|
||||
use crate::schema::email_verification::dsl::*;
|
||||
email_verification
|
||||
.filter(verification_token.eq(token))
|
||||
.first::<Self>(conn)
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
use crate::{newtypes::LocalUserId, schema::email_verification};
|
||||
|
||||
#[derive(Queryable, Identifiable, Clone)]
|
||||
#[table_name = "email_verification"]
|
||||
pub struct EmailVerification {
|
||||
pub id: i32,
|
||||
pub local_user_id: LocalUserId,
|
||||
pub email: String,
|
||||
pub verification_code: String,
|
||||
}
|
||||
|
||||
#[derive(Insertable, AsChangeset)]
|
||||
#[table_name = "email_verification"]
|
||||
pub struct EmailVerificationForm {
|
||||
pub local_user_id: LocalUserId,
|
||||
pub email: String,
|
||||
pub verification_token: String,
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
use crate::LemmyContext;
|
||||
use lemmy_api_common::blocking;
|
||||
use lemmy_db_schema::{
|
||||
newtypes::LocalUserId,
|
||||
source::email_verification::{EmailVerification, EmailVerificationForm},
|
||||
traits::Crud,
|
||||
};
|
||||
use lemmy_utils::{email::send_email, utils::generate_random_string, ApiError, LemmyError};
|
||||
|
||||
pub async fn send_verification_email(
|
||||
local_user_id: LocalUserId,
|
||||
new_email: &str,
|
||||
username: &str,
|
||||
context: &LemmyContext,
|
||||
) -> Result<(), LemmyError> {
|
||||
let settings = context.settings();
|
||||
let form = EmailVerificationForm {
|
||||
local_user_id,
|
||||
email: new_email.to_string(),
|
||||
verification_token: generate_random_string(),
|
||||
};
|
||||
// TODO: link should be replaced with a frontend route once that exists
|
||||
let verify_link = format!(
|
||||
"{}/api/v3/user/verify_email?token={}",
|
||||
settings.get_protocol_and_hostname(),
|
||||
&form.verification_token
|
||||
);
|
||||
blocking(context.pool(), move |conn| {
|
||||
EmailVerification::create(conn, &form)
|
||||
})
|
||||
.await??;
|
||||
|
||||
let subject = format!("Verify your email address for {}", settings.hostname);
|
||||
let body = format!(
|
||||
concat!(
|
||||
"Please click the link below to verify your email address ",
|
||||
"for the account @{}@{}. Ignore this email if the account isn't yours.\n\n",
|
||||
"<a href=\"{}\"></a>"
|
||||
),
|
||||
username, settings.hostname, verify_link
|
||||
);
|
||||
send_email(&subject, new_email, username, &body, &context.settings())
|
||||
.map_err(|e| ApiError::err("email_send_failed", e))?;
|
||||
|
||||
Ok(())
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
-- revert defaults from db for local user init
|
||||
alter table local_user alter column theme set default 'darkly';
|
||||
alter table local_user alter column default_listing_type set default 1;
|
||||
|
||||
-- remove tables and columns for optional email verification
|
||||
alter table site drop column require_email_verification;
|
||||
alter table local_user drop column email_verified;
|
||||
drop table email_verification;
|
@ -0,0 +1,15 @@
|
||||
-- use defaults from db for local user init
|
||||
alter table local_user alter column theme set default 'browser';
|
||||
alter table local_user alter column default_listing_type set default 2;
|
||||
|
||||
-- add tables and columns for optional email verification
|
||||
alter table site add column require_email_verification boolean not null default false;
|
||||
alter table local_user add column email_verified boolean not null default false;
|
||||
|
||||
create table email_verification (
|
||||
id serial primary key,
|
||||
local_user_id int references local_user(id) on update cascade on delete cascade not null,
|
||||
email text not null,
|
||||
verification_token text not null
|
||||
|
||||
);
|
Loading…
Reference in New Issue