require_once '../../common/ucpheader.php'; require_once '../../common/user.php'; verifyGroup('Moderators'); $_SESSION['mod_apps_token'] = uniqid(mt_rand(), true); //Generate token for moderator action $mysqlConn = connectToDatabase(); $pendingApps = getArrayFromSQLQuery($mysqlConn, 'SELECT app.guid, app.name, appver.number AS version, user.nick AS publisher FROM apps app LEFT JOIN appversions appver ON appver.versionId = app.version LEFT JOIN users user ON user.userId = app.publisher WHERE app.publishstate = 0 OR app.publishstate = 4 ORDER BY version ASC LIMIT 50'); $mysqlConn->close(); echo 'Pending apps/updates (showing only oldest 50):<br />'; $md5Token = md5($_SESSION['mod_apps_token']); foreach ($pendingApps as $app) { echo '<br />' . '<a href="appview.php?guid=' . $app['guid'] . '&token=' . $md5Token . '">' . $app['guid'] . '</a> (name: ' . escapeHTMLChars($app['name']) . ', version: ' . escapeHTMLChars($app['version']) . ', publisher: ' . escapeHTMLChars($app['publisher']) . ')'; } ?> <br /> <br /> <br /> <form action="appview.php" method="get"> Query app by GUID: <br /> <input type="text" name="guid" size="50"> <input type="hidden" name="token" value="<?php echo $md5Token; ?> "> <input type="submit" value="Query"> </form>
/** * Send a notification to a specific group * * @param string $groupName The name of the group to send the notification to * @param string $summary Short notification summary (should be up to 10 words) * @param string $body Full notification text * @param string $url URL to related page */ public function createGroupNotification($groupName, $summary, $body, $url = null) { //Insert notification entry into database executePreparedSQLQuery($this->mysqlConn, 'INSERT INTO notifications (groupId, summary, body, url) VALUES ((SELECT groupId FROM groups WHERE name = ?), ?, ?, ?)', 'ssss', [$groupName, escapeHTMLChars($summary), escapeHTMLChars($body), $url]); }
<?php $title = 'Mod CP'; require_once '../../common/ucpheader.php'; require_once '../../common/user.php'; verifyGroup('Moderators'); 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) {
if (!empty($app['webicon'])) { echo $app['webicon']; } else { if (!empty($app['largeIcon'])) { echo $app['largeIcon']; } else { echo '/img/no_icon.png'; } } ?> "/> <div class="app-content app-vertical-center-outer pull-left" style="padding:0 10px;background:#f3f3f3;width:100%;"> <div class="pull-left"> <h4 class="app-vertical-center-inner"> <span itemprop="name" style="float:left;overflow:hidden"> <div class="app-name"><?php echo escapeHTMLChars($app['name']); ?> <div class="dimmer"/></div></span><br/> <a href="/user/<?php echo $app['publisher']; ?> " style="color:black"><span itemprop="publisher" itemscope itemtype="http://schema.org/Organization" style="width:100%;padding:2px;font-size:14px"><?php echo $app['publisher']; ?> </span></a> </h4> </div> </div> <div class="app-content app-vertical-center-outer pull-right btn-toolbar" style="background:#f3f3f3;width:100%;padding:15px 10px"> <div class="app-vertical-center-inner" style="text-align: center;"> <div><span class="glyphicon glyphicon-download"></span> <?php
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.';
break; case 2: if (!empty($app['failpublishmessage'])) { echo '<button class="btn btn-danger disabled"><span class="glyphicon glyphicon-ban-circle"></span> ' . escapeHTMLChars($app['failpublishmessage']) . '</button>'; } else { echo '<button class="btn btn-danger disabled"><span class="glyphicon glyphicon-ban-circle"></span> Rejected</button>'; } break; case 3: echo '<button class="btn btn-danger disabled"><span class="glyphicon glyphicon-eye-close"></span> Hidden</button>'; break; case 4: echo '<button class="btn btn-info disabled"><span class="glyphicon glyphicon-ok"></span> Published (version ' . $app['version_new'] . ' pending approval)</button>'; break; case 5: echo '<button class="btn btn-warning disabled"><span class="glyphicon glyphicon-info-sign"></span> Published (version ' . $app['version_new'] . ': ' . escapeHTMLChars($app['failpublishmessage']) . ')</button>'; break; } ?> </div> <div class="pull-right" style="margin-left: 5px;"> <button class="btn btn-default disabled"><span class="glyphicon glyphicon-download"></span> <?php echo $app['downloads']; ?> downloads</button> </div> </div> </div> </div> </div>
throwExceptionIfTrue(mb_strlen($_POST['description']) > 300, 'Description is too long.'); //Check file upload errors foreach ($_FILES as $file) { throwExceptionIfTrue($file['error'] === 1 || $file['error'] === 2, $file['name'] . ' exceeds the file size limit.'); throwExceptionIfTrue($file['error'] === 3, $file['name'] . ' wasn\'t fully uploaded.'); throwExceptionIfTrue($file['error'] > 4, $file['name'] . ' encountered an internal error upon upload: ' . $file['error']); } //Check captcha $reCaptcha = new ReCaptcha(getConfigValue('apikey_recaptcha_secret')); $resp = $reCaptcha->verifyResponse($_SERVER["REMOTE_ADDR"], $_POST["g-recaptcha-response"]); throwExceptionIfTrue($resp == null || !$resp->success, 'Invalid or no captcha response.'); $appName = escapeHTMLChars($_POST['name']); $appVersion = escapeHTMLChars($_POST['version']); $appCategory = $_POST['category']; $appSubCategory = $subCategorySelected ? $_POST['subcategory'] : null; $appDescription = escapeHTMLChars(str_replace(['\\r\\n', '\\r', '\\n'], ' ', $_POST['description'])); $app3dsxPath = $_FILES['3dsx']['tmp_name']; $appSmdhPath = $_FILES['smdh']['tmp_name']; $isDeveloper = clientPartOfGroup('Developers'); $updatingApp = isset($_SESSION['user_app_version' . $guid]); //Check which optional files were uploaded $uploadingAppData = isset($_FILES['appdata']) && !deletingFile('appdata') && is_uploaded_file($_FILES['appdata']['tmp_name']); if ($uploadingAppData) { $appDataPath = $_FILES['appdata']['tmp_name']; } $uploadingWebIcon = isset($_FILES['webicon']) && !deletingFile('webicon') && is_uploaded_file($_FILES['webicon']['tmp_name']); if ($uploadingWebIcon) { $webIconPath = $_FILES['webicon']['tmp_name']; //Verify that image is JPEG/PNG $imageMIME = getimagesize($webIconPath)['mime']; throwExceptionIfTrue(!($imageMIME && ($imageMIME === 'image/jpeg' || $imageMIME === 'image/png')), 'Invalid hi-res icon file type. It must be in JPEG or PNG format.');
//Get app with requested GUID printAndExitIfTrue(count($matchingApps) != 1, 'Invalid app GUID.'); //Check if there is one app matching attempted GUID $currentApp = $matchingApps[0]; $screenshots = explode(',', $currentApp['screenshots']); //Print all app attributes foreach ($currentApp as $attributeName => $attributeValue) { if ($attributeName == 'screenshots') { for ($i = 0; $i < count($screenshots); $i++) { echo $attributeName . ' (' . ($i + 1) . '): <a href="' . $screenshots[$i] . '">' . $screenshots[$i] . '</a><br />'; } } else { if ($attributeName == '3dsx' || $attributeName == 'smdh' || $attributeName == 'appdata' || $attributeName == 'largeIcon') { echo $attributeName . ': <a href="' . $attributeValue . '">' . $attributeValue . '</a><br />'; } else { $safeValue = escapeHTMLChars($attributeValue); echo $attributeName . ': ' . $safeValue . '<br />'; } } } //Print icon echo '<img src="' . $currentApp['largeIcon'] . '" /><br />'; for ($i = 0; $i < count($screenshots); $i++) { echo '<img src="' . $screenshots[$i] . '" /> '; } ?> <br /> <br /> <form action="appset.php" method="post"> Set publish state:
printAndExitIfTrue(count($matchingApps) != 1, 'Invalid app GUID.'); //Check if there is one app matching attempted GUID/user combination $appToEdit = $matchingApps[0]; $_SESSION['publish_app_guid' . $guidId] = $appToEdit['guid']; $_SESSION['user_app_version' . $appToEdit['guid']] = $appToEdit['version']; } else { $_SESSION['publish_app_guid' . $guidId] = generateGUID(); } if (!isset($_SESSION['publish_token' . $_SESSION['publish_app_guid' . $guidId]])) { $_SESSION['publish_token' . $_SESSION['publish_app_guid' . $guidId]] = uniqid(mt_rand(), true); } $editing = isset($appToEdit); ?> <h1 class="animated bounceInDown text-center"><?php if (isset($appToEdit)) { echo 'Updating ' . escapeHTMLChars($appToEdit['name']); } else { echo 'Add a new application'; } ?> </h1> <br /> <?php if (isset($errorMessage)) { ?> <div class="animated shake alert alert-danger"> <a class="close" href="#" data-dismiss="alert">×</a> <strong>Error!</strong> <?php echo $errorMessage; ?>
<?php echo escapeHTMLChars($app['name']); ?> </span> <span class="app-version" itemprop="softwareVersion"> <?php echo escapeHTMLChars($app['version']); ?> </span> <br/> <a href="/user/<?php echo $app['publisher']; ?> " style="color:black"><span class="app-publisher" itemprop="publisher" itemscope itemtype="http://schema.org/Organization"> <?php echo escapeHTMLChars($app['publisher']); ?> </span></a> </h4> </div> </div> <div class="app-vertical-center-outer pull-right btn-toolbar"> <div class="app-vertical-center-inner"> <button class="btn btn-default disabled" style="display: inline-block">3DS</button> <button class="btn btn-default disabled"><span class="glyphicon glyphicon-download"></span> <?php echo $app['downloads']; ?> downloads </button> </div> </div> </div>