parent
7aba6aa58e
commit
074e186b0e
@ -0,0 +1,813 @@
|
||||
const mysql = require('mysql')
|
||||
const Spawner = require('child_process');
|
||||
const crypto = require('crypto');
|
||||
const request = require('request');
|
||||
const cheerio = require('cheerio');
|
||||
|
||||
|
||||
class Child
|
||||
{
|
||||
/**
|
||||
*
|
||||
* @param {String} userID -User's Hash
|
||||
*/
|
||||
constructor(userID)
|
||||
{
|
||||
this.ID = userID;
|
||||
this.child = Spawner.fork('./worker.js',[this.ID]);
|
||||
this.birth = process.uptime();
|
||||
this.timeOut = setTimeout(() => {
|
||||
this.child.kill('SIGINT');
|
||||
},2*60*60*1000);
|
||||
}
|
||||
get EOL()
|
||||
{
|
||||
const EOL = Math.trunc((this.timeOut._idleTimeout - ((process.uptime()*1000)-this.birth))/1000);
|
||||
return EOL>0?EOL:0;
|
||||
}
|
||||
getMapData()
|
||||
{
|
||||
return new Promise((resolve, reject)=>
|
||||
{
|
||||
this.child.send('MapData');
|
||||
this.child.on('message', m=>
|
||||
{
|
||||
if(typeof m == Object)
|
||||
{
|
||||
resolve(m.name);
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
waitStart()
|
||||
{
|
||||
return new Promise((resolve, reject)=>
|
||||
{
|
||||
var status = setInterval(() => {
|
||||
if(this.isOpen)
|
||||
{
|
||||
clearInterval(status);
|
||||
resolve(true)
|
||||
}
|
||||
}, 100);
|
||||
})
|
||||
}
|
||||
createMapImage()
|
||||
{
|
||||
return new Promise((resolve, reject)=>
|
||||
{
|
||||
this.child.send('MapImage')
|
||||
this.child.on('message', m=>
|
||||
{
|
||||
if(typeof m == String && m === 'Done')
|
||||
{
|
||||
resolve(m);
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
getConsole()
|
||||
{
|
||||
return new Promise((resolve, reject)=>
|
||||
{
|
||||
this.child.send('Console')
|
||||
this.child.on('message', m=>
|
||||
{
|
||||
resolve(m);
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
}module.exports.Child = Child;
|
||||
|
||||
|
||||
class playerCache
|
||||
{
|
||||
/**
|
||||
*
|
||||
* @param {String} Name
|
||||
* @param {String} SteamID
|
||||
* @param {Number} Ping
|
||||
* @param {String} Address IP
|
||||
* @param {Number} ConnectedSeconds
|
||||
* @param {Number} Health
|
||||
* @param {Object} Teammates ??'Not in a team'
|
||||
* @param {String} Position ??'Not spawned yet'
|
||||
*/
|
||||
constructor(Name, SteamID, Ping, Address,ConnectedSeconds, Health, Teammates, Position)
|
||||
{
|
||||
this.Displayname = Name;
|
||||
this.SteamID = SteamID;
|
||||
this.Address = Address;
|
||||
this.Health = Health;
|
||||
this.Teammates = Teammates??'NOT IN A TEAM';
|
||||
this.Position = Position??'NOT SPAWNED YET';
|
||||
this.Ping = Ping;
|
||||
this.ConnectedSeconds = ConnectedSeconds;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}module.exports.playerCache = playerCache;
|
||||
|
||||
|
||||
class ServerCache
|
||||
{
|
||||
constructor(ID,Hostname,MaxPlayers, GameTime, Framerate, NetworkIn, NetworkOut, Seed, WorldSize)
|
||||
{
|
||||
this.ID = ID;
|
||||
this.Hostname=Hostname;
|
||||
this.MaxPlayers =MaxPlayers;
|
||||
this.GameTime = GameTime;
|
||||
this.Framerate = Framerate;
|
||||
this.NetworkIn = NetworkIn;
|
||||
this.NetworkOut = NetworkOut;
|
||||
this.Seed = Seed;
|
||||
this.WorldSize = WorldSize;
|
||||
this.Console = [];
|
||||
}
|
||||
|
||||
get WorldData ()
|
||||
{
|
||||
return {
|
||||
Seed:this.Seed,
|
||||
Size:this.WorldSize,
|
||||
Time:this.GameTime
|
||||
}
|
||||
}
|
||||
get NetWorkData ()
|
||||
{
|
||||
return {
|
||||
Framerate:this.Framerate,
|
||||
In:this.NetworkIn,
|
||||
Out:this.NetworkIn
|
||||
}
|
||||
}
|
||||
get ConsoleData ()
|
||||
{
|
||||
return this.Console;
|
||||
}
|
||||
get BasicData ()
|
||||
{
|
||||
return {
|
||||
HostName:this.Hostname,
|
||||
MaxPlayers:this.MaxPlayers,
|
||||
GameTime:this.GameTime
|
||||
}
|
||||
}
|
||||
}module.exports.ServerCache = ServerCache;
|
||||
|
||||
|
||||
class pChild
|
||||
{
|
||||
|
||||
constructor(ip, port, pw)
|
||||
{
|
||||
this.ip = ip;
|
||||
this.port = port;
|
||||
this.pw = pw;
|
||||
this.child = Spawner.fork('./pWorker.js');
|
||||
}
|
||||
/**
|
||||
* @argument {*} - Anything
|
||||
*/
|
||||
sendData()
|
||||
{
|
||||
for (var i = 0; i < arguments.length; i++)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* To be used with programmed commands
|
||||
* @param {String} command - Command to be sent
|
||||
*/
|
||||
send(command)
|
||||
{
|
||||
return new Promise((resolve, reject)=>
|
||||
{
|
||||
this.child.send({'command':command, 'ip':this.ip, 'port':this.port, 'pw':this.pw});
|
||||
this.child.on('message', (m)=>
|
||||
{
|
||||
if(typeof m=='string')
|
||||
{
|
||||
if(m ==='end')
|
||||
{
|
||||
resolve();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
reject("Worker didn't respond to querry.")
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
close ()
|
||||
{
|
||||
return new Promise((resolve, reject)=>
|
||||
{
|
||||
resolve(this.child.disconnect());
|
||||
})
|
||||
}
|
||||
|
||||
}module.exports.pChild = pChild;
|
||||
class rustChild
|
||||
{
|
||||
constructor(size, seed)
|
||||
{
|
||||
this.child = Spawner.exec(`cmd /c updateServer.bat ${size} ${seed}`)
|
||||
}
|
||||
}module.exports.rustChild = rustChild;
|
||||
|
||||
|
||||
class DBConnection
|
||||
{
|
||||
constructor()
|
||||
{
|
||||
this.connection = mysql.createConnection(
|
||||
{
|
||||
host:'localhost',
|
||||
user:'root',
|
||||
password:'root',
|
||||
database:'legendary'
|
||||
})
|
||||
this.connection.connect();
|
||||
|
||||
}
|
||||
close()
|
||||
{
|
||||
setTimeout(() =>
|
||||
{
|
||||
this.connection.destroy();
|
||||
}, 2000);
|
||||
}
|
||||
//User
|
||||
get Users()
|
||||
{
|
||||
return new Promise((resolve, reject)=>
|
||||
{
|
||||
this.connection.query('Select * from administrator', (e, r, f)=>
|
||||
{
|
||||
if(!e)
|
||||
{
|
||||
let aux = JSON.parse(JSON.stringify(r))
|
||||
var payload =[];
|
||||
|
||||
for( var i = 0; i<aux.length; i++)
|
||||
{
|
||||
payload.push(aux[i].Hash)
|
||||
}
|
||||
resolve(payload);
|
||||
this.close();
|
||||
}
|
||||
else
|
||||
{
|
||||
reject(e)
|
||||
this.close();
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
hasSVData(Hash)
|
||||
{
|
||||
return new Promise((resolve, reject)=>
|
||||
{
|
||||
this.UData(Hash).then(
|
||||
m=>
|
||||
{
|
||||
|
||||
if(m.Server=='No server')
|
||||
{
|
||||
reject(false)
|
||||
}
|
||||
else
|
||||
{
|
||||
resolve(true)
|
||||
}
|
||||
}
|
||||
)
|
||||
})
|
||||
}
|
||||
UData(HASH)
|
||||
{
|
||||
return new Promise((resolve, reject)=>
|
||||
{
|
||||
this.connection.query(`SELECT * FROM administrator WHERE Hash = '${HASH}' `, (e, r, f)=>
|
||||
{
|
||||
if(e)reject(e);
|
||||
r = JSON.parse(JSON.stringify(r))[0];
|
||||
resolve({
|
||||
id:r.A_ID,
|
||||
Hash:r.Hash,
|
||||
Email:r.EHash,
|
||||
Server:r.IP || 'No server',
|
||||
Port: JSON.stringify(r.Port) || 'No server',
|
||||
SPW:r.sv_pw,
|
||||
Epoch:r.Epoch
|
||||
})
|
||||
this.close();
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
get_ID(hash)
|
||||
{
|
||||
return new Promise((resolve, reject)=>
|
||||
{
|
||||
|
||||
//User
|
||||
this.Users.then((x)=>
|
||||
{
|
||||
for(var i =0; i<x.length; i++)
|
||||
{
|
||||
if(x[i]==hash)
|
||||
{
|
||||
|
||||
this.UData(hash).then((m)=>
|
||||
{
|
||||
resolve(m.id);
|
||||
})
|
||||
.catch(()=>reject('no ID for this hash'))
|
||||
}
|
||||
}
|
||||
}).catch(m=>
|
||||
{
|
||||
console.log(m);
|
||||
reject('no ID for this HASH');
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
getCommands(Hash)
|
||||
{
|
||||
return new Promise((resolve, reject)=>
|
||||
{
|
||||
this.get_ID(Hash).then(id=>
|
||||
{
|
||||
this.connection.query(`Select * from legendary.timed_com where administrator_A_ID = '${id}'`, (e, r, f)=>
|
||||
{
|
||||
if(e)reject(e);
|
||||
resolve(JSON.parse(JSON.stringify(r)));
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
addCommand(Hash, Command, Loop, Send, tz)
|
||||
{
|
||||
this.get_ID(Hash).then(id=>
|
||||
{
|
||||
|
||||
this.connection.query(`INSERT INTO legendary.timed_com (\`Command\`, \`Loop\`, \`Send\`, \`administrator_A_ID\`) VALUES ('${Command}', '${Loop}', '${Send}', '${id}')`);
|
||||
this.close();
|
||||
})
|
||||
}
|
||||
|
||||
removeCommand(id)
|
||||
{
|
||||
return new Promise((resolve, reject)=>
|
||||
{
|
||||
this.connection.query(`DELETE FROM legendary.timed_com WHERE (T_ID = ${id});`, (e, r, f)=>
|
||||
{
|
||||
if(e)reject(e)
|
||||
if(r.affectedRows>0)resolve()
|
||||
})
|
||||
this.close()
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
editCommand(id, Command, Loop, Send, tz)
|
||||
{
|
||||
this.connection.query(`UPDATE legendary.timed_com SET \`Command\` = '${Command}', \`Loop\` = '${Loop}',\`Send\` = '${Send}' WHERE (T_ID = '${id}')`)
|
||||
this.close()
|
||||
}
|
||||
|
||||
addUser(Hash, EHash, Epoch)
|
||||
{
|
||||
if(Hash||EHash||Epoch)
|
||||
{
|
||||
this.connection.query(`INSERT INTO legendary.administrator (Hash, EHash, Epoch) VALUES ('${Hash}', '${EHash}', '${Epoch}')`)
|
||||
this.close()
|
||||
}
|
||||
}
|
||||
|
||||
updateUser(HASH, NewHASH)
|
||||
{
|
||||
return new Promise((resolve, reject)=>
|
||||
{
|
||||
this.get_ID(HASH).then((m)=>
|
||||
{
|
||||
this.connection.query(`UPDATE administrator SET Hash='${NewHASH}' WHERE A_ID = ${m}`);
|
||||
this.close();
|
||||
resolve(NewHASH);
|
||||
}).catch((err)=>reject(err));
|
||||
})
|
||||
}
|
||||
|
||||
addServer(HASH, IP, PW, PORT)
|
||||
{
|
||||
//needs to know what user should it be connected to
|
||||
this.connection.query(`INSERT INTO adminsitrator (ServerIP, ServerPW, ServerPort) VALUES ('${HASH}', '${IP}','${PW}', '${PORT}')`)
|
||||
this.close();
|
||||
}
|
||||
|
||||
updateServer(Hash, IP, PW, PORT)
|
||||
{
|
||||
this.get_ID(Hash).then((id)=>
|
||||
{
|
||||
this.connection.query(`UPDATE administrator SET IP = '${IP}', sv_pw = '${PW}', port='${PORT}' WHERE A_ID = ${id}`);
|
||||
this.close();
|
||||
}).catch(e=>console.log('error',e))
|
||||
}
|
||||
get_Players(Hash)
|
||||
{
|
||||
return new Promise((resolve, reject)=>
|
||||
{
|
||||
this.connection.query(`SELECT * FROM player INNER JOIN time ON player.p_id = time.player_p_id
|
||||
where administrator_a_id = (SELECT A_ID FROM administrator WHERE Hash = '${Hash}')
|
||||
order by player_p_id asc;`,(e,r,f)=>
|
||||
{
|
||||
if(e)reject(e);this.close;
|
||||
try
|
||||
{
|
||||
// console.log('Classes: DBConnection: Get_Players: r: ', r);
|
||||
r = JSON.parse(JSON.stringify(r));
|
||||
resolve(r)
|
||||
|
||||
} catch (err)
|
||||
{
|
||||
reject(err)
|
||||
}
|
||||
this.close;
|
||||
})
|
||||
})
|
||||
}
|
||||
}module.exports.DBConnection = DBConnection;
|
||||
|
||||
class _Crypto
|
||||
{
|
||||
constructor(User, Password)
|
||||
{
|
||||
this.salt = 'H$44Q3RVCd9X8Ef63tB4';
|
||||
this.secret = 'mYFUZX9NSx7K74r7Jh@O';
|
||||
this.pepper = String.fromCharCode(this.getRandomInt(65, 90));
|
||||
this.password = Password;
|
||||
this.user = User;
|
||||
this.algorithm = 'aes-192-cbc';
|
||||
|
||||
}
|
||||
get Hash() // to use on register
|
||||
{
|
||||
return this.hash()
|
||||
}
|
||||
hash(p)
|
||||
{
|
||||
if(!p)
|
||||
{
|
||||
return crypto.createHmac('sha256', this.secret).update(this.user+this.password+this.salt+this.pepper).digest('hex');
|
||||
}
|
||||
else
|
||||
{
|
||||
return crypto.createHmac('sha256', this.secret).update(this.user+this.password+this.salt+p).digest('hex');
|
||||
}
|
||||
}
|
||||
eHash(Email)
|
||||
{
|
||||
return new Buffer.from(Email).toString('base64');
|
||||
}
|
||||
|
||||
decrypt(eHash)
|
||||
{
|
||||
return new Buffer.from(eHash, 'base64').toString('utf8');
|
||||
}
|
||||
getRandomInt(min, max)
|
||||
{
|
||||
min = Math.ceil(min);
|
||||
max = Math.floor(max);
|
||||
return Math.floor(Math.random() * (max - min)) + min;
|
||||
}
|
||||
compare() // to use on login
|
||||
{
|
||||
return new Promise((resolve, reject)=>
|
||||
{
|
||||
new DBConnection().Users
|
||||
.then((Users)=>
|
||||
{
|
||||
for(var i=0; i<26;i++)
|
||||
{
|
||||
const nPepper = String.fromCharCode(65+i);
|
||||
const hash = this.hash(nPepper);
|
||||
for(var j = 0; j<Users.length; j++)
|
||||
{
|
||||
if(Users[j]==hash) resolve(hash);
|
||||
}
|
||||
}
|
||||
reject(false);
|
||||
})
|
||||
.catch((m)=>
|
||||
{
|
||||
console.log('error'+m);
|
||||
})
|
||||
|
||||
});
|
||||
}
|
||||
}module.exports._Crypto = _Crypto;
|
||||
|
||||
|
||||
class Epoch
|
||||
{
|
||||
/**
|
||||
*
|
||||
* @param {Number} Days - Must be and integer.
|
||||
*/
|
||||
constructor(Days)
|
||||
{
|
||||
this.Days = (Days*(24*60*60));
|
||||
this.epoch = this.epocher();
|
||||
}
|
||||
epocher()
|
||||
{
|
||||
return Math.floor(this.Days + Date.now()/1000)
|
||||
}
|
||||
/**
|
||||
* @param {String} time - Must follow the format of '18:12'.
|
||||
*/
|
||||
sEpoch(time)
|
||||
{
|
||||
let hours = time.split(':')[0];
|
||||
let minutes = time.split(':')[1];
|
||||
return Math.floor(this.next(hours, minutes)/1000);
|
||||
}
|
||||
/**
|
||||
* @param {Number} time - Must be and integer.
|
||||
*/
|
||||
toDate(time)
|
||||
{
|
||||
//console.log('classes:toDate:', time)
|
||||
const d = new Date(time*1000);
|
||||
return d.getHours()+':'+ d.getMinutes();
|
||||
}
|
||||
/**
|
||||
* Returns the next possible time for the command to be sent. Meaning if the hours inputed by the user
|
||||
* have already gone past this day then the epoch will be set for the next.
|
||||
* If not the epoch will be created like usual.
|
||||
*
|
||||
* @param {Number} hours
|
||||
* @param {Number} minutes
|
||||
*/
|
||||
next(hours, minutes)
|
||||
{
|
||||
var d= new Date();
|
||||
var payload = new Date(d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDate(), hours, minutes, 0, 0).getTime();
|
||||
//console.log('Classes:Next:',hours, minutes, payload)
|
||||
return payload;
|
||||
}
|
||||
}module.exports.Epoch = Epoch;
|
||||
|
||||
class IPTranslator
|
||||
{
|
||||
constructor(IP)
|
||||
{
|
||||
this.IP = IP;
|
||||
}
|
||||
translate()
|
||||
{
|
||||
return new Promise((resolve, reject)=>
|
||||
{
|
||||
request(`http://ip-api.com/json/${this.IP}`, (e,r,b)=>
|
||||
{
|
||||
var body
|
||||
if(!e)
|
||||
{
|
||||
try {
|
||||
body = JSON.parse(b);
|
||||
} catch (error) {
|
||||
console.log('IP Transalator: Bad Parse.');
|
||||
resolve('Err')
|
||||
}
|
||||
resolve(body);
|
||||
}
|
||||
else
|
||||
{
|
||||
resolve( {'status':'error'});
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
CC()
|
||||
{
|
||||
return new Promise((resolve, reject)=>
|
||||
{
|
||||
this.translate().then(m=>resolve(m.countryCode)).catch(e=>
|
||||
{
|
||||
console.log('IP Translator: CountryCode:'+e);
|
||||
reject(e);
|
||||
})
|
||||
})
|
||||
}
|
||||
}module.exports.IPTranslator = IPTranslator;
|
||||
|
||||
class VAC
|
||||
{
|
||||
constructor(SteamID)
|
||||
{
|
||||
this.SteamID = SteamID;
|
||||
}
|
||||
get ban()
|
||||
{
|
||||
return new Promise((resolve,reject)=>
|
||||
{
|
||||
request(`http://vacbanned.com/engine/check?qsearch=${this.SteamID}`, (e,r,b)=>
|
||||
{
|
||||
if(e)reject('VAC: Request:'+e)
|
||||
const $ = cheerio.load(b);
|
||||
// console.log('Worker: VAC: body: ', $('td').text());
|
||||
$('.strong').remove()
|
||||
request(`http://api.steampowered.com/IPlayerService/GetOwnedGames/v0001/?key=DCA47FAA9F3D1485FA8C1F4FA15A5266&steamid=${this.SteamID}&format=json`, (e,r,steamb)=>
|
||||
{
|
||||
if(e)reject('VAC: FS: Request:'+e)
|
||||
var fs;
|
||||
let aux
|
||||
//console.log('Vac class: SteamAPI', steamb)
|
||||
try
|
||||
{
|
||||
aux = JSON.parse(steamb)['response'].games;
|
||||
} catch (error)
|
||||
{
|
||||
console.log('JSON parse error: ',error);
|
||||
}
|
||||
if(aux)
|
||||
{
|
||||
for (let i = 0; i < aux.length; i++)
|
||||
{
|
||||
// console.log('VAC: FS: Request2: '+aux[i].appid, '252490');
|
||||
if(aux[i].appid)
|
||||
{
|
||||
if(aux[i].appid=='252490')
|
||||
{
|
||||
i = aux.length;
|
||||
fs = 'NO'
|
||||
}
|
||||
else
|
||||
{
|
||||
fs='Yes'
|
||||
}
|
||||
}
|
||||
}
|
||||
var vac;
|
||||
try {
|
||||
vac = $('td').text().replace(/ /g, '').split('Hex)')[1].replace(/\n/g, 'SPLIT').split('SPLIT')[1];
|
||||
} catch (error) {
|
||||
vac = 'Error';
|
||||
}
|
||||
let payload = {
|
||||
'vac':vac,
|
||||
'fs':fs
|
||||
}
|
||||
|
||||
// console.log('VAC: Payload: ', payload)
|
||||
resolve(payload);
|
||||
}
|
||||
else
|
||||
{
|
||||
var vac;
|
||||
try {
|
||||
vac = $('td').text().replace(/ /g, '').split('Hex)')[1].replace(/\n/g, 'SPLIT').split('SPLIT')[1];
|
||||
} catch (error) {
|
||||
vac = 'Error';
|
||||
}
|
||||
let payload = {
|
||||
'vac':vac,
|
||||
'fs':fs
|
||||
}
|
||||
resolve(payload);
|
||||
}
|
||||
})
|
||||
});
|
||||
})
|
||||
}
|
||||
}module.exports.VAC = VAC;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Use it to transform an hour value into miliseconds.
|
||||
* @param {Number} Hours - Hours to transform
|
||||
*/
|
||||
function hours(Hours)
|
||||
{
|
||||
return Hours*60*60*1000;
|
||||
}
|
||||
/**
|
||||
* This function writes a cookie on the client side.
|
||||
* Primary use: Store users Hash for every other page.
|
||||
* @argument {Response} res - Response: express response object.
|
||||
* @argument {String} name - Name of the cookie.
|
||||
* @argument {*} value - Value of the cookie.
|
||||
*/
|
||||
exports.baker = (res, name, value) =>
|
||||
{
|
||||
return new Promise((resolve,reject)=>
|
||||
{
|
||||
try
|
||||
{
|
||||
res.cookie(name, '',{maxAge:0});
|
||||
res.cookie(name, value, {maxAge:hours(2),path:'/',secure:false,httpOnly:false});
|
||||
resolve();
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
reject(e)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Hash used on register to check if there is already a user with the same credentials.
|
||||
* @param {String} user - User's email
|
||||
* @param {String} password - User's Password
|
||||
* @param {String} hash - User's identifying hash
|
||||
*/
|
||||
exports.bouncer = (user, password, hash) =>
|
||||
{
|
||||
return new Promise((resolve, reject)=>
|
||||
{
|
||||
new _Crypto(user, password).compare().then(m=>
|
||||
{
|
||||
if(hash)
|
||||
{
|
||||
if(m==hash)
|
||||
{
|
||||
resolve(m)
|
||||
}
|
||||
else
|
||||
{
|
||||
reject('You are on a different account.')
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
resolve(m)
|
||||
}
|
||||
}).catch(m=>
|
||||
{
|
||||
reject(m)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Reduces the number of decimal cases to the required value.
|
||||
|
||||
* @param {Number} num - The number you want to cut to size.
|
||||
* @param {Number} decimal - Ammount of decimal cases.
|
||||
*/
|
||||
exports.toFixed = (num, decimal)=>
|
||||
{
|
||||
decimal = decimal || 0;
|
||||
decimal = Math.pow(10, decimal);
|
||||
return Math.floor(num * decimal) / decimal;
|
||||
}
|
||||
/**
|
||||
* Transforms a value into a 0-1 value given the max value it could take.
|
||||
* @param {Number} val - Value to transform to percentage
|
||||
* @param {Number} max - Maximum the value could be
|
||||
*/
|
||||
exports.toPercent = (val, max)=>
|
||||
{
|
||||
return val/max;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the timezone difference to a time.
|
||||
* @param {String} time - Must follow 'HH:MM' format.
|
||||
* @param {Number} offSet - Number of minutes from gmt+0.
|
||||
*/
|
||||
exports.removeTZ = (time, offSet)=>
|
||||
{
|
||||
var h = parseInt(time.split(':')[0]);
|
||||
var maux = parseInt(time.split(':')[1]);
|
||||
var m = maux - offSet;
|
||||
var d = new Date();
|
||||
var payload = new Date(d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDate(), h, m, 0, 0).toString().split(' ')[4].split(' ')[0].slice(0,-3);
|
||||
return payload;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds timezone difference to a time.
|
||||
* @param {String} time - Must follow 'HH:MM' format.
|
||||
* @param {Number} offset - Number of minutes from gmt+0.
|
||||
*/
|
||||
exports.addTZ = (time, offset) =>
|
||||
{
|
||||
offset = parseInt(offset);
|
||||
let h = parseInt(time.split(':')[0]);
|
||||
let m = parseInt(time.split(':')[1])+offset;
|
||||
var d= new Date();
|
||||
return payload = new Date(d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDay(), h, m, 0, 0).toString().split(' ')[4].split(' ')[0].slice(0,-3);
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
.App {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.App-logo {
|
||||
height: 40vmin;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: no-preference) {
|
||||
.App-logo {
|
||||
animation: App-logo-spin infinite 20s linear;
|
||||
}
|
||||
}
|
||||
|
||||
.App-header {
|
||||
background-color: #282c34;
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: calc(10px + 2vmin);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.App-link {
|
||||
color: #61dafb;
|
||||
}
|
||||
|
||||
@keyframes App-logo-spin {
|
||||
from {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
import logo from './logo.svg';
|
||||
import './App.css';
|
||||
|
||||
function App() {
|
||||
return (
|
||||
<div className="App">
|
||||
<header className="App-header">
|
||||
<img src={logo} className="App-logo" alt="logo" />
|
||||
<p>
|
||||
Edit <code>src/App.js</code> and save to reload.
|
||||
</p>
|
||||
<a
|
||||
className="App-link"
|
||||
href="https://reactjs.org"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
Learn React
|
||||
</a>
|
||||
</header>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default App;
|
@ -1,8 +0,0 @@
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import App from './App';
|
||||
|
||||
test('renders learn react link', () => {
|
||||
render(<App />);
|
||||
const linkElement = screen.getByText(/learn react/i);
|
||||
expect(linkElement).toBeInTheDocument();
|
||||
});
|
@ -0,0 +1,43 @@
|
||||
.Frame
|
||||
{
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
position: fixed;
|
||||
left:0%;
|
||||
width: 100%;
|
||||
height: auto;
|
||||
-webkit-user-select: none;
|
||||
gap: 1px;
|
||||
|
||||
|
||||
}
|
||||
.Title
|
||||
{
|
||||
border: 1px solid rgba(240, 248, 255, 0);
|
||||
width: 100%;
|
||||
-webkit-app-region: drag;
|
||||
color:ivory;
|
||||
font-weight: bold;
|
||||
font-family:Verdana, Geneva, Tahoma, sans-serif;
|
||||
font-size: small;
|
||||
padding-left: 1em;
|
||||
padding-top: 0.25em;
|
||||
|
||||
}
|
||||
.btControl
|
||||
{
|
||||
background-color: rgb(22, 27, 28);
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
border: 1px solid black;
|
||||
cursor: pointer;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
color:ivory;
|
||||
}
|
||||
|
||||
span {
|
||||
position: relative;
|
||||
top:-23%;
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
.container
|
||||
{
|
||||
position: relative;
|
||||
width: 14em;
|
||||
top: 15em;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-evenly;
|
||||
align-items: stretch;
|
||||
text-align: center;
|
||||
}
|
||||
span
|
||||
{
|
||||
font-weight: bold;
|
||||
color:ivory;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.bt
|
||||
{
|
||||
width: auto;
|
||||
height: 2em;
|
||||
background-color: rgba(0, 0, 0, 0);
|
||||
border: 1px solid rgba(0, 0, 0, 0);
|
||||
color:ivory;
|
||||
font-weight: bold;
|
||||
cursor: pointer;
|
||||
}
|
||||
.Login
|
||||
{
|
||||
float:left;
|
||||
position: relative;
|
||||
left:2em;
|
||||
}
|
||||
.Register
|
||||
{
|
||||
float:right;
|
||||
position: relative;
|
||||
right: 1em;
|
||||
}
|
@ -1,43 +0,0 @@
|
||||
.Frame
|
||||
{
|
||||
display: flex;
|
||||
position: fixed;
|
||||
right: 0%;
|
||||
}
|
||||
.minimize
|
||||
{
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
border: 1px solid black;
|
||||
cursor: pointer;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
color:ivory;
|
||||
|
||||
}
|
||||
.Maximize
|
||||
{
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
border: 1px solid black;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
color:ivory;
|
||||
|
||||
}
|
||||
.Close
|
||||
{
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
border: 1px solid black;
|
||||
cursor: pointer;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
color:ivory;
|
||||
}
|
||||
span {
|
||||
position: relative;
|
||||
top:-23%;
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
import Login from "../Components/Login";
|
||||
const { cookieSlicer } = require("../lib");
|
||||
|
||||
function Home() {
|
||||
var Hash = cookieSlicer(document.cookie,'Hash');
|
||||
console.log(Hash)
|
||||
return (
|
||||
<div className="BODY">
|
||||
{Hash ? (
|
||||
<h1>Welcome back!</h1>
|
||||
//TODO: Actual Page
|
||||
) : (
|
||||
<Login/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Home;
|
@ -0,0 +1,176 @@
|
||||
import crypto from 'crypto';
|
||||
|
||||
export class _Crypto
|
||||
{
|
||||
constructor(User, Password)
|
||||
{
|
||||
this.salt = 'H$44Q3RVCd9X8Ef63tB4';
|
||||
this.secret = 'mYFUZX9NSx7K74r7Jh@O';
|
||||
this.pepper = String.fromCharCode(this.getRandomInt(65, 90));
|
||||
this.password = Password;
|
||||
this.user = User;
|
||||
this.algorithm = 'aes-192-cbc';
|
||||
|
||||
}
|
||||
get Hash() // to use on register
|
||||
{
|
||||
return this.hash()
|
||||
}
|
||||
hash(p)
|
||||
{
|
||||
|
||||
return crypto.createHmac('sha256', this.secret).update(this.user+this.password+this.salt + (p?p:this.pepper) ).digest('hex');
|
||||
|
||||
}
|
||||
eHash(Email)
|
||||
{
|
||||
return new Buffer.from(Email).toString('base64');
|
||||
}
|
||||
|
||||
decrypt(eHash)
|
||||
{
|
||||
return new Buffer.from(eHash, 'base64').toString('utf8');
|
||||
}
|
||||
getRandomInt(min, max)
|
||||
{
|
||||
min = Math.ceil(min);
|
||||
max = Math.floor(max);
|
||||
return Math.floor(Math.random() * (max - min)) + min;
|
||||
}
|
||||
//TODO: compare(hash)
|
||||
//Get hash from db run through the peper possibilties and see if there is a match.
|
||||
//return hash if true, null if false
|
||||
|
||||
}
|
||||
|
||||
export class Epoch
|
||||
{
|
||||
/**
|
||||
*
|
||||
* @param {Number} Days - Must be and integer.
|
||||
*/
|
||||
constructor(Days)
|
||||
{
|
||||
this.Days = (Days*(24*60*60));
|
||||
this.epoch = this.epocher();
|
||||
}
|
||||
epocher()
|
||||
{
|
||||
return Math.floor(this.Days + Date.now()/1000)
|
||||
}
|
||||
/**
|
||||
* @param {String} time - Must follow the format of '18:12'.
|
||||
*/
|
||||
sEpoch(time)
|
||||
{
|
||||
let hours = time.split(':')[0];
|
||||
let minutes = time.split(':')[1];
|
||||
return Math.floor(this.next(hours, minutes)/1000);
|
||||
}
|
||||
/**
|
||||
* @param {Number} time - Must be and integer.
|
||||
*/
|
||||
toDate(time)
|
||||
{
|
||||
//console.log('classes:toDate:', time)
|
||||
const d = new Date(time*1000);
|
||||
return d.getHours()+':'+ d.getMinutes();
|
||||
}
|
||||
/**
|
||||
* Returns the next possible time for the command to be sent. Meaning if the hours inputed by the user
|
||||
* have already gone past this day then the epoch will be set for the next.
|
||||
* If not the epoch will be created like usual.
|
||||
*
|
||||
* @param {Number} hours
|
||||
* @param {Number} minutes
|
||||
*/
|
||||
next(hours, minutes)
|
||||
{
|
||||
var d= new Date();
|
||||
var payload = new Date(d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDate(), hours, minutes, 0, 0).getTime();
|
||||
//console.log('Classes:Next:',hours, minutes, payload)
|
||||
return payload;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Use it to transform an hour value into miliseconds.
|
||||
* @param {Number} Hours - Hours to transform
|
||||
*/
|
||||
function hours(Hours)
|
||||
{
|
||||
return Hours*60*60*1000;
|
||||
}
|
||||
/**
|
||||
* This function writes a cookie on the client side.
|
||||
* Primary use: Store users Hash for every other page.
|
||||
* @argument {Response} res - Response: express response object.
|
||||
* @argument {String} name - Name of the cookie.
|
||||
* @argument {*} value - Value of the cookie.
|
||||
*/
|
||||
export function baker(res, name, value)
|
||||
{
|
||||
return new Promise((resolve,reject)=>
|
||||
{
|
||||
try
|
||||
{
|
||||
res.cookie(name, '',{maxAge:0});
|
||||
res.cookie(name, value, {maxAge:hours(2),path:'/',secure:false,httpOnly:false});
|
||||
resolve();
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
reject(e)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Hash used on register to check if there is already a user with the same credentials.
|
||||
* @param {String} user - User's email
|
||||
* @param {String} password - User's Password
|
||||
* @param {String} hash - User's identifying hash
|
||||
*/
|
||||
export function bouncer (user, password, hash)
|
||||
{
|
||||
return new Promise((resolve, reject)=>
|
||||
{
|
||||
//!Crypto compare needs to be reworked so this is legacy code not supposed to work
|
||||
// new _Crypto(user, password).compare().then(m=>
|
||||
// {
|
||||
// if(hash)
|
||||
// {
|
||||
// if(m==hash)
|
||||
// {
|
||||
// resolve(m)
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// reject('You are on a different account.')
|
||||
// }
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// resolve(m)
|
||||
// }
|
||||
// }).catch(m=>
|
||||
// {
|
||||
// reject(m)
|
||||
// })
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
export function cookieSlicer(cookie, id)
|
||||
{
|
||||
cookie = cookie.split(';');
|
||||
var result = new Map();
|
||||
for(var item of cookie)
|
||||
{
|
||||
let aux = item.split('=');
|
||||
result.set(aux[0], aux[1]);
|
||||
}
|
||||
return id?result.get(id):result;
|
||||
}
|
Before Width: | Height: | Size: 2.6 KiB |
Loading…
Reference in new issue