sendResponseCodeAndExitIfTrue(!isset($_POST['guid'], $_POST['publishstate'], $_POST['failpublishmessage'], $_POST['token']), 400); if (isset($_SESSION['mod_appview_token' . $_POST['guid']])) { $appViewToken = $_SESSION['mod_appview_token' . $_POST['guid']]; } sendResponseCodeAndExitIfTrue(!isset($appViewToken) || md5($appViewToken) !== $_POST['token'] || !is_numeric($_POST['publishstate']) || $_POST['publishstate'] < 0 || $_POST['publishstate'] > 5, 422); $appGuid = $_POST['guid']; $appPublishState = $_POST['publishstate']; $appFailPublishMessage = $_POST['publishstate'] == 2 || $_POST['publishstate'] == 5 ? escapeHTMLChars($_POST['failpublishmessage']) : ''; $mysqlConn = connectToDatabase(); if ($appPublishState == 1) { executePreparedSQLQuery($mysqlConn, 'UPDATE apps SET version = (SELECT versionId FROM appversions WHERE appGuid = ? ORDER BY versionId DESC LIMIT 1), publishstate = ?, failpublishmessage = ? WHERE guid = ? LIMIT 1', 'siss', [$appGuid, $appPublishState, $appFailPublishMessage, $appGuid]); //Update latest version and publish state in database } else { executePreparedSQLQuery($mysqlConn, 'UPDATE apps SET publishstate = ?, failpublishmessage = ? WHERE guid = ? LIMIT 1', 'iss', [$appPublishState, $appFailPublishMessage, $appGuid]); //Update publish state in database } if (isset($_POST['sendnotification']) && $_POST['sendnotification'] === 'yes') { $currentApp = getArrayFromSQLQuery($mysqlConn, 'SELECT name, publisher FROM apps WHERE guid = ?', 's', [$appGuid])[0]; $notificationUserId = $currentApp['publisher']; //Generate notification summary $notificationSummary = '"' . $currentApp['name'] . '" has been'; switch ($appPublishState) { case 1: //Published $notificationSummary .= ' approved.'; break; case 2: //Not approved $notificationSummary .= ' rejected.';
$groupToAdd = $_POST['grouptoadd']; //Insert group connection executePreparedSQLQuery($mysqlConn, 'INSERT IGNORE INTO groupconnections (userId, groupId) VALUES (?, ?)', 'ii', [$userId, $groupToAdd]); //Get group name $groupName = getArrayFromSQLQuery($mysqlConn, 'SELECT name FROM groups WHERE groupId = ?', 'i', [$groupToAdd])[0]['name']; //Create notification summary and body $notificationSummary = 'You are now part of "' . $groupName . '".'; $notificationBody = 'You have been added to the group "' . $groupName . '" by an administrator.'; } if (isset($_POST['grouptoremove'])) { $groupToRemove = $_POST['grouptoremove']; //Get group name $groupName = getArrayFromSQLQuery($mysqlConn, 'SELECT name FROM groups WHERE groupId = ?', 'i', [$groupToRemove])[0]['name']; //Remove group connection executePreparedSQLQuery($mysqlConn, 'DELETE FROM groupconnections WHERE userId = ? AND groupId = ?', 'ii', [$userId, $groupToRemove]); //Create notification summary and body $notificationSummary = 'You are no longer part of "' . $groupName . '".'; $notificationBody = 'You have been removed from the group "' . $groupName . '" by an administrator.'; } //Send notification if corresponding checkbox was checked if (isset($_POST['sendnotification']) && $_POST['sendnotification'] === 'yes') { $notificationManager = new notification_manager($mysqlConn); $notificationManager->createUserNotification($userId, $notificationSummary, $notificationBody); } $mysqlConn->close(); unset($_SESSION['admin_userview_token' . $userId]); unset($_SESSION['admin_users_token']); echo 'User group settings set.'; require_once '../../common/ucpfooter.php';
*/ require_once '../../common/user.php'; sendResponseCodeAndExitIfTrue(!isset($_SESSION['login_token']), 422); //Check if session login token is set $userToken = $_SESSION['login_token']; unset($_SESSION['login_token']); printAndExitIfTrue(clientLoggedIn(), 'You are already logged in.'); //Check if already logged in sendResponseCodeAndExitIfTrue(!isset($_POST['user'], $_POST['pass'], $_POST['logintoken']), 400); //Check if all expected POST vars are set sendResponseCodeAndExitIfTrue(md5($userToken) !== $_POST['logintoken'], 422); //Check if POST login token is correct $tryUserName = $_POST['user']; $tryUserPass = $_POST['pass']; $mysqlConn = connectToDatabase(); $matchingUsers = getArrayFromSQLQuery($mysqlConn, 'SELECT userId, password, nick FROM users WHERE LOWER(nick) = LOWER(?) LIMIT 1', 's', [$tryUserName]); printAndExitIfTrue(count($matchingUsers) != 1, 'Invalid username and/or password.'); //Check if there is one user matching attempted username $user = $matchingUsers[0]; printAndExitIfTrue(crypt($tryUserPass, $user['password']) !== $user['password'], 'Invalid username and/or password.'); //Check if password is correct $tokenSha1 = sha1($userToken); executePreparedSQLQuery($mysqlConn, 'UPDATE users SET token = ? WHERE userId = ? LIMIT 1', 'ss', [$tokenSha1, $user['userId']]); //Update user token in database $mysqlConn->close(); $_SESSION['user_id'] = $user['userId']; $_SESSION['user_nick'] = $user['nick']; $_SESSION['user_token'] = $tokenSha1; //Redirect to "my apps" list $redirectUrl = 'http://' . $_SERVER['HTTP_HOST'] . '/secure/myapps/'; header('Location: ' . $redirectUrl);
private function getNotificationObjects($count, $start, $includeRead) { //Get notifications from database $notifications = getArrayFromSQLQuery($this->mysqlConn, 'SELECT notifications.notificationId, notifications.userId, notifications.groupId, timeCreated, summary, body, url, CASE WHEN notificationreads.readId IS NOT NULL THEN 1 ELSE 0 END AS isRead FROM notifications' . $this->getJoinSQL() . $this->getWhereSQL($includeRead) . ' ORDER BY notifications.timeCreated DESC LIMIT ?, ?', 'ii', [$start, $count]); //Get notification objects $notificationObjects = $this->getObjectsFromNotificationArray($notifications); //Mark notifications as read foreach ($notificationObjects as $notification) { if (!$notification->isRead) { executePreparedSQLQuery($this->mysqlConn, 'INSERT IGNORE INTO notificationreads (userId, notificationId) VALUES (@curUserId, ?)', 'i', [$notification->notificationId]); } } return $notificationObjects; }
$secondLevelRequest = $param[1]; $guid = $param[2]; $matchingApps = getArrayFromSQLQuery($mysqlConn, 'SELECT appver.3dsx, appver.smdh, appver.appdata FROM appversions appver LEFT JOIN apps app ON appver.versionId = app.version WHERE app.guid = ? LIMIT 1', 's', [$guid]); printAndExitIfTrue(count($matchingApps) != 1, 'Invalid GUID.'); //Check if GUID is valid switch ($secondLevelRequest) { //TODO: More efficient code case '3dsx': //Update download count if IP not downloaded app already $ipHash = md5($_SERVER['REMOTE_ADDR']); $matchingDownloadIPs = getArrayFromSQLQuery($mysqlConn, 'SELECT downloadId FROM downloads WHERE appGuid = ? AND ipHash = ? LIMIT 1', 'ss', [$guid, $ipHash]); if (count($matchingDownloadIPs) == 0) { executePreparedSQLQuery($mysqlConn, 'INSERT INTO downloads (appGuid, ipHash) VALUES (?, ?)', 'ss', [$guid, $ipHash]); executePreparedSQLQuery($mysqlConn, 'UPDATE apps SET downloads = downloads + 1 WHERE guid = ? LIMIT 1', 's', [$guid]); } //Redirect to file header('Content-Length: ' . strlen($matchingApps[0]['3dsx'])); echo $matchingApps[0]['3dsx']; break; case 'smdh': //Redirect to file header('Content-Length: ' . strlen($matchingApps[0]['smdh'])); echo $matchingApps[0]['smdh']; break; case 'appdata': sendResponseCodeAndExitIfTrue($matchingApps[0]['appdata'] === null, 404); //Check if appdata exists //Redirect to file header('Content-Length: ' . strlen($matchingApps[0]['appdata']));
printAndExitIfTrue(!preg_match('`^[a-zA-Z0-9_]{1,}$`', $_POST['user']), 'Invalid username.'); printAndExitIfTrue(mb_strlen($_POST['user']) < 3, 'Username is too short.'); printAndExitIfTrue(mb_strlen($_POST['user']) > 24, 'Username is too long.'); //Check passwords printAndExitIfTrue($_POST['pass'] !== $_POST['pass2'], 'Passwords don\'t match.'); printAndExitIfTrue(mb_strlen($_POST['pass']) < 8, 'Password is too short.'); //Check e-mail printAndExitIfTrue(!filter_var($_POST['email'], FILTER_VALIDATE_EMAIL) || !checkdnsrr(substr($_POST['email'], strpos($_POST['email'], '@') + 1), 'MX'), 'Invalid email address.'); printAndExitIfTrue(mb_strlen($_POST['email']) > 255, 'E-mail is too long.'); //Check captcha $reCaptcha = new ReCaptcha(getConfigValue('apikey_recaptcha_secret')); $resp = $reCaptcha->verifyResponse($_SERVER["REMOTE_ADDR"], $_POST["g-recaptcha-response"]); printAndExitIfTrue($resp == null || !$resp->success, 'Invalid or no captcha response.'); $tryRegisterName = escapeHTMLChars($_POST['user']); $tryRegisterPass = $_POST['pass']; $tryRegisterEmail = escapeHTMLChars($_POST['email']); $hashedTryRegisterPass = crypt($tryRegisterPass, '$2y$07$' . uniqid(mt_rand(), true)); $mysqlConn = connectToDatabase(); //Check if there are any users with the same nick or email $matchingUsers = getArrayFromSQLQuery($mysqlConn, 'SELECT userId FROM users WHERE LOWER(nick) = LOWER(?) OR LOWER(email) = LOWER(?) LIMIT 1', 'ss', [$tryRegisterName, $tryRegisterEmail]); printAndExitIfTrue(count($matchingUsers) != 0, 'User with this name and/or email already exists.'); //Insert user into database $stmt = executePreparedSQLQuery($mysqlConn, 'INSERT INTO users (nick, password, email, token) VALUES (?, ?, ?, ?)', 'ssss', [$tryRegisterName, $hashedTryRegisterPass, $tryRegisterEmail, sha1($registerToken)], true); $userId = $stmt->insert_id; $stmt->close(); //Insert user group connection executePreparedSQLQuery($mysqlConn, 'INSERT INTO groupconnections (userId, groupId) VALUES (?, 1)', 'i', [$userId]); $mysqlConn->close(); print 'Register complete.';
/** * Get an array of rows from an SQL query with prepared statements * * @param mysqli $conn The MySQLi connection to execute the query on * @param string $sql The SQL statement to be prepared * @param string $bindParamTypes A string that contains one or more characters that specify the types of the corresponding bind variables (corresponds to $types in mysqli_stmt::bind_param) * @param array $bindParamVarsArr An array of variables to bind to the SQL query (corresponds to $var1 in mysqli_stmt::bind_param, however an array here) * @return array The returned rows from the SQL query */ function getArrayFromSQLQuery($conn, $sql, $bindParamTypes = null, $bindParamVarsArr = null) { $stmt = executePreparedSQLQuery($conn, $sql, $bindParamTypes, $bindParamVarsArr, true); $mysqlResult = $stmt->get_result(); //Get results $arr = array(); while ($mysqlRow = $mysqlResult->fetch_assoc()) { array_push($arr, $mysqlRow); //Push all rows to the array } $stmt->close(); return $arr; }
//...push it to storage and insert/update a database row for it $appScreenshotBlob = new blob(); $processedScreenshotHandle = processImage($_FILES['scr' . $i]['tmp_name'], 'screenshot'); $appScreenshotBlob->upload($blobRestProxy, getConfigValue('azure_container_screenshots'), stream_get_meta_data($processedScreenshotHandle)['uri']); $appScreenshotBlob->closeFileHandle(); executePreparedSQLQuery($mysqlConn, 'INSERT INTO screenshots (appGuid, imageIndex, url) VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE url = ?', 'siss', [$guid, $i, $appScreenshotBlob->url, $appScreenshotBlob->url]); } //Delete screenshots if desired if (deletingFile('scr' . $i)) { $matchingScreenshotsToDelete = getArrayFromSQLQuery($mysqlConn, 'SELECT url FROM screenshots WHERE appGuid = ? AND imageIndex = ?', 'si', [$guid, $i]); if (count($matchingScreenshotsToDelete) === 1) { //Delete screenshot from database executePreparedSQLQuery($mysqlConn, 'DELETE FROM screenshots WHERE appGuid = ? AND imageIndex = ?', 'si', [$guid, $i]); //Get screenshot blob name from URL $screenshotToDeleteBlobName = substr($matchingScreenshotsToDelete[0]['url'], strrpos($matchingScreenshotsToDelete[0]['url'], '/') + 1); //Delete screenshot from Azure storage $blobRestProxy->deleteBlob(getConfigValue('azure_container_screenshots'), $screenshotToDeleteBlobName); } } } unset($_SESSION['myapps_token' . $guid]); unset($_SESSION['publish_token' . $guid]); if ($isDeveloper || $updatingApp && $currentPublishState === 1 && !$updating3dsx && !$uploadingAppData) { echo 'Your application has been published.'; } else { //Prepare notification $notificationSummary = '"' . $appName . '" is awaiting approval.'; $notificationBody = $notificationSummary;
sendResponseCodeAndExitIfTrue(!isset($_POST['guidid']), 400); sendResponseCodeAndExitIfTrue(!isset($_SESSION['hide_app_guid' . $_POST['guidid']]), 422); //Check if GUID of app to remove is set $guid = $_SESSION['hide_app_guid' . $_POST['guidid']]; //Get GUID sendResponseCodeAndExitIfTrue(!isset($_SESSION['remove_token' . $guid]), 422); //Check if session app remove token is set $removeToken = $_SESSION['remove_token' . $guid]; sendResponseCodeAndExitIfTrue(!isset($_POST['pass'], $_POST['removetoken']), 400); //Check if all expected POST vars are set sendResponseCodeAndExitIfTrue(md5($removeToken) !== $_POST['removetoken'], 422); //Check if POST login token is correct printAndExitIfTrue(mb_substr($_POST['pass'], -1) !== '!', 'No exclamation mark entered at the end of the password.'); //Check if question mark was entered $tryUserPass = mb_substr($_POST['pass'], 0, -1); $mysqlConn = connectToDatabase(); $matchingUsers = getArrayFromSQLQuery($mysqlConn, 'SELECT password FROM users WHERE userId = ? LIMIT 1', 's', [$_SESSION['user_id']]); $user = $matchingUsers[0]; printAndExitIfTrue(crypt($tryUserPass, $user['password']) !== $user['password'], 'Invalid password.'); //Check if password is correct //Check if app not hidden already $matchingApps = getArrayFromSQLQuery($mysqlConn, 'SELECT publishstate FROM apps WHERE guid = ?', 's', [$guid]); printAndExitIfTrue($matchingApps[0]['publishstate'] === 2 || $matchingApps[0]['publishstate'] === 3, 'This app is rejected or already hidden.'); executePreparedSQLQuery($mysqlConn, 'UPDATE apps SET publishstate = 3 WHERE guid = ? LIMIT 1', 's', [$guid]); //Update publish state in database $mysqlConn->close(); unset($_SESSION['myapps_token' . $guid]); unset($_SESSION['remove_token' . $guid]); unset($_SESSION['hide_app_guid' . $_POST['guidid']]); //TODO: Actually remove the apps in the future? print 'App hidden.';