sync/src/utilities.js

289 lines
7.9 KiB
JavaScript
Raw Normal View History

2014-02-15 06:12:11 +00:00
(function () {
2018-04-07 22:30:30 +00:00
const root = module.exports;
const net = require("net");
const crypto = require("crypto");
2014-03-09 16:24:57 +00:00
2014-02-15 06:12:11 +00:00
root.isValidChannelName = function (name) {
2014-01-23 21:53:53 +00:00
return name.match(/^[\w-]{1,30}$/);
2013-08-16 15:37:26 +00:00
},
2014-02-15 06:12:11 +00:00
root.isValidUserName = function (name) {
2014-01-23 21:53:53 +00:00
return name.match(/^[\w-]{1,20}$/);
},
2014-02-15 06:12:11 +00:00
root.isValidEmail = function (email) {
2017-09-06 05:47:29 +00:00
if (typeof email !== "string") {
return false;
}
if (email.length > 255) {
return false;
}
if (!email.match(/^[^@]+?@[^@]+$/)) {
return false;
}
if (email.match(/^[^@]+?@(localhost|127\.0\.0\.1)$/)) {
return false;
}
return true;
},
2014-02-15 06:12:11 +00:00
root.randomSalt = function (length) {
var chars = "abcdefgihjklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "0123456789!@#$%^&*_+=~";
var salt = [];
for(var i = 0; i < length; i++) {
salt.push(chars[parseInt(Math.random()*chars.length)]);
}
return salt.join('');
2013-08-18 22:58:16 +00:00
},
2014-05-21 02:30:14 +00:00
root.getIPRange = function (ip) {
if (net.isIPv6(ip)) {
return root.expandIPv6(ip)
.replace(/((?:[0-9a-f]{4}:){3}[0-9a-f]{4}):(?:[0-9a-f]{4}:){3}[0-9a-f]{4}/, "$1");
} else {
return ip.replace(/((?:[0-9]+\.){2}[0-9]+)\.[0-9]+/, "$1");
}
},
root.getWideIPRange = function (ip) {
if (net.isIPv6(ip)) {
return root.expandIPv6(ip)
.replace(/((?:[0-9a-f]{4}:){2}[0-9a-f]{4}):(?:[0-9a-f]{4}:){4}[0-9a-f]{4}/, "$1");
} else {
return ip.replace(/([0-9]+\.[0-9]+)\.[0-9]+\.[0-9]+/, "$1");
}
},
root.expandIPv6 = function (ip) {
var result = "0000:0000:0000:0000:0000:0000:0000:0000".split(":");
var parts = ip.split("::");
var left = parts[0].split(":");
var i = 0;
left.forEach(function (block) {
while (block.length < 4) {
block = "0" + block;
}
result[i++] = block;
});
if (parts.length > 1) {
var right = parts[1].split(":");
i = 7;
right.forEach(function (block) {
while (block.length < 4) {
block = "0" + block;
}
result[i--] = block;
});
}
2016-08-09 03:34:03 +00:00
return result.join(":");
2014-05-21 02:30:14 +00:00
},
2014-02-15 06:12:11 +00:00
root.formatTime = function (sec) {
if(sec === "--:--")
return sec;
sec = Math.floor(+sec);
var h = "", m = "", s = "";
if(sec >= 3600) {
h = "" + Math.floor(sec / 3600);
if(h.length < 2)
h = "0" + h;
sec %= 3600;
}
m = "" + Math.floor(sec / 60);
if(m.length < 2)
m = "0" + m;
s = "" + (sec % 60);
if(s.length < 2)
s = "0" + s;
2013-08-29 00:25:53 +00:00
if(h === "")
return [m, s].join(":");
return [h, m, s].join(":");
2013-08-29 00:25:53 +00:00
},
2014-03-09 16:24:57 +00:00
root.parseTime = function (time) {
2014-05-22 13:22:58 +00:00
var parts = time.split(":").reverse();
2014-03-09 16:24:57 +00:00
var seconds = 0;
2018-04-07 22:30:30 +00:00
// TODO: consider refactoring to remove this suppression
/* eslint no-fallthrough: off */
2014-03-09 16:24:57 +00:00
switch (parts.length) {
case 3:
seconds += parseInt(parts[2]) * 3600;
case 2:
seconds += parseInt(parts[1]) * 60;
case 1:
seconds += parseInt(parts[0]);
break;
default:
break;
}
return seconds;
},
2014-02-15 06:12:11 +00:00
root.newRateLimiter = function () {
2013-08-29 00:25:53 +00:00
return {
count: 0,
lastTime: 0,
throttle: function (opts) {
if (typeof opts === "undefined")
opts = {};
var burst = +opts.burst,
sustained = +opts.sustained,
cooldown = +opts.cooldown;
if (isNaN(burst))
burst = 10;
if (isNaN(sustained))
sustained = 2;
if (isNaN(cooldown))
cooldown = burst / sustained;
2013-09-06 20:53:23 +00:00
// Cooled down, allow and clear buffer
if (this.lastTime < Date.now() - cooldown*1000) {
this.count = 1;
2013-08-29 00:25:53 +00:00
this.lastTime = Date.now();
return false;
}
2013-09-06 20:53:23 +00:00
// Haven't reached burst cap yet, allow
if (this.count < burst) {
this.count++;
2013-08-29 00:25:53 +00:00
this.lastTime = Date.now();
return false;
}
var diff = Date.now() - this.lastTime;
if (diff < 1000/sustained)
return true;
this.lastTime = Date.now();
return false;
}
};
2013-10-06 06:43:25 +00:00
},
2014-02-15 06:12:11 +00:00
root.formatLink = function (id, type) {
2013-10-06 06:43:25 +00:00
switch (type) {
case "yt":
2017-04-12 04:57:05 +00:00
return "https://youtu.be/" + id;
2013-10-06 06:43:25 +00:00
case "vi":
2017-04-12 04:57:05 +00:00
return "https://vimeo.com/" + id;
2013-10-06 06:43:25 +00:00
case "dm":
2017-04-12 04:57:05 +00:00
return "https://dailymotion.com/video/" + id;
2013-10-06 06:43:25 +00:00
case "sc":
return id;
case "li":
2017-04-12 04:57:05 +00:00
return "https://livestream.com/" + id;
2013-10-06 06:43:25 +00:00
case "tw":
2017-04-12 04:57:05 +00:00
return "https://twitch.tv/" + id;
2013-10-06 06:43:25 +00:00
case "rt":
return id;
case "im":
2017-04-12 04:57:05 +00:00
return "https://imgur.com/a/" + id;
2013-10-06 06:43:25 +00:00
case "us":
2017-05-14 11:02:32 +00:00
return "https://ustream.tv/channel/" + id;
2014-06-04 04:21:00 +00:00
case "gd":
return "https://docs.google.com/file/d/" + id;
case "fi":
return id;
2015-01-23 05:21:31 +00:00
case "hb":
2017-05-20 23:50:00 +00:00
return "https://www.smashcast.tv/" + id;
2016-08-09 03:34:03 +00:00
case "hl":
return id;
2016-08-03 05:35:00 +00:00
case "sb":
return "https://streamable.com/" + id;
2017-05-27 18:49:27 +00:00
case "tc":
return "https://clips.twitch.tv/" + id;
case "cm":
return id;
2013-10-06 06:43:25 +00:00
default:
return "";
}
2013-10-16 22:36:05 +00:00
},
2014-02-15 06:12:11 +00:00
root.isLive = function (type) {
2014-01-06 15:55:12 +00:00
switch (type) {
case "li":
case "tw":
case "us":
case "rt":
case "cu":
case "im":
2015-01-23 05:21:31 +00:00
case "hb":
2016-08-09 03:34:03 +00:00
case "hl":
2014-01-06 15:55:12 +00:00
return true;
default:
return false;
}
},
2014-02-15 06:12:11 +00:00
root.sha1 = function (data) {
if (!crypto) {
return "";
}
var shasum = crypto.createHash("sha1");
shasum.update(data);
return shasum.digest("hex");
2018-04-07 22:30:30 +00:00
},
root.cloakIP = function (ip) {
if (ip.match(/\d+\.\d+(\.\d+)?(\.\d+)?/)) {
return cloakIPv4(ip);
2018-04-07 22:30:30 +00:00
} else if (ip.match(/([0-9a-f]{1,4}:){1,7}[0-9a-f]{1,4}/)) {
return cloakIPv6(ip);
} else {
return ip;
}
function iphash(data, len) {
var md5 = crypto.createHash("md5");
md5.update(data);
return md5.digest("base64").substring(0, len);
}
function cloakIPv4(ip) {
var parts = ip.split(".");
var accumulator = "";
parts = parts.map(function (segment, i) {
var part = iphash(accumulator + segment + i, 3);
accumulator += segment;
return part;
});
while (parts.length < 4) parts.push("*");
return parts.join(".");
}
function cloakIPv6(ip) {
var parts = ip.split(":");
parts.splice(4, 4);
var accumulator = "";
parts = parts.map(function (segment, i) {
var part = iphash(accumulator + segment + i, 4);
accumulator += segment;
return part;
});
while (parts.length < 4) parts.push("*");
return parts.join(":");
}
2018-04-07 22:30:30 +00:00
};
2014-02-15 06:12:11 +00:00
})();