Skip to content

Commit

Permalink
refactor: replace koa-router with @koajs alternative
Browse files Browse the repository at this point in the history
closes #436
  • Loading branch information
panva committed Feb 15, 2019
1 parent 68dbece commit fe812e0
Show file tree
Hide file tree
Showing 8 changed files with 60 additions and 41 deletions.
5 changes: 3 additions & 2 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -648,7 +648,6 @@ expressApp.use(prefix, oidc.callback);
### to a koa application
```js
// assumes koa ^2.0.0
// assumes koa-router ^7.0.0
const mount = require('koa-mount');
const prefix = '/oidc';
koaApp.use(mount(prefix, oidc.app));
Expand Down Expand Up @@ -1209,7 +1208,9 @@ This example will
if (!allowed) {
throw new InvalidResource('unauthorized "resource" requested');
}
return transform(resourceParam, grantedResource); // => array of validated and transformed string audiences
// => array of validated and transformed string audiences or undefined if no audiences
// are to be listed
return transform(resourceParam, grantedResource);
}
},
formats: {
Expand Down
2 changes: 1 addition & 1 deletion example/routes/koa.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const querystring = require('querystring');

const bodyParser = require('koa-body');
const Router = require('koa-router');
const Router = require('koa-trie-router');

const { renderError } = require('../../lib/helpers/defaults'); // make your own, you'll need it anyway
const Account = require('../support/account');
Expand Down
2 changes: 1 addition & 1 deletion example/standalone.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ let server;
layout: '_layout',
root: path.join(__dirname, 'views'),
});
provider.use(routes(provider).routes());
provider.use(routes(provider).middleware());
server = provider.listen(PORT, () => {
console.log(`application is listening on port ${PORT}, check it's /.well-known/openid-configuration`);
});
Expand Down
69 changes: 46 additions & 23 deletions lib/helpers/initialize_app.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
const assert = require('assert');
const querystring = require('querystring');

const Router = require('koa-router');
const Router = require('koa-trie-router');
const getCors = require('@koa/cors');

const { homepage, version } = require('../../package.json');
Expand All @@ -13,12 +14,12 @@ const grants = require('../actions/grants');
const responseModes = require('../response_modes');
const error = require('../shared/error_handler');
const getAuthError = require('../shared/authorization_error_handler');
const invalidRoute = require('../shared/invalid_route');
const contextEnsureOidc = require('../shared/context_ensure_oidc');

const { InvalidRequest } = require('./errors');
const instance = require('./weak_cache');
const attention = require('./attention');
const { ROUTER_URL_METHOD } = require('./symbols');

