diff options
-rw-r--r-- | CHANGELOG.md | 1 | ||||
-rw-r--r-- | perllib/FixMyStreet/App/Controller/Auth.pm | 28 | ||||
-rw-r--r-- | perllib/FixMyStreet/App/Controller/Auth/Phone.pm | 6 | ||||
-rw-r--r-- | perllib/FixMyStreet/App/Controller/Auth/Profile.pm | 62 | ||||
-rw-r--r-- | perllib/FixMyStreet/App/Controller/My.pm | 4 | ||||
-rw-r--r-- | perllib/FixMyStreet/DB/Result/User.pm | 7 | ||||
-rw-r--r-- | t/app/controller/auth_profile.t | 151 | ||||
-rw-r--r-- | templates/web/base/auth/change_email.html | 39 | ||||
-rw-r--r-- | templates/web/base/auth/change_phone.html | 57 | ||||
-rw-r--r-- | templates/web/base/my/my.html | 43 | ||||
-rw-r--r-- | web/cobrands/sass/_base.scss | 2 |
11 files changed, 362 insertions, 38 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index c5a2bec22..6eb66566a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ - New features: - Optional verification of reports and updates, and logging in, using confirmation by phone text. + - Improved email/phone management in your profile. - Area summary statistics page in admin #1834 - Bugfixes - Shortlist menu item always remains a link #1855 diff --git a/perllib/FixMyStreet/App/Controller/Auth.pm b/perllib/FixMyStreet/App/Controller/Auth.pm index 0b156ddd3..b453f593b 100644 --- a/perllib/FixMyStreet/App/Controller/Auth.pm +++ b/perllib/FixMyStreet/App/Controller/Auth.pm @@ -114,7 +114,7 @@ they come back with a token (which contains the email/phone). sub code_sign_in : Private { my ( $self, $c ) = @_; - my $username = $c->get_param('username') || ''; + my $username = $c->stash->{username} = $c->get_param('username') || ''; my $parsed = FixMyStreet::SMS->parse_username($username); @@ -139,7 +139,6 @@ sub email_sign_in : Private { my $good_email = $email_checker->address($raw_email); if ( !$good_email ) { - $c->stash->{username} = $raw_email; $c->stash->{username_error} = $raw_email ? $email_checker->details : 'missing_email'; return; } @@ -172,7 +171,7 @@ sub email_sign_in : Private { $token_data->{twitter_id} = $c->session->{oauth}{twitter_id} if $c->get_param('oauth_need_email') && $c->session->{oauth}{twitter_id}; if ($c->stash->{current_user}) { - $token_data->{old_email} = $c->stash->{current_user}->email; + $token_data->{old_user_id} = $c->stash->{current_user}->id; $token_data->{r} = 'auth/change_email/success'; } @@ -214,7 +213,7 @@ sub token : Path('/M') : Args(1) { my $data = $c->forward('get_token', [ $url_token, 'email_sign_in' ]) || return; $c->stash->{token_not_found} = 1, return - if $data->{old_email} && (!$c->user_exists || $c->user->email ne $data->{old_email}); + if $data->{old_user_id} && (!$c->user_exists || $c->user->id ne $data->{old_user_id}); my $type = $data->{login_type} || 'email'; $c->detach( '/auth/process_login', [ $data, $type ] ); @@ -227,24 +226,27 @@ sub process_login : Private { $c->logout(); my $user = $c->model('DB::User')->find_or_new({ $type => $data->{$type} }); + my $ver = "${type}_verified"; # Bail out if this is a new user and SIGNUPS_DISABLED is set $c->detach( '/page_error_403_access_denied', [] ) - if FixMyStreet->config('SIGNUPS_DISABLED') && !$user->in_storage && !$data->{old_email}; + if FixMyStreet->config('SIGNUPS_DISABLED') && !$user->in_storage && !$data->{old_user_id}; - if ($data->{old_email}) { - # Were logged in as old_email, want to switch to email ($user) + if ($data->{old_user_id}) { + # Were logged in as old_user_id, want to switch to $user if ($user->in_storage) { - my $old_user = $c->model('DB::User')->find({ email => $data->{old_email} }); + my $old_user = $c->model('DB::User')->find({ id => $data->{old_user_id} }); if ($old_user) { $old_user->adopt($user); $user = $old_user; - $user->email($data->{email}); + $user->$type($data->{$type}); + $user->$ver(1); } } else { - # Updating to a new (to the db) email address, easier! - $user = $c->model('DB::User')->find({ email => $data->{old_email} }); - $user->email($data->{email}); + # Updating to a new (to the db) email address/phone number, easier! + $user = $c->model('DB::User')->find({ id => $data->{old_user_id} }); + $user->$type($data->{$type}); + $user->$ver(1); } } @@ -253,7 +255,7 @@ sub process_login : Private { $user->facebook_id( $data->{facebook_id} ) if $data->{facebook_id}; $user->twitter_id( $data->{twitter_id} ) if $data->{twitter_id}; $user->update_or_insert; - $c->authenticate( { $type => $data->{$type}, "${type}_verified" => 1 }, 'no_password' ); + $c->authenticate( { $type => $data->{$type}, $ver => 1 }, 'no_password' ); # send the user to their page $c->detach( 'redirect_on_signin', [ $data->{r}, $data->{p} ] ); diff --git a/perllib/FixMyStreet/App/Controller/Auth/Phone.pm b/perllib/FixMyStreet/App/Controller/Auth/Phone.pm index 4f9a72594..4e9f92596 100644 --- a/perllib/FixMyStreet/App/Controller/Auth/Phone.pm +++ b/perllib/FixMyStreet/App/Controller/Auth/Phone.pm @@ -53,7 +53,6 @@ sub sign_in : Private { } unless ($phone->is_mobile) { - $c->stash->{username} = $c->get_param('username'); # What was entered $c->stash->{username_error} = 'nonmobile'; return; } @@ -62,6 +61,7 @@ sub sign_in : Private { if ( FixMyStreet->config('SIGNUPS_DISABLED') && !$c->model('DB::User')->find({ phone => $number }) + && !$c->stash->{current_user} # don't break the change phone flow ) { $c->stash->{template} = 'auth/token.html'; return; @@ -78,6 +78,10 @@ sub sign_in : Private { name => $c->get_param('name'), password => $user->password, }; + if ($c->stash->{current_user}) { + $token_data->{old_user_id} = $c->stash->{current_user}->id; + $token_data->{r} = 'auth/change_phone/success'; + } $c->forward('send_token', [ $token_data, 'phone_sign_in', $number ]); } diff --git a/perllib/FixMyStreet/App/Controller/Auth/Profile.pm b/perllib/FixMyStreet/App/Controller/Auth/Profile.pm index 453b4a8a3..ecf009150 100644 --- a/perllib/FixMyStreet/App/Controller/Auth/Profile.pm +++ b/perllib/FixMyStreet/App/Controller/Auth/Profile.pm @@ -10,8 +10,8 @@ FixMyStreet::App::Controller::Auth::Profile - Catalyst Controller =head1 DESCRIPTION -Controller for all the authentication profile related pages - changing email, -password. +Controller for all the authentication profile related pages - adding/ changing/ +verifying email, phone, password. =head1 METHODS @@ -88,6 +88,64 @@ sub change_email : Path('/auth/change_email') { $c->forward('/auth/email_sign_in', [ $c->get_param('email') ]); } +sub change_phone : Path('/auth/change_phone') { + my ( $self, $c ) = @_; + + $c->stash->{template} = 'auth/change_phone.html'; + + $c->forward('/auth/get_csrf_token'); + + # If not a post then no submission + return unless $c->req->method eq 'POST'; + + $c->forward('/auth/check_csrf_token'); + $c->stash->{current_user} = $c->user; + + my $phone = $c->stash->{username} = $c->get_param('username') || ''; + my $parsed = FixMyStreet::SMS->parse_username($phone); + + # Allow removal of phone number, if we have verified email + if (!$phone && !$c->stash->{verifying} && $c->user->email_verified) { + $c->user->update({ phone => undef, phone_verified => 0 }); + $c->flash->{flash_message} = _('You have successfully removed your phone number.'); + $c->res->redirect('/my'); + $c->detach; + } + + $c->stash->{username_error} = 'missing_phone', return unless $phone; + $c->stash->{username_error} = 'other_phone', return unless $parsed->{phone}; + + # If we've not used a mobile and we're not specifically verifying, + # and phone isn't our only verified way of logging in, + # then allow change of number (for e.g. landline). + if (!FixMyStreet->config('SMS_AUTHENTICATION') || (!$parsed->{phone}->is_mobile && !$c->stash->{verifying} && $c->user->email_verified)) { + $c->user->update({ phone => $phone, phone_verified => 0 }); + $c->flash->{flash_message} = _('You have successfully added your phone number.'); + $c->res->redirect('/my'); + $c->detach; + } + + $c->forward('/auth/phone/sign_in', [ $parsed->{phone} ]); +} + +sub verify_item : Path('/auth/verify') : Args(1) { + my ( $self, $c, $type ) = @_; + $c->stash->{verifying} = 1; + $c->detach("change_$type"); +} + +sub change_email_success : Path('/auth/change_email/success') { + my ( $self, $c ) = @_; + $c->flash->{flash_message} = _('You have successfully confirmed your email address.'); + $c->res->redirect('/my'); +} + +sub change_phone_success : Path('/auth/change_phone/success') { + my ( $self, $c ) = @_; + $c->flash->{flash_message} = _('You have successfully verified your phone number.'); + $c->res->redirect('/my'); +} + __PACKAGE__->meta->make_immutable; 1; diff --git a/perllib/FixMyStreet/App/Controller/My.pm b/perllib/FixMyStreet/App/Controller/My.pm index 5b80a4a08..9647fae9a 100644 --- a/perllib/FixMyStreet/App/Controller/My.pm +++ b/perllib/FixMyStreet/App/Controller/My.pm @@ -176,6 +176,10 @@ sub setup_page_data : Private { any_zoom => 1, ) if @$pins; + + foreach (qw(flash_message)) { + $c->stash->{$_} = $c->flash->{$_} if $c->flash->{$_}; + } } sub planned_change : Path('planned/change') { diff --git a/perllib/FixMyStreet/DB/Result/User.pm b/perllib/FixMyStreet/DB/Result/User.pm index 4da9ef83a..296cf997d 100644 --- a/perllib/FixMyStreet/DB/Result/User.pm +++ b/perllib/FixMyStreet/DB/Result/User.pm @@ -147,6 +147,13 @@ sub username { return $self->phone_display if $self->phone_verified; } +sub phone_display { + my $self = shift; + return $self->phone unless $self->phone; + my $parsed = FixMyStreet::SMS->parse_username($self->phone); + return $parsed->{phone} ? $parsed->{phone}->format : $self->phone; +} + sub latest_anonymity { my $self = shift; my $p = $self->problems->search(undef, { order_by => { -desc => 'id' } } )->first; diff --git a/t/app/controller/auth_profile.t b/t/app/controller/auth_profile.t index 2472564e8..519086ff5 100644 --- a/t/app/controller/auth_profile.t +++ b/t/app/controller/auth_profile.t @@ -1,6 +1,11 @@ use FixMyStreet::TestMech; my $mech = FixMyStreet::TestMech->new; +use t::Mock::Twilio; + +my $twilio = t::Mock::Twilio->new; +LWP::Protocol::PSGI->register($twilio->to_psgi_app, host => 'api.twilio.com'); + my $test_email = 'test@example.com'; my $test_email2 = 'test@example.net'; my $test_password = 'foobar'; @@ -10,14 +15,14 @@ END { } # get a sign in email and change password -{ +subtest "Test change password page" => sub { $mech->clear_emails_ok; $mech->get_ok('/auth'); $mech->submit_form_ok( { form_name => 'general_auth', fields => { - username => "$test_email", + username => $test_email, r => 'faq', # Just as a test }, button => 'sign_in_by_code', @@ -61,8 +66,7 @@ END { $mech->content_contains( $test->{err}, "found expected error" ); } - my $user = - FixMyStreet::App->model('DB::User')->find( { email => $test_email } ); + my $user = FixMyStreet::App->model('DB::User')->find( { email => $test_email } ); ok $user, "got a user"; ok !$user->password, "user has no password"; @@ -82,9 +86,11 @@ END { $user->discard_changes(); ok $user->password, "user now has a password"; -} +}; subtest "Test change email page" => sub { + $mech->create_problems_for_body(1, 2514, 'Title1', { user => FixMyStreet::DB->resultset('User')->find( { email => $test_email } ) } ); + # Still signed in from the above test $mech->get_ok('/my'); $mech->follow_link_ok({url => '/auth/change_email'}); @@ -98,11 +104,18 @@ subtest "Test change email page" => sub { $mech->content_contains( 'Now check your email', "found check your email" ); my $link = $mech->get_link_from_email; $mech->get_ok($link); - is $mech->uri->path, '/auth/change_email/success', "redirected to the change_email page"; + is $mech->uri->path, '/my', "redirected to /my page"; $mech->content_contains('successfully confirmed'); ok(FixMyStreet::App->model('DB::User')->find( { email => $test_email2 } ), "got a user"); - ok(FixMyStreet::App->model('DB::User')->create( { email => $test_email, email_verified => 1 } ), "created old user"); + my $p = FixMyStreet::DB->resultset("Problem")->first; + is $p->user->email, $test_email2, 'problem user updated'; + + my $user1 = FixMyStreet::App->model('DB::User')->create( { email => $test_email, email_verified => 1 } ); + ok($user1, "created old user"); + $mech->create_problems_for_body(1, 2514, 'Title1', { user => $user1 } ); + + $mech->follow_link_ok({url => '/auth/change_email'}); $mech->submit_form_ok({ with_fields => { email => $test_email } }, "change_email back to $test_email" ); @@ -110,10 +123,15 @@ subtest "Test change email page" => sub { $mech->content_contains( 'Now check your email', "found check your email" ); $link = $mech->get_link_from_email; $mech->get_ok($link); - is $mech->uri->path, '/auth/change_email/success', "redirected to the change_email page"; + is $mech->uri->path, '/my', "redirected to /my page"; $mech->content_contains('successfully confirmed'); + for (FixMyStreet::DB->resultset("Problem")->all) { + is $_->user->email, $test_email; + } + # Test you can't click the link if logged out + $mech->follow_link_ok({url => '/auth/change_email'}); $mech->submit_form_ok({ with_fields => { email => $test_email } }, "change_email back to $test_email" ); @@ -125,3 +143,120 @@ subtest "Test change email page" => sub { isnt $mech->uri->path, '/auth/change_email/success', "not redirected to the change_email page"; $mech->content_contains('Sorry'); }; + +my $test_phone_bad = '01214960000000'; +my $test_landline = '01214960000'; +my $test_mobile = '+61491570156'; +my $test_mobile2 = '+61491570157'; + +my $user_mob2 = FixMyStreet::App->model('DB::User')->create( { + phone => $test_mobile, + phone_verified => 1, + name => 'Aus Mobile user', +} ); +$mech->create_problems_for_body(1, 2514, 'Title1', { user => $user_mob2 } ); + +subtest "Test add/verify/change phone page" => sub { + $mech->get_ok('/auth'); + $mech->submit_form_ok({ + with_fields => { + username => $test_email, + password_sign_in => $test_password, + }, + }); + + $mech->follow_link_ok({url => '/auth/change_phone'}); + $mech->submit_form_ok( { with_fields => { username => "" } }, "submit blank change phone form" ); + is $mech->uri->path, '/my', 'redirected'; + $mech->content_contains('successfully removed'); + + $mech->follow_link_ok({url => '/auth/change_phone'}); + $mech->submit_form_ok({ with_fields => { username => $test_phone_bad } }); + $mech->content_contains( 'Please check your phone number is correct', "found expected error" ); + + FixMyStreet::override_config({ + SMS_AUTHENTICATION => 1, + PHONE_COUNTRY => 'GB', + }, sub { + $mech->submit_form_ok({ with_fields => { username => $test_landline } }); + }); + is $mech->uri->path, '/my', 'redirected'; + $mech->content_contains('successfully added'); + + FixMyStreet::override_config({ + SMS_AUTHENTICATION => 1, + PHONE_COUNTRY => 'GB', + }, sub { + $mech->follow_link_ok({url => '/auth/verify/phone'}); + $mech->submit_form_ok({ with_fields => { username => $test_landline } }); + }); + $mech->content_contains( 'Please enter a mobile number', "found expected error" ); + + FixMyStreet::override_config({ + SMS_AUTHENTICATION => 1, + TWILIO_ACCOUNT_SID => 'AC123', + }, sub { + $mech->submit_form_ok({ with_fields => { username => $test_mobile } }); + }); + is $mech->uri->path, '/auth/verify/phone', "still on change phone page"; + $mech->content_contains( 'Now check your phone', "found check your phone" ); + + $mech->submit_form_ok({ + with_fields => { code => '00000' } + }, 'submit incorrect code'); + $mech->content_contains('Try again'); + + my $code = $twilio->get_text_code; + $mech->submit_form_ok({ + with_fields => { code => $code } + }, 'submit correct code'); + + my $user = FixMyStreet::App->model('DB::User')->find( { phone => $test_mobile } ); + ok $user, "user exists"; + is $user->email_verified, 1; + is $user->email, $test_email, 'email still same'; + is $mech->uri->path, '/my', "redirected to /my page"; + $mech->content_contains('successfully verified'); + $mech->logged_in_ok; +}; + +subtest "Test change phone to existing account" => sub { + $mech->get_ok('/auth'); + FixMyStreet::override_config({ + SMS_AUTHENTICATION => 1, + }, sub { + $mech->submit_form_ok({ + with_fields => { + username => $test_mobile, + password_sign_in => $test_password, + }, + }); + }); + + $mech->follow_link_ok({url => '/auth/change_phone'}); + + FixMyStreet::override_config({ + SMS_AUTHENTICATION => 1, + TWILIO_ACCOUNT_SID => 'AC123', + }, sub { + $mech->submit_form_ok({ with_fields => { username => $test_mobile2 } }); + }); + is $mech->uri->path, '/auth/change_phone', "still on change phone page"; + $mech->content_contains( 'Now check your phone', "found check your phone" ); + + my $code = $twilio->get_text_code; + $mech->submit_form_ok({ with_fields => { code => $code } }, 'submit correct code'); + + my $user = FixMyStreet::App->model('DB::User')->find( { phone => $test_mobile } ); + ok !$user, 'old user does not exist'; + $user = FixMyStreet::App->model('DB::User')->find( { phone => $test_mobile2 } ); + ok $user, "new mobile user exists"; + is $user->email_verified, 1; + is $user->email, $test_email, 'email still same'; + is $mech->uri->path, '/my', "redirected to /my page"; + $mech->content_contains('successfully verified'); + + for (FixMyStreet::DB->resultset("Problem")->all) { + is $_->user->email, $test_email; + } +}; diff --git a/templates/web/base/auth/change_email.html b/templates/web/base/auth/change_email.html index 6a0d6aed4..b3bec6b3e 100644 --- a/templates/web/base/auth/change_email.html +++ b/templates/web/base/auth/change_email.html @@ -1,14 +1,23 @@ -[% INCLUDE 'header.html', title = loc('Change email address'), bodyclass = 'authpage' %] - -<h1>[% loc('Change email address') %]</h1> - -[% IF c.req.args.0 == 'success' %] - <p class="form-success">[% loc('You have successfully confirmed your email address.') %]</p> -[% END %] - +[% +IF c.user.email_verified OR (c.user.email AND NOT verifying); + SET title = loc('Change email address'); +ELSIF c.user.email; + SET title = loc('Verify email address'); +ELSE; + SET title = loc('Add email address'); +END +-%] +[% INCLUDE 'header.html' bodyclass = 'authpage' %] + +<h1>[% title %]</h1> + +[% IF c.user.email_verified OR (c.user.email AND NOT verifying) %] [% loc('Your email address') %]: [% c.user.email %] +[% ELSIF c.user.email %] +[% DEFAULT username = c.user.email %] +[% END %] -<form action="[% c.uri_for_action('/auth/profile/change_email') %]" method="post" name="change_email"> +<form method="post" name="change_email"> <input type="hidden" name="token" value="[% csrf_token %]"> <fieldset> @@ -23,11 +32,17 @@ [% END %] <div class="form-field"> - <label for="email">[% loc('New email address:') %]</label> - <input class="form-control" type="email" name="email" id="email" value="[% email | html %]"> + <label for="email"> + [% IF NOT c.user.email_verified AND c.user.email AND verifying %] + [% loc('Email address') %]: + [% ELSE %] + [% loc('New email address:') %] + [% END %] + </label> + <input class="form-control" type="email" name="email" id="email" value="[% username | html %]"> </div> <div class="final-submit"> - <input type="submit" class="btn" value="[% loc('Change email address') %]"> + <input type="submit" class="btn" value="[% title %]"> </div> </fieldset> diff --git a/templates/web/base/auth/change_phone.html b/templates/web/base/auth/change_phone.html new file mode 100644 index 000000000..4b181f6c5 --- /dev/null +++ b/templates/web/base/auth/change_phone.html @@ -0,0 +1,57 @@ +[% +IF c.user.phone_verified OR (c.user.phone AND NOT verifying); + SET title = loc('Change phone number'); +ELSIF c.user.phone; + SET title = loc('Verify phone number'); +ELSE; + SET title = loc('Add phone number'); +END +-%] +[% INCLUDE 'header.html' bodyclass = 'authpage' %] + +<h1>[% title %]</h1> + +[% IF c.req.args.0 == 'success' %] + <p class="form-success">[% loc('You have successfully confirmed your phone number.') %]</p> +[% END %] + +[% IF c.user.phone_verified OR (c.user.phone AND NOT verifying) %] +[% loc('Your phone number') %]: [% c.user.phone_display %] +[% ELSIF c.user.phone %] +[% DEFAULT username = c.user.phone %] +[% END %] + +<form method="post" name="change_phone"> + <input type="hidden" name="token" value="[% csrf_token %]"> + + <fieldset> + [% IF username_error; + errors = { + nonmobile = loc('Please enter a mobile number'), + missing_phone = loc('Please enter your phone number'), + other_phone = loc('Please check your phone number is correct') + }; + loc_username_error = errors.$username_error || errors.other_phone; + %] + <div class="form-error">[% loc_username_error %]</div> + [% END %] + + <div class="form-field"> + <label for="phone"> + [% IF NOT c.user.phone_verified AND c.user.phone AND verifying %] + [% loc('Phone number') %]: + [% ELSE %] + [% loc('New phone number:') %] + [% END %] + </label> + <input class="form-control" type="tel" name="username" id="phone" value="[% username | html %]"> + </div> + <div class="final-submit"> + <input type="submit" class="btn" value="[% title %]"> + </div> + + </fieldset> +</form> + + +[% INCLUDE 'footer.html' %] diff --git a/templates/web/base/my/my.html b/templates/web/base/my/my.html index 1aaad6dc9..68fbc2ee8 100644 --- a/templates/web/base/my/my.html +++ b/templates/web/base/my/my.html @@ -17,11 +17,50 @@ <h1>[% loc('Your account') %]</h1> -<p>[% c.user.name %] [% c.user.email %]</p> +[% IF flash_message %] +<p class="form-success">[% flash_message %]</p> +[% END %] + +<style> +/* TODO XXX */ +li .my-account-buttons { + float: right; + margin: 0; +} +li .my-account-buttons a { + padding: 0 0.5em; +} +</style> +<ul> +<li>[% loc('Name:') %] [% c.user.name %] +<li>[% loc('Email:') %] [% c.user.email OR '-' %] + <p class="my-account-buttons"> + [% IF NOT c.user.email %] + <a href="/auth/change_email">[% loc('Add') %]</a> + [% ELSIF c.user.email_verified %] + <a href="/auth/change_email">[% loc('Change') %]</a> + [% ELSE %] + <a href="/auth/verify/email">[% loc('Verify') %]</a> + <a href="/auth/change_email">[% loc('Change') %]</a> + [% END %] + </p> +<li>[% loc('Phone:') %] [% c.user.phone_display OR '-' %] + <p class="my-account-buttons"> + [% IF NOT c.user.phone %] + <a href="/auth/change_phone">[% loc('Add') %]</a> + [% ELSIF c.user.phone_verified %] + <a href="/auth/change_phone">[% loc('Change') %]</a> + [% ELSE %] + [% IF c.config.SMS_AUTHENTICATION %] + <a href="/auth/verify/phone">[% loc('Verify') %]</a> + [% END %] + <a href="/auth/change_phone">[% loc('Change') %]</a> + [% END %] + </p> +</ul> <p class="my-account-buttons"> <a href="/auth/change_password">[% loc('Change password') %]</a> - <a href="/auth/change_email">[% loc('Change email') %]</a> <a href="/auth/sign_out">[% loc('Sign out') %]</a> </p> diff --git a/web/cobrands/sass/_base.scss b/web/cobrands/sass/_base.scss index 4cf18a09c..9d6052c45 100644 --- a/web/cobrands/sass/_base.scss +++ b/web/cobrands/sass/_base.scss @@ -228,6 +228,7 @@ input[type=file] { width: 100%; } +input[type=tel], input[type=number], input[type=text], input[type=password], @@ -403,6 +404,7 @@ select.form-control { .form-txt-submit-box { @include clearfix(); input[type=password], + input[type=tel], input[type=number], input[type=text], input[type=email] { |