Unverified Commit faf8952b authored by Birte Kristina Friesel's avatar Birte Kristina Friesel
Browse files

Send inactivity notification prior to account deletion

parent 6fc21cac
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
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 {
+30 −2
Original line number Diff line number Diff line
@@ -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 );
+31 −0
Original line number Diff line number Diff line
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;
+19 −2
Original line number Diff line number Diff line
@@ -23,7 +23,24 @@ sub mark_seen {

	$db->update(
		'users',
		{ last_seen => DateTime->now( time_zone => 'Europe/Berlin' ) },
		{
			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 }
	);
}