From 0563a284381bb9dabf851731479f6293337617dd Mon Sep 17 00:00:00 2001
From: Hypolite Petovan <hypolite@mrpetovan.com>
Date: Sun, 14 Oct 2018 08:58:27 -0400
Subject: [PATCH 1/6] Replace System::baseUrl() by App->getBaseURL() in
 mod/register

- Remove redundant System::baseUrl() in goaway() calls
- Add more generic Friendica\Model use statement
- Allow empty path in goaway()
---
 boot.php         |  2 +-
 mod/register.php | 40 ++++++++++++++++++++++++++--------------
 2 files changed, 27 insertions(+), 15 deletions(-)

diff --git a/boot.php b/boot.php
index 435de0923c..2433143ddb 100644
--- a/boot.php
+++ b/boot.php
@@ -647,7 +647,7 @@ function killme()
 /**
  * @brief Redirect to another URL and terminate this process.
  */
-function goaway($path)
+function goaway($path = '')
 {
 	if (strstr(normalise_link($path), 'http://')) {
 		$url = $path;
diff --git a/mod/register.php b/mod/register.php
index 454062d89b..2b3522234e 100644
--- a/mod/register.php
+++ b/mod/register.php
@@ -12,7 +12,7 @@ use Friendica\Core\PConfig;
 use Friendica\Core\System;
 use Friendica\Core\Worker;
 use Friendica\Database\DBA;
-use Friendica\Model\User;
+use Friendica\Model;
 use Friendica\Module\Tos;
 use Friendica\Util\DateTimeFormat;
 
@@ -67,7 +67,7 @@ function register_post(App $a)
 	$arr['language'] = L10n::getBrowserLanguage();
 
 	try {
-		$result = User::create($arr);
+		$result = Model\User::create($arr);
 	} catch (Exception $e) {
 		notice($e->getMessage());
 		return;
@@ -76,7 +76,7 @@ function register_post(App $a)
 	$user = $result['user'];
 
 	if ($netpublish && intval(Config::get('config', 'register_policy')) !== REGISTER_APPROVE) {
-		$url = System::baseUrl() . '/profile/' . $user['nickname'];
+		$url = $a->getBaseUrl() . '/profile/' . $user['nickname'];
 		Worker::add(PRIORITY_LOW, "Directory", $url);
 	}
 
@@ -92,12 +92,18 @@ function register_post(App $a)
 
 		// Only send a password mail when the password wasn't manually provided
 		if (!x($_POST, 'password1') || !x($_POST, 'confirm')) {
-			$res = User::sendRegisterOpenEmail(
-					$user['email'], Config::get('config', 'sitename'), System::baseUrl(), $user['username'], $result['password'], $user);
+			$res = Model\User::sendRegisterOpenEmail(
+				$user['email'],
+				Config::get('config', 'sitename'),
+				$a->getBaseUrl(),
+				$user['username'],
+				$result['password'],
+				$user
+			);
 
 			if ($res) {
 				info(L10n::t('Registration successful. Please check your email for further instructions.') . EOL);
-				goaway(System::baseUrl());
+				goaway();
 			} else {
 				notice(
 					L10n::t('Failed to send email message. Here your accout details:<br> login: %s<br> password: %s<br><br>You can change your password after login.',
@@ -108,12 +114,12 @@ function register_post(App $a)
 			}
 		} else {
 			info(L10n::t('Registration successful.') . EOL);
-			goaway(System::baseUrl());
+			goaway();
 		}
 	} elseif (intval(Config::get('config', 'register_policy')) === REGISTER_APPROVE) {
 		if (!strlen(Config::get('config', 'admin_email'))) {
 			notice(L10n::t('Your registration can not be processed.') . EOL);
-			goaway(System::baseUrl());
+			goaway();
 		}
 
 		$hash = random_string();
@@ -146,9 +152,9 @@ function register_post(App $a)
 				'source_name'  => $user['username'],
 				'source_mail'  => $user['email'],
 				'source_nick'  => $user['nickname'],
-				'source_link'  => System::baseUrl() . "/admin/users/",
-				'link'         => System::baseUrl() . "/admin/users/",
-				'source_photo' => System::baseUrl() . "/photo/avatar/" . $user['uid'] . ".jpg",
+				'source_link'  => $a->getBaseUrl() . "/admin/users/",
+				'link'         => $a->getBaseUrl() . "/admin/users/",
+				'source_photo' => $a->getBaseUrl() . "/photo/avatar/" . $user['uid'] . ".jpg",
 				'to_email'     => $admin['email'],
 				'uid'          => $admin['uid'],
 				'language'     => $admin['language'] ? $admin['language'] : 'en',
@@ -156,11 +162,17 @@ function register_post(App $a)
 			]);
 		}
 		// send notification to the user, that the registration is pending
-		User::sendRegisterPendingEmail(
-			$user['email'], Config::get('config', 'sitename'), $user['username']);
+		Model\User::sendRegisterPendingEmail(
+			$user['email'],
+			Config::get('config', 'sitename'),
+			$user['username'],
+			$a->getBaseURL(),
+			$user['nickname'],
+			$result['password']
+		);
 
 		info(L10n::t('Your registration is pending approval by the site owner.') . EOL);
-		goaway(System::baseUrl());
+		goaway();
 	}
 
 	return;

From f2bde919e5fe826fb32ab806b401667bd30ab23c Mon Sep 17 00:00:00 2001
From: Hypolite Petovan <hypolite@mrpetovan.com>
Date: Sun, 14 Oct 2018 11:30:39 -0400
Subject: [PATCH 2/6] Fix ignored show_in_notification_page parameter in
 notification()

---
 include/enotify.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/enotify.php b/include/enotify.php
index b184a6935e..882227e941 100644
--- a/include/enotify.php
+++ b/include/enotify.php
@@ -84,7 +84,7 @@ function notification($params)
 	// with $params['show_in_notification_page'] == false, the notification isn't inserted into
 	// the database, and an email is sent if applicable.
 	// default, if not specified: true
-	$show_in_notification_page = ((x($params, 'show_in_notification_page'))	? $params['show_in_notification_page']:true);
+	$show_in_notification_page = isset($params['show_in_notification_page']) ? $params['show_in_notification_page'] : true;
 
 	$additional_mail_header = "";
 	$additional_mail_header .= "Precedence: list\n";

From 7f143c3159615b4a10539447bcf250a5fca793a5 Mon Sep 17 00:00:00 2001
From: Hypolite Petovan <hypolite@mrpetovan.com>
Date: Sun, 14 Oct 2018 11:32:54 -0400
Subject: [PATCH 3/6] Fix various spelling mistakes

---
 mod/admin.php        | 4 ++--
 src/Database/DBA.php | 2 +-
 src/Model/User.php   | 2 +-
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/mod/admin.php b/mod/admin.php
index d0e8ab0e38..7574e684ec 100644
--- a/mod/admin.php
+++ b/mod/admin.php
@@ -33,11 +33,11 @@ require_once 'include/items.php';
 /**
  * @brief Process send data from the admin panels subpages
  *
- * This function acts as relais for processing the data send from the subpages
+ * This function acts as relay for processing the data send from the subpages
  * of the admin panel. Depending on the 1st parameter of the url (argv[1])
  * specialized functions are called to process the data from the subpages.
  *
- * The function itself does not return anything, but the subsequencely function
+ * The function itself does not return anything, but the subsequently function
  * return the HTML for the pages of the admin panel.
  *
  * @param App $a
diff --git a/src/Database/DBA.php b/src/Database/DBA.php
index c33fa2152f..8fd117e5d2 100644
--- a/src/Database/DBA.php
+++ b/src/Database/DBA.php
@@ -821,7 +821,7 @@ class DBA
 	 * @param array $param parameter array
 	 * @param bool $on_duplicate_update Do an update on a duplicate entry
 	 *
-	 * @return boolean was the insert successfull?
+	 * @return boolean was the insert successful?
 	 */
 	public static function insert($table, $param, $on_duplicate_update = false) {
 
diff --git a/src/Model/User.php b/src/Model/User.php
index b8b694de87..b61014b8a8 100644
--- a/src/Model/User.php
+++ b/src/Model/User.php
@@ -644,7 +644,7 @@ class User
 	}
 
 	/**
-	 * @brief Sends pending registration confiƕmation email
+	 * @brief Sends pending registration confirmation email
 	 *
 	 * @param string $email
 	 * @param string $sitename

From 123992384b9b5e65bc9c0ffecd9c557fdb3a29a8 Mon Sep 17 00:00:00 2001
From: Hypolite Petovan <hypolite@mrpetovan.com>
Date: Sun, 14 Oct 2018 11:34:34 -0400
Subject: [PATCH 4/6] Create Model\Register

- Add Model\User::exists method
---
 src/Model/Register.php | 131 +++++++++++++++++++++++++++++++++++++++++
 src/Model/User.php     |  11 ++++
 2 files changed, 142 insertions(+)
 create mode 100644 src/Model/Register.php

diff --git a/src/Model/Register.php b/src/Model/Register.php
new file mode 100644
index 0000000000..e54db87a6b
--- /dev/null
+++ b/src/Model/Register.php
@@ -0,0 +1,131 @@
+<?php
+
+/**
+ * @file src/Model/Register.php
+ */
+namespace Friendica\Model;
+
+use Friendica\Database\DBA;
+use Friendica\Util\DateTimeFormat;
+
+/**
+ * Class interacting with the register database table
+ *
+ * @author Hypolite Petovan <mrpetovan@gmail.com>
+ */
+class Register
+{
+	/**
+	 * Return the list of pending registrations
+	 *
+	 * @return array
+	 */
+	public static function getPending()
+	{
+		$stmt = DBA::p(
+			"SELECT `register`.*, `contact`.`name`, `user`.`email`
+			FROM `register`
+			INNER JOIN `contact` ON `register`.`uid` = `contact`.`uid`
+			INNER JOIN `user` ON `register`.`uid` = `user`.`uid`"
+		);
+
+		return DBA::toArray($stmt);
+	}
+
+	/**
+	 * Returns the pending registration count
+	 *
+	 * @return int
+	 */
+	public static function getPendingCount()
+	{
+		$register = DBA::fetchFirst(
+			"SELECT COUNT(*) AS `count`
+			FROM `register`
+			INNER JOIN `contact` ON `register`.`uid` = `contact`.`uid` AND `contact`.`self`"
+		);
+
+		return $register['count'];
+	}
+
+	/**
+	 * Returns the register record associated with the provided hash
+	 *
+	 * @param  string $hash
+	 * @return array
+	 */
+	public static function getByHash($hash)
+	{
+		return DBA::selectFirst('register', [], ['hash' => $hash]);
+	}
+
+	/**
+	 * Returns true if a register record exists with the provided hash
+	 *
+	 * @param  string  $hash
+	 * @return boolean
+	 */
+	public static function existsByHash($hash)
+	{
+		return DBA::exists('register', ['hash' => $hash]);
+	}
+
+	/**
+	 * Creates a register record for an invitation and returns the auto-generated code for it
+	 *
+	 * @return string
+	 */
+	public static function createForInvitation()
+	{
+		$code = autoname(8) . srand(1000, 9999);
+
+		$fields = [
+			'hash' => $code,
+			'created' => DateTimeFormat::utcNow()
+		];
+
+		DBA::insert('register', $fields);
+
+		return $code;
+	}
+
+	/**
+	 * Creates a register record for approval and returns the success of the database insert
+	 * Checks for the existence of the provided user id
+	 *
+	 * @param  integer $uid      The ID of the user needing approval
+	 * @param  string  $language The registration language
+	 * @param  string  $note     An additional message from the user
+	 * @return boolean
+	 */
+	public static function createForApproval($uid, $language, $note = '')
+	{
+		$hash = random_string();
+
+		if (!User::exists($uid)) {
+			return false;
+		}
+
+		$fields = [
+			'hash'     => $hash,
+			'created'  => DateTimeFormat::utcNow(),
+			'uid'      => $uid,
+			'password' => '', // Obsolete, slated for deletion
+			'language' => $language,
+			'note'     => $note
+		];
+
+		return DBA::insert('register', $fields);
+	}
+
+	/**
+	 * Deletes a register record by the provided hash and returns the success of the database deletion
+	 *
+	 * @param  string  $hash
+	 * @return boolean
+	 */
+	public static function deleteByHash($hash)
+	{
+		return DBA::delete('register', ['hash' => $hash]);
+	}
+}
diff --git a/src/Model/User.php b/src/Model/User.php
index b61014b8a8..ddd6ce1ed6 100644
--- a/src/Model/User.php
+++ b/src/Model/User.php
@@ -31,6 +31,17 @@ require_once 'include/text.php';
  */
 class User
 {
+	/**
+	 * Returns true if a user record exists with the provided id
+	 *
+	 * @param  integer $uid
+	 * @return boolean
+	 */
+	public static function exists($uid)
+	{
+		return DBA::exists('user', ['uid' => $uid]);
+	}
+
 	/**
 	 * @brief Returns the user id of a given profile url
 	 *

From 540adaf829b4835bf99fa47e58520cf998defb88 Mon Sep 17 00:00:00 2001
From: Hypolite Petovan <hypolite@mrpetovan.com>
Date: Sun, 14 Oct 2018 11:57:28 -0400
Subject: [PATCH 5/6] Use Model\Register methods in modules

- Update registration emails to avoid storing the plaintext password in
the register table
- Remove redundant sprintf() when used with L10n::t()
- Remove redundant Systen::baseUrl() with goaway()
---
 mod/admin.php      | 20 ++++++++------------
 mod/invite.php     |  7 +------
 mod/ping.php       |  6 +-----
 mod/register.php   | 17 ++++-------------
 mod/regmod.php     | 30 ++++++++++++-----------------
 src/Model/User.php | 47 ++++++++++++++++++++++++++++------------------
 6 files changed, 55 insertions(+), 72 deletions(-)

diff --git a/mod/admin.php b/mod/admin.php
index 7574e684ec..6189c4cb77 100644
--- a/mod/admin.php
+++ b/mod/admin.php
@@ -18,13 +18,14 @@ use Friendica\Database\DBA;
 use Friendica\Database\DBStructure;
 use Friendica\Model\Contact;
 use Friendica\Model\Item;
+use Friendica\Model\Register;
 use Friendica\Model\User;
 use Friendica\Module\Login;
 use Friendica\Module\Tos;
 use Friendica\Util\Arrays;
 use Friendica\Util\DateTimeFormat;
-use Friendica\Util\Temporal;
 use Friendica\Util\Network;
+use Friendica\Util\Temporal;
 
 require_once 'include/enotify.php';
 require_once 'include/text.php';
@@ -895,8 +896,7 @@ function admin_page_summary(App $a)
 
 	logger('accounts: ' . print_r($accounts, true), LOGGER_DATA);
 
-	$r = q("SELECT COUNT(`id`) AS `count` FROM `register`");
-	$pending = $r[0]['count'];
+	$pending = Register::getPendingCount();
 
 	$r = q("SELECT COUNT(*) AS `total` FROM `queue` WHERE 1");
 	$queue = (($r) ? $r[0]['total'] : 0);
@@ -912,10 +912,10 @@ function admin_page_summary(App $a)
 	$r = q("SHOW variables LIKE 'max_allowed_packet'");
 	$max_allowed_packet = (($r) ? $r[0]['Value'] : 0);
 
-	$server_settings = ['label' => L10n::t('Server Settings'), 
-				'php' => ['upload_max_filesize' => ini_get('upload_max_filesize'), 
-						  'post_max_size' => ini_get('post_max_size'), 
-						  'memory_limit' => ini_get('memory_limit')], 
+	$server_settings = ['label' => L10n::t('Server Settings'),
+				'php' => ['upload_max_filesize' => ini_get('upload_max_filesize'),
+						  'post_max_size' => ini_get('post_max_size'),
+						  'memory_limit' => ini_get('memory_limit')],
 				'mysql' => ['max_allowed_packet' => $max_allowed_packet]];
 
 	$t = get_markup_template('admin/summary.tpl');
@@ -1792,11 +1792,7 @@ function admin_page_users(App $a)
 	}
 
 	/* get pending */
-	$pending = q("SELECT `register`.*, `contact`.`name`, `user`.`email`
-				 FROM `register`
-				 INNER JOIN `contact` ON `register`.`uid` = `contact`.`uid`
-				 INNER JOIN `user` ON `register`.`uid` = `user`.`uid`;");
-
+	$pending = Register::getPending();
 
 	/* get users */
 	$total = q("SELECT COUNT(*) AS `total` FROM `user` WHERE 1");
diff --git a/mod/invite.php b/mod/invite.php
index 2a98d19ffc..7318b77ae9 100644
--- a/mod/invite.php
+++ b/mod/invite.php
@@ -58,14 +58,9 @@ function invite_post(App $a)
 		}
 
 		if ($invitation_only && ($invites_remaining || is_site_admin())) {
-			$code = autoname(8) . srand(1000, 9999);
+			$code = Friendica\Model\Register::createForInvitation();
 			$nmessage = str_replace('$invite_code', $code, $message);
 
-			$r = q("INSERT INTO `register` (`hash`,`created`) VALUES ('%s', '%s') ",
-				DBA::escape($code),
-				DBA::escape(DateTimeFormat::utcNow())
-			);
-
 			if (! is_site_admin()) {
 				$invites_remaining --;
 				if ($invites_remaining >= 0) {
diff --git a/mod/ping.php b/mod/ping.php
index ff0139f28f..5ea75727a1 100644
--- a/mod/ping.php
+++ b/mod/ping.php
@@ -202,11 +202,7 @@ function ping_init(App $a)
 		$mail_count = count($mails);
 
 		if (intval(Config::get('config', 'register_policy')) === REGISTER_APPROVE && is_site_admin()) {
-			$regs = q(
-				"SELECT `contact`.`name`, `contact`.`url`, `contact`.`micro`, `register`.`created`
-				FROM `contact` RIGHT JOIN `register` ON `register`.`uid` = `contact`.`uid`
-				WHERE `contact`.`self` = 1"
-			);
+			$regs = Friendica\Model\Register::getPending();
 
 			if (DBA::isResult($regs)) {
 				$register_count = count($regs);
diff --git a/mod/register.php b/mod/register.php
index 2b3522234e..79e9455cd5 100644
--- a/mod/register.php
+++ b/mod/register.php
@@ -11,10 +11,8 @@ use Friendica\Core\L10n;
 use Friendica\Core\PConfig;
 use Friendica\Core\System;
 use Friendica\Core\Worker;
-use Friendica\Database\DBA;
 use Friendica\Model;
 use Friendica\Module\Tos;
-use Friendica\Util\DateTimeFormat;
 
 require_once 'include/enotify.php';
 
@@ -86,7 +84,7 @@ function register_post(App $a)
 
 	if (intval(Config::get('config', 'register_policy')) === REGISTER_OPEN) {
 		if ($using_invites && $invite_id) {
-			q("delete * from register where hash = '%s' limit 1", DBA::escape($invite_id));
+			Model\Register::deleteByHash($invite_id);
 			PConfig::set($user['uid'], 'system', 'invites_remaining', $num_invites);
 		}
 
@@ -122,19 +120,11 @@ function register_post(App $a)
 			goaway();
 		}
 
-		$hash = random_string();
-		$r = q("INSERT INTO `register` ( `hash`, `created`, `uid`, `password`, `language`, `note` ) VALUES ( '%s', '%s', %d, '%s', '%s', '%s' ) ",
-			DBA::escape($hash),
-			DBA::escape(DateTimeFormat::utcNow()),
-			intval($user['uid']),
-			DBA::escape($result['password']),
-			DBA::escape(Config::get('system', 'language')),
-			DBA::escape($_POST['permonlybox'])
-		);
+		Model\Register::createForApproval($user['uid'], Config::get('system', 'language'), $_POST['permonlybox']);
 
 		// invite system
 		if ($using_invites && $invite_id) {
-			q("DELETE * FROM `register` WHERE `hash` = '%s' LIMIT 1", DBA::escape($invite_id));
+			Model\Register::deleteByHash($invite_id);
 			PConfig::set($user['uid'], 'system', 'invites_remaining', $num_invites);
 		}
 
@@ -163,6 +153,7 @@ function register_post(App $a)
 		}
 		// send notification to the user, that the registration is pending
 		Model\User::sendRegisterPendingEmail(
+			$user['uid'],
 			$user['email'],
 			Config::get('config', 'sitename'),
 			$user['username'],
diff --git a/mod/regmod.php b/mod/regmod.php
index 11d8eee412..433a8f5e4e 100644
--- a/mod/regmod.php
+++ b/mod/regmod.php
@@ -9,6 +9,7 @@ use Friendica\Core\L10n;
 use Friendica\Core\System;
 use Friendica\Core\Worker;
 use Friendica\Database\DBA;
+use Friendica\Model\Register;
 use Friendica\Model\User;
 use Friendica\Module\Login;
 
@@ -18,30 +19,24 @@ function user_allow($hash)
 {
 	$a = get_app();
 
-	$register = q("SELECT * FROM `register` WHERE `hash` = '%s' LIMIT 1",
-		DBA::escape($hash)
-	);
-
+	$register = Register::getByHash($hash);
 
 	if (!DBA::isResult($register)) {
 		return false;
 	}
 
 	$user = q("SELECT * FROM `user` WHERE `uid` = %d LIMIT 1",
-		intval($register[0]['uid'])
+		intval($register['uid'])
 	);
 
 	if (!DBA::isResult($user)) {
 		killme();
 	}
 
-	$r = q("DELETE FROM `register` WHERE `hash` = '%s'",
-		DBA::escape($register[0]['hash'])
-	);
-
+	Register::deleteByHash($hash);
 
 	$r = q("UPDATE `user` SET `blocked` = 0, `verified` = 1 WHERE `uid` = %d",
-		intval($register[0]['uid'])
+		intval($register['uid'])
 	);
 
 	$r = q("SELECT * FROM `profile` WHERE `uid` = %d AND `is-default` = 1",
@@ -54,14 +49,14 @@ function user_allow($hash)
 		}
 	}
 
-	L10n::pushLang($register[0]['language']);
+	L10n::pushLang($register['language']);
 
 	$res = User::sendRegisterOpenEmail(
 		$user[0]['email'],
 		Config::get('config', 'sitename'),
 		System::baseUrl(),
 		$user[0]['username'],
-		$register[0]['password'],
+		'Sent in a previous email',
 		$user[0]);
 
 	L10n::popLang();
@@ -77,20 +72,19 @@ function user_allow($hash)
 // allowed to have friends on this system
 function user_deny($hash)
 {
-	$register = q("SELECT * FROM `register` WHERE `hash` = '%s' LIMIT 1",
-		DBA::escape($hash)
-	);
+	$register = Register::getByHash($hash);
 
 	if (!DBA::isResult($register)) {
 		return false;
 	}
 
 	$user = q("SELECT * FROM `user` WHERE `uid` = %d LIMIT 1",
-		intval($register[0]['uid'])
+		intval($register['uid'])
 	);
 
-	DBA::delete('user', ['uid' => $register[0]['uid']]);
-	DBA::delete('register', ['hash' => $register[0]['hash']]);
+	DBA::delete('user', ['uid' => $register['uid']]);
+
+	Register::deleteByHash($register['hash']);
 
 	notice(L10n::t('Registration revoked for %s', $user[0]['username']) . EOL);
 	return true;
diff --git a/src/Model/User.php b/src/Model/User.php
index ddd6ce1ed6..2888410c7f 100644
--- a/src/Model/User.php
+++ b/src/Model/User.php
@@ -412,7 +412,7 @@ class User
 				throw new Exception(L10n::t('An invitation is required.'));
 			}
 
-			if (!DBA::exists('register', ['hash' => $invite_id])) {
+			if (!Register::existsByHash($invite_id)) {
 				throw new Exception(L10n::t('Invitation could not be verified.'));
 			}
 		}
@@ -660,22 +660,31 @@ class User
 	 * @param string $email
 	 * @param string $sitename
 	 * @param string $username
+	 * @param string $password Plaintext password
 	 * @return NULL|boolean from notification() and email() inherited
 	 */
-	public static function sendRegisterPendingEmail($email, $sitename, $username)
+	public static function sendRegisterPendingEmail($uid, $email, $sitename, $username, $siteurl, $nickname, $password)
 	{
 		$body = deindent(L10n::t('
 			Dear %1$s,
 				Thank you for registering at %2$s. Your account is pending for approval by the administrator.
-		'));
 
-		$body = sprintf($body, $username, $sitename);
+			Your login details are as follows:
+
+			Site Location:	%3$s
+			Login Name:		%4$s
+			Password:		%5$s
+		',
+			$body, $username, $sitename, $siteurl, $nickname, $password
+		));
 
 		return notification([
-			'type' => SYSTEM_EMAIL,
+			'type'     => SYSTEM_EMAIL,
+			'uid'      => $uid,
 			'to_email' => $email,
-			'subject'=> L10n::t('Registration at %s', $sitename),
-			'body' => $body]);
+			'subject'  => L10n::t('Registration at %s', $sitename),
+			'body'     => $body
+		]);
 	}
 
 	/**
@@ -695,7 +704,9 @@ class User
 		$preamble = deindent(L10n::t('
 			Dear %1$s,
 				Thank you for registering at %2$s. Your account has been created.
-		'));
+		',
+			$preamble, $username, $sitename
+		));
 		$body = deindent(L10n::t('
 			The login details are as follows:
 
@@ -722,19 +733,19 @@ class User
 
 			If you ever want to delete your account, you can do so at %3$s/removeme
 
-			Thank you and welcome to %2$s.'));
-
-		$preamble = sprintf($preamble, $username, $sitename);
-		$body = sprintf($body, $email, $sitename, $siteurl, $username, $password);
+			Thank you and welcome to %2$s.',
+			$body, $email, $sitename, $siteurl, $username, $password
+		));
 
 		return notification([
-			'uid' => $user['uid'],
+			'uid'      => $user['uid'],
 			'language' => $user['language'],
-			'type' => SYSTEM_EMAIL,
+			'type'     => SYSTEM_EMAIL,
 			'to_email' => $email,
-			'subject'=> L10n::t('Registration details for %s', $sitename),
-			'preamble'=> $preamble,
-			'body' => $body]);
+			'subject'  => L10n::t('Registration details for %s', $sitename),
+			'preamble' => $preamble,
+			'body'     => $body
+		]);
 	}
 
 	/**
@@ -771,7 +782,7 @@ class User
 		if ($uid == local_user()) {
 			unset($_SESSION['authenticated']);
 			unset($_SESSION['uid']);
-			goaway(System::baseUrl());
+			goaway();;
 		}
 	}
 }

From 9e1065ff87e22dcf38f97f203030bc7a73ae64ba Mon Sep 17 00:00:00 2001
From: Benjamin Lorteau <benjamin.lorteau@cbsinteractive.com>
Date: Mon, 15 Oct 2018 11:58:52 -0400
Subject: [PATCH 6/6] Improve transition from previous behavior

- Simplify Model\User methods parameter list
- Use DBA methods in mod/regmod
- Replace killme with exit in mod/regmod
- Simplify goaway() calls
---
 mod/register.php   | 11 +++------
 mod/regmod.php     | 57 ++++++++++++++++++----------------------------
 src/Model/User.php | 38 +++++++++++++++++++------------
 3 files changed, 48 insertions(+), 58 deletions(-)

diff --git a/mod/register.php b/mod/register.php
index 79e9455cd5..48fe67afc5 100644
--- a/mod/register.php
+++ b/mod/register.php
@@ -91,12 +91,10 @@ function register_post(App $a)
 		// Only send a password mail when the password wasn't manually provided
 		if (!x($_POST, 'password1') || !x($_POST, 'confirm')) {
 			$res = Model\User::sendRegisterOpenEmail(
-				$user['email'],
+				$user,
 				Config::get('config', 'sitename'),
 				$a->getBaseUrl(),
-				$user['username'],
-				$result['password'],
-				$user
+				$result['password']
 			);
 
 			if ($res) {
@@ -153,12 +151,9 @@ function register_post(App $a)
 		}
 		// send notification to the user, that the registration is pending
 		Model\User::sendRegisterPendingEmail(
-			$user['uid'],
-			$user['email'],
+			$user,
 			Config::get('config', 'sitename'),
-			$user['username'],
 			$a->getBaseURL(),
-			$user['nickname'],
 			$result['password']
 		);
 
diff --git a/mod/regmod.php b/mod/regmod.php
index 433a8f5e4e..3f6f0e04e3 100644
--- a/mod/regmod.php
+++ b/mod/regmod.php
@@ -20,44 +20,34 @@ function user_allow($hash)
 	$a = get_app();
 
 	$register = Register::getByHash($hash);
-
 	if (!DBA::isResult($register)) {
 		return false;
 	}
 
-	$user = q("SELECT * FROM `user` WHERE `uid` = %d LIMIT 1",
-		intval($register['uid'])
-	);
-
+	$user = User::getById($register['uid']);
 	if (!DBA::isResult($user)) {
-		killme();
+		exit();
 	}
 
 	Register::deleteByHash($hash);
 
-	$r = q("UPDATE `user` SET `blocked` = 0, `verified` = 1 WHERE `uid` = %d",
-		intval($register['uid'])
-	);
+	DBA::update('user', ['blocked' => false, 'verified' => true], ['uid' => $register['uid']]);
 
-	$r = q("SELECT * FROM `profile` WHERE `uid` = %d AND `is-default` = 1",
-		intval($user[0]['uid'])
-	);
-	if (DBA::isResult($r) && $r[0]['net-publish']) {
-		$url = System::baseUrl() . '/profile/' . $user[0]['nickname'];
-		if ($url && strlen(Config::get('system', 'directory'))) {
-			Worker::add(PRIORITY_LOW, "Directory", $url);
-		}
+	$profile = DBA::selectFirst('profile', ['net-publish'], ['uid' => $register['uid'], 'is-default' => true]);
+
+	if (DBA::isResult($profile) && $profile['net-publish'] && Config::get('system', 'directory')) {
+		$url = System::baseUrl() . '/profile/' . $user['nickname'];
+		Worker::add(PRIORITY_LOW, "Directory", $url);
 	}
 
 	L10n::pushLang($register['language']);
 
 	$res = User::sendRegisterOpenEmail(
-		$user[0]['email'],
+		$user,
 		Config::get('config', 'sitename'),
-		System::baseUrl(),
-		$user[0]['username'],
-		'Sent in a previous email',
-		$user[0]);
+		$a->getBaseUrl(),
+		defaults($register, 'password', 'Sent in a previous email')
+	);
 
 	L10n::popLang();
 
@@ -73,20 +63,20 @@ function user_allow($hash)
 function user_deny($hash)
 {
 	$register = Register::getByHash($hash);
-
 	if (!DBA::isResult($register)) {
 		return false;
 	}
 
-	$user = q("SELECT * FROM `user` WHERE `uid` = %d LIMIT 1",
-		intval($register['uid'])
-	);
+	$user = User::getById($register['uid']);
+	if (!DBA::isResult($user)) {
+		exit();
+	}
 
 	DBA::delete('user', ['uid' => $register['uid']]);
 
 	Register::deleteByHash($register['hash']);
 
-	notice(L10n::t('Registration revoked for %s', $user[0]['username']) . EOL);
+	notice(L10n::t('Registration revoked for %s', $user['username']) . EOL);
 	return true;
 }
 
@@ -94,17 +84,16 @@ function regmod_content(App $a)
 {
 	if (!local_user()) {
 		info(L10n::t('Please login.') . EOL);
-		$o = '<br /><br />' . Login::form($a->query_string, intval(Config::get('config', 'register_policy')) === REGISTER_CLOSED ? 0 : 1);
-		return $o;
+		return Login::form($a->query_string, intval(Config::get('config', 'register_policy')) === REGISTER_CLOSED ? 0 : 1);
 	}
 
-	if ((!is_site_admin()) || (x($_SESSION, 'submanage') && intval($_SESSION['submanage']))) {
+	if (!is_site_admin() || !empty($_SESSION['submanage'])) {
 		notice(L10n::t('Permission denied.') . EOL);
 		return '';
 	}
 
 	if ($a->argc != 3) {
-		killme();
+		exit();
 	}
 
 	$cmd = $a->argv[1];
@@ -112,13 +101,11 @@ function regmod_content(App $a)
 
 	if ($cmd === 'deny') {
 		user_deny($hash);
-		goaway(System::baseUrl() . "/admin/users/");
-		killme();
+		goaway('admin/users/');
 	}
 
 	if ($cmd === 'allow') {
 		user_allow($hash);
-		goaway(System::baseUrl() . "/admin/users/");
-		killme();
+		goaway('admin/users/');
 	}
 }
diff --git a/src/Model/User.php b/src/Model/User.php
index 2888410c7f..eb042eb8b4 100644
--- a/src/Model/User.php
+++ b/src/Model/User.php
@@ -43,9 +43,18 @@ class User
 	}
 
 	/**
-	 * @brief Returns the user id of a given profile url
+	 * @param  integer       $uid
+	 * @return array|boolean User record if it exists, false otherwise
+	 */
+	public static function getById($uid)
+	{
+		return DBA::selectFirst('user', [], ['uid' => $uid]);
+	}
+
+	/**
+	 * @brief Returns the user id of a given profile URL
 	 *
-	 * @param string $profile
+	 * @param string $url
 	 *
 	 * @return integer user id
 	 */
@@ -657,13 +666,13 @@ class User
 	/**
 	 * @brief Sends pending registration confirmation email
 	 *
-	 * @param string $email
+	 * @param array  $user     User record array
 	 * @param string $sitename
-	 * @param string $username
+	 * @param string $siteurl
 	 * @param string $password Plaintext password
 	 * @return NULL|boolean from notification() and email() inherited
 	 */
-	public static function sendRegisterPendingEmail($uid, $email, $sitename, $username, $siteurl, $nickname, $password)
+	public static function sendRegisterPendingEmail($user, $sitename, $siteurl, $password)
 	{
 		$body = deindent(L10n::t('
 			Dear %1$s,
@@ -675,13 +684,13 @@ class User
 			Login Name:		%4$s
 			Password:		%5$s
 		',
-			$body, $username, $sitename, $siteurl, $nickname, $password
+			$body, $user['username'], $sitename, $siteurl, $user['nickname'], $password
 		));
 
 		return notification([
 			'type'     => SYSTEM_EMAIL,
-			'uid'      => $uid,
-			'to_email' => $email,
+			'uid'      => $user['uid'],
+			'to_email' => $user['email'],
 			'subject'  => L10n::t('Registration at %s', $sitename),
 			'body'     => $body
 		]);
@@ -692,20 +701,19 @@ class User
 	 *
 	 * It's here as a function because the mail is sent from different parts
 	 *
-	 * @param string $email
+	 * @param array  $user     User record array
 	 * @param string $sitename
 	 * @param string $siteurl
-	 * @param string $username
-	 * @param string $password
+	 * @param string $password Plaintext password
 	 * @return NULL|boolean from notification() and email() inherited
 	 */
-	public static function sendRegisterOpenEmail($email, $sitename, $siteurl, $username, $password, $user)
+	public static function sendRegisterOpenEmail($user, $sitename, $siteurl, $password)
 	{
 		$preamble = deindent(L10n::t('
 			Dear %1$s,
 				Thank you for registering at %2$s. Your account has been created.
 		',
-			$preamble, $username, $sitename
+			$preamble, $user['username'], $sitename
 		));
 		$body = deindent(L10n::t('
 			The login details are as follows:
@@ -734,14 +742,14 @@ class User
 			If you ever want to delete your account, you can do so at %3$s/removeme
 
 			Thank you and welcome to %2$s.',
-			$body, $email, $sitename, $siteurl, $username, $password
+			$body, $user['email'], $sitename, $siteurl, $user['username'], $password
 		));
 
 		return notification([
 			'uid'      => $user['uid'],
 			'language' => $user['language'],
 			'type'     => SYSTEM_EMAIL,
-			'to_email' => $email,
+			'to_email' => $user['email'],
 			'subject'  => L10n::t('Registration details for %s', $sitename),
 			'preamble' => $preamble,
 			'body'     => $body