2018-10-15 12:23:34 +03:00
|
|
|
const models = require('../../../models');
|
2020-04-30 22:26:12 +03:00
|
|
|
const errors = require('@tryghost/errors');
|
2021-04-09 15:45:26 +03:00
|
|
|
const limitService = require('../../../services/limits');
|
2021-05-03 19:29:44 +03:00
|
|
|
const i18n = require('../../../../shared/i18n');
|
2018-10-15 12:23:34 +03:00
|
|
|
|
2021-04-07 07:52:26 +03:00
|
|
|
const authenticateContentApiKey = async function authenticateContentApiKey(req, res, next) {
|
2018-10-15 12:23:34 +03:00
|
|
|
// allow fallthrough to other auth methods or final ensureAuthenticated check
|
|
|
|
if (!req.query || !req.query.key) {
|
|
|
|
return next();
|
|
|
|
}
|
|
|
|
|
2019-08-12 14:56:09 +03:00
|
|
|
if (req.query.key.constructor === Array) {
|
2020-04-30 22:26:12 +03:00
|
|
|
return next(new errors.BadRequestError({
|
|
|
|
message: i18n.t('errors.middleware.auth.invalidRequest'),
|
2019-08-12 14:56:09 +03:00
|
|
|
code: 'INVALID_REQUEST'
|
|
|
|
}));
|
|
|
|
}
|
|
|
|
|
2018-10-15 12:23:34 +03:00
|
|
|
let key = req.query.key;
|
|
|
|
|
2021-04-07 07:52:26 +03:00
|
|
|
try {
|
2021-04-09 15:45:26 +03:00
|
|
|
const apiKey = await models.ApiKey.findOne({secret: key}, {withRelated: ['integration']});
|
2021-04-07 07:52:26 +03:00
|
|
|
|
2018-10-15 12:23:34 +03:00
|
|
|
if (!apiKey) {
|
2020-04-30 22:26:12 +03:00
|
|
|
return next(new errors.UnauthorizedError({
|
|
|
|
message: i18n.t('errors.middleware.auth.unknownContentApiKey'),
|
2018-10-15 12:23:34 +03:00
|
|
|
code: 'UNKNOWN_CONTENT_API_KEY'
|
|
|
|
}));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (apiKey.get('type') !== 'content') {
|
2020-04-30 22:26:12 +03:00
|
|
|
return next(new errors.UnauthorizedError({
|
|
|
|
message: i18n.t('errors.middleware.auth.invalidApiKeyType'),
|
2018-10-15 12:23:34 +03:00
|
|
|
code: 'INVALID_API_KEY_TYPE'
|
|
|
|
}));
|
|
|
|
}
|
|
|
|
|
2021-04-09 15:45:26 +03:00
|
|
|
// CASE: blocking all non-internal: "custom" and "builtin" integration requests when the limit is reached
|
|
|
|
if (limitService.isLimited('customIntegrations')
|
|
|
|
&& (apiKey.relations.integration && !['internal'].includes(apiKey.relations.integration.get('type')))) {
|
|
|
|
// NOTE: using "checkWouldGoOverLimit" instead of "checkIsOverLimit" here because flag limits don't have
|
|
|
|
// a concept of measuring if the limit has been surpassed
|
|
|
|
await limitService.errorIfWouldGoOverLimit('customIntegrations');
|
|
|
|
}
|
|
|
|
|
2018-10-15 12:23:34 +03:00
|
|
|
// authenticated OK, store the api key on the request for later checks and logging
|
|
|
|
req.api_key = apiKey;
|
2021-04-07 07:52:26 +03:00
|
|
|
|
2018-10-15 12:23:34 +03:00
|
|
|
next();
|
2021-04-07 07:52:26 +03:00
|
|
|
} catch (err) {
|
2021-04-09 15:45:26 +03:00
|
|
|
if (err instanceof errors.HostLimitError) {
|
|
|
|
next(err);
|
|
|
|
} else {
|
|
|
|
next(new errors.InternalServerError({err}));
|
|
|
|
}
|
2021-04-07 07:52:26 +03:00
|
|
|
}
|
2018-10-15 12:23:34 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
module.exports = {
|
|
|
|
authenticateContentApiKey
|
|
|
|
};
|