mirror of
https://github.com/KevinMidboe/zoff.git
synced 2025-10-29 18:00:23 +00:00
Added url for applying for api-tokens
This commit is contained in:
14
gulpfile.js
14
gulpfile.js
@@ -4,7 +4,7 @@ var gulp = require('gulp'),
|
||||
concat = require('gulp-concat');
|
||||
|
||||
gulp.task('js', function () {
|
||||
gulp.src(['server/VERSION.js', 'server/config/api_key.js', 'server/public/assets/js/*.js', '!server/public/assets/js/embed*', '!server/public/assets/js/remotecontroller.js', '!server/public/assets/js/callback.js'])
|
||||
gulp.src(['server/VERSION.js', 'server/config/api_key.js', 'server/public/assets/js/*.js', '!server/public/assets/js/embed*', '!server/public/assets/js/token*', '!server/public/assets/js/remotecontroller.js', '!server/public/assets/js/callback.js'])
|
||||
.pipe(uglify({
|
||||
mangle: true,
|
||||
compress: true,
|
||||
@@ -25,6 +25,17 @@ gulp.task('embed', function () {
|
||||
.pipe(gulp.dest('server/public/assets/dist'));
|
||||
});
|
||||
|
||||
gulp.task('token', function() {
|
||||
gulp.src(['server/public/assets/js/token*', 'server/public/assets/js/helpers.js'])
|
||||
.pipe(uglify({
|
||||
mangle: true,
|
||||
compress: true,
|
||||
enclose: true
|
||||
}))
|
||||
.pipe(concat('token.min.js'))
|
||||
.pipe(gulp.dest('server/public/assets/dist'));
|
||||
})
|
||||
|
||||
gulp.task('callback', function () {
|
||||
gulp.src(['server/VERSION.js', 'server/config/api_key.js', 'server/public/assets/js/callback.js'])
|
||||
.pipe(uglify({
|
||||
@@ -53,6 +64,7 @@ gulp.task('remotecontroller', function () {
|
||||
|
||||
gulp.task('default', function(){
|
||||
gulp.watch(['server/VERSION.js', 'server/public/assets/js/*.js'], ['js']);
|
||||
gulp.watch(['server/public/assets/js/token*.js', 'server/public/assets/js/helpers.js'], ['token']);
|
||||
gulp.watch(['server/VERSION.js', 'server/public/assets/js/*.js'], ['embed']);
|
||||
gulp.watch(['server/VERSION.js', 'server/public/assets/js/callback.js', 'server/public/assets/js/helpers.js'], ['callback']);
|
||||
//gulp.watch('server/public/assets/js/*.js', ['nochan']);
|
||||
|
||||
@@ -6,7 +6,7 @@ Under ``` /server/apps/ ```, there are two files, ``` admin.js ``` and ``` clien
|
||||
|
||||
All PUT, DELETE and POST endpoints have a 2-second waitlimit for each command per client. You'll get a response with Retry-After header for how long you have to wait. Shuffling in a player has a 5-second waitlimit, but per channel instead of per client.
|
||||
|
||||
If you want to skip the wait-times, send a mail to the team at contact@zoff.me, and get a token. Tokens are added to all the POST, PUT, DELETE, requests as ``` token: TOKEN ```.
|
||||
If you want to skip the wait-times, create a token at <a href="https://zoff.me/api/apply">https://zoff.me/api/apply</a>. Tokens are added to all the POST, PUT, DELETE, requests as ``` token: TOKEN ```.
|
||||
|
||||
All requests return things on this form (results field is added if successful.)
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ var ObjectId = mongojs.ObjectId;
|
||||
|
||||
db.collection("chat_logs").createIndex({ "createdAt": 1 }, { expireAfterSeconds: 600 });
|
||||
db.collection("timeout_api").createIndex({ "createdAt": 1 }, { expireAfterSeconds: 5 });
|
||||
db.collection("api_links").createIndex({ "createdAt": 1 }, { expireAfterSeconds: 86400 });
|
||||
db.on('connected', function(err) {
|
||||
console.log("connected");
|
||||
})
|
||||
|
||||
@@ -9,7 +9,7 @@ function thumbnail(msg, coll, guid, offline, socket) {
|
||||
if(msg.thumbnail.substring(0,2) != "//") msg.thumbnail = "//" + msg.thumbnail;
|
||||
var channel = msg.channel.toLowerCase();
|
||||
var hash = Functions.hash_pass(Functions.decrypt_string(socket.zoff_id, msg.adminpass));
|
||||
db.collection(channel + "_settings").update({id: "configs"}, function(err, docs){
|
||||
db.collection(channel + "_settings").find({id: "config"}, function(err, docs){
|
||||
if(docs.length > 0 && (docs[0].userpass == undefined || docs[0].userpass == "" || (msg.hasOwnProperty('pass') && docs[0].userpass == Functions.decrypt_string(socketid, msg.pass)))) {
|
||||
if(docs !== null && docs.length !== 0 && docs[0].adminpass !== "" && docs[0].adminpass == hash){
|
||||
db.collection("suggested_thumbnails").update({channel: channel}, {$set:{thumbnail: msg.thumbnail}}, {upsert:true}, function(err, docs){
|
||||
@@ -35,7 +35,7 @@ function description(msg, coll, guid, offline, socket) {
|
||||
}
|
||||
var channel = msg.channel.toLowerCase();
|
||||
var hash = Functions.hash_pass(Functions.decrypt_string(socket.zoff_id, msg.adminpass));
|
||||
db.collection(channel + "_settings").update({id: "configs"}, function(err, docs){
|
||||
db.collection(channel + "_settings").find({id: "config"}, function(err, docs){
|
||||
if(docs.length > 0 && (docs[0].userpass == undefined || docs[0].userpass == "" || (msg.hasOwnProperty('pass') && docs[0].userpass == Functions.decrypt_string(socketid, msg.pass)))) {
|
||||
if(docs !== null && docs.length !== 0 && docs[0].adminpass !== "" && docs[0].adminpass == hash){
|
||||
db.collection("suggested_descriptions").update({channel: channel}, {$set:{description: msg.description}}, {upsert:true}, function(err, docs){
|
||||
|
||||
@@ -30,17 +30,21 @@ $(document).on("click", "#refresh_all", function(e){
|
||||
}
|
||||
$(".header-api-fields").removeClass("hide");
|
||||
for(var i = 0; i < response.length; i++) {
|
||||
var to_add = api_token_list;
|
||||
var to_add = api_token_list.clone();
|
||||
to_add.find(".api_token_limit").val(response[i].limit);
|
||||
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(".api_token_limit").attr("id", response[i]._id + "-limit");
|
||||
to_add.find("#delete_api_token").attr("data-id", response[i]._id);
|
||||
to_add.find("#update_api_token").attr("data-id", response[i]._id);
|
||||
$(".channel_things").append(to_add);
|
||||
}
|
||||
},
|
||||
error: function(err) {
|
||||
}
|
||||
});
|
||||
|
||||
if(!$(".channel_things").hasClass("hide")) {
|
||||
$(".channel_things").addClass("hide")
|
||||
}
|
||||
@@ -116,11 +120,39 @@ if(!$(".channel_things").hasClass("hide")) {
|
||||
}
|
||||
$(".preloader-wrapper").removeClass("hide");
|
||||
|
||||
$(document).on("click", "#update_api_token", function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
var id = $(this).attr("data-id");
|
||||
var limit = $("#" + id + "-limit").val();
|
||||
var that = this;
|
||||
$(that).toggleClass("disabled");
|
||||
$("#delete_api_token").toggleClass("disabled");
|
||||
$.ajax({
|
||||
type: "PUT",
|
||||
url: "api/api_token",
|
||||
data: {
|
||||
id: id,
|
||||
limit: limit,
|
||||
},
|
||||
success: function(response) {
|
||||
if(response == "OK") {
|
||||
Materialize.toast("Updated limit!", 2000, "green lighten");
|
||||
} else {
|
||||
Materialize.toast("Something went wrong...", 2000, "red lighten");
|
||||
}
|
||||
$(that).toggleClass("disabled");
|
||||
$("#delete_api_token").toggleClass("disabled");
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$(document).on("click", "#delete_api_token", function(e) {
|
||||
e.preventDefault();
|
||||
var id = $(this).attr("data-id");
|
||||
var that = this;
|
||||
$(that).toggleClass("disabled");
|
||||
$("#update_api_token").toggleClass("disabled");
|
||||
$.ajax({
|
||||
type: "DELETE",
|
||||
url: "api/api_token",
|
||||
@@ -134,6 +166,7 @@ $(document).on("click", "#delete_api_token", function(e) {
|
||||
} else {
|
||||
Materialize.toast("Something went wrong...", 2000, "red lighten");
|
||||
$(that).toggleClass("disabled");
|
||||
$("#update_api_token").toggleClass("disabled");
|
||||
}
|
||||
},
|
||||
})
|
||||
@@ -153,10 +186,13 @@ function loaded() {
|
||||
$(".header-api-fields").removeClass("hide");
|
||||
for(var i = 0; i < response.length; i++) {
|
||||
var to_add = api_token_list.clone();
|
||||
to_add.find(".api_token_limit").val(response[i].limit);
|
||||
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(".api_token_limit").attr("id", response[i]._id + "-limit");
|
||||
to_add.find("#delete_api_token").attr("data-id", response[i]._id);
|
||||
to_add.find("#update_api_token").attr("data-id", response[i]._id);
|
||||
$(".channel_things").append(to_add);
|
||||
}
|
||||
},
|
||||
|
||||
@@ -91,6 +91,27 @@ body {
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
.token-container {
|
||||
padding-top: 64px;
|
||||
}
|
||||
|
||||
.token-form {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.full-form-token {
|
||||
background: rgba(0,0,0,.5);
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.center-loader-token {
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
#send-loader {
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
@@ -405,6 +426,10 @@ li.disabled span {
|
||||
user-select: text;
|
||||
}
|
||||
|
||||
.auto-pointer {
|
||||
cursor: auto !important;
|
||||
}
|
||||
|
||||
#chatchannel li:nth-child(even), #chatall li:nth-child(even) {
|
||||
background: rgba(0,0,0,.1);
|
||||
}
|
||||
|
||||
1
server/public/assets/dist/token.min.js
vendored
Normal file
1
server/public/assets/dist/token.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
!function(){$(document).ready(function(){$("#about").modal(),$(".help-button-footer").hide(),$("#contact").modal(),$("#contact-container").empty(),$("#contact-container").html("Send a mail to us: <a title='Open in client' href='mailto:contact@zoff.me?Subject=Contact%20Zoff'>contact@zoff.me</a>"),$("#submit-contact-form").hide(),$(".token-form").on("submit",function(e){e.preventDefault();var t=$("#email_address").val();$("#email_address").attr("readonly",!0),$(".submit").toggleClass("disabled"),$(".full-form-token").removeClass("hide");var a=grecaptcha.getResponse();$.ajax({type:"POST",url:"/api/apply",data:{email:t,"g-recaptcha-response":a},success:function(e){$(".full-form-token").addClass("hide"),"OK"!=e?($("#email_address").attr("readonly",!0),$(".submit").toggleClass("disabled"),Materialize.toast("Couldn't send email.",3e3,"red lighten")):(Materialize.toast("Email sent!",3e3,"green lighten"),grecaptcha.reset())},error:function(e){$(".full-form-token").addClass("hide"),$("#email_address").attr("readonly",!1),$(".submit").toggleClass("disabled")}})}),$("#submit-contact-form").on("click",function(e){e.preventDefault(),$("#contact-form").submit()})});Element.prototype.remove=function(){this.parentElement.removeChild(this)},NodeList.prototype.remove=HTMLCollection.prototype.remove=function(){for(var e=0,t=this.length;e<t;e++)this[e]&&this[e].parentElement&&this[e].parentElement.removeChild(this[e])},String.prototype.startsWith=function(e,t){return t=t||0,this.indexOf(e,t)===t}}();
|
||||
@@ -213,7 +213,7 @@ var Player = {
|
||||
"New state\nState: ",
|
||||
newState
|
||||
]);
|
||||
if(player.getCurrentTime() > startTime + Player.np.start && !fix_too_far) {
|
||||
if(player.getCurrentTime() > startTime + Player.np.start && !fix_too_far && autoplay) {
|
||||
Player.seekTo(seekTo);
|
||||
Player.playVideo();
|
||||
fix_too_far = true;
|
||||
|
||||
47
server/public/assets/js/token_apply.js
Normal file
47
server/public/assets/js/token_apply.js
Normal file
@@ -0,0 +1,47 @@
|
||||
$(document).ready(function() {
|
||||
$("#about").modal();
|
||||
$(".help-button-footer").hide();
|
||||
$("#contact").modal();
|
||||
|
||||
$("#contact-container").empty();
|
||||
$("#contact-container").html("Send a mail to us: <a title='Open in client' href='mailto:contact@zoff.me?Subject=Contact%20Zoff'>contact@zoff.me</a>");
|
||||
$("#submit-contact-form").hide();
|
||||
|
||||
$(".token-form").on("submit", function(e) {
|
||||
e.preventDefault();
|
||||
var email = $("#email_address").val();
|
||||
$("#email_address").attr("readonly", true);
|
||||
$(".submit").toggleClass("disabled");
|
||||
$(".full-form-token").removeClass("hide");
|
||||
var captcha_response = grecaptcha.getResponse();
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: "/api/apply",
|
||||
data: {
|
||||
email: email,
|
||||
"g-recaptcha-response": captcha_response,
|
||||
},
|
||||
success: function(response) {
|
||||
$(".full-form-token").addClass("hide");
|
||||
if(response != "OK") {
|
||||
$("#email_address").attr("readonly", true);
|
||||
$(".submit").toggleClass("disabled");
|
||||
Materialize.toast("Couldn't send email.", 3000, "red lighten");
|
||||
} else {
|
||||
Materialize.toast("Email sent!", 3000, "green lighten");
|
||||
grecaptcha.reset();
|
||||
}
|
||||
},
|
||||
error: function(response) {
|
||||
$(".full-form-token").addClass("hide");
|
||||
$("#email_address").attr("readonly", false);
|
||||
$(".submit").toggleClass("disabled");
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$('#submit-contact-form').on('click', function(e) {
|
||||
e.preventDefault();
|
||||
$("#contact-form").submit();
|
||||
});
|
||||
});
|
||||
@@ -111,21 +111,24 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="row header-api-fields">
|
||||
<div class="col s4">
|
||||
<div class="col s3">
|
||||
Name
|
||||
</div>
|
||||
<div class="col s4">
|
||||
<div class="col s3">
|
||||
Usage
|
||||
</div>
|
||||
<div class="col s1">
|
||||
Limit
|
||||
</div>
|
||||
</div>
|
||||
<div class="row" id="api_token_list">
|
||||
<div class="col s4 api_token_name">
|
||||
<div class="col s3 api_token_name truncate">
|
||||
</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 class="col s3 api_token_usage">
|
||||
</div>
|
||||
<input class="api_token_limit col s1" type="number" />
|
||||
<a href="#" id="update_api_token" class="btn waves-effect green col s2">UPDATE</a>
|
||||
<a href="#" id="delete_api_token" class="btn waves-effect red col s1">X</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
72
server/public/layouts/client/token.handlebars
Normal file
72
server/public/layouts/client/token.handlebars
Normal file
@@ -0,0 +1,72 @@
|
||||
<header>
|
||||
<nav id="fp-nav">
|
||||
<div class="nav-wrapper">
|
||||
<a href="#" class="brand-logo">
|
||||
<img class="zicon" src="/assets/images/z.svg" alt="zoff" title="Zoff" />
|
||||
</a>
|
||||
<div id="frontpage-viewer-counter" class="noselect" title="Divided among all channels. Hidden or not"></div>
|
||||
<ul class="right hide-on-med-and-down">
|
||||
<li><a class="header-buttons waves-effect waves-green" title="Remote control a Zoff player" href="https://remote.zoff.me">Remote</a></li>
|
||||
<li><a class="header-buttons modal-trigger waves-effect waves-orange" data-target="about">About</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
{{> modal/about}}
|
||||
<div id="donation" class="modal">
|
||||
<div class="modal-content">
|
||||
<h4>Thanks!</h4>
|
||||
<p>Thanks for your donation, we love you <3
|
||||
<br><br>
|
||||
We will use the money for something awesome, just you wait and see!
|
||||
<br><br>
|
||||
We might also add your name somewhere in the code as a sign of gratitude, see if you can find it! (Might take a day or two for us to see the donation and implement it..)
|
||||
</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<a href="#" class="modal-action modal-close waves-effect waves-green btn-flat">I'm awesome! (Close)</a>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<div id="main-container" class="token-container">
|
||||
<main class="center-align container">
|
||||
<div class="token-info left-align">
|
||||
{{#if activated}}
|
||||
<h1 class="center-align">API-token</h1>
|
||||
<p>Here is your api token</p>
|
||||
<h4 class="select auto-pointer">{{token}}</h3>
|
||||
<p>Use it wisely, and don't lose it!</p>
|
||||
<p>As of now, the tokens have no limit for how many requests you can do is 100 requests a second. If you need a higher limit, just contact the team and we'll set you up for as much as you need.</p>
|
||||
{{else}}
|
||||
<h2 class="center-align">API-token</h2>
|
||||
<p>Apply for a API-token with your email here! You'll get an email on the specified address, with a link. Follow that link, and the token will be shown to you! Take good care of it, and don't lose it. It won't be shown to you again.</p>
|
||||
<p>If you're wondering anything about how the api works, there is a guide on our GitHub. You can also click <a href="https://zoff.me/api/help">HERE</a> to be taken to the detailed README.</p>
|
||||
<p>As of now, the tokens have no limit for how many requests you can do is 100 requests a second. If you need a higher limit, just contact the team and we'll set you up for as much as you need.</p>
|
||||
{{/if}}
|
||||
</div>
|
||||
{{#if activated}}
|
||||
<iframe id="iframe" src="https://zoff.me/_embed#celebrate&808080" width="600px" height="300px"></iframe>
|
||||
{{else}}
|
||||
<form class="token-form row" type="post">
|
||||
<div class="row center">
|
||||
<div class="input-field col s6 offset-s3">
|
||||
<label for="email_address" class="noselect">Email</label>
|
||||
<input type="email" class="validate" id="email_address" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="col offset-s3">
|
||||
{{{captcha}}}
|
||||
</div>
|
||||
<div class="input-field col s12 m2">
|
||||
<input type="submit" class="btn submit" />
|
||||
</div>
|
||||
<div class="full-form-token valign-wrapper hide">
|
||||
<div class="preloader-wrapper medium active center-loader-token">
|
||||
{{> spinner}}
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
{{/if}}
|
||||
<p>Any lost tokens can easily be deleted by our admins, so just send us an email if something goes awry. Just click the CONTACT button in the footer, and we will be with you as fast as we can!</p>
|
||||
<br>
|
||||
</main>
|
||||
</div>
|
||||
@@ -15,7 +15,7 @@
|
||||
</div>
|
||||
</div>
|
||||
{{{captcha}}}
|
||||
<div class="valign hide" id="send-loader">
|
||||
<div class="valign-wrapper hide" id="send-loader">
|
||||
<div class="preloader-wrapper small active">
|
||||
{{> spinner}}
|
||||
</div>
|
||||
|
||||
@@ -171,7 +171,7 @@ 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);
|
||||
}
|
||||
@@ -190,6 +190,24 @@ router.route('/api/api_token').delete(function(req, res){
|
||||
}
|
||||
});
|
||||
|
||||
router.route('/api/api_token').put(function(req, res){
|
||||
if(req.isAuthenticated()){
|
||||
var id = req.body.id;
|
||||
var limit = req.body.limit;
|
||||
if(limit < 0) {
|
||||
res.sendStatus(500);
|
||||
return;
|
||||
}
|
||||
token_db.collection("api_token").update({_id: ObjectId(id)}, {$set: {limit: limit}}, function(err, success) {
|
||||
if(err) {
|
||||
res.sendStatus(500);
|
||||
return;
|
||||
}
|
||||
res.sendStatus(200);
|
||||
})
|
||||
}
|
||||
});
|
||||
|
||||
router.route('/api/api_token').post(function(req, res){
|
||||
if(req.isAuthenticated()){
|
||||
var name = req.body.name;
|
||||
|
||||
@@ -147,6 +147,7 @@ router.route('/api/list/:channel_name/:video_id').delete(function(req, res) {
|
||||
if(token_docs.length == 1 && token_docs[0].token == token) {
|
||||
authorized = true;
|
||||
}
|
||||
checkOveruseApiToken(authorized, token_docs, res, function() {
|
||||
checkTimeout(guid, res, authorized, "DELETE", function() {
|
||||
if(token != "" && !authorized) {
|
||||
updateTimeout(guid, res, authorized, "DELETE", function(err, docs) {
|
||||
@@ -194,6 +195,7 @@ router.route('/api/list/:channel_name/:video_id').delete(function(req, res) {
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
router.route('/api/conf/:channel_name').put(function(req, res) {
|
||||
res.header("Access-Control-Allow-Origin", "*");
|
||||
@@ -247,6 +249,7 @@ router.route('/api/conf/:channel_name').put(function(req, res) {
|
||||
if(token_docs.length == 1 && token_docs[0].token == token) {
|
||||
authorized = true;
|
||||
}
|
||||
checkOveruseApiToken(authorized, token_docs, res, function() {
|
||||
checkTimeout(guid, res, authorized, "CONFIG", function() {
|
||||
if(token != "" && !authorized) {
|
||||
updateTimeout(guid, res, authorized, "CONFIG", function(err, docs) {
|
||||
@@ -312,6 +315,7 @@ router.route('/api/conf/:channel_name').put(function(req, res) {
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
router.route('/api/list/:channel_name/:video_id').put(function(req,res) {
|
||||
res.header("Access-Control-Allow-Origin", "*");
|
||||
@@ -348,6 +352,7 @@ router.route('/api/list/:channel_name/:video_id').put(function(req,res) {
|
||||
if(token_docs.length == 1 && token_docs[0].token == token) {
|
||||
authorized = true;
|
||||
}
|
||||
checkOveruseApiToken(authorized, token_docs, res, function() {
|
||||
checkTimeout(guid, res, authorized, "PUT", function() {
|
||||
if(token != "" && !authorized) {
|
||||
updateTimeout(guid, res, authorized, "PUT", function(err, docs) {
|
||||
@@ -390,6 +395,7 @@ router.route('/api/list/:channel_name/:video_id').put(function(req,res) {
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
router.route('/api/list/:channel_name/__np__').post(function(req, res) {
|
||||
res.header("Access-Control-Allow-Origin", "*");
|
||||
@@ -420,6 +426,7 @@ router.route('/api/list/:channel_name/__np__').post(function(req, res) {
|
||||
if(token_docs.length == 1 && token_docs[0].token == token) {
|
||||
authorized = true;
|
||||
}
|
||||
checkOveruseApiToken(authorized, token_docs, res, function() {
|
||||
checkTimeout(guid, res, authorized, "POST", function() {
|
||||
if(token != "" && !authorized) {
|
||||
updateTimeout(guid, res, authorized, "POST", function(err, docs) {
|
||||
@@ -453,6 +460,7 @@ router.route('/api/list/:channel_name/__np__').post(function(req, res) {
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
router.route('/api/list/:channel_name/:video_id').post(function(req,res) {
|
||||
res.header("Access-Control-Allow-Origin", "*");
|
||||
@@ -502,6 +510,7 @@ router.route('/api/list/:channel_name/:video_id').post(function(req,res) {
|
||||
if(token_docs.length == 1 && token_docs[0].token == token) {
|
||||
authorized = true;
|
||||
}
|
||||
checkOveruseApiToken(authorized, token_docs, res, function() {
|
||||
checkTimeout(guid, res, authorized, "POST", function() {
|
||||
if(token != "" && !authorized) {
|
||||
updateTimeout(guid, res, authorized, "POST", function(err, docs) {
|
||||
@@ -587,6 +596,7 @@ router.route('/api/list/:channel_name/:video_id').post(function(req,res) {
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
router.route('/api/list/:channel_name').get(function(req, res) {
|
||||
res.header("Access-Control-Allow-Origin", "*");
|
||||
@@ -707,6 +717,7 @@ router.route('/api/conf/:channel_name').post(function(req, res) {
|
||||
if(token_docs.length == 1 && token_docs[0].token == token) {
|
||||
authorized = true;
|
||||
}
|
||||
checkOveruseApiToken(authorized, token_docs, res, function() {
|
||||
checkTimeout(guid, res, authorized, "POST", function() {
|
||||
if(token != "" && !authorized) {
|
||||
updateTimeout(guid, res, authorized, "DELETE", function(err, docs) {
|
||||
@@ -746,6 +757,36 @@ router.route('/api/conf/:channel_name').post(function(req, res) {
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function checkOveruseApiToken(authorized, token_docs, res, callback) {
|
||||
if(authorized || (authorized && token_docs[0].limit == 0)) {
|
||||
callback();
|
||||
return;
|
||||
}
|
||||
db.collection("timeout_api").find({guid: token_docs[0].token}, function(e, doc) {
|
||||
if(doc.length == 1) {
|
||||
var this_doc = doc[0];
|
||||
var date = new Date(this_doc[0].createdAt);
|
||||
date.setSeconds(date.getSeconds() + 1);
|
||||
var now = new Date();
|
||||
var retry_in = (date.getTime() - now.getTime()) / 1000;
|
||||
if(this_doc.used > token_docs[0].limit && retry_in > 0) {
|
||||
res.header({'Retry-After': retry_in});
|
||||
res.status(429).send(JSON.stringify(error.tooMany));
|
||||
return;
|
||||
} else {
|
||||
db.collection("timeout_api").update({guid: token}, {$inc: {used: 1}}, function(e, d) {
|
||||
callback();
|
||||
});
|
||||
}
|
||||
} else {
|
||||
db.collection("timeout_api").insert({guid: token, used: 0, createdAt: new Date(), type: "ALL"}, function(e, d) {
|
||||
callback();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
router.route('/api/list/:channel_name').post(function(req, res) {
|
||||
res.header("Access-Control-Allow-Origin", "*");
|
||||
@@ -777,6 +818,7 @@ router.route('/api/list/:channel_name').post(function(req, res) {
|
||||
if(token_docs.length == 1 && token_docs[0].token == token) {
|
||||
authorized = true;
|
||||
}
|
||||
checkOveruseApiToken(authorized, token_docs, res, function() {
|
||||
checkTimeout(guid, res, authorized, "POST", function() {
|
||||
if(token != "" && !authorized) {
|
||||
updateTimeout(guid, res, authorized, "POST", function(err, docs) {
|
||||
@@ -812,6 +854,7 @@ 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) {
|
||||
@@ -831,8 +874,8 @@ router.route('/api/imageblob').post(function(req, res) {
|
||||
});
|
||||
});
|
||||
|
||||
var nodemailer = require('nodemailer');
|
||||
try {
|
||||
var nodemailer = require('nodemailer');
|
||||
var mailconfig = require(path.join(__dirname, '../../config/mailconfig.js'));
|
||||
var recaptcha_config = require(path.join(__dirname, '../../config/recaptcha.js'));
|
||||
var Recaptcha = require('express-recaptcha');
|
||||
@@ -840,6 +883,61 @@ try {
|
||||
var RECAPTCHA_SECRET_KEY = recaptcha_config.key;
|
||||
var recaptcha = new Recaptcha(RECAPTCHA_SITE_KEY, RECAPTCHA_SECRET_KEY);
|
||||
|
||||
router.route('/api/apply').post(recaptcha.middleware.verify, function(req, res) {
|
||||
if(req.body.email == "" || req.body.email == undefined) {
|
||||
res.send("failed");
|
||||
return;
|
||||
}
|
||||
if(req.recaptcha.error == null) {
|
||||
var name = req.body.email;
|
||||
var id = crypto.createHash('sha256').update(uniqid()).digest('base64');
|
||||
var uniqid_link = crypto.createHash('sha256').update(uniqid()).digest('hex');
|
||||
token_db.collection("api_token").find({name: name}, function(err, results_find) {
|
||||
if(results_find.length > 0) {
|
||||
res.send("failed");
|
||||
return;
|
||||
}
|
||||
token_db.collection("api_token").insert({name: name, token: id, usage: 0, active: false}, function(err, docs){
|
||||
token_db.collection("api_links").insert({id: uniqid_link, token: id, createdAt: new Date()}, function(err, docs) {
|
||||
let transporter = nodemailer.createTransport(mailconfig);
|
||||
|
||||
transporter.verify(function(error, success) {
|
||||
if (error) {
|
||||
token_db.collection("api_links").remove({id: uniqid_link}, function(e,d) {
|
||||
res.send("failed");
|
||||
return;
|
||||
})
|
||||
} else {
|
||||
var subject = 'ZOFF: API-key';
|
||||
var message = "Link to API-key: <a href='https://zoff.me/api/apply/" + uniqid_link + "'/>https://zoff.me/api/apply/" + uniqid_link + "</a>\n\nThis link expires in 1 day.";
|
||||
var msg = {
|
||||
from: mailconfig.from,
|
||||
to: name,
|
||||
subject: subject,
|
||||
text: message,
|
||||
html: message,
|
||||
}
|
||||
transporter.sendMail(msg, (error, info) => {
|
||||
if (error) {
|
||||
res.status(400).send("failed");
|
||||
transporter.close();
|
||||
return;
|
||||
}
|
||||
res.status(200).send("success");
|
||||
transporter.close();
|
||||
return;
|
||||
});
|
||||
}
|
||||
});
|
||||
})
|
||||
});
|
||||
})
|
||||
} else {
|
||||
res.send("failed");
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
router.route('/api/mail').post(recaptcha.middleware.verify, function(req, res) {
|
||||
if(req.recaptcha.error == null) {
|
||||
let transporter = nodemailer.createTransport(mailconfig);
|
||||
@@ -916,7 +1014,7 @@ function checkTimeout(guid, res, authorized, type, callback) {
|
||||
}, function(err, docs) {
|
||||
if(docs.length > 0) {
|
||||
var date = new Date(docs[0].createdAt);
|
||||
date.setSeconds(date.getSeconds() + 2);
|
||||
date.setSeconds(date.getSeconds() + 1);
|
||||
var now = new Date();
|
||||
var retry_in = (date.getTime() - now.getTime()) / 1000;
|
||||
if(retry_in > 0) {
|
||||
|
||||
@@ -4,6 +4,8 @@ var path = require('path');
|
||||
var year = new Date().getYear()+1900;
|
||||
var path = require('path');
|
||||
var analytics = "xx";
|
||||
var mongojs = require('mongojs');
|
||||
var token_db = mongojs("tokens");
|
||||
try {
|
||||
analytics = require(path.join(path.join(__dirname, '../../config/'), 'analytics.js'));
|
||||
} catch(e) {
|
||||
@@ -44,6 +46,52 @@ router.route('/').post(function(req, res, next){
|
||||
root(req, res, next);
|
||||
});
|
||||
|
||||
router.route('/api/apply/:id').get(function(req,res) {
|
||||
var id = req.params.id;
|
||||
token_db.collection('api_links').find({id: id}, function(err, result) {
|
||||
if(result.length == 1) {
|
||||
token_db.collection('api_links').remove({id: id}, function(e,d) {
|
||||
token_db.collection('api_token').update({id: result[0].token}, {$set: {active: true }}, function(e,d) {
|
||||
var data = {
|
||||
year: year,
|
||||
javascript_file: "token.min.js",
|
||||
captcha: res.recaptcha,
|
||||
analytics: analytics,
|
||||
activated: true,
|
||||
token: result[0].token,
|
||||
correct: true,
|
||||
}
|
||||
res.render('layouts/client/token', data);
|
||||
});
|
||||
})
|
||||
} else {
|
||||
var data = {
|
||||
year: year,
|
||||
javascript_file: "token.min.js",
|
||||
captcha: res.recaptcha,
|
||||
analytics: analytics,
|
||||
activated: false,
|
||||
id:"",
|
||||
correct: false,
|
||||
}
|
||||
res.render('layouts/client/token', data);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
router.route('/api/apply').get(function(req, res, next) {
|
||||
var data = {
|
||||
year: year,
|
||||
javascript_file: "token.min.js",
|
||||
captcha: res.recaptcha,
|
||||
analytics: analytics,
|
||||
activated: false,
|
||||
id: "",
|
||||
correct: false,
|
||||
}
|
||||
res.render('layouts/client/token', data);
|
||||
});
|
||||
|
||||
function root(req, res, next) {
|
||||
try{
|
||||
|
||||
Reference in New Issue
Block a user