-
-
Notifications
You must be signed in to change notification settings - Fork 884
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement email verification (fixes #219) #1956
Conversation
5f48865
to
c278055
Compare
c278055
to
c199215
Compare
Updated, works fine now in my testing. It will require some frontend changes though:
|
Run this to make sure your commit hooks are up to date, it missed an unwrap:
|
updated |
@@ -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; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pub enum ListingType {
All,
Local,
Subscribed,
Community,
}
I noticed in the DB the default is 1
or Local
, but when a new user registers, it uses subscribed. I spose subscribed is the better default here, so this is good.
// no email verification if the site is not setup yet | ||
let mut email_verification = false; | ||
|
||
// Make sure site has open registration | ||
if let Ok(site) = blocking(context.pool(), Site::read_simple).await? { | ||
if !site.open_registration { | ||
return Err(ApiError::err_plain("registration_closed").into()); | ||
} | ||
email_verification = site.require_email_verification; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of mut, you could probably do let email_verification = if let ...
// Log the user in directly if email verification is not required | ||
let jwt = if email_verification { | ||
send_verification_email( | ||
inserted_local_user.id, | ||
// we check at the beginning of this method that email is set | ||
&inserted_local_user.email.expect("email was provided"), | ||
&inserted_person.name, | ||
context, | ||
) | ||
.await?; | ||
None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good, I'll have to remember to create a translation string for "Your application has been sent" or something like that, for when jwt is None
on a register.
The other possibility is to add an optional application_sent: bool
field to LoginResponse. That might be more clear.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm doing the registration_application
stuff, and I also need to add a registration_sent: bool
for that too, so you might as well add one here for verify_email_sent
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did this now on my PR, so don't worry about this one.
Ok(LoginResponse { | ||
jwt: data.auth.to_owned(), | ||
}) | ||
Ok(LoginResponse { jwt: None }) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This never really made sense in the first place, and now we'll get conflicting responses. Could you create DeleteAccountResponse { success: bool }
below here.
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)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should also add a time filter to protect this... maybe a week? Example: https://github.com/LemmyNet/lemmy/blob/main/crates/db_schema/src/impls/password_reset_request.rs#L57
pub person_id: Option<PersonId>, | ||
pub password_encrypted: Option<String>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ignore that above.
// TODO: link should be replaced with a frontend route once that exists | ||
let verify_link = format!( | ||
"{}/api/v3/user/verify_email?token={}", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Go ahead and make it {}/verify_email?...
, I can start adding that front end soon.
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, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be removed. There should only be one email
field, on the local_user table.
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 | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add published.
.route("/unread_count", web::get().to(route_get::<GetUnreadCount>)), | ||
.route("/unread_count", web::get().to(route_get::<GetUnreadCount>)) | ||
// TODO: currently GET for easier testing, but should probably be POST | ||
.route("/verify_email", web::get().to(route_get::<VerifyEmail>)), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Go ahead and make POST, I can start working on the front end for this soon.
Don't force push to this, because I'll be working off it from another branch. |
show_read_posts: Some(true), | ||
show_new_post_notifs: Some(false), | ||
send_notifications_to_email: Some(false), | ||
email_verified: Some(!email_verification), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just noticed this too. If email_verification is false, this will incorrectly get set to true, when no email has been actually verified. This should just be Some(false)
pub person_id: Option<PersonId>, | ||
pub password_encrypted: Option<String>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ignore that above.
I'll close this as I've merged its work and some updates into #1949 |
very much wip