add a human check to registrations
[authserver.git] / app / index.php
CommitLineData
133aecbe
RK
1<?php
2/* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
4 * You can obtain one at http://mozilla.org/MPL/2.0/. */
5
6// Include the common auth system files (including the OAuth2 Server object).
7require_once(__DIR__.'/authsystem.inc.php');
8
4c6d8064 9$errors = $utils->checkForSecureConnection();
b0e48c35 10$utils->sendSecurityHeaders();
d26d08a1 11
7be13777 12// Initialize the HTML document with our basic elements.
3f24953f 13extract($utils->initHTMLDocument(sprintf(_('%s Authentication Server'), $utils->settings['operator_name']))); // sets $document, $html, $head, $title, $body
d26d08a1
RK
14
15if (!count($errors)) {
4c6d8064 16 $session = $utils->initSession(); // Read session or create new session and set cookie.
d26d08a1 17 $user = array('id' => 0, 'email' => '');
b19743bc 18 $pagetype = 'default';
4c6d8064 19 if (is_null($session)) {
3f24953f
RK
20 $errors[] = _('The session system is not working.').' '
21 .sprintf(_('Please <a href="%s">contact %s</a> and tell the team about this.'), $utils->settings['operator_contact_url'], $utils->settings['operator_name']);
4c6d8064
RK
22 }
23 elseif (array_key_exists('logout', $_GET)) {
24 $result = $db->prepare('UPDATE `auth_sessions` SET `logged_in` = FALSE WHERE `id` = :sessid;');
25 if (!$result->execute(array(':sessid' => $session['id']))) {
26 $utils->log('logout_failure', 'session: '.$session['id']);
b217e836 27 $errors[] = _('Unexpected error while logging out.');
4c6d8064
RK
28 }
29 $session['logged_in'] = 0;
30 }
31 elseif (array_key_exists('email', $_POST)) {
fb7b39f0 32 if (!preg_match('/^[^@]+@([^@]+\.[^@]+|localhost)$/', $_POST['email'])) {
4c6d8064
RK
33 $errors[] = _('The email address is invalid.');
34 }
d42db7c5
RK
35 elseif ($utils->verifyTimeCode($_POST['tcode'] ?? '', $session)) {
36 $result = $db->prepare('SELECT `id`, `pwdhash`, `email`, `status`, `verify_hash`, `group_id`, `hcheck_question`, `hcheck_solution` FROM `auth_users` WHERE `email` = :email;');
4c6d8064 37 $result->execute(array(':email' => $_POST['email']));
d42db7c5
RK
38 $user_data = $result->fetch(PDO::FETCH_ASSOC);
39 if ($user_data) {
40 $user = $user_data;
41 }
60e46184
RK
42 // If we need to add the email to a group, note here which user's group we should be added to - otherwise, set to 0.
43 $addgroup = (array_key_exists('grouptoexisting', $_POST) && intval($session['user']) && ($session['user'] != @$user['id'])) ? $session['user'] : 0;
d42db7c5 44 if ($user['id'] && $user['status'] != 'unchecked' && array_key_exists('pwd', $_POST)) {
4c6d8064
RK
45 // existing user, check password
46 if (($user['status'] == 'ok') && $utils->pwdVerify(@$_POST['pwd'], $user)) {
47 // Check if a newer hashing algorithm is available
48 // or the cost has changed
49 if ($utils->pwdNeedsRehash($user)) {
50 // If so, create a new hash, and replace the old one
51 $newHash = $utils->pwdHash($_POST['pwd']);
52 $result = $db->prepare('UPDATE `auth_users` SET `pwdhash` = :pwdhash WHERE `id` = :userid;');
53 if (!$result->execute(array(':pwdhash' => $newHash, ':userid' => $user['id']))) {
54 $utils->log('user_hash_save_failure', 'user: '.$user['id']);
55 }
56 else {
57 $utils->log('pwd_rehash_success', 'user: '.$user['id']);
58 }
59 }
d26d08a1 60
4c6d8064
RK
61 // Log user in - update session key for that, see https://wiki.mozilla.org/WebAppSec/Secure_Coding_Guidelines#Login
62 $utils->log('login', 'user: '.$user['id']);
60e46184
RK
63 $prev_session = $session;
64 $session = $utils->getLoginSession($user['id'], $session);
4c6d8064
RK
65 // If a verify_hash if set on a verified user, a password reset had been requested. As a login works right now, cancel that reset request by deleting the hash.
66 if (strlen(@$user['verify_hash'])) {
67 $result = $db->prepare('UPDATE `auth_users` SET `verify_hash` = \'\' WHERE `id` = :userid;');
68 if (!$result->execute(array(':userid' => $user['id']))) {
69 $utils->log('empty_vhash_failure', 'user: '.$user['id']);
70 }
71 else {
72 $user['verify_hash'] = '';
73 }
74 }
60e46184 75 $utils->doRedirectIfSet($prev_session);
d26d08a1 76 }
89975cb9 77 else {
4c6d8064 78 $errors[] = _('This password is invalid or your email is not verified yet. Did you type them correctly?');
89975cb9 79 }
d26d08a1 80 }
4c6d8064
RK
81 else {
82 // new user: check password, create user and send verification; existing users: re-send verification or send password change instructions
83 if (array_key_exists('pwd', $_POST)) {
84 $errors += $utils->checkPasswordConstraints(strval($_POST['pwd']), $_POST['email']);
85 }
86 if (!count($errors)) {
87 // Put user into the DB
e876642c 88 if (!$user['id']) {
4c6d8064
RK
89 $newHash = $utils->pwdHash($_POST['pwd']);
90 $vcode = $utils->createVerificationCode();
d42db7c5
RK
91 $result = $db->prepare('INSERT INTO `auth_users` (`email`, `pwdhash`, `status`, `verify_hash`) VALUES (:email, :pwdhash, :status, :vcode);');
92 if (!$result->execute(array(':email' => $_POST['email'], ':pwdhash' => $newHash, ':status' => 'unchecked', ':vcode' => $vcode))) {
60e46184 93 $utils->log('user_insert_failure', 'email: '.$_POST['email'].' - '.$result->errorInfo()[2]);
3f24953f
RK
94 $errors[] = _('Could not add user.').' '
95 .sprintf(_('Please <a href="%s">contact %s</a> and tell the team about this.'), $utils->settings['operator_contact_url'], $utils->settings['operator_name']);
4c6d8064 96 }
d42db7c5
RK
97 $user = [
98 'id' => $db->lastInsertId(),
99 'email' => $_POST['email'],
100 'pwdhash' => $newHash,
101 'status' => 'unchecked',
102 'verify_hash' => $vcode,
103 'hcheck_question' => null,
104 'hcheck_solution' => null,
105 ];
4c6d8064 106 $utils->log('new_user', 'user: '.$user['id'].', email: '.$user['email']);
e876642c 107 }
d42db7c5
RK
108 $utils->log('user_log_check', 'user: '.$user['id'].', email: '.$user['email'].', status: '.$user['status']);
109 if ($user['status'] == 'unchecked' && !is_null($user['hcheck_question']) && array_key_exists('hcheck_solution', $_POST)) {
110 if ($_POST['hcheck_solution'] == $user['hcheck_solution']) {
111 $result = $db->prepare('UPDATE `auth_users` SET `status` = :status, `hcheck_question` = :hcquestion, `hcheck_solution` = :hcsolution WHERE `id` = :userid;');
112 if (!$result->execute(array(':status' => 'unverified', ':hcquestion' => null, ':hcsolution' => null, ':userid' => $user['id']))) {
113 $errors[] = _('Could not update user status.').' '
114 .sprintf(_('Please <a href="%s">contact %s</a> and tell the team about this.'), $utils->settings['operator_contact_url'], $utils->settings['operator_name']);
115 }
116 $user['status'] = 'unverified';
117 $utils->log('user_checked', 'user: '.$user['id'].', email: '.$user['email']);
118 }
119 else {
120 $errors[] = _('Solution was not correct. Please start over.');
121 $utils->log('user_check_failed', 'user: '.$user['id'].', email: '.$user['email']);
122 }
123 }
124 if ($user['status'] == 'unchecked') {
125 // Display a humanity check.
126 $pagetype = 'human_check';
127 // simple numbers, we stay within the 0 to 100 range
128 $num1 = mt_rand(0, 10);
129 $num2 = mt_rand($num1, 100);
130 $operation = mt_rand(0, 1); // 0 is addition, 1 is subtraction
131 if ($operation == 0) {
132 $user['hcheck_question'] = sprintf(_('%s plus %s equals'), ($num2 - $num1), $num1);
133 $user['hcheck_solution'] = $num2;
134 }
135 else {
136 $user['hcheck_question'] = sprintf(_('%s minus %s equals'), $num2, $num1);
137 $user['hcheck_solution'] = $num2 - $num1;
138 }
139 $result = $db->prepare('UPDATE `auth_users` SET `hcheck_question` = :hcquestion, `hcheck_solution` = :hcsolution WHERE `id` = :userid;');
140 if (!$result->execute(array(':hcquestion' => $user['hcheck_question'], ':hcsolution' => $user['hcheck_solution'], ':userid' => $user['id']))) {
141 $errors[] = _('Could not generate check for being a human.').' '
142 .sprintf(_('Please <a href="%s">contact %s</a> and tell the team about this.'), $utils->settings['operator_contact_url'], $utils->settings['operator_name']);
143 }
144 }
145 elseif ($user['status'] == 'unverified') {
4c6d8064
RK
146 // Send email for verification and show message to point to it.
147 $mail = new email();
148 $mail->setCharset('utf-8');
149 $mail->addHeader('X-KAIRO-AUTH', 'email_verification');
150 $mail->addRecipient($user['email']);
3f24953f
RK
151 $mail->setSender($utils->settings['info_from_email'], sprintf(_('%s Authentication Service'), $utils->settings['operator_name']));
152 $mail->setSubject(sprintf(_('Email Verification for %s Authentication'), $utils->settings['operator_name']));
4c6d8064
RK
153 $mail->addMailText(_('Welcome!')."\n\n");
154 $mail->addMailText(sprintf(_('This email address, %s, has been used for registration on "%s".'),
3f24953f 155 $user['email'], sprintf(_('%s Authentication Service'), $utils->settings['operator_name']))."\n\n");
4c6d8064 156 $mail->addMailText(_('Please confirm that registration by clicking the following link (or calling it up in your browser):')."\n");
409b55f4 157 $mail->addMailText($utils->getDomainBaseURL().strstr($_SERVER['REQUEST_URI'], '?', true)
4c6d8064
RK
158 .'?email='.rawurlencode($user['email']).'&verification_code='.rawurlencode($user['verify_hash'])."\n\n");
159 $mail->addMailText(_('With this confirmation, you accept that we handle your data for the purpose of logging you into other websites when you request that.')."\n");
160 $mail->addMailText(_('Those websites will get to know your email address but not your password, which we store securely.')."\n");
161 $mail->addMailText(_('If you do not call this confirmation link within 72 hours, your data will be deleted from our database.')."\n\n");
3f24953f 162 $mail->addMailText(sprintf(_('The %s team'), $utils->settings['operator_name']));
4c6d8064
RK
163 //$mail->setDebugAddress("robert@localhost");
164 $mailsent = $mail->send();
165 if ($mailsent) {
166 $pagetype = 'verification_sent';
167 }
168 else {
169 $utils->log('verify_mail_failure', 'user: '.$user['id'].', email: '.$user['email']);
3f24953f
RK
170 $errors[] = _('The confirmation email could not be sent to you.').' '
171 .sprintf(_('Please <a href="%s">contact %s</a> and tell the team about this.'), $utils->settings['operator_contact_url'], $utils->settings['operator_name']);
4c6d8064 172 }
b19743bc 173 }
4c6d8064
RK
174 else {
175 // Password reset requested with "Password forgotten?" function.
176 $vcode = $utils->createVerificationCode();
177 $result = $db->prepare('UPDATE `auth_users` SET `verify_hash` = :vcode WHERE `id` = :userid;');
178 if (!$result->execute(array(':vcode' => $vcode, ':userid' => $user['id']))) {
179 $utils->log('vhash_set_failure', 'user: '.$user['id']);
3f24953f
RK
180 $errors[] = _('Could not initiate reset request.').' '
181 .sprintf(_('Please <a href="%s">contact %s</a> and tell the team about this.'), $utils->settings['operator_contact_url'], $utils->settings['operator_name']);
4c6d8064
RK
182 }
183 else {
184 $utils->log('pwd_reset_request', 'user: '.$user['id'].', email: '.$user['email']);
185 $resetcode = $vcode.dechex($user['id'] + $session['id']).'_'.$utils->createTimeCode($session, null, 60);
186 // Send email with instructions for resetting the password.
187 $mail = new email();
188 $mail->setCharset('utf-8');
189 $mail->addHeader('X-KAIRO-AUTH', 'password_reset');
190 $mail->addRecipient($user['email']);
3f24953f
RK
191 $mail->setSender($utils->settings['info_from_email'], sprintf(_('%s Authentication Service'), $utils->settings['operator_name']));
192 $mail->setSubject(sprintf(_('How to reset your password for %s Authentication'), $utils->settings['operator_name']));
4c6d8064
RK
193 $mail->addMailText(_('Hi,')."\n\n");
194 $mail->addMailText(sprintf(_('A request for setting a new password for this email address, %s, has been submitted on "%s".'),
3f24953f 195 $user['email'], sprintf(_('%s Authentication Service'), $utils->settings['operator_name']))."\n\n");
4c6d8064 196 $mail->addMailText(_('You can set a new password by clicking the following link (or calling it up in your browser):')."\n");
409b55f4 197 $mail->addMailText($utils->getDomainBaseURL().strstr($_SERVER['REQUEST_URI'], '?', true)
4c6d8064
RK
198 .'?email='.rawurlencode($user['email']).'&reset_code='.rawurlencode($resetcode)."\n\n");
199 $mail->addMailText(_('If you do not call this confirmation link within 1 hour, this link expires and the existing password is being kept in place.')."\n\n");
3f24953f 200 $mail->addMailText(sprintf(_('The %s team'), $utils->settings['operator_name']));
4c6d8064
RK
201 //$mail->setDebugAddress("robert@localhost");
202 $mailsent = $mail->send();
203 if ($mailsent) {
204 $pagetype = 'resetmail_sent';
205 }
206 else {
207 $utils->log('pwd_reset_mail_failure', 'user: '.$user['id'].', email: '.$user['email']);
3f24953f
RK
208 $errors[] = _('The email with password reset instructions could not be sent to you.').' '
209 .sprintf(_('Please <a href="%s">contact %s</a> and tell the team about this.'), $utils->settings['operator_contact_url'], $utils->settings['operator_name']);
89975cb9
RK
210 }
211 }
212 }
213 }
89975cb9 214 }
60e46184
RK
215 if (!count($errors) && ($addgroup > 0)) {
216 // We should add the login email to the group of that existing user.
217 $result = $db->prepare('SELECT `group_id` FROM `auth_users` WHERE `id` = :userid;');
218 $result->execute(array(':userid' => $addgroup));
219 $grpuser = $result->fetch(PDO::FETCH_ASSOC);
220 if (!intval($grpuser['group_id'])) {
221 // If that user doesn't have a group, put him into a group with his own user ID.
222 $result = $db->prepare('UPDATE `auth_users` SET `group_id` = :groupid WHERE `id` = :userid;');
223 if (!$result->execute(array(':groupid' => $addgroup, ':userid' => $addgroup))) {
224 $utils->log('group_save_failure', 'user: '.$addgroup);
225 }
226 else {
227 $utils->log('new grouping', 'user: '.$addgroup.', group: '.$addgroup);
228 }
229 }
230 // Save grouping for the new or logged-in user.
231 $result = $db->prepare('UPDATE `auth_users` SET `group_id` = :groupid WHERE `id` = :userid;');
232 if (!$result->execute(array(':groupid' => $addgroup, ':userid' => $user['id']))) {
233 $utils->log('group_save_failure', 'user: '.$user['id']);
234 }
235 else {
236 $utils->log('new grouping', 'user: '.$user['id'].', group: '.$addgroup);
237 $user['group_id'] = $addgroup;
238 }
239 }
4c6d8064
RK
240 }
241 else {
e66b9a25 242 $errors[] = _('The form you used was not valid. Possibly it has expired and you need to initiate the action again, or you have disabled cookies for this site.');
4c6d8064
RK
243 }
244 }
245 elseif (array_key_exists('reset', $_GET)) {
246 if ($session['logged_in']) {
fb7b39f0 247 $result = $db->prepare('SELECT `id`,`email`,`group_id` FROM `auth_users` WHERE `id` = :userid;');
4c6d8064
RK
248 $result->execute(array(':userid' => $session['user']));
249 $user = $result->fetch(PDO::FETCH_ASSOC);
250 if (!$user['id']) {
251 $utils->log('reset_user_read_failure', 'user: '.$session['user']);
252 }
253 $pagetype = 'resetpwd';
254 }
255 else {
256 // Display form for entering email.
257 $pagetype = 'resetstart';
258 }
259 }
260 elseif (array_key_exists('verification_code', $_GET)) {
fb7b39f0 261 $result = $db->prepare('SELECT `id`,`email`,`group_id` FROM `auth_users` WHERE `email` = :email AND `status` = \'unverified\' AND `verify_hash` = :vcode;');
4c6d8064
RK
262 $result->execute(array(':email' => @$_GET['email'], ':vcode' => $_GET['verification_code']));
263 $user = $result->fetch(PDO::FETCH_ASSOC);
264 if ($user['id']) {
265 $result = $db->prepare('UPDATE `auth_users` SET `verify_hash` = \'\', `status` = \'ok\' WHERE `id` = :userid;');
266 if (!$result->execute(array(':userid' => $user['id']))) {
267 $utils->log('verification_save_failure', 'user: '.$user['id']);
3f24953f
RK
268 $errors[] = _('Could not save confirmation.').' '
269 .sprintf(_('Please <a href="%s">contact %s</a> and tell the team about this.'), $utils->settings['operator_contact_url'], $utils->settings['operator_name']);
4c6d8064
RK
270 }
271 $pagetype = 'verification_done';
272 }
273 else {
274 $errors[] = _('The confirmation link you called is not valid. Possibly it has expired and you need to try registering again.');
275 }
276 }
277 elseif (array_key_exists('reset_code', $_GET)) {
278 $reset_fail = true;
fb7b39f0 279 $result = $db->prepare('SELECT `id`,`email`,`verify_hash`,`group_id` FROM `auth_users` WHERE `email` = :email');
4c6d8064
RK
280 $result->execute(array(':email' => @$_GET['email']));
281 $user = $result->fetch(PDO::FETCH_ASSOC);
282 if ($user['id']) {
283 // Deconstruct reset code and verify it.
284 if (preg_match('/^([0-9a-f]{'.strlen($user['verify_hash']).'})([0-9a-f]+)_(\d+\.\d+)$/', $_GET['reset_code'], $regs)) {
285 $tcode_sessid = hexdec($regs[2]) - $user['id'];
286 $result = $db->prepare('SELECT `id`,`sesskey` FROM `auth_sessions` WHERE `id` = :sessid;');
287 $result->execute(array(':sessid' => $tcode_sessid));
288 $row = $result->fetch(PDO::FETCH_ASSOC);
289 if ($row) {
290 $tcode_session = $row;
291 if (($regs[1] == $user['verify_hash']) &&
292 $utils->verifyTimeCode($regs[3], $session, 60)) {
293 // Set a new verify_hash for the actual password reset.
294 $user['verify_hash'] = $utils->createVerificationCode();
295 $result = $db->prepare('UPDATE `auth_users` SET `verify_hash` = :vcode WHERE `id` = :userid;');
296 if (!$result->execute(array(':vcode' => $user['verify_hash'], ':userid' => $user['id']))) {
297 $utils->log('vhash_reset_failure', 'user: '.$user['id']);
e876642c 298 }
4c6d8064
RK
299 $result = $db->prepare('UPDATE `auth_sessions` SET `user` = :userid WHERE `id` = :sessid;');
300 if (!$result->execute(array(':userid' => $user['id'], ':sessid' => $session['id']))) {
301 $utils->log('reset_session_set_user_failure', 'session: '.$session['id']);
e876642c 302 }
4c6d8064
RK
303 $pagetype = 'resetpwd';
304 $reset_fail = false;
e876642c
RK
305 }
306 }
b19743bc 307 }
d26d08a1 308 }
4c6d8064
RK
309 if ($reset_fail) {
310 $errors[] = _('The password reset link you called is not valid. Possibly it has expired and you need to call the "Password forgotten?" function again.');
311 }
d26d08a1 312 }
ea0452ad 313 elseif (array_key_exists('clients', $_GET)) {
fb7b39f0 314 $result = $db->prepare('SELECT `id`,`email`,`group_id` FROM `auth_users` WHERE `id` = :userid;');
ea0452ad
RK
315 $result->execute(array(':userid' => $session['user']));
316 $user = $result->fetch(PDO::FETCH_ASSOC);
317 if ($session['logged_in'] && $user['id']) {
318 if (array_key_exists('client_id', $_POST) && (strlen($_POST['client_id']) >= 5)) {
319 $clientid = $_POST['client_id'];
320 $clientsecret = $utils->createClientSecret();
321 $rediruri = strval(@$_POST['redirect_uri']);
322 $scope = strval(@$_POST['scope']);
323 $result = $db->prepare('INSERT INTO `oauth_clients` (`client_id`, `client_secret`, `redirect_uri`, `scope`, `user_id`) VALUES (:clientid, :secret, :rediruri, :scope, :userid);');
324 if (!$result->execute(array(':clientid' => $clientid,
325 ':secret' => $clientsecret,
326 ':rediruri' => $rediruri,
327 ':scope' => $scope,
328 ':userid' => $user['id']))) {
329 $utils->log('client_save_failure', 'client: '.$clientid);
3f24953f
RK
330 $errors[] = _('Unexpectedly failed to save new client information.').' '
331 .sprintf(_('Please <a href="%s">contact %s</a> and tell the team about this.'), $utils->settings['operator_contact_url'], $utils->settings['operator_name']);
ea0452ad
RK
332 }
333 }
334 if (!count($errors)) {
335 // List clients
336 $result = $db->prepare('SELECT `client_id`,`client_secret`,`redirect_uri`,`scope` FROM `oauth_clients` WHERE `user_id` = :userid;');
337 $result->execute(array(':userid' => $user['id']));
338 $clients = $result->fetchAll(PDO::FETCH_ASSOC);
339 if (!$clients) { $clients = array(); }
340 $pagetype = 'clientlist';
341 }
342 }
343 else {
344 $errors[] = _('This function is only available if you are logged in.');
345 }
346 }
4c6d8064 347 elseif (intval($session['user'])) {
60e46184 348 $result = $db->prepare('SELECT `id`,`email`,`verify_hash`,`group_id` FROM `auth_users` WHERE `id` = :userid;');
4c6d8064
RK
349 $result->execute(array(':userid' => $session['user']));
350 $user = $result->fetch(PDO::FETCH_ASSOC);
351 if (!$user['id']) {
352 $utils->log('user_read_failure', 'user: '.$session['user']);
d26d08a1 353 }
4c6d8064
RK
354 // Password reset requested.
355 if (array_key_exists('pwd', $_POST) && array_key_exists('reset', $_POST) && array_key_exists('tcode', $_POST)) {
356 // If not logged in, a password reset needs to have the proper vcode set.
357 if (!$session['logged_in'] && (!strlen(@$_POST['vcode']) || ($_POST['vcode'] != $user['verify_hash']))) {
358 $errors[] = _('Password reset failed. The reset form you used was not valid. Possibly it has expired and you need to initiate the password reset again.');
359 }
360 // If not logged in, a password reset also needs to have the proper email set.
361 if (!$session['logged_in'] && !count($errors) && (@$_POST['email_hidden'] != $user['email'])) {
362 $errors[] = _('Password reset failed. The reset form you used was not valid. Possibly it has expired and you need to initiate the password reset again.');
363 }
364 // Check validity of time code.
365 if (!count($errors) && !$utils->verifyTimeCode($_POST['tcode'], $session)) {
366 $errors[] = _('Password reset failed. The reset form you used was not valid. Possibly it has expired and you need to initiate the password reset again.');
367 }
368 $errors += $utils->checkPasswordConstraints(strval($_POST['pwd']), $user['email']);
369 if (!count($errors)) {
370 $newHash = $utils->pwdHash($_POST['pwd']);
371 $result = $db->prepare('UPDATE `auth_users` SET `pwdhash` = :pwdhash, `verify_hash` = \'\' WHERE `id` = :userid;');
372 if (!$result->execute(array(':pwdhash' => $newHash, ':userid' => $session['user']))) {
373 $utils->log('pwd_reset_failure', 'user: '.$session['user']);
3f24953f
RK
374 $errors[] = _('Password reset failed.').' '
375 .sprintf(_('Please <a href="%s">contact %s</a> and tell the team about this.'), $utils->settings['operator_contact_url'], $utils->settings['operator_name']);
4c6d8064
RK
376 }
377 else {
378 $pagetype = 'reset_done';
379 }
380 }
b19743bc 381 }
60e46184
RK
382 else {
383 $utils->doRedirectIfSet($session);
384 }
d26d08a1
RK
385 }
386}
387
388if (!count($errors)) {
d42db7c5
RK
389 if ($pagetype == 'human_check') {
390 $para = $body->appendElement('p', _('This is a new registration, please verify that you are a human by solving the calculation below.'));
391 $para->setAttribute('class', 'humancheckinfo');
392 $form = $body->appendForm('./', 'POST', 'humancheckform');
393 $form->setAttribute('id', 'humancheckform');
394 $ulist = $form->appendElement('ul');
395 $ulist->setAttribute('class', 'flat humancheck');
396 $litem = $ulist->appendElement('li');
397 $litem->setAttribute('class', 'donotshow');
398 $inptxt = $litem->appendInputEmail('email', 30, 20, 'login_email', $user['email']);
399 $inptxt->setAttribute('autocomplete', 'email');
400 $inptxt->setAttribute('placeholder', _('Email'));
401 $litem = $ulist->appendElement('li');
402 $litem->appendText($user['hcheck_question'].' ');
403 $inptxt = $litem->appendInputText('hcheck_solution', 20, 10, 'hcheck_solution');
404 $litem = $ulist->appendElement('li');
405 $litem->appendInputHidden('tcode', $utils->createTimeCode($session));
406 $submit = $litem->appendInputSubmit(_('Continue Registration'));
407 $para = $form->appendElement('p');
408 $para->setAttribute('class', 'toplink small');
409 $link = $para->appendLink('./', _('Cancel'));
410 }
411 elseif ($pagetype == 'verification_sent') {
b19743bc
RK
412 $para = $body->appendElement('p', sprintf(_('An email for confirmation has been sent to %s. Please follow the link provided there to complete the process.'), $user['email']));
413 $para->setAttribute('class', 'verifyinfo pending');
409b55f4
RK
414 $para = $body->appendElement('p', _('Reload this page after you confirm to continue.'));
415 $para->setAttribute('class', 'verifyinfo pending');
e66b9a25
RK
416 $para = $body->appendElement('p');
417 $para->setAttribute('class', 'verifyinfo pending');
418 $link = $para->appendLink('./', _('Reload'));
b19743bc 419 }
89975cb9
RK
420 elseif ($pagetype == 'resetmail_sent') {
421 $para = $body->appendElement('p',
422 _('An email has been sent to the requested account with further information. If you do not receive an email then please confirm you have entered the same email address used during account registration.'));
423 $para->setAttribute('class', 'resetinfo pending');
e66b9a25
RK
424 $para = $body->appendElement('p');
425 $para->setAttribute('class', 'resetinfo pending small');
426 $link = $para->appendLink('./', _('Back to top'));
89975cb9 427 }
b19743bc
RK
428 elseif ($pagetype == 'resetstart') {
429 $para = $body->appendElement('p', _('If you forgot your password or didn\'t receive the registration confirmation, please enter your email here.'));
430 $para->setAttribute('class', '');
77f0f9ff 431 $form = $body->appendForm('./?reset', 'POST', 'resetform');
b19743bc
RK
432 $form->setAttribute('id', 'loginform');
433 $form->setAttribute('class', 'loginarea hidden');
434 $ulist = $form->appendElement('ul');
435 $ulist->setAttribute('class', 'flat login');
436 $litem = $ulist->appendElement('li');
437 $inptxt = $litem->appendInputEmail('email', 30, 20, 'login_email');
438 $inptxt->setAttribute('autocomplete', 'email');
439 $inptxt->setAttribute('required', '');
440 $inptxt->setAttribute('placeholder', _('Email'));
441 $litem = $ulist->appendElement('li');
ac442755 442 $litem->appendInputHidden('tcode', $utils->createTimeCode($session));
b19743bc 443 $submit = $litem->appendInputSubmit(_('Send instructions to email'));
e66b9a25
RK
444 $para = $form->appendElement('p');
445 $para->setAttribute('class', 'toplink small');
446 $link = $para->appendLink('./', _('Cancel'));
b19743bc
RK
447 }
448 elseif ($pagetype == 'resetpwd') {
89975cb9 449 $para = $body->appendElement('p', sprintf(_('You can set a new password for %s here.'), $user['email']));
e66b9a25 450 $para->setAttribute('class', 'newpwdinfo');
77f0f9ff 451 $form = $body->appendForm('./', 'POST', 'newpwdform');
b19743bc
RK
452 $form->setAttribute('id', 'loginform');
453 $form->setAttribute('class', 'loginarea hidden');
454 $ulist = $form->appendElement('ul');
455 $ulist->setAttribute('class', 'flat login');
456 $litem = $ulist->appendElement('li');
e876642c
RK
457 $litem->setAttribute('class', 'donotshow');
458 $inptxt = $litem->appendInputEmail('email_hidden', 30, 20, 'login_email', $user['email']);
459 $inptxt->setAttribute('autocomplete', 'email');
460 $inptxt->setAttribute('placeholder', _('Email'));
461 $litem = $ulist->appendElement('li');
b19743bc
RK
462 $inptxt = $litem->appendInputPassword('pwd', 20, 20, 'login_pwd', '');
463 $inptxt->setAttribute('required', '');
464 $inptxt->setAttribute('placeholder', _('Password'));
465 $inptxt->setAttribute('class', 'login');
466 $litem = $ulist->appendElement('li');
e876642c 467 $litem->appendInputHidden('reset', '');
ac442755 468 $litem->appendInputHidden('tcode', $utils->createTimeCode($session));
89975cb9
RK
469 if (!$session['logged_in'] && strlen(@$user['verify_hash'])) {
470 $litem->appendInputHidden('vcode', $user['verify_hash']);
471 }
b19743bc 472 $submit = $litem->appendInputSubmit(_('Save password'));
e66b9a25
RK
473 $para = $form->appendElement('p');
474 $para->setAttribute('class', 'toplink small');
475 $link = $para->appendLink('./', _('Cancel'));
b19743bc 476 }
ea0452ad
RK
477 elseif ($pagetype == 'clientlist') {
478 $scopes = array('clientreg', 'email');
479 $form = $body->appendForm('?clients', 'POST', 'newclientform');
480 $form->setAttribute('id', 'clientform');
481 $tbl = $form->appendElement('table');
482 $tbl->setAttribute('class', 'clientlist border');
483 $thead = $tbl->appendElement('thead');
484 $trow = $thead->appendElement('tr');
485 $trow->appendElement('th', _('Client ID'));
486 $trow->appendElement('th', _('Client Secrect'));
487 $trow->appendElement('th', _('Redirect URI'));
488 $trow->appendElement('th', _('Scope'));
489 $trow->appendElement('th');
490 $tbody = $tbl->appendElement('tbody');
491 foreach ($clients as $client) {
492 $trow = $tbody->appendElement('tr');
493 $trow->appendElement('td', $client['client_id']);
494 $trow->appendElement('td', $client['client_secret']);
495 $trow->appendElement('td', $client['redirect_uri']);
496 $trow->appendElement('td', $client['scope']);
497 $trow->appendElement('td'); // Future: Delete link?
498 }
499 // Form fields for adding a new one.
500 $tfoot = $tbl->appendElement('tfoot');
501 $trow = $tfoot->appendElement('tr');
502 $cell = $trow->appendElement('td');
503 $inptxt = $cell->appendInputText('client_id', 80, 25, 'client_id');
504 $cell = $trow->appendElement('td'); // Empty, as secret will be generated.
505 $cell = $trow->appendElement('td');
506 $inptxt = $cell->appendInputText('redirect_uri', 500, 50, 'redirect_uri');
507 $cell = $trow->appendElement('td');
508 $select = $cell->appendElementSelect('scope');
509 foreach ($scopes as $scope) {
510 $select->appendElementOption($scope, $scope);
511 }
512 //$inptxt = $cell->appendInputText('scope', 100, 20, 'scope');
513 $cell = $trow->appendElement('td');
514 $submit = $cell->appendInputSubmit(_('Create'));
e66b9a25
RK
515 $para = $form->appendElement('p');
516 $para->setAttribute('class', 'toplink');
517 $link = $para->appendLink('./', _('Back to top'));
ea0452ad 518 }
60e46184 519 elseif ($session['logged_in'] && (!array_key_exists('addemail', $_GET))) {
e876642c
RK
520 if ($pagetype == 'reset_done') {
521 $para = $body->appendElement('p', _('Your password has successfully been reset.'));
522 $para->setAttribute('class', 'resetinfo done');
523 }
d26d08a1
RK
524 $div = $body->appendElement('div', $user['email']);
525 $div->setAttribute('class', 'loginheader');
60e46184
RK
526 $groupmails = $utils->getGroupedEmails($user['group_id'], $user['email']);
527 if (count($groupmails)) {
528 $para = $div->appendElement('p', _('Grouped with: ').implode(', ', $groupmails));
529 $para->setAttribute('class', 'small groupmails');
530 }
d26d08a1
RK
531 $div = $body->appendElement('div');
532 $div->setAttribute('class', 'loginlinks');
b19743bc
RK
533 $ulist = $div->appendElement('ul');
534 $ulist->setAttribute('class', 'flat');
535 $litem = $ulist->appendElement('li');
77f0f9ff 536 $link = $litem->appendLink('./?logout', _('Log out'));
60e46184
RK
537 $litem = $ulist->appendElement('li');
538 $link = $litem->appendLink('./?addemail', _('Add another email address'));
3875e0fb 539 if (($utils->client_reg_email_whitelist === false) || (in_array($user['email'], $utils->client_reg_email_whitelist))) {
ea0452ad
RK
540 $litem = $ulist->appendElement('li');
541 $link = $litem->appendLink('./?clients', _('Manage OAuth2 clients'));
542 }
b19743bc 543 $litem = $ulist->appendElement('li');
77f0f9ff 544 $litem->appendLink('./?reset', _('Set new password'));
d26d08a1
RK
545 }
546 else { // not logged in
60e46184 547 $addfields = array();
b19743bc
RK
548 if ($pagetype == 'verification_done') {
549 $para = $body->appendElement('p', _('Hooray! Your email was successfully confirmed! You can log in now.'));
550 $para->setAttribute('class', 'verifyinfo done');
551 }
e876642c
RK
552 elseif ($pagetype == 'reset_done') {
553 $para = $body->appendElement('p', _('Your password has successfully been reset. You can log in now with the new password.'));
554 $para->setAttribute('class', 'resetinfo done');
555 }
60e46184
RK
556 elseif (array_key_exists('addemail', $_GET)) {
557 $para = $body->appendElement('p', sprintf(_('Add another email grouped with %s by either logging in with it or specifying the email and a new password to use.'), $user['email']));
558 $para->setAttribute('class', 'addemailinfo');
559 $addfields['grouptoexisting'] = '1';
560 }
561 $utils->appendLoginForm($body, $session, $user, $addfields);
d26d08a1
RK
562 }
563}
564
565if (count($errors)) {
566 $body->appendElement('p', ((count($errors) <= 1)
567 ?_('The following error was detected')
568 :_('The following errors were detected')).':');
569 $list = $body->appendElement('ul');
570 $list->setAttribute('class', 'flat warn');
571 foreach ($errors as $msg) {
9b32cdeb
RK
572 $item = $list->appendElement('li');
573 $item->appendHTMLMarkup($msg);
d26d08a1 574 }
b19743bc 575 $body->appendButton(_('Back'), 'history.back();');
133aecbe
RK
576}
577
578// Send HTML to client.
579print($document->saveHTML());
580?>