token handling and verification

This commit is contained in:
pitu 2017-01-17 00:37:54 -03:00
parent 0da43c4520
commit bdfd512c10
8 changed files with 135 additions and 70 deletions

View File

@ -6,6 +6,9 @@ module.exports = {
Ideally the only options you should change are port and basedomain. Ideally the only options you should change are port and basedomain.
*/ */
// Should this instance of loli-safe be private? If so, a client token will be needed for uploads
private: true,
// Your base domain where the app is running. Remember to finish it with '/' // Your base domain where the app is running. Remember to finish it with '/'
basedomain: 'https://i.kanacchi.moe/', basedomain: 'https://i.kanacchi.moe/',

View File

@ -5,18 +5,18 @@ let galleryController = {}
galleryController.list = function(req, res, next){ galleryController.list = function(req, res, next){
if(config.TOKEN === true) if(config.private === true)
if(req.headers.auth !== config.clientToken) if(req.headers.auth !== config.clientToken)
return res.status(401).send('not-authorized') return res.status(401).send('not-authorized')
db.table('gallery').select('id', 'name').then((data) => { db.table('gallery').select('id', 'name').then((galleries) => {
res.json({ data }) return res.json({ galleries })
}) })
} }
galleryController.test = function(req, res, next){ galleryController.test = function(req, res, next){
if(config.TOKEN === true) if(config.private === true)
if(req.headers.auth !== config.clientToken) if(req.headers.auth !== config.clientToken)
return res.status(401).send('not-authorized') return res.status(401).send('not-authorized')

View File

@ -22,7 +22,7 @@ const upload = multer({
uploadsController.upload = function(req, res, next){ uploadsController.upload = function(req, res, next){
if(config.TOKEN === true) if(config.private === true)
if(req.headers.auth !== config.clientToken) if(req.headers.auth !== config.clientToken)
return res.status(401).send('not-authorized') return res.status(401).send('not-authorized')
@ -70,9 +70,8 @@ uploadsController.upload = function(req, res, next){
uploadsController.list = function(req, res){ uploadsController.list = function(req, res){
if(config.TOKEN === true) if(req.headers.auth !== config.adminToken)
if(req.headers.auth !== config.clientToken) return res.status(401).send('not-authorized')
return res.status(401).send('not-authorized')
db.table('files').then((files) => { db.table('files').then((files) => {

View File

@ -9,7 +9,7 @@
</head> </head>
<body> <body>
<section class="hero is-fullheight has-text-centered"> <section class="hero is-fullheight has-text-centered" id="home">
<div class="hero-body"> <div class="hero-body">
<div class="container"> <div class="container">
<p id="b"> <p id="b">
@ -39,6 +39,14 @@
<div class="column"></div> <div class="column"></div>
</div> </div>
<div class="columns">
<div class="column"></div>
<div class="column"><a href="https://chrome.google.com/webstore/detail/loli-safe-uploader/enkkmplljfjppcdaancckgilmgoiofnj/related" target="_blank" class="is-danger">Uploader Chrome extension</a></div>
<div class="column"></div>
</div>
<div id="uploads"> <div id="uploads">
<div id="template" class="columns"> <div id="template" class="columns">
<div class="column"> <div class="column">

View File

@ -82,11 +82,13 @@ img.logo { height: 200px; margin-top: 20px; }
------------------ */ ------------------ */
section#dashboard { display: none } section#dashboard { display: none }
section#auth input { background: rgba(0, 0, 0, 0); }
section#auth input, section#auth a { section#auth input, section#auth a {
border-left: 0px; border-left: 0px;
border-top: 0px; border-top: 0px;
border-right: 0px; border-right: 0px;
border-radius: 0px; border-radius: 0px;
background: rgba(0, 0, 0, 0);
box-shadow: 0 0 0; box-shadow: 0 0 0;
} }
section#dashboard .table { font-size: 12px }

View File

@ -1,15 +1,11 @@
window.onload = function () { window.onload = function () {
if(!localStorage.admintoken){ var page;
askForToken();
return;
}
var dashboard = document.getElementById('dashboard'); if(!localStorage.admintoken)
var page = document.getElementById('page'); return askForToken();
dashboard.style.display = 'block'; prepareDashboard();
prepareMenu();
function askForToken(){ function askForToken(){
document.getElementById('tokenSubmit').addEventListener('click', function(){ document.getElementById('tokenSubmit').addEventListener('click', function(){
@ -21,15 +17,35 @@ window.onload = function () {
xhr.onreadystatechange = function() { xhr.onreadystatechange = function() {
if (xhr.readyState == XMLHttpRequest.DONE) { if (xhr.readyState == XMLHttpRequest.DONE) {
try{
var json = JSON.parse(xhr.responseText);
if(json.success === false)
return alert(json.description);
localStorage.admintoken = document.getElementById('token').value;
prepareDashboard();
}catch(e){
console.log(e);
}
console.log(xhr.responseText);
// xhr.responseText // xhr.responseText
} }
} }
xhr.open('POST', '/api/info', true); xhr.open('GET', '/api/verify', true);
xhr.setRequestHeader('type', 'admin');
xhr.setRequestHeader('token', document.getElementById('token').value);
xhr.send(null); xhr.send(null);
} }
} }
function prepareMenu(){ function prepareDashboard(){
page = document.getElementById('page');
document.getElementById('auth').style.display = 'none';
document.getElementById('dashboard').style.display = 'block';
document.getElementById('itemUploads').addEventListener('click', function(){ document.getElementById('itemUploads').addEventListener('click', function(){
getUploads(); getUploads();
}); });
@ -45,44 +61,47 @@ window.onload = function () {
xhr.onreadystatechange = function() { xhr.onreadystatechange = function() {
if(xhr.readyState == XMLHttpRequest.DONE){ if(xhr.readyState == XMLHttpRequest.DONE){
if(xhr.responseText !== 'not-authorized'){
var json = JSON.parse(xhr.responseText); if(xhr.responseText === 'not-authorized')
return notAuthorized();
var container = document.createElement('div'); var json = JSON.parse(xhr.responseText);
container.innerHTML = `
<table class="table">
<thead>
<tr>
<th>File</th>
<th>Gallery</th>
<th>Date</th>
</tr>
</thead>
<tbody id="table">
</tbody>
</table>`;
page.appendChild(container);
var table = document.getElementById('table'); var container = document.createElement('div');
container.innerHTML = `
<table class="table">
<thead>
<tr>
<th>File</th>
<th>Gallery</th>
<th>Date</th>
</tr>
</thead>
<tbody id="table">
</tbody>
</table>`;
page.appendChild(container);
for(var item of json){ var table = document.getElementById('table');
var tr = document.createElement('tr'); for(var item of json){
tr.innerHTML = `
<tr>
<th><a href="${item.file}" target="_blank">${item.file}</a></th>
<th>${item.gallery}</th>
<td>${item.date}</td>
</tr>
`;
table.appendChild(tr); var tr = document.createElement('tr');
} tr.innerHTML = `
<tr>
<th><a href="${item.file}" target="_blank">${item.file}</a></th>
<th>${item.gallery}</th>
<td>${item.date}</td>
</tr>
`;
table.appendChild(tr);
} }
} }
} }
xhr.open('GET', '/api/uploads', true); xhr.open('GET', '/api/uploads', true);
xhr.setRequestHeader('auth', localStorage.token); xhr.setRequestHeader('auth', localStorage.admintoken);
xhr.send(null); xhr.send(null);
} }
@ -93,4 +112,9 @@ window.onload = function () {
} }
function notAuthorized() {
localStorage.removeItem("admintoken");
location.reload();
}
} }

View File

@ -8,7 +8,7 @@ window.onload = function () {
var xhr = new XMLHttpRequest(); var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() { xhr.onreadystatechange = function() {
if (xhr.readyState == XMLHttpRequest.DONE) { if (xhr.readyState == XMLHttpRequest.DONE) {
USINGTOKEN = JSON.parse(xhr.responseText).token; USINGTOKEN = JSON.parse(xhr.responseText).private;
prepareTokenThing(); prepareTokenThing();
} }
} }
@ -20,14 +20,14 @@ window.onload = function () {
if(!USINGTOKEN) return getInfo(); if(!USINGTOKEN) return getInfo();
if(!localStorage.token){ if(!localStorage.token){
document.getElementById('tokenContainer').style.display = 'flex'
document.getElementById('tokenSubmit').addEventListener('click', function(){ document.getElementById('tokenSubmit').addEventListener('click', function(){
getInfo(document.getElementById('token').value) getInfo(document.getElementById('token').value)
}); });
}else{ return document.getElementById('tokenContainer').style.display = 'flex';
getInfo(localStorage.token);
} }
getInfo(localStorage.token);
} }
function prepareDropzone(){ function prepareDropzone(){
@ -91,23 +91,25 @@ window.onload = function () {
xhr.onreadystatechange = function() { xhr.onreadystatechange = function() {
if (xhr.readyState == XMLHttpRequest.DONE) { if (xhr.readyState == XMLHttpRequest.DONE) {
if(xhr.responseText !== 'not-authorized'){
if(xhr.responseText === 'not-authorized')
div = document.createElement('div'); return notAuthorized();
div.id = 'dropzone';
div.innerHTML = 'Click here or drag and drop files';
div.style.display = 'flex';
document.getElementById('btnGithub').style.display = 'none'; div = document.createElement('div');
document.getElementById('tokenContainer').style.display = 'none'; div.id = 'dropzone';
document.getElementById('uploadContainer').appendChild(div); div.innerHTML = 'Click here or drag and drop files';
document.getElementById('panel').style.display = 'block'; div.style.display = 'flex';
if(xhr.responseText.maxFileSize) maxSize = JSON.parse(xhr.responseText).maxFileSize;
if(token) localStorage.token = token;
prepareDropzone(); document.getElementById('btnGithub').style.display = 'none';
} document.getElementById('tokenContainer').style.display = 'none';
document.getElementById('uploadContainer').appendChild(div);
document.getElementById('panel').style.display = 'block';
if(xhr.responseText.maxFileSize) maxSize = JSON.parse(xhr.responseText).maxFileSize;
if(token) localStorage.token = token;
prepareDropzone();
} }
} }
xhr.open('GET', '/api/info', true); xhr.open('GET', '/api/info', true);
@ -117,4 +119,9 @@ window.onload = function () {
xhr.send(null); xhr.send(null);
} }
function notAuthorized() {
localStorage.removeItem("token");
location.reload();
}
}; };

View File

@ -4,12 +4,34 @@ const uploadController = require('../controllers/uploadController')
const galleryController = require('../controllers/galleryController') const galleryController = require('../controllers/galleryController')
routes.get ('/check', (req, res, next) => { routes.get ('/check', (req, res, next) => {
return res.json({token: config.TOKEN}) return res.json({ private: config.private })
})
routes.get ('/verify', (req, res, next) => {
let type = req.headers.type
let token = req.headers.token
if(type === undefined) return res.json({ success: false, description: 'No type provided.' })
if(token === undefined) return res.json({ success: false, description: 'No token provided.' })
if(type !== 'client' && type !== 'admin') return res.json({ success: false, description: 'Wrong type provided.' })
if(type === 'client'){
if(token !== config.clientToken) return res.json({ success: false, description: 'Token mismatch.' })
return res.json({ success: true })
}
if(type === 'admin'){
if(token !== config.adminToken) return res.json({ success: false, description: 'Token mismatch.' })
return res.json({ success: true })
}
return res.json({ success: false, description: '(╯°□°)╯︵ ┻━┻' })
}) })
routes.get('/info', (req, res, next) => { routes.get('/info', (req, res, next) => {
if(config.TOKEN === true) if(config.private === true)
if(req.headers.auth !== config.clientToken) if(req.headers.auth !== config.clientToken)
return res.status(401).send('not-authorized') return res.status(401).send('not-authorized')