const jsonwebtoken = require('jsonwebtoken') const fs = require('fs') const IncomingMessage = require('http').IncomingMessage const url = require('url') const query = require('querystring') const SERVER_HMAC = (process.env['WSS_HMAC']) ? fs.readFileSync(process.env['WSS_HMAC']) : fs.readFileSync('./wss-hmac.secret') const USER_HMAC = (process.env['HMAC']) ? fs.readFileSync(process.env['HMAC']) : fs.readFileSync('./hmac.secret') exports.verify = function(token) { /** * @param {String} token * @returns 'user' on user connection * @returns 'server' on server connection * @retusn false on failure */ const vconfig = { clockTolerance: 3, } try { const decoded = jsonwebtoken.verify(token, USER_HMAC, vconfig); return 'user' } catch (err) { try { const decoded = jsonwebtoken.verify(token, SERVER_HMAC, {ignoreNotBefore: true}) return 'server' } catch (err) { return false } } } /** * @param {IncomingMessage} req */ exports.prepare_auth = function(req) { // NOTE: Why? because setting headers from the server is completely undocumented and I've ran // through basically every library under the sun I literally con't be fucked to // read people's code for a feature that could have a fucking tweet as documentation // Typical User connections are setup with authentication in the headers // Requested channel is the path const full = url.parse(req.url) const path = full.pathname const jwt = query.parse(full.query)['jwt'] if(!path || !jwt) { return [null, null] } else { return [jwt, path] } }