Adding option to name api-keys and removing them

This commit is contained in:
Kasper Rynning-Tønnesen
2018-03-03 18:16:49 +01:00
parent e6eb066911
commit ceebba6253
4 changed files with 233 additions and 64 deletions

View File

@@ -4,15 +4,43 @@ var connection_options = {
'force new connection': true 'force new connection': true
}; };
var socket = io.connect(window.location.protocol + '//' + window.location.hostname + ':8080', connection_options); var socket = io.connect(window.location.protocol + '//' + window.location.hostname + ':8080', connection_options);
var api_token_list;
$(document).ready(function(){ $(document).ready(function(){
$('ul.tabs').tabs(); $('ul.tabs').tabs();
api_token_list = $("#api_token_list").clone();
$("#api_token_list").remove();
loaded();
}); });
$(document).on("click", "#refresh_all", function(e){ $(document).on("click", "#refresh_all", function(e){
e.preventDefault(); e.preventDefault();
$("#descriptions_cont").empty(); $("#descriptions_cont").empty();
$("#thumbnails_cont").empty(); $("#thumbnails_cont").empty();
$("#api_token_name").remove();
$.ajax({
type: "GET",
url: "/api/api_token",
success: function(response) {
if(response.length == 0) {
if(!$(".header-api-fields").hasClass("hide")) {
$(".header-api-fields").addClass("hide");
}
return;
}
$(".header-api-fields").removeClass("hide");
for(var i = 0; i < response.length; i++) {
var to_add = api_token_list;
to_add.attr("id", response[i]._id);
to_add.find(".api_token_name").text(response[i].name);
to_add.find(".api_token_usage").text(response[i].usage);
to_add.find("#delete_api_token").attr("data-id", response[i]._id);
$(".channel_things").append(to_add);
}
},
error: function(err) {
}
});
if(!$(".channel_things").hasClass("hide")) { if(!$(".channel_things").hasClass("hide")) {
$(".channel_things").addClass("hide") $(".channel_things").addClass("hide")
} }
@@ -88,59 +116,120 @@ if(!$(".channel_things").hasClass("hide")) {
} }
$(".preloader-wrapper").removeClass("hide"); $(".preloader-wrapper").removeClass("hide");
$.ajax({ $(document).on("click", "#delete_api_token", function(e) {
type: "GET", e.preventDefault();
url: "/api/lists", var id = $(this).attr("data-id");
success: function(response){ var that = this;
var output_pinned = '<option value="" disabled selected>Channels</option>'; $(that).toggleClass("disabled");
var output_delete = '<option value="" disabled selected>Channels</option>'; $.ajax({
for(var x = 0; x < response.length; x++){ type: "DELETE",
if(response[x].count > 5){ url: "api/api_token",
output_pinned += "<option class='" + response[x]._id + "' value='" + response[x]._id + "'>" + response[x]._id + "</option>"; data: {
id: id
},
success: function(response) {
if(response == "success") {
Materialize.toast("Removed token!", 2000, "green lighten");
$("#" + id).remove();
} else {
Materialize.toast("Something went wrong...", 2000, "red lighten");
$(that).toggleClass("disabled");
} }
output_delete += "<option class='" + response[x]._id + "' value='" + response[x]._id + "'>" + response[x]._id + "</option>"; },
} })
$("#frontpage_pinned").html(output_pinned);
$("#remove_thumbnail").html(output_delete);
$("#remove_description").html(output_delete);
$("#delete_list_name").html(output_delete);
$("#delete_userpass_name").html(output_delete);
$("#delete_channel_name").html(output_delete);
$("select").material_select();
if(!$(".preloader-wrapper").hasClass("hide")) {
$(".preloader-wrapper").addClass("hide")
}
$(".channel_things").removeClass("hide");
}
}); });
$.ajax({ function loaded() {
type: "GET", $.ajax({
url: "/api/names", type: "GET",
success: function(response) { url: "/api/api_token",
for(var i = 0; i < response.length; i++) { success: function(response) {
var icon = ""; if(response.length == 0) {
if(response[i].icon && response[i].icon != "") { if(!$(".header-api-fields").hasClass("hide")) {
icon = "<img class='chat-icon' src='" + response[i].icon + "' alt='" + response[i]._id + "'>"; $(".header-api-fields").addClass("hide");
}
return;
} }
$(".names-container").append("<div class='col s12'><div class='name-chat col s3'>" + icon + response[i]._id + "</div><input type='text' class='" + response[i]._id + "_input col s7'><a class='btn green waves-effect col s2 m1 approve_name' href='#' data-name='" + response[i]._id + "'><i class='material-icons'>check</i></a></div>"); $(".header-api-fields").removeClass("hide");
for(var i = 0; i < response.length; i++) {
var to_add = api_token_list.clone();
to_add.attr("id", response[i]._id);
to_add.find(".api_token_name").text(response[i].name);
to_add.find(".api_token_usage").text(response[i].usage);
to_add.find("#delete_api_token").attr("data-id", response[i]._id);
$(".channel_things").append(to_add);
}
},
error: function(err) {
} }
}, });
});
$.ajax({ $.ajax({
type: "GET", type: "GET",
url: "/api/thumbnails", url: "/api/lists",
success: function(response){ success: function(response){
if(response.length > 0){ var output_pinned = '<option value="" disabled selected>Channels</option>';
$(".thumbnails-badge").removeClass("hide"); var output_delete = '<option value="" disabled selected>Channels</option>';
$(".thumbnails-badge").text(response.length); for(var x = 0; x < response.length; x++){
if(response[x].count > 5){
output_pinned += "<option class='" + response[x]._id + "' value='" + response[x]._id + "'>" + response[x]._id + "</option>";
}
output_delete += "<option class='" + response[x]._id + "' value='" + response[x]._id + "'>" + response[x]._id + "</option>";
}
$("#frontpage_pinned").html(output_pinned);
$("#remove_thumbnail").html(output_delete);
$("#remove_description").html(output_delete);
$("#delete_list_name").html(output_delete);
$("#delete_userpass_name").html(output_delete);
$("#delete_channel_name").html(output_delete);
$("select").material_select();
if(!$(".preloader-wrapper").hasClass("hide")) {
$(".preloader-wrapper").addClass("hide")
}
$(".channel_things").removeClass("hide");
} }
add_to_tab("thumbnails", response); });
}
}); $.ajax({
type: "GET",
url: "/api/names",
success: function(response) {
for(var i = 0; i < response.length; i++) {
var icon = "";
if(response[i].icon && response[i].icon != "") {
icon = "<img class='chat-icon' src='" + response[i].icon + "' alt='" + response[i]._id + "'>";
}
$(".names-container").append("<div class='col s12'><div class='name-chat col s3'>" + icon + response[i]._id + "</div><input type='text' class='" + response[i]._id + "_input col s7'><a class='btn green waves-effect col s2 m1 approve_name' href='#' data-name='" + response[i]._id + "'><i class='material-icons'>check</i></a></div>");
}
},
});
$.ajax({
type: "GET",
url: "/api/thumbnails",
success: function(response){
if(response.length > 0){
$(".thumbnails-badge").removeClass("hide");
$(".thumbnails-badge").text(response.length);
}
add_to_tab("thumbnails", response);
}
});
$.ajax({
type: "GET",
url: "/api/descriptions",
success: function(response){
if(response.length > 0){
$(".descriptions-badge").removeClass("hide");
$(".descriptions-badge").text(response.length);
}
add_to_tab("descriptions", response);
}
});
}
$(document).on("click", ".approve_name", function(e) { $(document).on("click", ".approve_name", function(e) {
var that = this; var that = this;
@@ -168,18 +257,6 @@ $(document).on("click", ".thumbnail_link", function(e) {
window.open("https:" + this.value,'_blank'); window.open("https:" + this.value,'_blank');
}); });
$.ajax({
type: "GET",
url: "/api/descriptions",
success: function(response){
if(response.length > 0){
$(".descriptions-badge").removeClass("hide");
$(".descriptions-badge").text(response.length);
}
add_to_tab("descriptions", response);
}
});
function add_to_tab(dest, resp){ function add_to_tab(dest, resp){
for(var x = 0; x < resp.length; x++){ for(var x = 0; x < resp.length; x++){
if(dest == "thumbnails"){ if(dest == "thumbnails"){
@@ -207,12 +284,30 @@ $(document).on("click", "#get_token", function(e){
$(document).on("click", "#get_api_token", function(e){ $(document).on("click", "#get_api_token", function(e){
e.preventDefault(); e.preventDefault();
var name = $("#new_api_token_name").val();
if(name == "") {
Materialize.toast("Empty name..!", 2000, "red lighten");
return;
}
$("#new_api_token_name").val("");
$("#get_api_token").toggleClass("disabled");
$.ajax({ $.ajax({
type: "GET", type: "POST",
url: "/api/api_token", url: "/api/api_token",
data: {
name: name,
},
success: function(response){ success: function(response){
if(response != false){ if(response != false){
Materialize.toast("Gotten token", 2000, "green lighten");
$("#new_api_token").val(response.token); $("#new_api_token").val(response.token);
$("#get_api_token").toggleClass("disabled");
var to_add = api_token_list;
to_add.attr("id", response._id);
to_add.find(".api_token_name").text(name);
to_add.find(".api_token_usage").text(0);
to_add.find("#delete_api_token").attr("data-id", response._id);
$(".channel_things").append(to_add);
} }
} }
}) })

View File

@@ -100,13 +100,33 @@
</div> </div>
<div class="row"> <div class="row">
<div class="input-field col s8 m10"> <div class="input-field col s4 m5">
<input type="text" id="new_api_token_name" />
</div>
<div class="input-field col s4 m5">
<input type="text" readonly id="new_api_token" /> <input type="text" readonly id="new_api_token" />
</div> </div>
<div class="col s2"> <div class="col s2">
<a href="#" id="get_api_token" class="btn waves-effect purple">GET API</a> <a href="#" id="get_api_token" class="btn waves-effect purple">GET API</a>
</div> </div>
</div> </div>
<div class="row header-api-fields">
<div class="col s4">
Name
</div>
<div class="col s4">
Usage
</div>
</div>
<div class="row" id="api_token_list">
<div class="col s4 api_token_name">
</div>
<div class="col s4 api_token_usage">
</div>
<div class="col s2">
<a href="#" id="delete_api_token" class="btn waves-effect red">REMOVE</a>
</div>
</div>
</div> </div>
</div> </div>
<div id="thumbnails" class="col s12"> <div id="thumbnails" class="col s12">

View File

@@ -7,6 +7,7 @@ var db = mongojs(mongo_db_cred.config);
var token_db = mongojs("tokens"); var token_db = mongojs("tokens");
var uniqid = require('uniqid'); var uniqid = require('uniqid');
var crypto = require('crypto'); var crypto = require('crypto');
var ObjectId = mongojs.ObjectId;
router.use(function(req, res, next) { router.use(function(req, res, next) {
next(); // make sure we go to the next routes and don't stop here next(); // make sure we go to the next routes and don't stop here
@@ -166,11 +167,37 @@ router.route('/api/token').get(function(req, res){
} }
}); });
router.route('/api/api_token').get(function(req, res){ router.route('/api/api_token').get(function(req, res) {
if(req.isAuthenticated()) {
token_db.collection("api_token").find({token: {$exists: true}}, function(err, all) {
res.json(all);
})
} else {
res.sendStatus(403);
}
});
router.route('/api/api_token').delete(function(req, res){
if(req.isAuthenticated()){ if(req.isAuthenticated()){
var id = req.body.id;
token_db.collection("api_token").remove({_id: ObjectId(id)}, function(err, success) {
if(err) {
res.send("failed");
return;
}
res.send("success");
})
}
});
router.route('/api/api_token').post(function(req, res){
if(req.isAuthenticated()){
var name = req.body.name;
var id = crypto.createHash('sha256').update(uniqid()).digest('base64'); var id = crypto.createHash('sha256').update(uniqid()).digest('base64');
token_db.collection("api_token").insert({token: id}, function(err, docs){ token_db.collection("api_token").insert({name: name, token: id, usage: 0}, function(err, docs){
res.json({token: id}); token_db.collection("api_token").find({token: id}, function(err, d) {
res.json({token: id, _id: d[0]._id});
});
}); });
} else { } else {
res.send(false); res.send(false);

View File

@@ -170,6 +170,9 @@ router.route('/api/list/:channel_name/:video_id').delete(function(req, res) {
dont_increment = true; dont_increment = true;
} }
db.collection(channel_name).remove({id:video_id}, function(err, docs){ db.collection(channel_name).remove({id:video_id}, function(err, docs){
if(authorized) {
incrementToken(token);
}
io.to(channel_name).emit("channel", {type:"deleted", value: video_id}); io.to(channel_name).emit("channel", {type:"deleted", value: video_id});
if(!dont_increment) { if(!dont_increment) {
db.collection("frontpage_lists").update({_id: channel_name, count: {$gt: 0}}, {$inc: {count: -1}, $set:{accessed: Functions.get_time()}}, {upsert: true}, function(err, docs){ db.collection("frontpage_lists").update({_id: channel_name, count: {$gt: 0}}, {$inc: {count: -1}, $set:{accessed: Functions.get_time()}}, {upsert: true}, function(err, docs){
@@ -294,6 +297,9 @@ router.route('/api/conf/:channel_name').put(function(req, res) {
frontpage:frontpage, accessed: Functions.get_time()} frontpage:frontpage, accessed: Functions.get_time()}
}, },
{upsert:true}, function(err, docs){ {upsert:true}, function(err, docs){
if(authorized) {
incrementToken(token);
}
updateTimeout(guid, res, authorized, "CONFIG", function(err, docs) { updateTimeout(guid, res, authorized, "CONFIG", function(err, docs) {
var to_return = error.no_error; var to_return = error.no_error;
to_return.results = [obj]; to_return.results = [obj];
@@ -365,6 +371,9 @@ router.route('/api/list/:channel_name/:video_id').put(function(req,res) {
song[0].votes += 1; song[0].votes += 1;
song[0].guids.push(guid); song[0].guids.push(guid);
db.collection(channel_name).update({id: video_id}, {$inc:{votes:1}, $set:{added:Functions.get_time(), type: "video"}, $push :{guids: guid}}, function(err, success) { db.collection(channel_name).update({id: video_id}, {$inc:{votes:1}, $set:{added:Functions.get_time(), type: "video"}, $push :{guids: guid}}, function(err, success) {
if(authorized) {
incrementToken(token);
}
io.to(channel_name).emit("channel", {type: "vote", value: video_id, time: Functions.get_time()}); io.to(channel_name).emit("channel", {type: "vote", value: video_id, time: Functions.get_time()});
List.getNextSong(channel_name, function() { List.getNextSong(channel_name, function() {
updateTimeout(guid, res, authorized, "PUT", function(err, docs) { updateTimeout(guid, res, authorized, "PUT", function(err, docs) {
@@ -421,6 +430,9 @@ router.route('/api/list/:channel_name/__np__').post(function(req, res) {
db.collection(channel_name).find({now_playing: true}, toShowChannel, function(err, list) { db.collection(channel_name).find({now_playing: true}, toShowChannel, function(err, list) {
if(list.length > 0) { if(list.length > 0) {
db.collection(channel_name + "_settings").find({ id: "config" }, function(err, conf) { db.collection(channel_name + "_settings").find({ id: "config" }, function(err, conf) {
if(authorized) {
incrementToken(token);
}
if(conf.length == 0) { if(conf.length == 0) {
res.status(404).send(JSON.stringify(error.not_found.list)); res.status(404).send(JSON.stringify(error.not_found.list));
return; return;
@@ -530,6 +542,9 @@ router.route('/api/list/:channel_name/:video_id').post(function(req,res) {
}); });
} }
db.collection(channel_name).update({"id": new_song.id}, new_song, {upsert: true}, function(err, success) { db.collection(channel_name).update({"id": new_song.id}, new_song, {upsert: true}, function(err, success) {
if(authorized) {
incrementToken(token);
}
if(create_frontpage_lists) { if(create_frontpage_lists) {
db.collection("frontpage_lists").update({"_id": channel_name, "count" : (authenticated ? 1 : 0), "frontpage": true, "accessed": Functions.get_time(), "viewers": 1}, {upsert: true}, function(err, docs) { db.collection("frontpage_lists").update({"_id": channel_name, "count" : (authenticated ? 1 : 0), "frontpage": true, "accessed": Functions.get_time(), "viewers": 1}, {upsert: true}, function(err, docs) {
if(authenticated) { if(authenticated) {
@@ -712,6 +727,9 @@ router.route('/api/conf/:channel_name').post(function(req, res) {
} else { } else {
conf.userpass = false; conf.userpass = false;
} }
if(authorized) {
incrementToken(token);
}
updateTimeout(guid, res, authorized, "POST", function(err, docs) { updateTimeout(guid, res, authorized, "POST", function(err, docs) {
var to_return = error.no_error; var to_return = error.no_error;
to_return.results = conf; to_return.results = conf;
@@ -776,6 +794,9 @@ router.route('/api/list/:channel_name').post(function(req, res) {
res.status(403).send(JSON.stringify(error.not_authenticated)); res.status(403).send(JSON.stringify(error.not_authenticated));
return; return;
} }
if(authorized) {
incrementToken(token);
}
updateTimeout(guid, res, authorized, "POST", function(err, docs) { updateTimeout(guid, res, authorized, "POST", function(err, docs) {
var to_return = error.no_error; var to_return = error.no_error;
to_return.results = list; to_return.results = list;
@@ -792,6 +813,12 @@ router.route('/api/list/:channel_name').post(function(req, res) {
}); });
}); });
function incrementToken(token) {
token_db.collection("api_token").update({token: token}, {$inc: {usage: 1}}, function(err, doc) {
});
}
router.route('/api/imageblob').post(function(req, res) { router.route('/api/imageblob').post(function(req, res) {
var Jimp = require("jimp"); var Jimp = require("jimp");
Jimp.read('https://img.youtube.com/vi/' + req.body.id + '/mqdefault.jpg', function (err, image) { Jimp.read('https://img.youtube.com/vi/' + req.body.id + '/mqdefault.jpg', function (err, image) {
@@ -915,7 +942,7 @@ function validateLogin(adminpass, userpass, channel_name, type, res, callback) {
var exists = false; var exists = false;
if(conf.length > 0 && ((conf[0].userpass == undefined || conf[0].userpass == "" || conf[0].userpass == userpass))) { if(conf.length > 0 && ((conf[0].userpass == undefined || conf[0].userpass == "" || conf[0].userpass == userpass))) {
exists = true; exists = true;
} else if(conf.length > 0 && type != "config") { } else if(conf.length > 0 && type == "config") {
res.status(404).send(JSON.stringify(error.not_found.list)); res.status(404).send(JSON.stringify(error.not_found.list));
return; return;
} else if(conf.length == 0) { } else if(conf.length == 0) {