UNPKG

swagger-stats

Version:

API Telemetry and APM. Trace API calls and Monitor API performance, health and usage statistics in Node.js Microservices, based on express routes and Swagger (Open API) specification

133 lines (114 loc) 4.41 kB
const swsSettings = require('./swssettings'); const debug = require('debug')('sws:auth'); const basicAuth = require("basic-auth"); const Cookies = require('cookies'); const { v1: uuidv1 } = require('uuid'); /* Authentication */ class SwsAuth { constructor() { this.sessionIDs = {}; this.expireIntervalId = null; } storeSessionID(sid){ let tsSec = Date.now() + swsSettings.sessionMaxAge*1000; this.sessionIDs[sid] = tsSec; //debug('Session ID updated: %s=%d', sid,tssec); if( !this.expireIntervalId ){ this.expireIntervalId = setInterval(() => {this.expireSessionIDs();},500); } } removeSessionID(sid){ delete this.sessionIDs[sid]; } // If authentication is enabled, executed periodically and expires old session IDs expireSessionIDs(){ let tssec = Date.now(); let expired = []; for(let sid in this.sessionIDs){ if(this.sessionIDs[sid] < (tssec + 500)){ expired.push(sid); } } for(let i=0;i<expired.length;i++){ delete this.sessionIDs[expired[i]]; debug('Session ID expired: %s', expired[i]); } } async processAuth(req,res) { if( !swsSettings.authentication ){ return true; } if( swsSettings.customAuth ){ return swsSettings.customAuth(req); } let cookies = new Cookies( req, res ); // Check session cookie let sessionIdCookie = cookies.get('sws-session-id'); if( (sessionIdCookie !== undefined) && (sessionIdCookie !== null) ){ if( sessionIdCookie in this.sessionIDs ){ // renew it //sessionIDs[sessionIdCookie] = Date.now(); this.storeSessionID(sessionIdCookie); cookies.set('sws-session-id',sessionIdCookie,{path:swsSettings.basePath+swsSettings.uriPath,maxAge:swsSettings.sessionMaxAge*1000}); // Ok req['sws-auth'] = true; return true; } } let authInfo = basicAuth(req); let authenticated = false; let msg = 'Authentication required'; if( (authInfo !== undefined) && (authInfo!==null) && ('name' in authInfo) && ('pass' in authInfo)){ if(typeof swsSettings.onAuthenticate === 'function'){ let onAuthResult = null; try{ onAuthResult = await swsSettings.onAuthenticate(req, authInfo.name, authInfo.pass); }catch (e){ msg = `Authentication error: ${e.message}`; res.statusCode = 403; res.end(msg); return false; } if( onAuthResult ){ authenticated = true; // Session is only for stats requests if(req.url.startsWith(swsSettings.pathStats)){ // Generate session id let sessid = uuidv1(); this.storeSessionID(sessid); // Set session cookie with expiration in 15 min cookies.set('sws-session-id',sessid,{path:swsSettings.basePath+swsSettings.uriPath,maxAge:swsSettings.sessionMaxAge*1000}); } req['sws-auth'] = true; return true; } else { res.statusCode = 403; res.end(msg); return false; } }else{ res.statusCode = 403; res.end(msg); return false; } }else{ res.statusCode = 403; res.end(msg); return false; } } processLogout(req,res){ let cookies = new Cookies( req, res ); let sessionIdCookie = cookies.get('sws-session-id'); if( (sessionIdCookie !== undefined) && (sessionIdCookie !== null) ){ if( sessionIdCookie in this.sessionIDs ){ this.removeSessionID(sessionIdCookie); cookies.set('sws-session-id'); // deletes cookie } } res.statusCode = 200; res.end('Logged out'); } } let swsAuth = new SwsAuth(); module.exports = swsAuth;