Send inactivity notification prior to account deletion

This commit is contained in:
Daniel Friesel 2022-02-14 21:58:30 +01:00
parent 6fc21cac41
commit faf8952b87
No known key found for this signature in database
GPG key ID: 100D5BFB5166E005
4 changed files with 94 additions and 4 deletions

View file

@ -1,4 +1,5 @@
package Travelynx::Command::database; package Travelynx::Command::database;
# 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
@ -1055,6 +1056,19 @@ my @migrations = (
} }
); );
}, },
# v23 -> v24
# travelynx 1.22 warns about upcoming account deletion due to inactivity
sub {
my ($db) = @_;
$db->query(
qq{
alter table users add column deletion_notified timestamptz;
comment on column users.deletion_notified is 'Time at which warning about upcoming account deletion due to inactivity was sent';
update schema_version set version = 24;
}
);
},
); );
sub setup_db { sub setup_db {

View file

@ -18,6 +18,7 @@ sub run {
my $verification_deadline = $now->clone->subtract( hours => 48 ); my $verification_deadline = $now->clone->subtract( hours => 48 );
my $deletion_deadline = $now->clone->subtract( hours => 72 ); my $deletion_deadline = $now->clone->subtract( hours => 72 );
my $old_deadline = $now->clone->subtract( years => 1 ); my $old_deadline = $now->clone->subtract( years => 1 );
my $old_notification_deadline = $now->clone->subtract( weeks => 4 );
my $db = $self->app->pg->db; my $db = $self->app->pg->db;
my $tx = $db->begin; my $tx = $db->begin;
@ -82,12 +83,39 @@ sub run {
printf( "Pruned %d pending mail change(s)\n", $rows ); printf( "Pruned %d pending mail change(s)\n", $rows );
} }
my $to_notify = $db->select(
'users',
[ 'id', 'name', 'email', 'last_seen' ],
{
last_seen => { '<', $old_deadline },
deletion_notified => undef
}
);
for my $user ( $to_notify->hashes->each ) {
$self->app->sendmail->age_deletion_notification(
name => $user->{name},
email => $user->{email},
last_seen => $user->{last_seen},
login_url => $self->app->base_url_for('login')->to_abs,
account_url => $self->app->base_url_for('account')->to_abs,
imprint_url => $self->app->base_url_for('impressum')->to_abs,
);
$self->app->users->mark_deletion_notified( uid => $user->{id} );
}
my $to_delete = $db->select( 'users', ['id'], my $to_delete = $db->select( 'users', ['id'],
{ deletion_requested => { '<', $deletion_deadline } } ); { deletion_requested => { '<', $deletion_deadline } } );
my @uids_to_delete = $to_delete->arrays->map( sub { shift->[0] } )->each; my @uids_to_delete = $to_delete->arrays->map( sub { shift->[0] } )->each;
$to_delete $to_delete = $db->select(
= $db->select( 'users', ['id'], { last_seen => { '<', $old_deadline } } ); 'users',
['id'],
{
last_seen => { '<', $old_deadline },
deletion_notified => { '<', $old_notification_deadline }
}
);
push( @uids_to_delete, push( @uids_to_delete,
$to_delete->arrays->map( sub { shift->[0] } )->each ); $to_delete->arrays->map( sub { shift->[0] } )->each );

View file

@ -1,4 +1,5 @@
package Travelynx::Helper::Sendmail; package Travelynx::Helper::Sendmail;
# 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
@ -41,4 +42,34 @@ sub custom {
return try_to_sendmail($reg_mail); return try_to_sendmail($reg_mail);
} }
sub age_deletion_notification {
my ( $self, %opt ) = @_;
my $name = $opt{name};
my $email = $opt{email};
my $last_seen = $opt{last_seen};
my $login_url = $opt{login_url};
my $account_url = $opt{account_url};
my $imprint_url = $opt{imprint_url};
my $body = "Hallo ${name},\n\n";
$body
.= "Dein travelynx-Account wurde seit dem ${last_seen} nicht verwendet.\n";
$body
.= "Im Sinne der Datensparsamkeit wird er daher in vier Wochen gelöscht.\n";
$body
.= "Falls du den Account weiterverwenden möchtest, kannst du dich unter\n";
$body .= "<$login_url> anmelden.\n";
$body
.= "Durch die Anmeldung wird die Löschung automatisch abgebrochen.\n\n";
$body
.= "Falls du den Account löschen, aber zuvor deine Daten exportieren möchtest,\n";
$body .= "kannst du dich unter obiger URL anmelden, unter <$account_url>\n";
$body
.= "deine Daten exportieren und anschließend den Account löschen lassen.\n\n\n";
$body .= "Impressum: ${imprint_url}\n";
return $self->custom( $email,
'travelynx: Löschung deines Accounts', $body );
}
1; 1;

View file

@ -23,8 +23,25 @@ sub mark_seen {
$db->update( $db->update(
'users', 'users',
{ last_seen => DateTime->now( time_zone => 'Europe/Berlin' ) }, {
{ id => $uid } last_seen => DateTime->now( time_zone => 'Europe/Berlin' ),
deletion_notified => undef
},
{ id => $uid }
);
}
sub mark_deletion_notified {
my ( $self, %opt ) = @_;
my $uid = $opt{uid};
my $db = $opt{db} // $self->{pg}->db;
$db->update(
'users',
{
deletion_notified => DateTime->now( time_zone => 'Europe/Berlin' ),
},
{ id => $uid }
); );
} }