[FIX] Merge conflict with development

This commit is contained in:
Sebastian Grewe 2014-04-24 11:43:38 +02:00
commit 43bf7be200
21 changed files with 9233 additions and 50 deletions

View File

@ -29,6 +29,14 @@ if (!$session_start) {
}
@setcookie(session_name(), session_id(), time()+$config['cookie']['duration'], $config['cookie']['path'], $config['cookie']['domain'], $config['cookie']['secure'], $config['cookie']['httponly']);
// Set the timezone if a user has it set, default UTC
if (isset($_SESSION['USERDATA']['timezone'])) {
$aTimezones = DateTimeZone::listIdentifiers();
date_default_timezone_set($aTimezones[$_SESSION['USERDATA']['timezone']]);
} else {
date_default_timezone_set('UTC');
}
// Our default template to load, pages can overwrite this later
$master_template = 'master.tpl';

View File

@ -7,8 +7,15 @@ class User extends Base {
private $user = array();
// get and set methods
private function getHash($string) {
return hash('sha256', $string.$this->salt);
private function getHash($string, $version=0, $pepper='') {
switch($version) {
case 0:
return hash('sha256', $string.$this->salt);
break;
case 1:
return '$' . $version . '$' . $pepper . '$' . hash('sha256', $string.$this->salt.$pepper);
break;
}
}
public function getUserName($id) {
return $this->getSingle($id, 'username', 'id');
@ -28,6 +35,12 @@ class User extends Base {
public function getUserEmailById($id) {
return $this->getSingle($id, 'email', 'id', 'i');
}
public function getUserPasswordHashById($id) {
return $this->getSingle($id, 'pass', 'id', 'i');
}
public function getUserPinHashById($id) {
return $this->getSingle($id, 'pin', 'id', 'i');
}
public function getUserNoFee($id) {
return $this->getSingle($id, 'no_fees', 'id');
}
@ -257,11 +270,13 @@ class User extends Base {
* @param pin int PIN to check
* @return bool
**/
public function checkPin($userId, $pin=false) {
public function checkPin($userId, $pin='') {
$this->debug->append("STA " . __METHOD__, 4);
$this->debug->append("Confirming PIN for $userId and pin $pin", 2);
$stmt = $this->mysqli->prepare("SELECT pin FROM $this->table WHERE id=? AND pin=? LIMIT 1");
$pin_hash = $this->getHash($pin);
$strPinHash = $this->getUserPinHashById($userId);
$aPin = explode('$', $strPinHash);
count($aPin) == 1 ? $pin_hash = $this->getHash($pin, 0) : $pin_hash = $this->getHash($pin, $aPin[1], $aPin[2]);
$stmt = $this->mysqli->prepare("SELECT pin FROM $this->table WHERE id = ? AND pin = ? LIMIT 1");
if ($stmt->bind_param('is', $userId, $pin_hash) && $stmt->execute() && $stmt->bind_result($row_pin) && $stmt->fetch()) {
$this->setUserPinFailed($userId, 0);
return ($pin_hash === $row_pin);
@ -289,15 +304,17 @@ class User extends Base {
$this->debug->append("STA " . __METHOD__, 4);
$username = $this->getUserName($userID);
$email = $this->getUserEmail($username);
$current = $this->getHash($current);
$strPasswordHash = $this->getUserPasswordHashById($userID);
$aPassword = explode('$', $strPasswordHash);
count($aPassword) == 1 ? $password_hash = $this->getHash($current, 0) : $password_hash = $this->getHash($current, $aPassword[1], $aPassword[2]);
$newpin = intval( '0' . rand(1,9) . rand(0,9) . rand(0,9) . rand(0,9) );
$aData['username'] = $username;
$aData['email'] = $email;
$aData['pin'] = $newpin;
$newpin = $this->getHash($newpin);
$newpin = $this->getHash($newpin, HASH_VERSION, bin2hex(openssl_random_pseudo_bytes(32)));
$aData['subject'] = 'PIN Reset Request';
$stmt = $this->mysqli->prepare("UPDATE $this->table SET pin = ? WHERE ( id = ? AND pass = ? )");
if ($this->checkStmt($stmt) && $stmt->bind_param('sis', $newpin, $userID, $current) && $stmt->execute()) {
if ($this->checkStmt($stmt) && $stmt->bind_param('sis', $newpin, $userID, $password_hash) && $stmt->execute()) {
if ($stmt->errno == 0 && $stmt->affected_rows === 1) {
if ($this->mail->sendMail('pin/reset', $aData)) {
$this->log->log("info", "$username was sent a pin reset e-mail");
@ -407,7 +424,7 @@ class User extends Base {
$this->setErrorMessage('A request has already been sent to your e-mail address. Please wait an hour for it to expire.');
return false;
}
/**
* Update the accounts password
* @param userID int User ID
@ -427,8 +444,10 @@ class User extends Base {
$this->setErrorMessage( 'New password is too short, please use more than 8 chars' );
return false;
}
$current = $this->getHash($current);
$new = $this->getHash($new1);
$strPasswordHash = $this->getUserPasswordHashById($userID);
$aPassword = explode('$', $strPasswordHash);
count($aPassword) == 1 ? $password_hash = $this->getHash($current, 0) : $password_hash = $this->getHash($current, $aPassword[1], $aPassword[2]);
$new = $this->getHash($new1, HASH_VERSION, bin2hex(openssl_random_pseudo_bytes(32)));
if ($this->config['twofactor']['enabled'] && $this->config['twofactor']['options']['changepw']) {
$tValid = $this->token->isTokenValid($userID, $strToken, 6);
if ($tValid) {
@ -448,7 +467,7 @@ class User extends Base {
}
$stmt = $this->mysqli->prepare("UPDATE $this->table SET pass = ? WHERE ( id = ? AND pass = ? )");
if ($this->checkStmt($stmt)) {
$stmt->bind_param('sis', $new, $userID, $current);
$stmt->bind_param('sis', $new, $userID, $password_hash);
$stmt->execute();
if ($stmt->errno == 0 && $stmt->affected_rows === 1) {
$this->log->log("info", $this->getUserName($userID)." updated password");
@ -460,7 +479,7 @@ class User extends Base {
$this->setErrorMessage( 'Unable to update password, current password wrong?' );
return false;
}
/**
* Update account information from the edit account page
* @param userID int User ID
@ -470,7 +489,7 @@ class User extends Base {
* @param strToken string Token for confirmation
* @return bool
**/
public function updateAccount($userID, $address, $threshold, $donate, $email, $is_anonymous, $strToken) {
public function updateAccount($userID, $address, $threshold, $donate, $email, $timezone, $is_anonymous, $strToken) {
$this->debug->append("STA " . __METHOD__, 4);
$bUser = false;
$donate = round($donate, 2);
@ -538,10 +557,10 @@ class User extends Base {
return false;
}
}
// We passed all validation checks so update the account
$stmt = $this->mysqli->prepare("UPDATE $this->table SET coin_address = ?, ap_threshold = ?, donate_percent = ?, email = ?, is_anonymous = ? WHERE id = ?");
if ($this->checkStmt($stmt) && $stmt->bind_param('sddsii', $address, $threshold, $donate, $email, $is_anonymous, $userID) && $stmt->execute()) {
$stmt = $this->mysqli->prepare("UPDATE $this->table SET coin_address = ?, ap_threshold = ?, donate_percent = ?, email = ?, timezone = ?, is_anonymous = ? WHERE id = ?");
if ($this->checkStmt($stmt) && $stmt->bind_param('sddssii', $address, $threshold, $donate, $email, $timezone, $is_anonymous, $userID) && $stmt->execute()) {
$this->log->log("info", $this->getUserName($userID)." updated their account details");
return true;
}
@ -577,14 +596,15 @@ class User extends Base {
private function checkUserPassword($username, $password) {
$this->debug->append("STA " . __METHOD__, 4);
$user = array();
$password_hash = $this->getHash($password);
$stmt = $this->mysqli->prepare("SELECT username, id, is_admin FROM $this->table WHERE LOWER(username) = LOWER(?) AND pass = ? LIMIT 1");
if ($this->checkStmt($stmt) && $stmt->bind_param('ss', $username, $password_hash) && $stmt->execute() && $stmt->bind_result($row_username, $row_id, $row_admin)) {
$stmt = $this->mysqli->prepare("SELECT username, pass, id, timezone, is_admin FROM $this->table WHERE LOWER(username) = LOWER(?) LIMIT 1");
if ($this->checkStmt($stmt) && $stmt->bind_param('s', $username) && $stmt->execute() && $stmt->bind_result($row_username, $row_password, $row_id, $row_timezone, $row_admin)) {
$stmt->fetch();
$stmt->close();
$aPassword = explode('$', $row_password);
count($aPassword) == 1 ? $password_hash = $this->getHash($password, 0) : $password_hash = $this->getHash($password, $aPassword[1], $aPassword[2]);
// Store the basic login information
$this->user = array('username' => $row_username, 'id' => $row_id, 'is_admin' => $row_admin);
return strtolower($username) === strtolower($row_username);
$this->user = array('username' => $row_username, 'id' => $row_id, 'timezone' => $row_timezone, 'is_admin' => $row_admin);
return $password_hash === $row_password && strtolower($username) === strtolower($row_username);
}
return $this->sqlError();
}
@ -683,7 +703,7 @@ class User extends Base {
$this->debug->append("Fetching user information for user id: $userID");
$stmt = $this->mysqli->prepare("
SELECT
id, username, pin, api_key, is_admin, is_anonymous, email, no_fees,
id, username, pin, api_key, is_admin, is_anonymous, email, timezone, no_fees,
IFNULL(donate_percent, '0') as donate_percent, coin_address, ap_threshold
FROM $this->table
WHERE id = ? LIMIT 0,1");
@ -788,9 +808,9 @@ class User extends Base {
}
// Create hashed strings using original string and salt
$password_hash = $this->getHash($password1);
$pin_hash = $this->getHash($pin);
$apikey_hash = $this->getHash($username);
$password_hash = $this->getHash($password1, HASH_VERSION, bin2hex(openssl_random_pseudo_bytes(32)));
$pin_hash = $this->getHash($pin, HASH_VERSION, bin2hex(openssl_random_pseudo_bytes(32)));
$apikey_hash = $this->getHash($username, 0);
$username_clean = strip_tags($username);
$signup_time = time();
@ -841,7 +861,7 @@ class User extends Base {
$this->setErrorMessage( 'New password is too short, please use more than 8 chars' );
return false;
}
$new_hash = $this->getHash($new1);
$new_hash = $this->getHash($new1, HASH_VERSION, bin2hex(openssl_random_pseudo_bytes(32)));
$stmt = $this->mysqli->prepare("UPDATE $this->table SET pass = ? WHERE id = ?");
if ($this->checkStmt($stmt) && $stmt->bind_param('si', $new_hash, $aToken['account_id']) && $stmt->execute() && $stmt->affected_rows === 1) {
if ($this->token->deleteToken($aToken['token'])) {

View File

@ -13,8 +13,9 @@ $aSettings['website'][] = array(
'tooltip' => 'Enable or Disable maintenance mode. Only admins can still login.'
);
$aSettings['website'][] = array(
'display' => 'Message of the Day', 'type' => 'text',
'size' => 25,
'display' => 'Message of the Day', 'type' => 'textarea',
'size' => 20,
'height' => 3,
'default' => '',
'name' => 'system_motd', 'value' => $setting->getValue('system_motd'),
'tooltip' => 'Display a message of the day as information popup if set.'

View File

@ -132,10 +132,11 @@ if ($user->isAuthenticated()) {
if ($config['twofactor']['enabled'] && $config['twofactor']['options']['details'] && !$ea_editable) {
$_SESSION['POPUP'][] = array('CONTENT' => 'You have not yet unlocked account updates.', 'TYPE' => 'alert alert-danger');
} else if (!$config['csrf']['enabled'] || $config['csrf']['enabled'] && $csrftoken->valid) {
if ($user->updateAccount($_SESSION['USERDATA']['id'], $_POST['paymentAddress'], $_POST['payoutThreshold'], $_POST['donatePercent'], $_POST['email'], $_POST['is_anonymous'], $oldtoken_ea)) {
$_SESSION['POPUP'][] = array('CONTENT' => 'Account details updated', 'TYPE' => 'alert alert-success');
if ($user->updateAccount($_SESSION['USERDATA']['id'], $_POST['paymentAddress'], $_POST['payoutThreshold'], $_POST['donatePercent'], $_POST['email'], $_POST['timezone'], $_POST['is_anonymous'], $oldtoken_ea)) {
$_SESSION['USERDATA']['timezone'] = $_POST['timezone'];
$_SESSION['POPUP'][] = array('CONTENT' => 'Account details updated', 'TYPE' => 'alert alert-success');
} else {
$_SESSION['POPUP'][] = array('CONTENT' => 'Failed to update your account: ' . $user->getError(), 'TYPE' => 'alert alert-danger');
$_SESSION['POPUP'][] = array('CONTENT' => 'Failed to update your account: ' . $user->getError(), 'TYPE' => 'alert alert-danger');
}
} else {
$_SESSION['POPUP'][] = array('CONTENT' => $csrftoken->getErrorWithDescriptionHTML(), 'TYPE' => 'alert alert-warning');
@ -197,6 +198,10 @@ if ($config['twofactor']['enabled'] && $user->isAuthenticated()) {
$smarty->assign("DETAILSSENT", $ea_sent);
}
// Grab our timezones
$smarty->assign('TIMEZONES', DateTimeZone::listIdentifiers());
// Fetch donation threshold
$smarty->assign("DONATE_THRESHOLD", $config['donate_threshold']);
// Tempalte specifics

View File

@ -4,6 +4,7 @@ $defflip = (!cfip()) ? exit(header('HTTP/1.1 401 Unauthorized')) : 1;
define('MPOS_VERSION', '0.0.4');
define('DB_VERSION', '0.0.10');
define('CONFIG_VERSION', '0.0.8');
define('HASH_VERSION', 1);
// Fetch installed database version
$db_version = $setting->getValue('DB_VERSION');

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -15,6 +15,7 @@ CREATE TABLE IF NOT EXISTS `accounts` (
`username` varchar(40) NOT NULL,
`pass` varchar(255) NOT NULL,
`email` varchar(255) DEFAULT NULL COMMENT 'Assocaited email: used for validating users, and re-setting passwords',
`timezone` varchar(35) NOT NULL DEFAULT '415',
`notify_email` VARCHAR( 255 ) NULL DEFAULT NULL,
`loggedIp` varchar(255) DEFAULT NULL,
`is_locked` tinyint(1) NOT NULL DEFAULT '0',

View File

@ -30,6 +30,14 @@
<label>E-Mail</label>
{nocache}<input class="form-control" type="text" name="email" value="{$GLOBAL.userdata.email|escape}" size="20" {if $GLOBAL.twofactor.enabled && $GLOBAL.twofactor.options.details && !$DETAILSUNLOCKED}id="disabledInput" disabled{/if}/>{/nocache}
</div>
<div class="form-group">
<label>Timezone</label>
{nocache}
<select class="form-control" name="timezone">
{html_options options=$TIMEZONES selected=$GLOBAL.userdata.timezone}
</select>
{/nocache}
</div>
<div class="form-group">
<label>Payment Address</label>
{nocache}<input class="form-control" type="text" name="paymentAddress" value="{$smarty.request.paymentAddress|default:$GLOBAL.userdata.coin_address|escape}" size="40" {if $GLOBAL.twofactor.enabled && $GLOBAL.twofactor.options.details && !$DETAILSUNLOCKED}id="disabledInput" disabled{/if}/>{/nocache}

View File

@ -26,7 +26,7 @@
<link href="{$PATH}/css/design/{$GLOBAL.config.website_design}.css" rel="stylesheet">
{/if}
<script src="{$PATH}/js/jquery-2.0.3.min.js"></script>
<script src="{$PATH}/js/jquery-2.1.0.min.js"></script>
<script src="{$PATH}/js/jquery.cookie.js"></script>
<script src="{$PATH}/js/jquery.md5.js"></script>
<script src="{$PATH}/js/bootstrap.min.js"></script>

View File

@ -2,7 +2,7 @@
<body>
<p>Hello valued miner,</p><br />
<p>{nocache}{$DATA.username}{/nocache} invited you to participate on this pool:
<p>http://{$smarty.server.SERVER_NAME}{$smarty.server.SCRIPT_NAME}?page=register&token={nocache}{$DATA.token}{/nocache}</p>
<p>http{if $smarty.server.HTTPS|default:"" eq "on"}s{/if}://{$smarty.server.SERVER_NAME}{$smarty.server.SCRIPT_NAME}?page=register&token={nocache}{$DATA.token}{/nocache}</p>
{if $DATA.message}<p>Personal message:</p><p>{nocache}{$DATA.message}{/nocache}</p>{/if}
<p></p>
<p>Cheers,</p>

View File

@ -2,8 +2,8 @@
<body>
<p>You have a pending request to change your account details.</p>
<p>If you initiated this request, please follow the link below to confirm your changes. If you did NOT, please notify an administrator.</p>
<p>http://{$smarty.server.SERVER_NAME}{$smarty.server.SCRIPT_NAME}?page=account&action=edit&ea_token={nocache}{$DATA.token}{/nocache}</p>
<p>http{if $smarty.server.HTTPS|default:"" eq "on"}s{/if}://{$smarty.server.SERVER_NAME}{$smarty.server.SCRIPT_NAME}?page=account&action=edit&ea_token={nocache}{$DATA.token}{/nocache}</p>
<br/>
<br/>
</body>
</html>
</html>

View File

@ -2,8 +2,8 @@
<body>
<p>You have a pending request to change your password.</p>
<p>If you initiated this request, please follow the link below to confirm your changes. If you did NOT, please notify an administrator.</p>
<p>http://{$smarty.server.SERVER_NAME}{$smarty.server.SCRIPT_NAME}?page=account&action=edit&cp_token={nocache}{$DATA.token}{/nocache}</p>
<p>http{if $smarty.server.HTTPS|default:"" eq "on"}s{/if}://{$smarty.server.SERVER_NAME}{$smarty.server.SCRIPT_NAME}?page=account&action=edit&cp_token={nocache}{$DATA.token}{/nocache}</p>
<br/>
<br/>
</body>
</html>
</html>

View File

@ -1,7 +1,7 @@
<html>
<body>
<p>You account has been locked due to too many failed password or PIN attempts. Please follow the URL below to unlock your account.</p>
<p>http://{$smarty.server.SERVER_NAME}{$smarty.server.SCRIPT_NAME}?page=account&action=unlock&token={nocache}{$DATA.token}{/nocache}</p>
<p>http{if $smarty.server.HTTPS|default:"" eq "on"}s{/if}://{$smarty.server.SERVER_NAME}{$smarty.server.SCRIPT_NAME}?page=account&action=unlock&token={nocache}{$DATA.token}{/nocache}</p>
<br/>
<br/>
</body>

View File

@ -2,8 +2,8 @@
<body>
<p>You have a pending request to manually withdraw funds.</p>
<p>If you initiated this request, please follow the link below to confirm your changes. If you did NOT, please notify an administrator.</p>
<p>http://{$smarty.server.SERVER_NAME}{$smarty.server.SCRIPT_NAME}?page=account&action=edit&wf_token={nocache}{$DATA.token}{/nocache}</p>
<p>http{if $smarty.server.HTTPS|default:"" eq "on"}s{/if}://{$smarty.server.SERVER_NAME}{$smarty.server.SCRIPT_NAME}?page=account&action=edit&wf_token={nocache}{$DATA.token}{/nocache}</p>
<br/>
<br/>
</body>
</html>
</html>

View File

@ -2,7 +2,7 @@
<body>
<p>Hello {nocache}{$DATA.username}{/nocache},</p><br />
<p>You have requested a password reset through our online form. In order to complete the request please follow this link:</p>
<p>http://{$smarty.server.SERVER_NAME}{$smarty.server.SCRIPT_NAME}?page=password&action=change&token={nocache}{$DATA.token}{/nocache}</p>
<p>http{if $smarty.server.HTTPS|default:"" eq "on"}s{/if}://{$smarty.server.SERVER_NAME}{$smarty.server.SCRIPT_NAME}?page=password&action=change&token={nocache}{$DATA.token}{/nocache}</p>
<p>You will be asked to change your password. You can then use this new password to login to your account.</p>
<p>Cheers,</p>
<p>{$WEBSITENAME}</p>

View File

@ -2,7 +2,7 @@
<body>
<p>Hello {nocache}{$DATA.username}{/nocache},</p><br />
<p>You have created a new account. In order to complete the registration process please follow this link:</p>
<p>http://{$smarty.server.SERVER_NAME}{$smarty.server.SCRIPT_NAME}?page=account&action=confirm&token={nocache}{$DATA.token}{/nocache}</p>
<p>http{if $smarty.server.HTTPS|default:"" eq "on"}s{/if}://{$smarty.server.SERVER_NAME}{$smarty.server.SCRIPT_NAME}?page=account&action=confirm&token={nocache}{$DATA.token}{/nocache}</p>
<p></p>
<p>Cheers,</p>
<p>{$WEBSITENAME}</p>

View File

@ -0,0 +1,30 @@
<?php
function run_009() {
// Ugly but haven't found a better way
global $setting, $config, $user, $mysqli;
// Version information
$db_version_old = '0.0.8'; // What version do we expect
$db_version_new = '0.0.9'; // What is the new version we wish to upgrade to
$db_version_now = $setting->getValue('DB_VERSION'); // Our actual version installed
// Upgrade specific variables
$aSql[] = "ALTER TABLE " . $user->getTableName() . " ADD `timezone` VARCHAR(35) NOT NULL DEFAULT '415' AFTER `email`";
$aSql[] = "UPDATE " . $setting->getTableName() . " SET value = '0.0.9' WHERE name = 'DB_VERSION'";
if ($db_version_now == $db_version_old && version_compare($db_version_now, DB_VERSION, '<')) {
// Run the upgrade
echo '- Starting database migration to version ' . $db_version_new . PHP_EOL;
foreach ($aSql as $sql) {
echo '- Preparing: ' . $sql . PHP_EOL;
$stmt = $mysqli->prepare($sql);
if ($stmt && $stmt->execute()) {
echo '- success' . PHP_EOL;
} else {
echo '- failed: ' . $mysqli->error . PHP_EOL;
exit(1);
}
}
}
}
?>