41103000d2
refs https://github.com/TryGhost/Toolbox/issues/292 - Allows to detect and extract admin api key ID value. The reason why we are not dealing withe the "secret" value here in a similar way as Content API key is to keep the package independent from the model layer. It only provides "identification" information along with the key type so that the version mismatch data service can deal with this information in an optimal way (just one db query).
58 lines
1.3 KiB
JavaScript
58 lines
1.3 KiB
JavaScript
const jwt = require('jsonwebtoken');
|
|
|
|
/**
|
|
* Remove 'Ghost' from raw authorization header and extract the JWT token.
|
|
* Eg. Authorization: Ghost ${JWT}
|
|
* @param {string} header
|
|
*/
|
|
const extractTokenFromHeader = (header) => {
|
|
const [scheme, token] = header.split(' ');
|
|
|
|
if (/^Ghost$/i.test(scheme)) {
|
|
return token;
|
|
}
|
|
};
|
|
|
|
const extractAdminAPIKey = (token) => {
|
|
const decoded = jwt.decode(token, {complete: true});
|
|
|
|
if (!decoded || !decoded.header || !decoded.header.kid) {
|
|
return null;
|
|
}
|
|
|
|
return decoded.header.kid;
|
|
};
|
|
|
|
/**
|
|
* @typedef {object} ApiKey
|
|
* @prop {string} key
|
|
* @prop {string} type
|
|
*/
|
|
|
|
/**
|
|
* When it's a Content API the function resolves with the value of the key secret.
|
|
* When it's an Admin API the function resolves with the value of the key id.
|
|
*
|
|
* @param {import('express').Request} req
|
|
* @returns {ApiKey}
|
|
*/
|
|
const extractAPIKey = (req) => {
|
|
let keyValue = null;
|
|
let keyType = null;
|
|
|
|
if (req.query && req.query.key) {
|
|
keyValue = req.query.key;
|
|
keyType = 'content';
|
|
} else if (req.headers && req.headers.authorization) {
|
|
keyValue = extractAdminAPIKey(extractTokenFromHeader(req.headers.authorization));
|
|
keyType = 'admin';
|
|
}
|
|
|
|
return {
|
|
key: keyValue,
|
|
type: keyType
|
|
};
|
|
};
|
|
|
|
module.exports = extractAPIKey;
|