diff options
author | Yorhel <git@yorhel.nl> | 2019-10-01 16:44:09 +0200 |
---|---|---|
committer | Yorhel <git@yorhel.nl> | 2019-10-01 16:46:14 +0200 |
commit | 1a9a4b4bdb8f3b6d7d0ad12032c17c44a8287a09 (patch) | |
tree | 7d5082d95647de2bdfa87c99eb68488d293da923 /lib/VNWeb/User | |
parent | 9fd566e41a5a187c104de6869e9583ea5a19585c (diff) |
Minor refactor: Actually, let's split up RegReset.pm
This way we have a 1-to-1 mapping between VNWeb::* stuff and elm/
modules, which makes it much easier to see which code belongs to what.
I did add a VNWeb::User::Edit stub for definitions that can be re-used
among the small forms.
Diffstat (limited to 'lib/VNWeb/User')
-rw-r--r-- | lib/VNWeb/User/Edit.pm | 12 | ||||
-rw-r--r-- | lib/VNWeb/User/Login.pm | 13 | ||||
-rw-r--r-- | lib/VNWeb/User/PassReset.pm | 42 | ||||
-rw-r--r-- | lib/VNWeb/User/PassSet.pm | 40 | ||||
-rw-r--r-- | lib/VNWeb/User/RegReset.pm | 143 | ||||
-rw-r--r-- | lib/VNWeb/User/Register.pm | 59 |
6 files changed, 157 insertions, 152 deletions
diff --git a/lib/VNWeb/User/Edit.pm b/lib/VNWeb/User/Edit.pm new file mode 100644 index 00000000..96945d0c --- /dev/null +++ b/lib/VNWeb/User/Edit.pm @@ -0,0 +1,12 @@ +package VNWeb::User::Edit; + +use VNWeb::Prelude; + +# Some validations in this form are also used by Login.elm, PassReset.elm, PassSet.elm and Register.elm +elm_form UserEdit => undef, form_compile(in => { + email => { email => 1 }, + password => { password => 1 }, + username => { username => 1 }, +}); + +1; diff --git a/lib/VNWeb/User/Login.pm b/lib/VNWeb/User/Login.pm index bd8f75ab..160e6d99 100644 --- a/lib/VNWeb/User/Login.pm +++ b/lib/VNWeb/User/Login.pm @@ -3,14 +3,6 @@ package VNWeb::User::Login; use VNWeb::Prelude; -my $LOGIN = form_compile in => { - username => { username => 1 }, - password => { password => 1 } -}; - -elm_form UserLogin => $LOGIN, $LOGIN; - - TUWF::get '/u/login' => sub { return tuwf->resRedirect('/', 'temp') if auth; @@ -23,7 +15,10 @@ TUWF::get '/u/login' => sub { }; -json_api '/u/login', $LOGIN, sub { +json_api '/u/login', { + username => { username => 1 }, + password => { password => 1 } +}, sub { my $data = shift; my $ip = norm_ip tuwf->reqIP; diff --git a/lib/VNWeb/User/PassReset.pm b/lib/VNWeb/User/PassReset.pm new file mode 100644 index 00000000..0037fdff --- /dev/null +++ b/lib/VNWeb/User/PassReset.pm @@ -0,0 +1,42 @@ +package VNWeb::User::PassReset; + +use VNWeb::Prelude; + +TUWF::get '/u/newpass' => sub { + return tuwf->resRedirect('/', 'temp') if auth; + framework_ title => 'Password reset', index => 0, sub { + elm_ 'User.PassReset'; + }; +}; + + +json_api '/u/newpass', { + email => { email => 1 }, +}, sub { + my $data = shift; + + my($id, $token) = auth->resetpass($data->{email}); + return elm_BadEmail if !$id; + + my $name = tuwf->dbVali('SELECT username FROM users WHERE id =', \$id); + my $body = sprintf + "Hello %s," + ."\n\n" + ."Your VNDB.org login has been disabled, you can now set a new password by following the link below:" + ."\n\n" + ."%s" + ."\n\n" + ."Now don't forget your password again! :-)" + ."\n\n" + ."vndb.org", + $name, tuwf->reqBaseURI()."/u$id/setpass/$token"; + + tuwf->mail($body, + To => $data->{email}, + From => 'VNDB <noreply@vndb.org>', + Subject => "Password reset for $name", + ); + elm_Success +}; + +1; diff --git a/lib/VNWeb/User/PassSet.pm b/lib/VNWeb/User/PassSet.pm new file mode 100644 index 00000000..940b84bf --- /dev/null +++ b/lib/VNWeb/User/PassSet.pm @@ -0,0 +1,40 @@ +package VNWeb::User::PassSet; + +use VNWeb::Prelude; + + +# Compatibility with old the URL format +TUWF::get qr{/$RE{uid}/setpass}, sub { tuwf->resRedirect(sprintf('/u%d/setpass/%s', tuwf->capture('id'), tuwf->reqGet('t')||''), 'temp') }; + + +my $reset_url = qr{/$RE{uid}/setpass/(?<token>[a-f0-9]{40})}; + +TUWF::get $reset_url, sub { + return tuwf->resRedirect('/', 'temp') if auth; + + my $id = tuwf->capture('id'); + my $token = tuwf->capture('token'); + my $name = tuwf->dbVali('SELECT username FROM users WHERE id =', \$id); + + return tuwf->resNotFound if !$name || !auth->isvalidtoken($id, $token); + + framework_ title => 'Set password', index => 0, sub { + elm_ 'User.PassSet', tuwf->compile({}), tuwf->reqPath; + }; +}; + + +json_api $reset_url, { + password => { password => 1 }, +}, sub { + my $data = shift; + my $id = tuwf->capture('id'); + my $token = tuwf->capture('token'); + + return elm_InsecurePass if is_insecurepass($data->{password}); + die "Invalid reset token" if !auth->setpass($id, $token, undef, $data->{password}); + tuwf->dbExeci('UPDATE users SET email_confirmed = true WHERE id =', \$id); + elm_Success +}; + +1; diff --git a/lib/VNWeb/User/RegReset.pm b/lib/VNWeb/User/RegReset.pm deleted file mode 100644 index 92808e95..00000000 --- a/lib/VNWeb/User/RegReset.pm +++ /dev/null @@ -1,143 +0,0 @@ -# User registration and password reset. These functions share some common code. -package VNWeb::User::RegReset; - -use VNWeb::Prelude; - - -# Generate some Elm code for the HTML5 validations, the Send and Recv types -# aren't used, they're simple enough to maintain manually. -elm_form RegReset => undef, form_compile(in => { - email => { email => 1 }, - password => { password => 1 }, - username => { username => 1 }, - vns => { uint => 1 }, -}); - - -TUWF::get '/u/newpass' => sub { - return tuwf->resRedirect('/', 'temp') if auth; - framework_ title => 'Password reset', index => 0, sub { - elm_ 'User.PassReset'; - }; -}; - - -json_api '/u/newpass', { - email => { email => 1 }, -}, sub { - my $data = shift; - - my($id, $token) = auth->resetpass($data->{email}); - return elm_BadEmail if !$id; - - my $name = tuwf->dbVali('SELECT username FROM users WHERE id =', \$id); - my $body = sprintf - "Hello %s," - ."\n\n" - ."Your VNDB.org login has been disabled, you can now set a new password by following the link below:" - ."\n\n" - ."%s" - ."\n\n" - ."Now don't forget your password again! :-)" - ."\n\n" - ."vndb.org", - $name, tuwf->reqBaseURI()."/u$id/setpass/$token"; - - tuwf->mail($body, - To => $data->{email}, - From => 'VNDB <noreply@vndb.org>', - Subject => "Password reset for $name", - ); - elm_Success -}; - - -# Compatibility with old the URL format -TUWF::get qr{/$RE{uid}/setpass}, sub { tuwf->resRedirect(sprintf('/u%d/setpass/%s', tuwf->capture('id'), tuwf->reqGet('t')||''), 'temp') }; - - -my $reset_url = qr{/$RE{uid}/setpass/(?<token>[a-f0-9]{40})}; - -TUWF::get $reset_url, sub { - return tuwf->resRedirect('/', 'temp') if auth; - - my $id = tuwf->capture('id'); - my $token = tuwf->capture('token'); - my $name = tuwf->dbVali('SELECT username FROM users WHERE id =', \$id); - - return tuwf->resNotFound if !$name || !auth->isvalidtoken($id, $token); - - framework_ title => 'Set password', index => 0, sub { - elm_ 'User.PassSet', tuwf->compile({}), tuwf->reqPath; - }; -}; - - -json_api $reset_url, { - password => { password => 1 }, -}, sub { - my $data = shift; - my $id = tuwf->capture('id'); - my $token = tuwf->capture('token'); - - return elm_InsecurePass if is_insecurepass($data->{password}); - die "Invalid reset token" if !auth->setpass($id, $token, undef, $data->{password}); - tuwf->dbExeci('UPDATE users SET email_confirmed = true WHERE id =', \$id); - elm_Success -}; - - -TUWF::get '/u/register', sub { - return tuwf->resRedirect('/', 'temp') if auth; - framework_ title => 'Register', index => 0, sub { - elm_ 'User.Register'; - }; -}; - - -json_api '/u/register', { - username => { username => 1 }, - email => { email => 1 }, - vns => { int => 1 }, -}, sub { - my $data = shift; - - my $num = tuwf->dbVali("SELECT count FROM stats_cache WHERE section = 'vn'"); - return elm_Bot if $data->{vns} < $num*0.995 || $data->{vns} > $num*1.005; - return elm_Taken if tuwf->dbVali('SELECT 1 FROM users WHERE username =', \$data->{username}); - return elm_DoubleEmail if tuwf->dbVali(select => sql_func user_emailexists => \$data->{email}); - - my $ip = tuwf->reqIP; - return elm_DoubleIP if tuwf->dbVali( - q{SELECT 1 FROM users WHERE registered >= NOW()-'1 day'::interval AND ip <<}, - $ip =~ /:/ ? \"$ip/48" : \"$ip/30" - ); - - my $id = tuwf->dbVali('INSERT INTO users', { - username => $data->{username}, - mail => $data->{email}, - ip => $ip, - }, 'RETURNING id'); - my(undef, $token) = auth->resetpass($data->{email}); - - my $body = sprintf - "Hello %s," - ."\n\n" - ."Someone has registered an account on VNDB.org with your email address. To confirm your registration, follow the link below." - ."\n\n" - ."%s" - ."\n\n" - ."If you don't remember creating an account on VNDB.org recently, please ignore this e-mail." - ."\n\n" - ."vndb.org", - $data->{username}, tuwf->reqBaseURI()."/u$id/setpass/$token"; - - tuwf->mail($body, - To => $data->{email}, - From => 'VNDB <noreply@vndb.org>', - Subject => "Confirm registration for $data->{username}", - ); - elm_Success -}; - -1; diff --git a/lib/VNWeb/User/Register.pm b/lib/VNWeb/User/Register.pm new file mode 100644 index 00000000..c093fcee --- /dev/null +++ b/lib/VNWeb/User/Register.pm @@ -0,0 +1,59 @@ +package VNWeb::User::Register; + +use VNWeb::Prelude; + + +TUWF::get '/u/register', sub { + return tuwf->resRedirect('/', 'temp') if auth; + framework_ title => 'Register', index => 0, sub { + elm_ 'User.Register'; + }; +}; + + +json_api '/u/register', { + username => { username => 1 }, + email => { email => 1 }, + vns => { int => 1 }, +}, sub { + my $data = shift; + + my $num = tuwf->dbVali("SELECT count FROM stats_cache WHERE section = 'vn'"); + return elm_Bot if $data->{vns} < $num*0.995 || $data->{vns} > $num*1.005; + return elm_Taken if tuwf->dbVali('SELECT 1 FROM users WHERE username =', \$data->{username}); + return elm_DoubleEmail if tuwf->dbVali(select => sql_func user_emailexists => \$data->{email}); + + my $ip = tuwf->reqIP; + return elm_DoubleIP if tuwf->dbVali( + q{SELECT 1 FROM users WHERE registered >= NOW()-'1 day'::interval AND ip <<}, + $ip =~ /:/ ? \"$ip/48" : \"$ip/30" + ); + + my $id = tuwf->dbVali('INSERT INTO users', { + username => $data->{username}, + mail => $data->{email}, + ip => $ip, + }, 'RETURNING id'); + my(undef, $token) = auth->resetpass($data->{email}); + + my $body = sprintf + "Hello %s," + ."\n\n" + ."Someone has registered an account on VNDB.org with your email address. To confirm your registration, follow the link below." + ."\n\n" + ."%s" + ."\n\n" + ."If you don't remember creating an account on VNDB.org recently, please ignore this e-mail." + ."\n\n" + ."vndb.org", + $data->{username}, tuwf->reqBaseURI()."/u$id/setpass/$token"; + + tuwf->mail($body, + To => $data->{email}, + From => 'VNDB <noreply@vndb.org>', + Subject => "Confirm registration for $data->{username}", + ); + elm_Success +}; + +1; |