From d5a506d05cc2bf53a76b6bf4beef12a34aedf023 Mon Sep 17 00:00:00 2001 From: Michael Andreen Date: Fri, 5 Jun 2009 23:30:21 +0200 Subject: [PATCH] Let users change email address --- database/email.sql | 7 +++ lib/NDWeb/Controller/Settings.pm | 84 +++++++++++++++++++++++++++++++- root/src/settings/index.tt2 | 4 ++ 3 files changed, 93 insertions(+), 2 deletions(-) create mode 100644 database/email.sql diff --git a/database/email.sql b/database/email.sql new file mode 100644 index 0000000..c1e8a84 --- /dev/null +++ b/database/email.sql @@ -0,0 +1,7 @@ +DROP TABLE IF EXISTS email_change; +CREATE TABLE email_change ( + id TEXT PRIMARY KEY DEFAULT (md5((now() + random() * interval '100 year')::text)), + uid INTEGER NOT NULL REFERENCES users(uid), + email TEXT NOT NULL, + confirmed BOOLEAN NOT NULL DEFAULT false +); diff --git a/lib/NDWeb/Controller/Settings.pm b/lib/NDWeb/Controller/Settings.pm index 4a60ebe..3f09a43 100644 --- a/lib/NDWeb/Controller/Settings.pm +++ b/lib/NDWeb/Controller/Settings.pm @@ -2,11 +2,14 @@ package NDWeb::Controller::Settings; use strict; use warnings; +use feature ":5.10"; use parent 'Catalyst::Controller'; use NDWeb::Include; use DateTime::TimeZone; +use Mail::Sendmail; +use Email::Valid; =head1 NAME @@ -40,10 +43,11 @@ sub index :Path :Args(0) { } $c->stash(stylesheets => \@stylesheets); - my ($birthday,$timezone) = $dbh->selectrow_array(q{ -SELECT birthday,timezone FROM users WHERE uid = $1 + my ($birthday,$timezone,$email) = $dbh->selectrow_array(q{ +SELECT birthday,timezone,email FROM users WHERE uid = $1 },undef,$c->user->id); $c->stash(birthday => $birthday); + $c->stash(email => $c->flash->{email} // $email); my @timezone = split m{/},$timezone,2; $c->stash(timezone => \@timezone); @@ -116,6 +120,82 @@ sub changePassword : Local { $c->res->redirect($c->uri_for('')); } +sub changeEmail : Local { + my ( $self, $c ) = @_; + my $dbh = $c->model; + + my $email = $c->req->param('email'); + + unless (Email::Valid->address($email)){ + $c->flash(email => $email); + $c->flash(error => 'Invalid email address'); + $c->res->redirect($c->uri_for('')); + return, + } + + eval{ + my $insert = $dbh->prepare(q{ +INSERT INTO email_change (uid,email) VALUES ($1,$2) RETURNING id; + }); + $insert->execute($c->user->id,$email); + + my ($id) = $insert->fetchrow_array; + + my %mail = ( + smtp => 'ruin.nu', + To => $email, + From => 'NewDawn Command ', + 'Content-type' => 'text/plain; charset="UTF-8"', + Subject => 'Change email address', + Message => qq{ +You have requested to change email address on the NewDawn website. +If that is not the case, then feel free to ignore this email. Otherwise +use the following url to confirm the change: + +}.$c->uri_for('confirmEmail',$id)."\n", + ); + + if (sendmail %mail) { + $c->flash(error => 'Sent mail for confirmation.'); + }else { + $c->flash(error => $Mail::Sendmail::error); + } + }; + if($@){ + if($@ =~ /duplicate key value violates unique constraint/){ + $c->flash(email => $email); + $c->flash(error => 'Something went wrong, try to set the email again'); + }else{ + die $@; + } + } + $c->res->redirect($c->uri_for('')); +} + +sub confirmEmail : Local { + my ( $self, $c, $id ) = @_; + my $dbh = $c->model; + + $dbh->begin_work; + my $query = $dbh->prepare(q{ +UPDATE email_change SET confirmed = TRUE +WHERE uid = $1 AND id = $2 AND NOT confirmed +RETURNING email + }); + $query->execute($c->user->id,$id); + my ($email) = $query->fetchrow_array; + + if ($email){ + $dbh->do(q{UPDATE users SET email = $2 WHERE uid = $1} + ,undef,$c->user->id,$email); + $c->flash(error => "Email updated."); + }else{ + $c->flash(error => "$id is not a valid change id for your account, or already confirmed"); + } + $dbh->commit; + $c->res->redirect($c->uri_for('')); +} + =head1 AUTHOR diff --git a/root/src/settings/index.tt2 b/root/src/settings/index.tt2 index 4e1c96f..6faddb5 100644 --- a/root/src/settings/index.tt2 +++ b/root/src/settings/index.tt2 @@ -9,6 +9,10 @@
+
Email + +
+
Birthday YYYY-MM-DD: -- 2.39.2