]> ruin.nu Git - ndwebbie.git/commitdiff
Let users change email address
authorMichael Andreen <harv@ruin.nu>
Fri, 5 Jun 2009 21:30:21 +0000 (23:30 +0200)
committerMichael Andreen <harv@ruin.nu>
Sat, 6 Jun 2009 19:22:52 +0000 (21:22 +0200)
database/email.sql [new file with mode: 0644]
lib/NDWeb/Controller/Settings.pm
root/src/settings/index.tt2

diff --git a/database/email.sql b/database/email.sql
new file mode 100644 (file)
index 0000000..c1e8a84
--- /dev/null
@@ -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
+);
index 4a60ebebf53354378a35390568121cc6cafcbb45..3f09a435f8e57979dfa99e37b466432c901900bb 100644 (file)
@@ -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 <nd@ruin.nu>',
+                       '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
 
index 4e1c96f833135b08ff7f97a8236f46c53c7452d4..6faddb5043376fdb9aa7f01501fb8b01e853e63f 100644 (file)
@@ -9,6 +9,10 @@
        <br>
        <input type="submit" value="Change">
 </fieldset></form>
+<form action="[% c.uri_for('changeEmail') %]" method="post"><fieldset> <legend>Email</legend>
+       <input type="text" name="email" value="[% email | html %]">
+       <br><input type="submit" value="Change">
+</fieldset></form>
 <form action="[% c.uri_for('changeBirthday') %]" method="post"><fieldset> <legend>Birthday</legend>
        YYYY-MM-DD:
        <input type="text" name="birthday" value="[% birthday %]" id="birthday">