summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorDaniel Friesel <derf@finalrewind.org>2022-02-14 21:58:30 +0100
committerDaniel Friesel <derf@finalrewind.org>2022-02-14 21:58:30 +0100
commitfaf8952b8732d6314e3d3429f5cc761564565e44 (patch)
tree0247aa13ee6f06f33f53b848503d1e0fb42ce884 /lib
parent6fc21cac41e3b1bf4a6484fed736aec27b340b63 (diff)
Send inactivity notification prior to account deletion
Diffstat (limited to 'lib')
-rw-r--r--lib/Travelynx/Command/database.pm14
-rw-r--r--lib/Travelynx/Command/maintenance.pm32
-rw-r--r--lib/Travelynx/Helper/Sendmail.pm31
-rw-r--r--lib/Travelynx/Model/Users.pm21
4 files changed, 94 insertions, 4 deletions
diff --git a/lib/Travelynx/Command/database.pm b/lib/Travelynx/Command/database.pm
index 4f7c792..eb2443c 100644
--- a/lib/Travelynx/Command/database.pm
+++ b/lib/Travelynx/Command/database.pm
@@ -1,4 +1,5 @@
package Travelynx::Command::database;
+
# Copyright (C) 2020 Daniel Friesel
#
# 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 {
diff --git a/lib/Travelynx/Command/maintenance.pm b/lib/Travelynx/Command/maintenance.pm
index 5f609cb..58189ff 100644
--- a/lib/Travelynx/Command/maintenance.pm
+++ b/lib/Travelynx/Command/maintenance.pm
@@ -18,6 +18,7 @@ sub run {
my $verification_deadline = $now->clone->subtract( hours => 48 );
my $deletion_deadline = $now->clone->subtract( hours => 72 );
my $old_deadline = $now->clone->subtract( years => 1 );
+ my $old_notification_deadline = $now->clone->subtract( weeks => 4 );
my $db = $self->app->pg->db;
my $tx = $db->begin;
@@ -82,12 +83,39 @@ sub run {
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'],
{ deletion_requested => { '<', $deletion_deadline } } );
my @uids_to_delete = $to_delete->arrays->map( sub { shift->[0] } )->each;
- $to_delete
- = $db->select( 'users', ['id'], { last_seen => { '<', $old_deadline } } );
+ $to_delete = $db->select(
+ 'users',
+ ['id'],
+ {
+ last_seen => { '<', $old_deadline },
+ deletion_notified => { '<', $old_notification_deadline }
+ }
+ );
push( @uids_to_delete,
$to_delete->arrays->map( sub { shift->[0] } )->each );
diff --git a/lib/Travelynx/Helper/Sendmail.pm b/lib/Travelynx/Helper/Sendmail.pm
index 8a7b1f1..376861d 100644
--- a/lib/Travelynx/Helper/Sendmail.pm
+++ b/lib/Travelynx/Helper/Sendmail.pm
@@ -1,4 +1,5 @@
package Travelynx::Helper::Sendmail;
+
# Copyright (C) 2020 Daniel Friesel
#
# SPDX-License-Identifier: AGPL-3.0-or-later
@@ -41,4 +42,34 @@ sub custom {
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;
diff --git a/lib/Travelynx/Model/Users.pm b/lib/Travelynx/Model/Users.pm
index 1371b8a..70d81c4 100644
--- a/lib/Travelynx/Model/Users.pm
+++ b/lib/Travelynx/Model/Users.pm
@@ -23,8 +23,25 @@ sub mark_seen {
$db->update(
'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 }
);
}