]> ruin.nu Git - ndwebbie.git/blob - lib/NDWeb/Controller/Settings.pm
Move sms and hostname to settings
[ndwebbie.git] / lib / NDWeb / Controller / Settings.pm
1 package NDWeb::Controller::Settings;
2
3 use strict;
4 use warnings;
5 use feature ":5.10";
6 use parent 'Catalyst::Controller';
7
8 use NDWeb::Include;
9
10 use DateTime::TimeZone;
11 use Mail::Sendmail;
12 use Email::Valid;
13
14 =head1 NAME
15
16 NDWeb::Controller::Settings - Catalyst Controller
17
18 =head1 DESCRIPTION
19
20 Catalyst Controller.
21
22 =head1 METHODS
23
24 =cut
25
26
27 =head2 index 
28
29 =cut
30
31 sub index :Path :Args(0) {
32         my ( $self, $c ) = @_;
33         my $dbh = $c->model;
34
35         $c->stash(error => $c->flash->{error});
36
37         my @stylesheets = ('Default');
38         my $dir = $c->path_to('root/static/css/black.css')->dir;
39         while (my $file = $dir->next){
40                 if(!$file->is_dir && $file->basename =~ m{^(\w+)\.css$}){
41                         push @stylesheets,$1;
42                 }
43         }
44         $c->stash(stylesheets => \@stylesheets);
45
46         my $u = $dbh->selectrow_hashref(q{
47 SELECT birthday,timezone,email,discord_id,sms,call_if_needed,sms_note,hostmask
48 FROM users WHERE uid = $1
49                 },undef,$c->user->id);
50         $c->stash(u => $u);
51         $c->stash(email =>  $c->flash->{email} // $u->{email});
52         $c->stash(discord_id =>  $c->flash->{discord_id} // $u->{discord_id});
53
54         my @timezone = split m{/},$u->{timezone},2;
55         $c->stash(timezone => \@timezone);
56
57         my @cat = DateTime::TimeZone->categories;
58         unshift @cat, 'GMT';
59         $c->stash(tzcategories => \@cat);
60
61         my @countries = DateTime::TimeZone->names_in_category($timezone[0]);
62         $c->stash(tzcountries => \@countries);
63 }
64
65 sub changeStylesheet : Local {
66         my ( $self, $c ) = @_;
67         my $dbh = $c->model;
68
69         my $query = $dbh->prepare(q{UPDATE users SET css = NULLIF($2,'Default')
70                 WHERE uid = $1
71         });
72         my $css = html_escape $c->req->param('stylesheet');
73         $query->execute($c->user->id,$css);
74
75         $c->res->redirect($c->uri_for(''));
76 }
77
78 sub changeBirthday : Local {
79         my ( $self, $c ) = @_;
80         my $dbh = $c->model;
81
82         my $query = $dbh->prepare(q{UPDATE users SET birthday = NULLIF($2,'')::date
83                 WHERE uid = $1
84                 });
85         eval{
86                 my $birthday = html_escape $c->req->param('birthday');
87                 $query->execute($c->user->id,$birthday);
88         };
89         if ($@){
90                 if ($@ =~ /invalid input syntax for type date/){
91                         $c->flash(error => 'Bad syntax for day, use YYYY-MM-DD.');
92                 }else{
93                         $c->flash(error => $@);
94                 }
95         }
96         $c->res->redirect($c->uri_for(''));
97 }
98
99 sub changeTimezone : Local {
100         my ( $self, $c ) = @_;
101         my $dbh = $c->model;
102
103         my $timezone = $c->req->param('timezone');
104         my $query = $dbh->prepare(q{UPDATE users SET timezone = $2 WHERE uid = $1});
105         eval{
106                 $dbh->selectrow_array(q{SELECT NOW() AT TIME ZONE $1},undef,$timezone);
107                 $query->execute($c->user->id,$timezone );
108         };
109         if ($@){
110                 $c->flash(error => $@);
111         }
112         $c->res->redirect($c->uri_for(''));
113 }
114
115 sub changePassword : Local {
116         my ( $self, $c ) = @_;
117         my $dbh = $c->model;
118
119         my $pass = $c->req->param('pass');
120         if (length $pass < 4) {
121                 $c->flash(error => "Your password need to be at least 4 characters");
122         } else {
123                 my $query = $dbh->prepare(q{UPDATE users SET password = $1
124                         WHERE password = crypt($2,password) AND uid = $3
125                 });
126                 my $oldpass = $c->req->param('oldpass');
127                 $query->execute($pass,$oldpass,$c->user->id);
128
129                 $c->flash(error => "Old password was invalid") unless $query->rows;
130         }
131
132         $c->res->redirect($c->uri_for(''));
133 }
134
135 sub changeEmail : Local {
136         my ( $self, $c ) = @_;
137         my $dbh = $c->model;
138
139         my $email = $c->req->param('email');
140
141         if ($email =~ /^\s*$/) {
142                 my $update = $dbh->prepare(q{
143 UPDATE users SET email = NULL WHERE uid = $1;
144                         });
145                 $update->execute($c->user->id);
146                 $c->flash(error => 'email cleared');
147                 $c->res->redirect($c->uri_for(''));
148                 return,
149         }
150
151         unless (Email::Valid->address($email)){
152                 $c->flash(email => $email);
153                 $c->flash(error => 'Invalid email address');
154                 $c->res->redirect($c->uri_for(''));
155                 return,
156         }
157
158         eval{
159                 my $insert = $dbh->prepare(q{
160 INSERT INTO email_change (uid,email) VALUES ($1,$2) RETURNING id;
161                         });
162                 $insert->execute($c->user->id,$email);
163
164                 my ($id) = $insert->fetchrow_array;
165
166                 my %mail = (
167                         smtp => 'localhost',
168                         To      => $email,
169                         From    => 'NewDawn Command <nd@ruin.nu>',
170                         'Content-type' => 'text/plain; charset="UTF-8"',
171                         Subject => 'Change email address',
172                         Message => qq{
173 You have requested to change email address on the NewDawn website.
174 If that is not the case, then feel free to ignore this email. Otherwise
175 use the following url to confirm the change:
176
177 }.$c->uri_for('confirmEmail',$id)."\n",
178                 );
179
180                 if (sendmail %mail) {
181                         $c->flash(error => 'Sent mail for confirmation.');
182                 }else {
183                         $c->flash(email => $email);
184                         $c->flash(error => $Mail::Sendmail::error);
185                 }
186         };
187         if($@){
188                 if($@ =~ /duplicate key value violates unique constraint/){
189                         $c->flash(email => $email);
190                         $c->flash(error => 'Something went wrong, try to set the email again');
191                 }else{
192                         die $@;
193                 }
194         }
195         $c->res->redirect($c->uri_for(''));
196 }
197
198 sub postsmsupdate : Local {
199         my ( $self, $c ) = @_;
200         my $dbh = $c->model;
201
202         my $callme = $c->req->param('callme') || 0;
203         my $sms = html_escape $c->req->param('sms');
204         my $smsnote = $c->req->param('smsnote');
205         $dbh->do(q{
206 UPDATE users SET sms = $1, call_if_needed =  $2, sms_note = $3 WHERE uid = $4
207                 },undef, $sms, $callme, $smsnote, $c->user->id);
208
209         $c->res->redirect($c->uri_for(''));
210 }
211
212 sub changeDiscordId : Local {
213         my ( $self, $c ) = @_;
214         my $dbh = $c->model;
215
216         my $discord_id = $c->req->param('discord_id');
217
218         if ($discord_id =~ /^\s*$/) {
219                 my $update = $dbh->prepare(q{
220 UPDATE users SET discord_id = NULL WHERE uid = $1;
221                         });
222                 $update->execute($c->user->id);
223                 $c->flash(error => 'discord id cleared');
224                 $c->res->redirect($c->uri_for(''));
225                 return,
226         }
227
228         eval{
229                 my $update = $dbh->prepare(q{
230 UPDATE users SET discord_id = $2 WHERE uid = $1;
231                         });
232                 $update->execute($c->user->id,$discord_id);
233         };
234         if($@){
235                 if($@ =~ /duplicate key value violates unique constraint/){
236                         $c->flash(discord_id => $discord_id);
237                         $c->flash(error => 'Someone else is using this discord id, duplicate account?');
238                 }else{
239                         die $@;
240                 }
241         }
242         $c->res->redirect($c->uri_for(''));
243 }
244
245 sub confirmEmail : Local {
246         my ( $self, $c, $id ) = @_;
247         my $dbh = $c->model;
248
249         $dbh->begin_work;
250         my $query = $dbh->prepare(q{
251 UPDATE email_change SET confirmed = TRUE
252 WHERE uid = $1 AND id = $2 AND NOT confirmed
253 RETURNING email
254                 });
255         $query->execute($c->user->id,$id);
256         my ($email) = $query->fetchrow_array;
257
258         if ($email){
259                 $dbh->do(q{UPDATE users SET email = $2 WHERE uid = $1}
260                         ,undef,$c->user->id,$email);
261                 $c->flash(error => "Email updated.");
262         }else{
263                 $c->flash(error => "$id is not a valid change id for your account, or already confirmed");
264         }
265         $dbh->commit;
266         $c->res->redirect($c->uri_for(''));
267 }
268
269 sub posthostupdate : Local {
270         my ( $self, $c ) = @_;
271         my $dbh = $c->model;
272
273         my $hostname = html_escape $c->req->param('hostname');
274         $dbh->do(q{UPDATE users SET hostmask = ? WHERE uid = ?
275                 },undef, $hostname, $c->user->id);
276
277         $c->res->redirect($c->uri_for(''));
278 }
279
280 =head1 AUTHOR
281
282 Michael Andreen (harv@ruin.nu)
283
284 =head1 LICENSE
285
286 GPL 2.0, or later.
287
288 =cut
289
290 1;