diff options
author | Yorhel <git@yorhel.nl> | 2019-10-03 17:33:33 +0200 |
---|---|---|
committer | Yorhel <git@yorhel.nl> | 2019-10-03 17:33:35 +0200 |
commit | 3f7769d2ba4047e8766e511b7a42c7aa4721f6f8 (patch) | |
tree | fb3263931645793e280f30e1bce0271281b496b6 /lib | |
parent | 0965af5fd74cf53503bb7ae0262d31c25f894385 (diff) |
Require email confirmation when changing email address
This ensures that the email address linked to a user is always valid and
actually belong(s|ed) to that user.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/VNWeb/Auth.pm | 18 | ||||
-rw-r--r-- | lib/VNWeb/Elm.pm | 1 | ||||
-rw-r--r-- | lib/VNWeb/User/Edit.pm | 53 |
3 files changed, 62 insertions, 10 deletions
diff --git a/lib/VNWeb/Auth.pm b/lib/VNWeb/Auth.pm index 0b43074a..7143f203 100644 --- a/lib/VNWeb/Auth.pm +++ b/lib/VNWeb/Auth.pm @@ -238,13 +238,17 @@ sub setpass { } -# Change a users' password, requires that the current logged in user is an admin. -sub admin_setpass { - my($self, $uid, $pass) = @_; - my $encpass = $self->_preparepass($pass); - tuwf->dbVali(select => - sql_func user_admin_setpass => \$uid, \$self->{uid}, sql_fromhex($self->{token}), sql_fromhex($encpass) - ) +sub setmail_token { + my($self, $mail) = @_; + my $token = unpack 'H*', urandom(20); + tuwf->dbExeci(select => sql_func user_setmail_token => \$self->uid, sql_fromhex($self->token), sql_fromhex(sha1_hex lc $token), \$mail); + $token; +} + + +sub setmail_confirm { + my(undef, $uid, $token) = @_; + tuwf->dbVali(select => sql_func user_setmail_confirm => \$uid, sql_fromhex sha1_hex lc $token); } diff --git a/lib/VNWeb/Elm.pm b/lib/VNWeb/Elm.pm index 78fad8c8..e83faf25 100644 --- a/lib/VNWeb/Elm.pm +++ b/lib/VNWeb/Elm.pm @@ -45,6 +45,7 @@ my %apis = ( DoubleEmail => [], # Account with same email already exists DoubleIP => [], # Account with same IP already exists BadCurPass => [], # Current password is incorrect when changing password + MailChange => [], # A confirmation mail has been sent to change a user's email address ); diff --git a/lib/VNWeb/User/Edit.pm b/lib/VNWeb/User/Edit.pm index 8b1f1ea2..4e67bf4e 100644 --- a/lib/VNWeb/User/Edit.pm +++ b/lib/VNWeb/User/Edit.pm @@ -34,6 +34,11 @@ my $FORM = form_compile in => { elm_form UserEdit => undef, $FORM; +sub _getmail { + my $uid = shift; + tuwf->dbVali(select => sql_func user_getmail => \$uid, \auth->uid, sql_fromhex auth->token); +} + TUWF::get qr{/$RE{uid}/edit}, sub { my $u = tuwf->dbRowi(q{ SELECT id, username, perm, ign_votes, hide_list, show_nsfw, traits_sexual, @@ -43,7 +48,7 @@ TUWF::get qr{/$RE{uid}/edit}, sub { return tuwf->resNotFound if !can_edit u => $u; - $u->{email} = tuwf->dbVali(select => sql_func user_getmail => \$u->{id}, \auth->uid, sql_fromhex auth->token); + $u->{email} = _getmail $u->{id}; $u->{authmod} = auth->permUsermod; $u->{password} = undef; $u->{skin} ||= config->{skin_default}; @@ -65,6 +70,8 @@ TUWF::get qr{/$RE{uid}/edit}, sub { json_api qr{/u/edit}, $FORM, sub { my $data = shift; + my $username = tuwf->dbVali('SELECT username FROM users WHERE id =', \$data->{id}); + return tuwf->resNotFound if !$username; return elm_Unauth if !can_edit u => $data; if(auth->permUsermod) { @@ -88,12 +95,52 @@ json_api qr{/u/edit}, $FORM, sub { } } - tuwf->dbExeci(select => sql_func user_setmail => \$data->{id}, \auth->uid, sql_fromhex(auth->token), \$data->{email}); + my $ret = \&elm_Success; + + my $oldmail = _getmail $data->{id}; + if($data->{email} ne $oldmail) { + if(auth->permUsermod) { + tuwf->dbExeci(select => sql_func user_admin_setmail => \$data->{id}, \auth->uid, sql_fromhex(auth->token), \$data->{email}); + } else { + my $token = auth->setmail_token($data->{email}); + my $body = sprintf + "Hello %s," + ."\n\n" + ."To confirm that you want to change the email address associated with your VNDB.org account from %s to %s, click the link below:" + ."\n\n" + ."%s" + ."\n\n" + ."vndb.org", + $username, $oldmail, $data->{email}, tuwf->reqBaseURI()."/u$data->{id}/setmail/$token"; + + tuwf->mail($body, + To => $data->{email}, + From => 'VNDB <noreply@vndb.org>', + Subject => "Confirm e-mail change for $username", + ); + $ret = \&elm_MailChange; + } + } $data->{skin} = '' if $data->{skin} eq config->{skin_default}; auth->prefSet($_, $data->{$_}, $data->{id}) for qw/hide_list show_nsfw traits_sexual tags_all tags_cont tags_ero tags_tech spoilers skin customcss/; - elm_Success + $ret->(); +}; + + +TUWF::get qr{/$RE{uid}/setmail/(?<token>[a-f0-9]{40})}, sub { + my $success = auth->setmail_confirm(tuwf->capture('id'), tuwf->capture('token')); + my $title = $success ? 'E-mail confirmed' : 'Error confirming email'; + framework_ title => $title, index => 0, sub { + div_ class => 'mainbox', sub { + h1_ $title; + div_ class => $success ? 'notice' : 'warning', sub { + p_ "Your e-mail address has been updated!" if $success; + p_ "Invalid or expired confirmation link." if !$success; + }; + }; + }; }; 1; |