use a separate table for registration tokens
This commit is contained in:
parent
a57a24c2d6
commit
048767149e
6 changed files with 70 additions and 22 deletions
|
@ -728,17 +728,26 @@ sub startup {
|
|||
);
|
||||
|
||||
$self->helper(
|
||||
'get_user_token' => sub {
|
||||
my ( $self, $uid ) = @_;
|
||||
'verify_registration_token' => sub {
|
||||
my ( $self, $uid, $token ) = @_;
|
||||
|
||||
my $res = $self->pg->db->select(
|
||||
'users',
|
||||
[ 'name', 'status', 'token' ],
|
||||
{ id => $uid }
|
||||
my $db = $self->pg->db;
|
||||
my $tx = $db->begin;
|
||||
|
||||
my $res = $db->select(
|
||||
'pending_registrations',
|
||||
'count(*) as count',
|
||||
{
|
||||
user_id => $uid,
|
||||
token => $token
|
||||
}
|
||||
);
|
||||
|
||||
if ( my $ret = $res->array ) {
|
||||
return @{$ret};
|
||||
if ( $res->hash->{count} ) {
|
||||
$db->update( 'users', { status => 1 }, { id => $uid } );
|
||||
$db->delete( 'pending_registrations', { user_id => $uid } );
|
||||
$tx->commit;
|
||||
return 1;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -976,15 +985,23 @@ sub startup {
|
|||
status => 0,
|
||||
public_level => 0,
|
||||
email => $email,
|
||||
token => $token,
|
||||
password => $password,
|
||||
registered_at => $now,
|
||||
last_seen => $now,
|
||||
},
|
||||
{ returning => 'id' }
|
||||
);
|
||||
my $uid = $res->hash->{id};
|
||||
|
||||
return $res->hash->{id};
|
||||
$db->insert(
|
||||
'pending_registrations',
|
||||
{
|
||||
user_id => $uid,
|
||||
token => $token
|
||||
}
|
||||
);
|
||||
|
||||
return $uid;
|
||||
}
|
||||
);
|
||||
|
||||
|
|
|
@ -424,6 +424,38 @@ my @migrations = (
|
|||
}
|
||||
);
|
||||
},
|
||||
|
||||
# v9 -> v10
|
||||
# Add pending_registrations table. The users.token column is no longer
|
||||
# needed.
|
||||
sub {
|
||||
my ($db) = @_;
|
||||
$db->query(
|
||||
qq{
|
||||
create table pending_registrations (
|
||||
user_id integer not null references users (id) primary key,
|
||||
token varchar(80) not null
|
||||
);
|
||||
comment on table pending_registrations is 'Verification tokens for newly registered accounts';
|
||||
update schema_version set version = 10;
|
||||
}
|
||||
);
|
||||
my $res = $db->select( 'users', [ 'id', 'token' ], { status => 0 } );
|
||||
for my $user ( $res->hashes->each ) {
|
||||
$db->insert(
|
||||
'pending_registrations',
|
||||
{
|
||||
user_id => $user->{id},
|
||||
token => $user->{token}
|
||||
}
|
||||
);
|
||||
}
|
||||
$db->query(
|
||||
qq{
|
||||
alter table users drop column token;
|
||||
}
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
sub setup_db {
|
||||
|
|
|
@ -59,7 +59,8 @@ sub run {
|
|||
}
|
||||
);
|
||||
}
|
||||
$db->delete( 'users', { id => $user->{id} } );
|
||||
$db->delete( 'pending_registrations', { user_id => $user->{id} } );
|
||||
$db->delete( 'users', { id => $user->{id} } );
|
||||
printf( "Pruned unverified user %d\n", $user->{id} );
|
||||
}
|
||||
|
||||
|
|
|
@ -159,20 +159,16 @@ sub verify {
|
|||
my $id = $self->stash('id');
|
||||
my $token = $self->stash('token');
|
||||
|
||||
my @db_user = $self->get_user_token($id);
|
||||
|
||||
if ( not @db_user ) {
|
||||
if ( not $id =~ m{ ^ \d+ $ }x ) {
|
||||
$self->render( 'register', invalid => 'token' );
|
||||
return;
|
||||
}
|
||||
|
||||
my ( $db_name, $db_status, $db_token ) = @db_user;
|
||||
|
||||
if ( not $db_name or $token ne $db_token or $db_status != 0 ) {
|
||||
if ( not $self->verify_registration_token( $id, $token ) ) {
|
||||
$self->render( 'register', invalid => 'token' );
|
||||
return;
|
||||
}
|
||||
$self->app->pg->db->update( 'users', { status => 1 }, { id => $id } );
|
||||
|
||||
$self->render( 'login', from => 'verification' );
|
||||
}
|
||||
|
||||
|
|
|
@ -71,9 +71,11 @@ $t->post_ok(
|
|||
);
|
||||
$t->status_is(200)->content_like(qr{nicht freigeschaltet});
|
||||
|
||||
my $res = $t->app->pg->db->select( 'users', [ 'id', 'token' ],
|
||||
{ name => 'someone' } );
|
||||
my ( $uid, $token ) = @{ $res->hash }{qw{id token}};
|
||||
my $res = $t->app->pg->db->select( 'users', ['id'], { name => 'someone' } );
|
||||
my $uid = $res->hash->{id};
|
||||
$res = $t->app->pg->db->select( 'pending_registrations', ['token'],
|
||||
{ user_id => $uid } );
|
||||
my $token = $res->hash->{token};
|
||||
|
||||
# Successful verification
|
||||
$t->get_ok("/reg/${uid}/${token}");
|
||||
|
|
|
@ -47,7 +47,7 @@
|
|||
% }
|
||||
% elsif ($invalid eq 'token') {
|
||||
<span class="card-title">Ungültiger Token</span>
|
||||
<p>Die Verifikation deiner Mail-Adresse ist fehlgeschlagen oder du hast den Token schon einmal verwendet.</p>
|
||||
<p>Möglicherweise ist die Verifikation deiner Mail-Adresse fehlgeschlagen oder du hast den Token schon einmal verwendet.</p>
|
||||
% }
|
||||
% elsif ($invalid eq 'confirmation') {
|
||||
<span class="card-title">Account nicht freigeschaltet</span>
|
||||
|
|
Loading…
Reference in a new issue