const webfingerRoute = '/.well-known/webfinger';
const discoveryRoute = '/.well-known/openid-configuration';
Expand All @@ -33,10 +34,12 @@ module.exports = function initializeApp() {

const ensureOIDC = contextEnsureOidc(this);

const routeMap = new Map();
function routerAssert(name, route, ...stack) {
assert(typeof name === 'string' && name.charAt(0) !== '/', `invalid route name ${name}`);
assert(typeof route === 'string' && route.charAt(0) === '/', `invalid route ${route}`);
stack.forEach(middleware => assert.deepEqual(typeof middleware, 'function'), 'invalid middleware');
routeMap.set(name, route);
}
async function ensureSessionSave(ctx, next) {
try {
Expand All @@ -47,25 +50,48 @@ module.exports = function initializeApp() {
}
}
}
function namedRoute(name, ctx, next) {
ctx._matchedRouteName = name;
return next();
}

router[ROUTER_URL_METHOD] = function routeUrl(name, opts = {}) {
let path = routeMap.get(name);

if (!path) {
throw new Error(`No route found for name: ${name}`);
}

Object.entries(opts).forEach(([key, value]) => {
path = path.replace(`:${key}`, value);
});

if ('query' in opts) {
path = `${path}?${querystring.stringify(opts.query)}`;
}

return path;
};

const get = (name, route, ...stack) => {
routerAssert(name, route, ...stack);
router.get(name, route, ensureOIDC, ensureSessionSave, ...stack);
router.get(route, namedRoute.bind(undefined, name), ensureOIDC, ensureSessionSave, ...stack);
};
const post = (name, route, ...stack) => {
routerAssert(name, route, ...stack);
router.post(name, route, ensureOIDC, ensureSessionSave, ...stack);
router.post(route, namedRoute.bind(undefined, name), ensureOIDC, ensureSessionSave, ...stack);
};
const del = (name, route, ...stack) => {
routerAssert(name, route, ...stack);
router.del(name, route, ensureOIDC, ...stack);
router.del(route, namedRoute.bind(undefined, name), ensureOIDC, ...stack);
};
const put = (name, route, ...stack) => {
routerAssert(name, route, ...stack);
router.put(name, route, ensureOIDC, ...stack);
router.put(route, namedRoute.bind(undefined, name), ensureOIDC, ...stack);
};
const options = (name, route, ...stack) => {
routerAssert(name, route, ...stack);
router.options(name, route, ensureOIDC, ...stack);
router.options(route, namedRoute.bind(undefined, name), ensureOIDC, ...stack);
};

const { routes } = configuration;
Expand Down Expand Up @@ -188,7 +214,7 @@ module.exports = function initializeApp() {
post('code_verification', routes.code_verification, error(this, 'code_verification.error'), ...codeVerification.post, ...postCodeVerification);

const deviceResume = getAuthorization(this, 'device_resume');
get('device_resume', `${routes.code_verification}/:user_code/:grant/`, error(this, 'device_resume.error'), ...deviceResume);
get('device_resume', `${routes.code_verification}/:user_code/:grant`, error(this, 'device_resume.error'), ...deviceResume);
}

if (configuration.features.devInteractions) {
Expand All @@ -215,23 +241,20 @@ module.exports = function initializeApp() {
proxyWarning.firstInternal = true;

app.use(proxyWarning);
app.use(router.routes());
app.use(error(this));
app.use(invalidRoute);

const allowedMethodsMiddleware = router.allowedMethods({
throw: true,
methodNotAllowed: () => new InvalidRequest('method not allowed', 405),
notImplemented: () => new InvalidRequest('not implemented', 501),
});
app.use(async (ctx, next) => {
try {
await allowedMethodsMiddleware(ctx, next);
} catch (err) {
if (err.statusCode === 405) {
err.error_description = `method ${ctx.method} not allowed on ${ctx.path}`;
}
throw err;
await next();
if (!router.isImplementedMethod(ctx.method)) {
throw new InvalidRequest('not implemented', 501);
}

if (ctx.status === 404 && ctx.message === 'Not Found') {
throw new InvalidRequest('unrecognized route', 404);
}

if (ctx.status === 405) {
throw new InvalidRequest(`method ${ctx.method} not allowed on ${ctx.path}`, 405);
}
});
app.use(router.middleware());
};
3 changes: 3 additions & 0 deletions lib/helpers/symbols.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = {
ROUTER_URL_METHOD: Symbol('ROUTER_URL_METHOD'),
};
4 changes: 2 additions & 2 deletions lib/provider.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ if (HTTP2_STABLE) {
const { DEFAULT_HTTP_OPTIONS } = require('./consts');
const attention = require('./helpers/attention');
const getConfiguration = require('./helpers/configuration');
const { ROUTER_URL_METHOD } = require('./helpers/symbols');
const instance = require('./helpers/weak_cache');
const initializeKeystore = require('./helpers/initialize_keystore');
const initializeAdapter = require('./helpers/initialize_adapter');
Expand Down Expand Up @@ -201,8 +202,7 @@ class Provider extends events.EventEmitter {
checkInit(this);
const { router } = instance(this);

const routerUrl = router.url(name, opts);
if (routerUrl instanceof Error) throw routerUrl; // specific to koa-router
const routerUrl = router[ROUTER_URL_METHOD](name, opts);

return [mountPath, routerUrl].join('');
}
Expand Down
8 changes: 0 additions & 8 deletions lib/shared/invalid_route.js

This file was deleted.

8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
"got": "^9.3.2",
"jsesc": "^2.5.2",
"koa": "^2.6.2",
"koa-router": "^7.4.0",
"koa-trie-router": "^2.1.6",
"lodash": "^4.17.11",
"lru-cache": "^5.1.1",
"nanoid": "^2.0.0",
Expand All @@ -58,22 +58,22 @@
"uuid": "^3.3.2"
},
"devDependencies": {
"@commitlint/cli": "^7.2.1",
"@commitlint/cli": "^7.5.2",
"@commitlint/config-conventional": "^7.1.2",
"chai": "^4.2.0",
"clear-module": "^3.0.0",
"eslint": "^5.9.0",
"eslint-config-airbnb-base": "^13.1.0",
"eslint-plugin-import": "^2.14.0",
"husky": "^1.2.0",
"koa-body": "^4.0.4",
"koa-body": "^4.0.8",
"koa-ejs": "^4.1.2",
"koa-helmet": "^4.0.0",
"koa-mount": "^4.0.0",
"mocha": "^5.2.0",
"moment": "^2.22.2",
"nock": "^10.0.2",
"nyc": "^13.1.0",
"nyc": "^13.3.0",
"sinon": "^7.1.1",
"supertest": "^3.3.0",
"timekeeper": "^2.1.2"
Expand Down

0 comments on commit fe812e0

Please sign in to comment.