mirror of
https://github.com/jambonz/jambonz-api-server.git
synced 2026-07-05 03:31:56 +00:00
ed51d8b13f
major merge of features from the hosted branch that was created temporarily during the initial launch of jambonz.org
104 lines
3.4 KiB
JavaScript
104 lines
3.4 KiB
JavaScript
const Strategy = require('passport-http-bearer').Strategy;
|
|
const {getMysqlConnection} = require('../db');
|
|
const {hashString} = require('../utils/password-utils');
|
|
const debug = require('debug')('jambonz:api-server');
|
|
const jwt = require('jsonwebtoken');
|
|
const sql = `
|
|
SELECT *
|
|
FROM api_keys
|
|
WHERE api_keys.token = ?`;
|
|
|
|
function makeStrategy(logger, retrieveKey) {
|
|
return new Strategy(
|
|
async function(token, done) {
|
|
logger.debug(`validating with token ${token}`);
|
|
jwt.verify(token, process.env.JWT_SECRET, async(err, decoded) => {
|
|
if (err) {
|
|
if (err.name === 'TokenExpiredError') {
|
|
logger.debug('jwt expired');
|
|
return done(null, false);
|
|
}
|
|
/* its not a jwt obtained through login, check api leys */
|
|
checkApiTokens(logger, token, done);
|
|
}
|
|
else {
|
|
/* validated -- make sure it is not on blacklist */
|
|
try {
|
|
const s = `jwt:${hashString(token)}`;
|
|
const result = await retrieveKey(s);
|
|
if (result) {
|
|
debug(`result from searching for ${s}: ${result}`);
|
|
logger.info('jwt invalidated after logout');
|
|
return done(null, false);
|
|
}
|
|
} catch (err) {
|
|
debug(err);
|
|
logger.info({err}, 'Error checking blacklist for jwt');
|
|
}
|
|
const {user_sid, account_sid, email, name} = decoded;
|
|
//logger.debug({user_sid, account_sid}, 'successfully validated jwt');
|
|
const scope = ['account'];
|
|
const user = {
|
|
account_sid,
|
|
user_sid,
|
|
jwt: token,
|
|
email,
|
|
name,
|
|
hasScope: (s) => s === 'account',
|
|
hasAdminAuth: false,
|
|
hasServiceProviderAuth: false,
|
|
hasAccountAuth: true
|
|
};
|
|
return done(null, user, {scope});
|
|
}
|
|
});
|
|
}
|
|
);
|
|
}
|
|
|
|
const checkApiTokens = (logger, token, done) => {
|
|
getMysqlConnection((err, conn) => {
|
|
if (err) {
|
|
logger.error(err, 'Error retrieving mysql connection');
|
|
return done(err);
|
|
}
|
|
conn.query(sql, [token], (err, results, fields) => {
|
|
conn.release();
|
|
if (err) {
|
|
logger.error(err, 'Error querying for api key');
|
|
return done(err);
|
|
}
|
|
if (0 == results.length) return done(null, false);
|
|
if (results.length > 1) {
|
|
logger.info(`api key ${token} exists in multiple rows of api_keys table!!`);
|
|
return done(null, false);
|
|
}
|
|
|
|
// found api key
|
|
const scope = [];
|
|
if (results[0].account_sid === null && results[0].service_provider_sid === null) {
|
|
scope.push.apply(scope, ['admin', 'service_provider', 'account']);
|
|
}
|
|
else if (results[0].service_provider_sid) {
|
|
scope.push.apply(scope, ['service_provider', 'account']);
|
|
}
|
|
else {
|
|
scope.push('account');
|
|
}
|
|
|
|
const user = {
|
|
account_sid: results[0].account_sid,
|
|
service_provider_sid: results[0].service_provider_sid,
|
|
hasScope: (s) => scope.includes(s),
|
|
hasAdminAuth: scope.length === 3,
|
|
hasServiceProviderAuth: scope.includes('service_provider'),
|
|
hasAccountAuth: scope.includes('account') && !scope.includes('service_provider')
|
|
};
|
|
logger.info(user, `successfully validated with scope ${scope}`);
|
|
return done(null, user, {scope});
|
|
});
|
|
});
|
|
};
|
|
|
|
module.exports = makeStrategy;
|