2020-05-08 22:53:21 +00:00
|
|
|
<?php
|
|
|
|
namespace EEPROM;
|
|
|
|
|
|
|
|
function mszDieIfNotAuth(): void {
|
|
|
|
if(!User::hasActive()) {
|
2020-05-12 18:30:22 +00:00
|
|
|
$mszUserId = (new Auth\MisuzuAuth)->verifyToken(strval(filter_input(INPUT_COOKIE, 'msz_auth')));
|
2020-05-08 22:53:21 +00:00
|
|
|
if($mszUserId > 0)
|
|
|
|
User::byId($mszUserId)->setActive();
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!User::hasActive() || User::active()->getId() !== 1) {
|
|
|
|
http_response_code(403);
|
|
|
|
header('Content-Type: text/html; charset=utf-8');
|
|
|
|
echo <<<HTML
|
|
|
|
<!doctype html>
|
|
|
|
<html>
|
|
|
|
<head>
|
|
|
|
<meta charset="utf-8"/>
|
|
|
|
<title>Access Denied</title>
|
|
|
|
<style>
|
|
|
|
body {
|
|
|
|
font: 12px/20px Tahoma, Geneva, 'Dejavu Sans', Arial, Helvetica, sans-serif;
|
|
|
|
background-color: #111;
|
|
|
|
text-align: center;
|
|
|
|
color: #fff;
|
|
|
|
}
|
|
|
|
h1 { margin: 2em; }
|
|
|
|
</style>
|
|
|
|
</head>
|
|
|
|
<body>
|
|
|
|
<h1>Access Denied</h1>
|
|
|
|
<p><img src="//static.flash.moe/images/access-denied-mkt.png" alt="Access Denied"/></p>
|
|
|
|
</body>
|
|
|
|
</html>
|
|
|
|
HTML;
|
|
|
|
exit;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if($reqPath === '/flash') {
|
|
|
|
mszDieIfNotAuth();
|
|
|
|
header('Content-Type: text/html; charset=utf-8');
|
|
|
|
|
|
|
|
echo <<<HTML
|
|
|
|
<!doctype html>
|
|
|
|
<html>
|
|
|
|
<head>
|
|
|
|
<meta charset="utf-8"/>
|
|
|
|
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
|
|
|
<title>EEPROM Flash</title>
|
|
|
|
<link href="/flash/style.css" type="text/css" rel="stylesheet"/>
|
|
|
|
</head>
|
|
|
|
<body class="initial">
|
|
|
|
<noscript><div class="nojs">Enable Javascript!</div></noscript>
|
|
|
|
<div class="header">
|
|
|
|
<div>
|
|
|
|
<h1>EEPROM Flash</h1>
|
|
|
|
<nav>
|
|
|
|
<div id="_nav_users">Users <span>...</span></div>
|
|
|
|
<div id="_nav_appls">Applications <span>...</span></div>
|
|
|
|
<div id="_nav_uplds">Uploads <span>...</span></div>
|
|
|
|
</nav>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="wrapper">
|
|
|
|
<div class="hidden" id="_cnt_users">
|
|
|
|
<h2>Users</h2>
|
|
|
|
<div id="_cnt_users_list" class="list users-list">
|
|
|
|
<div class="list-item users-list-item">
|
|
|
|
<div></div>
|
|
|
|
<div>ID</div>
|
|
|
|
<div>Size Multiplier</div>
|
|
|
|
<div>Created</div>
|
|
|
|
<div>Restricted</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="hidden" id="_cnt_appls">
|
|
|
|
<h2>Applications</h2>
|
|
|
|
<div id="_cnt_appls_list" class="list appls-list">
|
|
|
|
<div class="list-item appls-list-item">
|
|
|
|
<div></div>
|
|
|
|
<div>ID</div>
|
|
|
|
<div>Name</div>
|
|
|
|
<div>Size Limit</div>
|
|
|
|
<div>Size Multiplier Allowed</div>
|
|
|
|
<div>File Lifetime (Seconds)</div>
|
|
|
|
<div>Created</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="hidden" id="_cnt_uplds">
|
|
|
|
<h2>Uploads</h2>
|
|
|
|
<div id="_cnt_uplds_list" class="list uplds-list">
|
|
|
|
<div class="list-item uplds-list-item">
|
|
|
|
<div></div>
|
|
|
|
<div>ID</div>
|
|
|
|
<div>Application</div>
|
|
|
|
<div>Uploader</div>
|
|
|
|
<div>Name</div>
|
|
|
|
<div>Size</div>
|
|
|
|
<div>Type</div>
|
|
|
|
<div>Created</div>
|
|
|
|
<div>Deleted</div>
|
|
|
|
<div>DMCA'd</div>
|
|
|
|
<div>Accessed</div>
|
|
|
|
<div>Expires</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<script src="/flash/script.js" type="text/javascript" charset="utf-8"></script>
|
|
|
|
</body>
|
|
|
|
</html>
|
|
|
|
HTML;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if($reqPath === '/flash/stats.json') {
|
|
|
|
mszDieIfNotAuth();
|
|
|
|
header('Content-Type: application/json; charset=utf-8');
|
|
|
|
$getStats = DB::prepare('
|
|
|
|
SELECT (
|
|
|
|
SELECT COUNT(`app_id`)
|
|
|
|
FROM `prm_applications`
|
|
|
|
) AS `applications`, (
|
|
|
|
SELECT COUNT(`upload_id`)
|
|
|
|
FROM `prm_uploads`
|
|
|
|
) AS `uploads`, (
|
|
|
|
SELECT COUNT(`user_id`)
|
|
|
|
FROM `prm_users`
|
|
|
|
) AS `users`
|
|
|
|
');
|
|
|
|
$getStats->execute();
|
|
|
|
echo json_encode($getStats->fetchObject());
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if($reqPath === '/flash/users.json') {
|
|
|
|
mszDieIfNotAuth();
|
|
|
|
header('Content-Type: application/json; charset=utf-8');
|
|
|
|
echo json_encode(User::all(10, intval(filter_input(INPUT_GET, 'after', FILTER_SANITIZE_NUMBER_INT))));
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
if($reqPath === '/flash/uploads.json') {
|
|
|
|
mszDieIfNotAuth();
|
|
|
|
header('Content-Type: application/json; charset=utf-8');
|
|
|
|
echo json_encode(Upload::all(20, strval(filter_input(INPUT_GET, 'after'))));
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
if($reqPath === '/flash/applications.json') {
|
|
|
|
mszDieIfNotAuth();
|
|
|
|
header('Content-Type: application/json; charset=utf-8');
|
|
|
|
echo json_encode(Application::all(10, intval(filter_input(INPUT_GET, 'after', FILTER_SANITIZE_NUMBER_INT))));
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if($reqPath === '/flash/style.css') {
|
|
|
|
mszDieIfNotAuth();
|
|
|
|
header('Content-Type: text/css; charset=utf-8');
|
|
|
|
echo <<<STYLE
|
|
|
|
* {
|
|
|
|
margin: 0;
|
|
|
|
padding: 0;
|
|
|
|
box-sizing: border-box;
|
|
|
|
position: relative;
|
|
|
|
outline-style: none !important;
|
|
|
|
}
|
|
|
|
html, body {
|
|
|
|
width: 100%;
|
|
|
|
height: 100%;
|
|
|
|
}
|
|
|
|
body {
|
|
|
|
font: 12px/20px Tahoma, Geneva, 'Dejavu Sans', Arial, Helvetica, sans-serif;
|
|
|
|
background-color: #111;
|
|
|
|
color: #fff;
|
|
|
|
margin-top: -1px;
|
|
|
|
padding-top: 1px;
|
|
|
|
}
|
|
|
|
|
|
|
|
.nojs {
|
|
|
|
border: 5px solid #f00;
|
|
|
|
background-color: #c00;
|
|
|
|
color: #fff;
|
|
|
|
font-weight: 700;
|
|
|
|
font-size: 1.5em;
|
|
|
|
margin: 10px;
|
|
|
|
padding: 10px;
|
|
|
|
}
|
|
|
|
.hidden {
|
|
|
|
display: none !important;
|
|
|
|
visibility: hidden !important;
|
|
|
|
}
|
|
|
|
|
|
|
|
.header {
|
|
|
|
display: flex;
|
|
|
|
flex-direction: column;
|
|
|
|
justify-content: center;
|
|
|
|
background-color: #191919;
|
|
|
|
position: absolute;
|
|
|
|
top: 0;
|
|
|
|
left: 0;
|
|
|
|
z-index: 999999999;
|
|
|
|
width: 100%;
|
|
|
|
height: 100px;
|
|
|
|
padding: 0 10px;
|
|
|
|
transition: height .5s;
|
|
|
|
}
|
|
|
|
.initial .header {
|
|
|
|
width: 100%;
|
|
|
|
height: 100%;
|
|
|
|
}
|
|
|
|
.header h1 {
|
|
|
|
margin: 10px;
|
|
|
|
}
|
|
|
|
.header nav {
|
|
|
|
display: flex;
|
|
|
|
margin: 0 5px;
|
|
|
|
}
|
|
|
|
.header nav > div {
|
|
|
|
flex: 0 0 auto;
|
|
|
|
padding: 2px 10px;
|
|
|
|
margin: 1px;
|
|
|
|
background-color: #222;
|
|
|
|
border-radius: 20px;
|
|
|
|
cursor: pointer;
|
|
|
|
transition: background-color .2s;
|
|
|
|
}
|
|
|
|
.header nav > div > span {
|
|
|
|
font-weight: 700;
|
|
|
|
}
|
|
|
|
.header nav > div:hover,
|
|
|
|
.header nav > div:focus {
|
|
|
|
background-color: #444;
|
|
|
|
}
|
|
|
|
.header nav > div:active,
|
|
|
|
.header nav > .active {
|
|
|
|
background-color: #292929;
|
|
|
|
}
|
|
|
|
|
|
|
|
.wrapper {
|
|
|
|
padding-top: 100px;
|
|
|
|
}
|
|
|
|
.wrapper h2 {
|
|
|
|
margin: 10px;
|
|
|
|
}
|
|
|
|
|
|
|
|
.list {
|
|
|
|
display: flex;
|
|
|
|
flex-direction: column;
|
|
|
|
}
|
|
|
|
.list-item {
|
|
|
|
display: flex;
|
|
|
|
}
|
|
|
|
.list-item > div {
|
|
|
|
flex: 1 1 auto;
|
|
|
|
}
|
|
|
|
STYLE;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if($reqPath === '/flash/script.js') {
|
|
|
|
mszDieIfNotAuth();
|
|
|
|
header('Content-Type: application/javascript; charset=utf-8');
|
|
|
|
echo <<<SCRIPT
|
|
|
|
var objStats,
|
|
|
|
navActive, cntActive,
|
|
|
|
navUsers, cntUsers,
|
|
|
|
navAppls, cntAppls,
|
|
|
|
navUplds, cntUplds;
|
|
|
|
|
|
|
|
function switchContainer(target, button) {
|
|
|
|
if(cntActive)
|
|
|
|
cntActive.classList.add('hidden');
|
|
|
|
if(navActive)
|
|
|
|
navActive.classList.remove('active');
|
|
|
|
cntActive = target;
|
|
|
|
cntActive.classList.remove('hidden');
|
|
|
|
navActive = button;
|
|
|
|
navActive.classList.add('active');
|
|
|
|
document.body.classList.remove('initial');
|
|
|
|
}
|
|
|
|
|
|
|
|
function renderUserList(list) {
|
|
|
|
var target = document.getElementById('_cnt_users_list');
|
|
|
|
while(target.children.length > 1)
|
|
|
|
target.removeChild(target.lastElementChild);
|
|
|
|
|
|
|
|
for(var i = 0; i < list.length; ++i) {
|
|
|
|
var info = list[i],
|
|
|
|
elem = target.appendChild(document.createElement('div'));
|
|
|
|
elem.className = 'list-item users-list-item';
|
|
|
|
|
|
|
|
var actField = elem.appendChild(document.createElement('div'));
|
|
|
|
actField.textContent = 'Actions';
|
|
|
|
|
|
|
|
var idField = elem.appendChild(document.createElement('div'));
|
|
|
|
idField.textContent = info.id.toString();
|
|
|
|
|
|
|
|
var smField = elem.appendChild(document.createElement('div'));
|
|
|
|
smField.textContent = info.size_multi.toString();
|
|
|
|
|
|
|
|
var crField = elem.appendChild(document.createElement('div'));
|
|
|
|
crField.textContent = info.created.toString();
|
|
|
|
|
|
|
|
var rsField = elem.appendChild(document.createElement('div'));
|
|
|
|
rsField.textContent = !info.restricted ? 'No' : info.restricted.toString();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function renderApplList(list) {
|
|
|
|
var target = document.getElementById('_cnt_appls_list');
|
|
|
|
while(target.children.length > 1)
|
|
|
|
target.removeChild(target.lastElementChild);
|
|
|
|
|
|
|
|
for(var i = 0; i < list.length; ++i) {
|
|
|
|
var info = list[i],
|
|
|
|
elem = target.appendChild(document.createElement('div'));
|
|
|
|
elem.className = 'list-item appls-list-item';
|
|
|
|
|
|
|
|
var actField = elem.appendChild(document.createElement('div'));
|
|
|
|
actField.textContent = 'Actions';
|
|
|
|
|
|
|
|
var idField = elem.appendChild(document.createElement('div'));
|
|
|
|
idField.textContent = info.id.toString();
|
|
|
|
|
|
|
|
var nmField = elem.appendChild(document.createElement('div'));
|
|
|
|
nmField.textContent = info.name.toString();
|
|
|
|
|
|
|
|
var slField = elem.appendChild(document.createElement('div'));
|
|
|
|
slField.textContent = info.size_limit.toString();
|
|
|
|
|
|
|
|
var smField = elem.appendChild(document.createElement('div'));
|
|
|
|
smField.textContent = info.size_multi ? 'Yes' : 'No';
|
|
|
|
|
|
|
|
var flField = elem.appendChild(document.createElement('div'));
|
|
|
|
flField.textContent = info.expiry.toString();
|
|
|
|
|
|
|
|
var crField = elem.appendChild(document.createElement('div'));
|
|
|
|
crField.textContent = info.created.toString();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function renderUpldList(list) {
|
|
|
|
var target = document.getElementById('_cnt_uplds_list');
|
|
|
|
while(target.children.length > 1)
|
|
|
|
target.removeChild(target.lastElementChild);
|
|
|
|
|
|
|
|
for(var i = 0; i < list.length; ++i) {
|
|
|
|
var info = list[i],
|
|
|
|
elem = target.appendChild(document.createElement('div'));
|
|
|
|
elem.className = 'list-item uplds-list-item';
|
|
|
|
|
|
|
|
var actField = elem.appendChild(document.createElement('div'));
|
|
|
|
actField.textContent = 'Actions';
|
|
|
|
|
|
|
|
var idField = elem.appendChild(document.createElement('div'));
|
|
|
|
idField.textContent = info.id.toString();
|
|
|
|
|
|
|
|
var apField = elem.appendChild(document.createElement('div'));
|
|
|
|
apField.textContent = info.appl.toString();
|
|
|
|
|
|
|
|
var usField = elem.appendChild(document.createElement('div'));
|
|
|
|
usField.textContent = info.user.toString();
|
|
|
|
|
|
|
|
var nmField = elem.appendChild(document.createElement('div'));
|
|
|
|
nmField.textContent = info.name.toString();
|
|
|
|
|
|
|
|
var szField = elem.appendChild(document.createElement('div'));
|
|
|
|
szField.textContent = info.size.toString();
|
|
|
|
|
|
|
|
var ftField = elem.appendChild(document.createElement('div'));
|
|
|
|
ftField.textContent = info.type.toString();
|
|
|
|
|
|
|
|
var crField = elem.appendChild(document.createElement('div'));
|
|
|
|
crField.textContent = info.created.toString();
|
|
|
|
|
|
|
|
var dlField = elem.appendChild(document.createElement('div'));
|
|
|
|
dlField.textContent = !info.deleted ? 'No' : info.deleted.toString();
|
|
|
|
|
|
|
|
var dmField = elem.appendChild(document.createElement('div'));
|
|
|
|
dmField.textContent = !info.dmca ? 'No' : info.dmca.toString();
|
|
|
|
|
|
|
|
var acField = elem.appendChild(document.createElement('div'));
|
|
|
|
acField.textContent = !info.accessed ? 'No' : info.accessed.toString();
|
|
|
|
|
|
|
|
var exField = elem.appendChild(document.createElement('div'));
|
|
|
|
exField.textContent = !info.expires ? 'No' : info.expires.toString();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function switchContUsers(ev) {
|
|
|
|
switchContainer(cntUsers, this);
|
|
|
|
loadPageData('users', null, renderUserList);
|
|
|
|
}
|
|
|
|
function switchContAppls(ev) {
|
|
|
|
switchContainer(cntAppls, this);
|
|
|
|
loadPageData('applications', null, renderApplList);
|
|
|
|
}
|
|
|
|
function switchContUplds(ev) {
|
|
|
|
switchContainer(cntUplds, this);
|
|
|
|
loadPageData('uploads', null, renderUpldList);
|
|
|
|
}
|
|
|
|
|
|
|
|
function loadPageData(src, after, callback) {
|
|
|
|
var url = '/flash/' + encodeURI(src.toString()) + '.json';
|
|
|
|
if(after)
|
|
|
|
url += '?after=' + encodeURIComponent(after.toString());
|
|
|
|
var xhr = new XMLHttpRequest;
|
|
|
|
xhr.onreadystatechange = function() {
|
|
|
|
if(xhr.readyState !== 4)
|
|
|
|
return;
|
|
|
|
var json = JSON.parse(xhr.responseText);
|
|
|
|
console.log(json);
|
|
|
|
if(json && callback)
|
|
|
|
callback(json);
|
|
|
|
};
|
|
|
|
xhr.open('GET', url);
|
|
|
|
xhr.send();
|
|
|
|
}
|
|
|
|
function refreshNavStats(callback) {
|
|
|
|
var xhr = new XMLHttpRequest;
|
|
|
|
xhr.onreadystatechange = function() {
|
|
|
|
if(xhr.readyState !== 4)
|
|
|
|
return;
|
|
|
|
var stats = JSON.parse(xhr.responseText);
|
|
|
|
if(!stats)
|
|
|
|
return;
|
|
|
|
objStats = stats;
|
|
|
|
if(callback)
|
|
|
|
callback.call(this);
|
|
|
|
navUsers.querySelector('span').textContent = objStats.users;
|
|
|
|
navAppls.querySelector('span').textContent = objStats.applications;
|
|
|
|
navUplds.querySelector('span').textContent = objStats.uploads;
|
|
|
|
}.bind(this);
|
|
|
|
xhr.open('GET', '/flash/stats.json');
|
|
|
|
xhr.send();
|
|
|
|
};
|
|
|
|
|
|
|
|
window.addEventListener('load', function() {
|
|
|
|
setInterval(refreshNavStats, 30000);
|
|
|
|
refreshNavStats(function() {
|
|
|
|
navUsers = document.getElementById('_nav_users');
|
|
|
|
cntUsers = document.getElementById('_cnt_users');
|
|
|
|
navUsers.onclick = switchContUsers;
|
|
|
|
|
|
|
|
navAppls = document.getElementById('_nav_appls');
|
|
|
|
cntAppls = document.getElementById('_cnt_appls');
|
|
|
|
navAppls.onclick = switchContAppls;
|
|
|
|
|
|
|
|
navUplds = document.getElementById('_nav_uplds');
|
|
|
|
cntUplds = document.getElementById('_cnt_uplds');
|
|
|
|
navUplds.onclick = switchContUplds;
|
|
|
|
}.bind(this));
|
|
|
|
});
|
|
|
|
SCRIPT;
|
|
|
|
return true;
|
|
|
|
}
|