223 lines
5.9 KiB
JavaScript
223 lines
5.9 KiB
JavaScript
// ABOUT
|
|
// Runs the SyncLounge Web App - handles serving the static web content and link shortening services
|
|
// Port defaults to 8088
|
|
// REQUIRED: --url argument
|
|
|
|
const args = require("args-parser")(process.argv)
|
|
if (!args['url']){
|
|
console.log('Missing required argument -url. EG. "node webapp.js --url=http://example.com/slweb". This URL is used for redirecting invite links.')
|
|
return
|
|
}
|
|
var accessIp = args['url'] // EG 'http://95.231.444.12:8088/slweb' or 'http://example.com/slweb'
|
|
if (accessIp.indexOf('/slweb') == -1){
|
|
console.log('WARNING: /slweb was not found in your url. Unless you have changed the URL Base make sure to include this.')
|
|
}
|
|
var PORT = 8088
|
|
if (args['port']){
|
|
PORT = parseInt(args['port'])
|
|
} else {
|
|
console.log('Defaulting to port 8088')
|
|
}
|
|
|
|
var express = require('express');
|
|
var path = require('path');
|
|
var cors = require('cors')
|
|
var jsonfile = require('jsonfile')
|
|
var bodyParser = require('body-parser')
|
|
var file = 'ptinvites.json'
|
|
|
|
|
|
var root = express()
|
|
root.use( bodyParser() )
|
|
// root.use(bodyParser.urlencoded({ extended: true }))
|
|
|
|
// Setup our web app
|
|
root.use('/slweb/', express.static(path.join(__dirname, 'dist')));
|
|
|
|
|
|
// Merge everything together
|
|
|
|
root.get('/slweb/invite/:id', (req,res) => {
|
|
console.log('handling an invite')
|
|
let shortObj = shortenedLinks[req.params.id]
|
|
if (!shortObj){
|
|
return res.send('Invite expired')
|
|
}
|
|
console.log('Redirecting an invite link')
|
|
console.log(JSON.stringify(shortObj, null, 4))
|
|
return res.redirect(shortObj.fullUrl)
|
|
})
|
|
root.post('/slweb/invite', (req, res) => {
|
|
res.setHeader('Content-Type', 'application/json')
|
|
if (!req.body) {
|
|
return res.send({
|
|
success: false,
|
|
msg: 'ERR: You did not send any POST data'
|
|
}).end()
|
|
}
|
|
console.log('Generating Invite URL via the API.')
|
|
let data = {}
|
|
let fields = ['slserver', 'slroom', 'slpassword', 'owner']
|
|
for (let i = 0; i < fields.length; i++) {
|
|
if (!req.body[fields[i]]) {
|
|
return res.send({
|
|
success: false,
|
|
msg: 'ERR: You did not specify ' + fields[i],
|
|
field: fields[i]
|
|
}).end()
|
|
}
|
|
data[fields[i]] = req.body[fields[i]]
|
|
}
|
|
return res.send({
|
|
url: shortenObj(data),
|
|
success: true,
|
|
generatedAt: new Date().getTime(),
|
|
details: data
|
|
}).end()
|
|
|
|
|
|
|
|
})
|
|
root.use('/',express.static(path.join(__dirname, 'dist')))
|
|
|
|
root.get('/ptweb',(req,res) => {
|
|
console.log('ptweb redirect')
|
|
return res.redirect('/slweb')
|
|
})
|
|
|
|
root.get('*',(req, res) => {
|
|
console.log('Catch all', req.url)
|
|
return res.redirect('/slweb')
|
|
})
|
|
|
|
|
|
|
|
root.use(cors())
|
|
|
|
var rootserver = require('http').createServer(root);
|
|
|
|
var webapp_io = require('socket.io')(rootserver, { path: '/slweb/socket.io'} )
|
|
|
|
function getUniqueId(){
|
|
while (true){
|
|
let testId = (0|Math.random()*9e6).toString(36)
|
|
if (!shortenedLinks[testId]){ // Check if we already have a shortURL using that id
|
|
return testId
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
function shortenObj(data){
|
|
let returnable = {}
|
|
returnable.urlOrigin = accessIp
|
|
returnable.owner = data.owner
|
|
|
|
returnable.slserver = data.slserver
|
|
returnable.slroom = data.slroom
|
|
returnable.slpassword = data.slpassword
|
|
|
|
returnable.starttime = (new Date).getTime()
|
|
returnable.id = getUniqueId()
|
|
returnable.shortUrl = accessIp + '/invite/' + returnable.id
|
|
|
|
let params = {
|
|
slserver: data.slserver,
|
|
slroom: data.slroom,
|
|
owner: data.owner
|
|
}
|
|
if (data.slpassword){
|
|
params.slpassword = data.slpassword
|
|
}
|
|
let query = ''
|
|
for (let key in params) {
|
|
query += encodeURIComponent(key) + '=' + encodeURIComponent(params[key]) + '&';
|
|
}
|
|
returnable.fullUrl = accessIp + '/#/join?' + query
|
|
|
|
shortenedLinks[returnable.id] = returnable
|
|
saveToFile(shortenedLinks, () => {})
|
|
return returnable.shortUrl
|
|
}
|
|
|
|
webapp_io.on('connection', (socket) => {
|
|
console.log('New connection to the webapp socket')
|
|
socket.on('shorten',(data) => {
|
|
console.log('Creating a shortened link')
|
|
socket.emit('shorten-result', shortenObj(data))
|
|
})
|
|
})
|
|
|
|
function saveToFile(content,callback){
|
|
jsonfile.writeFile(file, content, (err) => {
|
|
return callback(err)
|
|
})
|
|
}
|
|
|
|
function loadFromFile(callback){
|
|
jsonfile.readFile(file, (err, obj) => {
|
|
if (err || !obj){
|
|
// File doesn't exist or an error occured
|
|
return callback({})
|
|
} else {
|
|
return callback(obj)
|
|
}
|
|
})
|
|
}
|
|
|
|
function killOldInvites(){
|
|
let now = (new Date).getTime()
|
|
loadFromFile((data) => {
|
|
if (!data){
|
|
return
|
|
}
|
|
console.log('Deleting invites over 1 month old..')
|
|
let oldSize = Object.keys(data).length
|
|
for (let key in data){
|
|
let invite = data[key]
|
|
if (Math.abs(invite.starttime - now) > 2629746000){
|
|
delete data[key]
|
|
}
|
|
}
|
|
console.log('Deleted ' + Math.abs(oldSize - Object.keys(data).length) + ' old invites')
|
|
saveToFile(data,()=>{})
|
|
})
|
|
}
|
|
killOldInvites()
|
|
|
|
|
|
var shortenedLinks = {}
|
|
loadFromFile((result) => {
|
|
shortenedLinks = result
|
|
// const cluster = require('cluster');
|
|
// const http = require('http');
|
|
// const numCPUs = require('os').cpus().length;
|
|
|
|
// if (cluster.isMaster) {
|
|
// // Fork workers.
|
|
// setInterval(() => {
|
|
// if (cluster.isMaster) {
|
|
// killOldInvites()
|
|
// }
|
|
// }, 3600000)
|
|
// for (let i = 0; i < numCPUs; i++) {
|
|
// cluster.fork();
|
|
// }
|
|
|
|
// cluster.on('exit', (thread, code, signal) => {
|
|
// console.log(`thread ${thread.process.pid} died`, code, signal)
|
|
// });
|
|
// } else {
|
|
// rootserver.listen(PORT)
|
|
// }
|
|
rootserver.listen(PORT)
|
|
})
|
|
|
|
console.log('SyncLounge WebApp successfully started on port ' + PORT)
|
|
|
|
|
|
|
|
|
|
|
|
|