From aa5e196481ff0552de3d637f582008d9274915e6 Mon Sep 17 00:00:00 2001 From: Manager Bot Date: Wed, 23 Nov 2022 07:34:05 +0000 Subject: [PATCH] New registration system. --- Web/lib/MJB/Web.pm | 13 +- Web/lib/MJB/Web/Controller/Auth.pm | 136 +++++++++++++++--- ...gister.html.ep => register_invite.html.ep} | 2 - Web/templates/auth/register_open.html.ep | 35 +++++ 4 files changed, 159 insertions(+), 27 deletions(-) rename Web/templates/auth/{register.html.ep => register_invite.html.ep} (95%) create mode 100644 Web/templates/auth/register_open.html.ep diff --git a/Web/lib/MJB/Web.pm b/Web/lib/MJB/Web.pm index 63d4c62..88c5d85 100644 --- a/Web/lib/MJB/Web.pm +++ b/Web/lib/MJB/Web.pm @@ -157,11 +157,14 @@ sub startup ($self) { $r->get ( '/contact' )->to( 'Root#contact' )->name('show_contact' ); # User registration, login, and logout. - $r->get ( '/register' )->to( 'Auth#register' )->name('show_register' ); - $r->post ( '/register' )->to( 'Auth#do_register' )->name('do_register' ); - $r->get ( '/login' )->to( 'Auth#login' )->name('show_login' ); - $r->post ( '/login' )->to( 'Auth#do_login' )->name('do_login' ); - $auth->get( '/logout' )->to( 'Auth#do_logout' )->name('do_logout' ); + $r->get ( '/register' )->to( 'Auth#register' )->name('show_register' ); + $r->get ( '/register/open' )->to( 'Auth#register_open' )->name('show_register_open' ); + $r->post ( '/register/open' )->to( 'Auth#do_register_open' )->name('do_register_open' ); + $r->get ( '/register/invite' )->to( 'Auth#register_invite' )->name('show_register_invite' ); + $r->post ( '/register/invite' )->to( 'Auth#do_register_invite' )->name('do_register_invite' ); + $r->get ( '/login' )->to( 'Auth#login' )->name('show_login' ); + $r->post ( '/login' )->to( 'Auth#do_login' )->name('do_login' ); + $auth->get( '/logout' )->to( 'Auth#do_logout' )->name('do_logout' ); # User Forgot Password Workflow. $r->get ( '/forgot' )->to('Auth#forgot' )->name('show_forgot' ); diff --git a/Web/lib/MJB/Web/Controller/Auth.pm b/Web/lib/MJB/Web/Controller/Auth.pm index 1c6e3bf..aaa0fdf 100644 --- a/Web/lib/MJB/Web/Controller/Auth.pm +++ b/Web/lib/MJB/Web/Controller/Auth.pm @@ -12,38 +12,138 @@ use DateTime; #== # GET /register | show_register | templates/auth/register.html.ep +# +# Send the user to whatever the default registration system is. #== sub register ( $c ) { + return $c->redirect_to( $c->url_for( 'show_register_stripe' ) ) + if $c->config->{register}{default} eq 'stripe'; + + return $c->redirect_to( $c->url_for( 'show_register_invite' ) ) + if $c->config->{register}{default} eq 'invite'; + + return $c->redirect_to( $c->url_for( 'show_register_open' ) ) + if $c->config->{register}{default} eq 'open'; + + # No default registration system. + return $c->redirect_to( $c->url_for( 'show_homepage' ) ); +} +#== +# GET /register/open | show_register_open | templates/auth/register_open.html.ep +#== +sub register_open ( $c ) { + # Don't allow this user registration method unless register.enable_open is true. + return $c->redirect_to( $c->url_for( 'show_register' ) ) + unless $c->config->{register}{enable_open}; } #== -# POST /register | do_register +# POST /register/open | do_register_open # name | The name of the person who is registering an account # email | The email address of the person registering the account # password | The password they would like to use # password_confirm | The same password again, in case they don't know it for sure -# invite | An invite code -- required when config->{register}->{require_invite} is true +# +# Create an account for the user and login to that account once it has been created. +#== +sub do_register_open ( $c ) { + my $name = $c->stash->{form}->{name} = $c->param('name'); + my $email = $c->stash->{form}->{email} = $c->param('email'); + my $password = $c->stash->{form}->{password} = $c->param('password'); + my $p_confirm = $c->stash->{form}->{password_confirm} = $c->param('password_confirm'); + + # Don't allow this user registration method unless register.enable_open is true. + return $c->redirect_to( $c->url_for( 'show_register' ) ) + unless $c->config->{register}{enable_open}; + + push @{$c->stash->{errors}}, "Name is required" unless $name; + push @{$c->stash->{errors}}, "Email is required" unless $email; + push @{$c->stash->{errors}}, "Password is required" unless $password; + push @{$c->stash->{errors}}, "Confirm Password is required" unless $p_confirm; + + return $c->redirect_error( 'show_register' ) + if $c->stash->{errors}; + + push @{$c->stash->{errors}}, "Password and confirm password must match" + unless $p_confirm eq $password; + + push @{$c->stash->{errors}}, "Password must be at least 8 characters" + unless length($password) >= 8; + + push @{$c->stash->{errors}}, "That email address is already registered." + if $c->db->people( { email => $email } )->count; + + return $c->redirect_error( 'show_register_open' ) + if $c->stash->{errors}; + + my $person = try { + $c->db->storage->schema->txn_do( sub { + my $person = $c->db->resultset('Person')->create({ + email => $c->param('email'), + name => $c->param('name'), + }); + $person->new_related('auth_password', {})->set_password($c->param('password')); + + # Notify the system about the new account. + $c->db->system_notes->create({ + source => 'User Registration (Open)', + content => 'An account was created for ' . $person->email, + }); + + return $person; + }); + } catch { + push @{$c->stash->{errors}}, "Account could not be created: $_"; + }; + + return $c->redirect_error( 'show_register_open' ) + if $c->stash->{errors}; + + # Log the user in and send them to the dashboard. + $c->session->{uid} = $person->id; + $c->redirect_to( $c->url_for( 'show_dashboard' ) ); +} + +#== +# GET /register/invite | show_register_invite | templates/auth/register_invite.html.ep +#== +sub register_invite ( $c ) { + $c->stash->{form}->{invite_code} ||= $c->param('code'); + + # Don't allow this user registration method unless register.enable_invite is true. + return $c->redirect_to( $c->url_for( 'show_register' ) ) + unless $c->config->{register}{enable_invite}; +} + +#== +# POST /register/invite | do_register_invite +# name | The name of the person who is registering an account +# email | The email address of the person registering the account +# password | The password they would like to use +# password_confirm | The same password again, in case they don't know it for sure +# invite | A valid invite code # # Create an account for the user and login to that account once it has been created. # # If an invite code is used and is only valid once, it will be updated so it may no longer be used. #== -sub do_register ( $c ) { +sub do_register_invite ( $c ) { my $name = $c->stash->{form}->{name} = $c->param('name'); my $email = $c->stash->{form}->{email} = $c->param('email'); my $password = $c->stash->{form}->{password} = $c->param('password'); my $p_confirm = $c->stash->{form}->{password_confirm} = $c->param('password_confirm'); my $invite = $c->stash->{form}->{invite_code} = $c->param('invite_code'); + # Don't allow this user registration method unless register.enable_invite is true. + return $c->redirect_to( $c->url_for( 'show_register' ) ) + unless $c->config->{register}{enable_invite}; + push @{$c->stash->{errors}}, "Name is required" unless $name; push @{$c->stash->{errors}}, "Email is required" unless $email; push @{$c->stash->{errors}}, "Password is required" unless $password; push @{$c->stash->{errors}}, "Confirm Password is required" unless $p_confirm; - - if ( $c->config->{register}->{require_invite} ) { - push @{$c->stash->{errors}}, "Invite code is required" unless $invite; - } + push @{$c->stash->{errors}}, "Invite code is required" unless $invite; return $c->redirect_error( 'show_register' ) if $c->stash->{errors}; @@ -57,12 +157,10 @@ sub do_register ( $c ) { push @{$c->stash->{errors}}, "That email address is already registered." if $c->db->people( { email => $email } )->count; - if ( $c->config->{register}->{require_invite} ) { - push @{$c->stash->{errors}}, "That invite code is not valid." - unless $c->db->invites( { code => $invite, is_active => 1 } )->count >= 1; - } + push @{$c->stash->{errors}}, "That invite code is not valid." + unless $c->db->invites( { code => $invite, is_active => 1 } )->count >= 1; - return $c->redirect_error( 'show_register' ) + return $c->redirect_error( 'show_register_invite' ) if $c->stash->{errors}; my $person = try { @@ -75,17 +173,15 @@ sub do_register ( $c ) { # Notify the system about the new account. $c->db->system_notes->create({ - source => 'User Registration', + source => 'User Registration (Invite)', content => 'An account was created for ' . $person->email, }); # If a one-time use invite code was used, invalidate it. - if ( $c->config->{register}->{require_invite} ) { - my $invite = $c->db->invites( { code => $invite, is_active => 1 } )->first; - if ( $invite->is_one_time_use ) { - $invite->is_active( 0 ); - $invite->update; - } + my $invite_record = $c->db->invites( { code => $invite, is_active => 1 } )->first; + if ( $invite_record->is_one_time_use ) { + $invite_record->is_active( 0 ); + $invite_record->update; } return $person; @@ -94,7 +190,7 @@ sub do_register ( $c ) { push @{$c->stash->{errors}}, "Account could not be created: $_"; }; - return $c->redirect_error( 'show_register' ) + return $c->redirect_error( 'show_register_invite' ) if $c->stash->{errors}; # Log the user in and send them to the dashboard. diff --git a/Web/templates/auth/register.html.ep b/Web/templates/auth/register_invite.html.ep similarity index 95% rename from Web/templates/auth/register.html.ep rename to Web/templates/auth/register_invite.html.ep index 7813886..69c06d2 100644 --- a/Web/templates/auth/register.html.ep +++ b/Web/templates/auth/register_invite.html.ep @@ -30,13 +30,11 @@ value => $c->stash->{form}->{password_confirm} %> - % if ( $c->config->{register}->{require_invite} ) { <%= include '_base/form/input', type => 'text', name => 'invite_code', title => 'Invitation Code', help => '', value => $c->stash->{form}->{invite_code} %> - % } diff --git a/Web/templates/auth/register_open.html.ep b/Web/templates/auth/register_open.html.ep new file mode 100644 index 0000000..5191b39 --- /dev/null +++ b/Web/templates/auth/register_open.html.ep @@ -0,0 +1,35 @@ +% layout 'standard', title => 'Register', sb_active => 'register'; + +

Create an account

+ +%= include '_base/status_window'; + +
+ + <%= include '_base/form/input', type => 'text', name => 'name', + title => 'Your name', + help => '', + value => $c->stash->{form}->{name} + %> + + <%= include '_base/form/input', type => 'email', name => 'email', + title => 'Email Address', + help => '', + value => $c->stash->{form}->{email} + %> + + <%= include '_base/form/input', type => 'password', name => 'password', + title => 'Password', + help => '', + value => $c->stash->{form}->{password} + %> + + <%= include '_base/form/input', type => 'password', name => 'password_confirm', + title => 'Confirm Password', + help => '', + value => $c->stash->{form}->{password_confirm} + %> + + +
+