mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-11-11 00:37:55 +03:00
Removed versioning from api-key/admin auth
refs: https://github.com/TryGhost/Toolbox/issues/229 - our api-key audience handling code is still relying on internal api version config - the regex used is also buggy (it expects 3 parts, which isn't true without versions) and doesn't always match, in which case it can cause the tests to hang - we already had some very similar code in the version-rewrite middleware which is also validates exact values for version and api type - moved this code into a util inside api-version-compatibility-service - using this code, all the tests still pass as is, but when I start to adjust them to cover more cases, none hang (test changes coming in a separate commit)
This commit is contained in:
parent
1afe52c657
commit
6dc3f1bf56
@ -49,5 +49,6 @@ module.exports.contentVersion = (req, res, next) => {
|
||||
};
|
||||
|
||||
module.exports.versionRewrites = require('./mw-version-rewrites');
|
||||
module.exports.legacyApiPathMatch = require('./legacy-api-path-match');
|
||||
|
||||
module.exports.init = init;
|
||||
|
@ -0,0 +1,21 @@
|
||||
const pathMatch = require('path-match')();
|
||||
|
||||
module.exports = (url) => {
|
||||
let apiRouteMatcher = '/:version(v2|v3|v4|canary)?/:api(admin|content)/*';
|
||||
|
||||
if (url.startsWith('/ghost/api')) {
|
||||
apiRouteMatcher = `/ghost/api${apiRouteMatcher}`;
|
||||
}
|
||||
|
||||
if (!url.endsWith('/')) {
|
||||
url += '/';
|
||||
}
|
||||
|
||||
let {version, api} = pathMatch(apiRouteMatcher)(url);
|
||||
|
||||
if (version === [null]) {
|
||||
version = null;
|
||||
}
|
||||
|
||||
return {version, api};
|
||||
};
|
@ -1,4 +1,4 @@
|
||||
const routeMatch = require('path-match')();
|
||||
const legacyApiPathMatch = require('./legacy-api-path-match');
|
||||
const urlUtils = require('../../../shared/url-utils');
|
||||
|
||||
/**
|
||||
@ -9,7 +9,7 @@ const urlUtils = require('../../../shared/url-utils');
|
||||
* @param {import('express').NextFunction} next
|
||||
*/
|
||||
module.exports = (req, res, next) => {
|
||||
let {version} = routeMatch('/:version(v2|v3|v4|canary)/:api(admin|content)/*')(req.url);
|
||||
let {version} = legacyApiPathMatch(req.url);
|
||||
|
||||
// If we don't match a valid version, carry on
|
||||
if (!version) {
|
||||
|
@ -3,7 +3,7 @@ const url = require('url');
|
||||
const models = require('../../../models');
|
||||
const errors = require('@tryghost/errors');
|
||||
const limitService = require('../../../services/limits');
|
||||
const config = require('../../../../shared/config');
|
||||
const {legacyApiPathMatch} = require('../../../services/api-version-compatibility');
|
||||
const tpl = require('@tryghost/tpl');
|
||||
const _ = require('lodash');
|
||||
|
||||
@ -139,19 +139,20 @@ const authenticateWithToken = async (req, res, next, {token, JWT_OPTIONS}) => {
|
||||
// https://github.com/auth0/node-jsonwebtoken/issues/208#issuecomment-231861138
|
||||
const secret = Buffer.from(apiKey.get('secret'), 'hex');
|
||||
|
||||
const {pathname} = url.parse(req.originalUrl);
|
||||
const [hasMatch, version, api] = pathname.match(/ghost\/api\/([^/]+)\/([^/]+)\/(.+)*/); // eslint-disable-line no-unused-vars
|
||||
// Using req.originalUril means we get the right url even if version-rewrites have happened
|
||||
const {version, api} = legacyApiPathMatch(req.originalUrl);
|
||||
|
||||
// ensure the token was meant for this api
|
||||
let options;
|
||||
if (!config.get('api:versions:all').includes(version)) {
|
||||
// CASE: non-versioned api request
|
||||
|
||||
if (version) {
|
||||
// CASE: legacy versioned api request
|
||||
options = Object.assign({
|
||||
audience: new RegExp(`\/?${version}\/?$`) // eslint-disable-line no-useless-escape
|
||||
audience: new RegExp(`/?${version}/${api}/?$`)
|
||||
}, JWT_OPTIONS);
|
||||
} else {
|
||||
options = Object.assign({
|
||||
audience: new RegExp(`\/?${version}\/${api}\/?$`) // eslint-disable-line no-useless-escape
|
||||
audience: new RegExp(`/?${api}/?$`)
|
||||
}, JWT_OPTIONS);
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,68 @@
|
||||
const assert = require('assert');
|
||||
|
||||
const legacyApiPathMatch = require('../../../../../core/server/services/api-version-compatibility/legacy-api-path-match');
|
||||
|
||||
describe('Legacy Path Match', function () {
|
||||
it('returns null, admin for all supported permutations', function () {
|
||||
const permutations = [
|
||||
'/ghost/api/admin/',
|
||||
'/admin/',
|
||||
'/ghost/api/admin',
|
||||
'/admin',
|
||||
'/ghost/api/admin/session/',
|
||||
'/admin/session/',
|
||||
'/ghost/api/admin/session',
|
||||
'/admin/session',
|
||||
'/ghost/api/admin/session/something/',
|
||||
'/admin/session/something/',
|
||||
'/ghost/api/admin/session/something',
|
||||
'/admin/session/something'
|
||||
];
|
||||
|
||||
permutations.forEach((url) => {
|
||||
assert.deepEqual(legacyApiPathMatch(url), {version: null, api: 'admin'}, url);
|
||||
});
|
||||
});
|
||||
|
||||
it('returns canary, admin for all supported permutations', function () {
|
||||
const permutations = [
|
||||
'/ghost/api/canary/admin/',
|
||||
'/canary/admin/',
|
||||
'/ghost/api/canary/admin',
|
||||
'/canary/admin',
|
||||
'/ghost/api/canary/admin/session/',
|
||||
'/canary/admin/session/',
|
||||
'/ghost/api/canary/admin/session',
|
||||
'/canary/admin/session',
|
||||
'/ghost/api/canary/admin/session/something/',
|
||||
'/canary/admin/session/something/',
|
||||
'/ghost/api/canary/admin/session/something',
|
||||
'/canary/admin/session/something'
|
||||
];
|
||||
|
||||
permutations.forEach((url) => {
|
||||
assert.deepEqual(legacyApiPathMatch(url), {version: 'canary', api: 'admin'}, url);
|
||||
});
|
||||
});
|
||||
|
||||
it('returns v4, admin for all permutations', function () {
|
||||
const permutations = [
|
||||
'/ghost/api/v4/admin/',
|
||||
'/v4/admin/',
|
||||
'/ghost/api/v4/admin',
|
||||
'/v4/admin',
|
||||
'/ghost/api/v4/admin/session/',
|
||||
'/v4/admin/session/',
|
||||
'/ghost/api/v4/admin/session',
|
||||
'/v4/admin/session',
|
||||
'/ghost/api/v4/admin/session/something/',
|
||||
'/v4/admin/session/something/',
|
||||
'/ghost/api/v4/admin/session/something',
|
||||
'/v4/admin/session/something'
|
||||
];
|
||||
|
||||
permutations.forEach((url) => {
|
||||
assert.deepEqual(legacyApiPathMatch(url), {version: 'v4', api: 'admin'}, url);
|
||||
});
|
||||
});
|
||||
});
|
Loading…
Reference in New Issue
Block a user