106 lines
No EOL
4.2 KiB
JavaScript
106 lines
No EOL
4.2 KiB
JavaScript
const jwt = require('jsonwebtoken');
|
|
const uaParser = require('ua-parser-js');
|
|
const {geoip} = require('./geoIP');
|
|
const {extractPeerId} = require('./helper');
|
|
|
|
let debug = process.env.debug === "1";
|
|
|
|
const BASE_sessionInfo = {
|
|
"pageTitle": "Page",
|
|
"active": true,
|
|
"live": true,
|
|
"sessionID": "0",
|
|
"metadata": {},
|
|
"userID": "",
|
|
"userUUID": "",
|
|
"projectKey": "",
|
|
"revID": "",
|
|
"timestamp": 0,
|
|
"trackerVersion": "",
|
|
"isSnippet": true,
|
|
"userOs": "",
|
|
"userBrowser": "",
|
|
"userBrowserVersion": "",
|
|
"userDevice": "",
|
|
"userDeviceType": "",
|
|
"userCountry": "",
|
|
"projectId": 0
|
|
};
|
|
|
|
|
|
const extractSessionInfo = function (socket) {
|
|
if (socket.handshake.query.sessionInfo !== undefined) {
|
|
debug && console.log("received headers");
|
|
debug && console.log(socket.handshake.headers);
|
|
socket.handshake.query.sessionInfo = JSON.parse(socket.handshake.query.sessionInfo);
|
|
socket.handshake.query.sessionInfo = {...BASE_sessionInfo, ...socket.handshake.query.sessionInfo};
|
|
|
|
let ua = uaParser(socket.handshake.headers['user-agent']);
|
|
socket.handshake.query.sessionInfo.userOs = ua.os.name || null;
|
|
socket.handshake.query.sessionInfo.userBrowser = ua.browser.name || null;
|
|
socket.handshake.query.sessionInfo.userBrowserVersion = ua.browser.version || null;
|
|
socket.handshake.query.sessionInfo.userDevice = ua.device.model || null;
|
|
socket.handshake.query.sessionInfo.userDeviceType = ua.device.type || 'desktop';
|
|
socket.handshake.query.sessionInfo.userCountry = null;
|
|
if (geoip() !== null) {
|
|
debug && console.log(`looking for location of ${socket.handshake.headers['x-forwarded-for'] || socket.handshake.address}`);
|
|
try {
|
|
let ip = socket.handshake.headers['x-forwarded-for'] || socket.handshake.address;
|
|
ip = ip.split(",")[0];
|
|
let country = geoip().country(ip);
|
|
socket.handshake.query.sessionInfo.userCountry = country.country.isoCode;
|
|
} catch (e) {
|
|
debug && console.log("geoip-country failed");
|
|
debug && console.log(e);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
function generateAccessToken(payload) {
|
|
return jwt.sign(payload, process.env.ASSIST_JWT_SECRET, {expiresIn: process.env.ASSIST_JWT_EXPIRATION || '30m'});
|
|
}
|
|
|
|
const JWT_TOKEN_PREFIX = "Bearer ";
|
|
|
|
function check(socket, next) {
|
|
if (socket.handshake.query.identity === 'session') {
|
|
return next();
|
|
}
|
|
if (socket.handshake.query.peerId && socket.handshake.auth && socket.handshake.auth.token) {
|
|
let token = socket.handshake.auth.token;
|
|
if (token.startsWith(JWT_TOKEN_PREFIX)) {
|
|
token = token.substring(JWT_TOKEN_PREFIX.length);
|
|
}
|
|
jwt.verify(token, process.env.ASSIST_JWT_SECRET, (err, decoded) => {
|
|
debug && console.log("JWT payload:");
|
|
debug && console.log(decoded);
|
|
if (err) {
|
|
debug && console.error(err);
|
|
return next(new Error('Authentication error'));
|
|
}
|
|
const {projectKey, sessionId} = extractPeerId(socket.handshake.query.peerId);
|
|
if (!projectKey || !sessionId) {
|
|
debug && console.error("Missing attribute:");
|
|
debug && console.error(`projectKey:${projectKey}, sessionId:${sessionId}`);
|
|
return next(new Error('Authentication error'));
|
|
}
|
|
if (String(projectKey) !== String(decoded.projectKey) || String(sessionId) !== String(decoded.sessionId)) {
|
|
debug && console.error(`Trying to access projectKey:${projectKey} instead of ${decoded.projectKey}\nor`);
|
|
debug && console.error(`Trying to access sessionId:${sessionId} instead of ${decoded.sessionId}`);
|
|
return next(new Error('Authorization error'));
|
|
}
|
|
socket.decoded = decoded;
|
|
return next();
|
|
});
|
|
} else {
|
|
debug && console.error("something missing in:");
|
|
debug && console.error(socket.handshake);
|
|
return next(new Error('Authentication error'));
|
|
}
|
|
}
|
|
|
|
module.exports = {
|
|
extractSessionInfo,
|
|
authorizer: {generateAccessToken, check}
|
|
}; |