allow users to change their name
This commit is contained in:
parent
08abde269b
commit
6cee1e20ef
4 changed files with 164 additions and 77 deletions
|
@ -2548,6 +2548,7 @@ sub startup {
|
||||||
$authed_r->get('/fgr')->to('passengerrights#list_candidates');
|
$authed_r->get('/fgr')->to('passengerrights#list_candidates');
|
||||||
$authed_r->get('/account/password')->to('account#password_form');
|
$authed_r->get('/account/password')->to('account#password_form');
|
||||||
$authed_r->get('/account/mail')->to('account#change_mail');
|
$authed_r->get('/account/mail')->to('account#change_mail');
|
||||||
|
$authed_r->get('/account/name')->to('account#change_name');
|
||||||
$authed_r->get('/export.json')->to('account#json_export');
|
$authed_r->get('/export.json')->to('account#json_export');
|
||||||
$authed_r->get('/history.json')->to('traveling#json_history');
|
$authed_r->get('/history.json')->to('traveling#json_history');
|
||||||
$authed_r->get('/history.csv')->to('traveling#csv_history');
|
$authed_r->get('/history.csv')->to('traveling#csv_history');
|
||||||
|
@ -2572,6 +2573,7 @@ sub startup {
|
||||||
->to('passengerrights#generate');
|
->to('passengerrights#generate');
|
||||||
$authed_r->post('/account/password')->to('account#change_password');
|
$authed_r->post('/account/password')->to('account#change_password');
|
||||||
$authed_r->post('/account/mail')->to('account#change_mail');
|
$authed_r->post('/account/mail')->to('account#change_mail');
|
||||||
|
$authed_r->post('/account/name')->to('account#change_name');
|
||||||
$authed_r->post('/delete')->to('account#delete');
|
$authed_r->post('/delete')->to('account#delete');
|
||||||
$authed_r->post('/logout')->to('account#do_logout');
|
$authed_r->post('/logout')->to('account#do_logout');
|
||||||
$authed_r->post('/set_token')->to('api#set_token');
|
$authed_r->post('/set_token')->to('api#set_token');
|
||||||
|
|
|
@ -468,6 +468,93 @@ sub change_mail {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub change_name {
|
||||||
|
my ($self) = @_;
|
||||||
|
|
||||||
|
my $action = $self->req->param('action');
|
||||||
|
my $password = $self->req->param('password');
|
||||||
|
my $old_name = $self->current_user->{name};
|
||||||
|
my $new_name = $self->req->param('name');
|
||||||
|
|
||||||
|
if ( $action and $action eq 'update_name' ) {
|
||||||
|
if ( $self->validation->csrf_protect->has_error('csrf_token') ) {
|
||||||
|
$self->render(
|
||||||
|
'change_name',
|
||||||
|
invalid => 'csrf',
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( not length($new_name) ) {
|
||||||
|
$self->render( 'change_name', invalid => 'user_empty' );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( $new_name !~ m{ ^ [0-9a-zA-Z_-]+ $ }x ) {
|
||||||
|
$self->render( 'change_name', invalid => 'user_format' );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( not $self->authenticate( $old_name, $self->param('password') ) ) {
|
||||||
|
$self->render( 'change_name', invalid => 'password' );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
# This call is technically superfluous. The users table has a unique
|
||||||
|
# constraint on the "name" column, so having two users with the same name
|
||||||
|
# is not possible. However, to minimize the number of failed SQL
|
||||||
|
# queries, we first do a select check here and only attempt an update
|
||||||
|
# if it succeeded.
|
||||||
|
if ( $self->users->check_if_user_name_exists( name => $new_name ) ) {
|
||||||
|
$self->render( 'change_name', invalid => 'user_collision' );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
my $success = $self->users->change_name(
|
||||||
|
uid => $self->current_user->{id},
|
||||||
|
name => $new_name
|
||||||
|
);
|
||||||
|
|
||||||
|
if ( not $success ) {
|
||||||
|
$self->render( 'change_name', invalid => 'user_collision' );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$self->flash( success => 'name' );
|
||||||
|
$self->redirect_to('account');
|
||||||
|
|
||||||
|
my $ip = $self->req->headers->header('X-Forwarded-For');
|
||||||
|
my $ua = $self->req->headers->user_agent;
|
||||||
|
my $date = DateTime->now( time_zone => 'Europe/Berlin' )
|
||||||
|
->strftime('%d.%m.%Y %H:%M:%S %z');
|
||||||
|
|
||||||
|
# In case Mojolicious is not running behind a reverse proxy
|
||||||
|
$ip
|
||||||
|
//= sprintf( '%s:%s', $self->tx->remote_address,
|
||||||
|
$self->tx->remote_port );
|
||||||
|
my $confirm_url
|
||||||
|
= $self->url_for('confirm_mail')->to_abs->scheme('https');
|
||||||
|
my $imprint_url = $self->url_for('impressum')->to_abs->scheme('https');
|
||||||
|
|
||||||
|
my $body = "Hallo ${new_name},\n\n";
|
||||||
|
$body
|
||||||
|
.= "Der Name deines Travelynx-Accounts wurde erfolgreich geändert.\n";
|
||||||
|
$body .= "Alter Name: ${old_name}\n";
|
||||||
|
$body .= "Neue Name: ${new_name}\n\n";
|
||||||
|
$body .= "Daten zur Anfrage:\n";
|
||||||
|
$body .= " * Datum: ${date}\n";
|
||||||
|
$body .= " * Client: ${ip}\n";
|
||||||
|
$body .= " * UserAgent: ${ua}\n\n\n";
|
||||||
|
$body .= "Impressum: ${imprint_url}\n";
|
||||||
|
|
||||||
|
$self->sendmail->custom( $self->current_user->{email},
|
||||||
|
'travelynx: Name geändert', $body );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$self->render('change_name');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
sub password_form {
|
sub password_form {
|
||||||
my ($self) = @_;
|
my ($self) = @_;
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
package Travelynx::Model::Users;
|
package Travelynx::Model::Users;
|
||||||
|
|
||||||
# Copyright (C) 2020 Daniel Friesel
|
# Copyright (C) 2020 Daniel Friesel
|
||||||
#
|
#
|
||||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
@ -101,11 +102,7 @@ sub set_privacy {
|
||||||
my $uid = $opt{uid};
|
my $uid = $opt{uid};
|
||||||
my $public_level = $opt{level};
|
my $public_level = $opt{level};
|
||||||
|
|
||||||
$db->update(
|
$db->update( 'users', { public_level => $public_level }, { id => $uid } );
|
||||||
'users',
|
|
||||||
{ public_level => $public_level },
|
|
||||||
{ id => $uid }
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sub mark_for_password_reset {
|
sub mark_for_password_reset {
|
||||||
|
@ -128,8 +125,7 @@ sub mark_for_password_reset {
|
||||||
{
|
{
|
||||||
user_id => $uid,
|
user_id => $uid,
|
||||||
token => $token,
|
token => $token,
|
||||||
requested_at =>
|
requested_at => DateTime->now( time_zone => 'Europe/Berlin' )
|
||||||
DateTime->now( time_zone => 'Europe/Berlin' )
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -170,8 +166,7 @@ sub mark_for_mail_change {
|
||||||
user_id => $uid,
|
user_id => $uid,
|
||||||
email => $email,
|
email => $email,
|
||||||
token => $token,
|
token => $token,
|
||||||
requested_at =>
|
requested_at => DateTime->now( time_zone => 'Europe/Berlin' )
|
||||||
DateTime->now( time_zone => 'Europe/Berlin' )
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
on_conflict => \
|
on_conflict => \
|
||||||
|
@ -198,11 +193,7 @@ sub change_mail_with_token {
|
||||||
)->hash;
|
)->hash;
|
||||||
|
|
||||||
if ($res_h) {
|
if ($res_h) {
|
||||||
$db->update(
|
$db->update( 'users', { email => $res_h->{email} }, { id => $uid } );
|
||||||
'users',
|
|
||||||
{ email => $res_h->{email} },
|
|
||||||
{ id => $uid }
|
|
||||||
);
|
|
||||||
$db->delete( 'pending_mails', { user_id => $uid } );
|
$db->delete( 'pending_mails', { user_id => $uid } );
|
||||||
$tx->commit;
|
$tx->commit;
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -210,6 +201,20 @@ sub change_mail_with_token {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub change_name {
|
||||||
|
my ( $self, %opt ) = @_;
|
||||||
|
my $db = $opt{db} // $self->{pg}->db;
|
||||||
|
my $uid = $opt{uid};
|
||||||
|
|
||||||
|
eval { $db->update( 'users', { name => $opt{name} }, { id => $uid } ); };
|
||||||
|
|
||||||
|
if ($@) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
sub remove_password_token {
|
sub remove_password_token {
|
||||||
my ( $self, %opt ) = @_;
|
my ( $self, %opt ) = @_;
|
||||||
my $db = $opt{db} // $self->{pg}->db;
|
my $db = $opt{db} // $self->{pg}->db;
|
||||||
|
@ -358,11 +363,7 @@ sub set_password_hash {
|
||||||
my $uid = $opt{uid};
|
my $uid = $opt{uid};
|
||||||
my $password = $opt{password_hash};
|
my $password = $opt{password_hash};
|
||||||
|
|
||||||
$db->update(
|
$db->update( 'users', { password => $password }, { id => $uid } );
|
||||||
'users',
|
|
||||||
{ password => $password },
|
|
||||||
{ id => $uid }
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sub check_if_user_name_exists {
|
sub check_if_user_name_exists {
|
||||||
|
@ -370,11 +371,9 @@ sub check_if_user_name_exists {
|
||||||
my $db = $opt{db} // $self->{pg}->db;
|
my $db = $opt{db} // $self->{pg}->db;
|
||||||
my $user_name = $opt{name};
|
my $user_name = $opt{name};
|
||||||
|
|
||||||
my $count = $db->select(
|
my $count
|
||||||
'users',
|
= $db->select( 'users', 'count(*) as count', { name => $user_name } )
|
||||||
'count(*) as count',
|
->hash->{count};
|
||||||
{ name => $user_name }
|
|
||||||
)->hash->{count};
|
|
||||||
|
|
||||||
if ($count) {
|
if ($count) {
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -422,15 +421,11 @@ sub use_history {
|
||||||
my $value = $opt{set};
|
my $value = $opt{set};
|
||||||
|
|
||||||
if ($value) {
|
if ($value) {
|
||||||
$db->update(
|
$db->update( 'users', { use_history => $value }, { id => $uid } );
|
||||||
'users',
|
|
||||||
{ use_history => $value },
|
|
||||||
{ id => $uid }
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return $db->select( 'users', ['use_history'],
|
return $db->select( 'users', ['use_history'], { id => $uid } )
|
||||||
{ id => $uid } )->hash->{use_history};
|
->hash->{use_history};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,10 @@
|
||||||
<div class="col s12">
|
<div class="col s12">
|
||||||
<div class="card success-color">
|
<div class="card success-color">
|
||||||
<div class="card-content white-text">
|
<div class="card-content white-text">
|
||||||
% if ($success eq 'mail') {
|
% if ($success eq 'name') {
|
||||||
|
<span class="card-title">Name geändert</span>
|
||||||
|
% }
|
||||||
|
% elsif ($success eq 'mail') {
|
||||||
<span class="card-title">Mail-Adresse geändert</span>
|
<span class="card-title">Mail-Adresse geändert</span>
|
||||||
% }
|
% }
|
||||||
% elsif ($success eq 'password') {
|
% elsif ($success eq 'password') {
|
||||||
|
@ -41,7 +44,7 @@
|
||||||
<table class="striped">
|
<table class="striped">
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="row">Name</th>
|
<th scope="row">Name</th>
|
||||||
<td><%= $acc->{name} %></td>
|
<td><a href="/account/name"><i class="material-icons">edit</i></a><%= $acc->{name} %></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="row">Mail</th>
|
<th scope="row">Mail</th>
|
||||||
|
|
Loading…
Reference in a new issue