diff --git a/lib/index.js b/lib/index.js index 651f943..b3226b8 100644 --- a/lib/index.js +++ b/lib/index.js @@ -121,8 +121,29 @@ internals.connectionInfo = function (server, routes, options, connectionInfo) { const defaultStrategy = Hoek.reach(server, 'auth.settings.default.strategies'); let authStrategy = route.settings.auth ? route.settings.auth.strategies.toString() : false; - const authScope = (route.settings.auth && route.settings.auth.access) ? - route.settings.auth.access[0].scope.selection.toString() : false; + let authScope = []; + + const required = Hoek.reach(route, 'settings.auth.access.0.scope.required', { default: '' }); + if (required !== '' ) { + authScope.push(required.map((item) => `+${item}`).join(', ')); + } + + const forbidden = Hoek.reach(route, 'settings.auth.access.0.scope.forbidden', { default: '' }); + if (forbidden !== '' ) { + authScope.push(forbidden.map((item) => `!${item}`).join(', ')); + } + + const selection = Hoek.reach(route, 'settings.auth.access.0.scope.selection', { default: '' }); + if (selection !== '') { + authScope.push(selection.join(', ')); + } + + if (authScope.length > 0) { + authScope = authScope.join(', '); + } + else { + authScope = false; + } if (route.settings.auth === undefined) { authStrategy = defaultStrategy ? String(defaultStrategy) : false; diff --git a/package.json b/package.json index c3f4843..34eb6af 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "description": "blipp is a simple hapi plugin to display the routes table at startup", "main": "lib/index.js", "scripts": { - "test": "lab -a code -v -t 100 -L" + "test": "lab -a code -v -t 100 -L -I queueMicrotask" }, "repository": { "type": "git", diff --git a/test/index.js b/test/index.js index e547e9b..1af032c 100644 --- a/test/index.js +++ b/test/index.js @@ -46,7 +46,37 @@ const internals = { { method: 'GET', path: '/all', description: 'a route on all connections', auth: false, scope: false }, { method: 'GET', path: '/api', description: 'api routes', auth: false, scope: false }, { method: 'POST', path: '/apost/{foo}/comment/{another}', description: '', auth: false, scope: false }, - { method: 'GET', path: '/hi', description: '', auth: 'findme', scope: 'tester' }, + { method: 'GET', path: '/hi', description: '', auth: 'findme', scope: '+tester1, !tester3, tester2' }, + { method: 'DELETE', path: '/post/{id}', description: '', auth: false, scope: false } + ] + }], + requiredScopeResult: [{ + routes: [ + { method: 'GET', path: '/', description: 'main index', auth: false, scope: false }, + { method: 'GET', path: '/all', description: 'a route on all connections', auth: false, scope: false }, + { method: 'GET', path: '/api', description: 'api routes', auth: false, scope: false }, + { method: 'POST', path: '/apost/{foo}/comment/{another}', description: '', auth: false, scope: false }, + { method: 'GET', path: '/hi', description: '', auth: 'findme', scope: '+tester1' }, + { method: 'DELETE', path: '/post/{id}', description: '', auth: false, scope: false } + ] + }], + forbiddenScopeResult: [{ + routes: [ + { method: 'GET', path: '/', description: 'main index', auth: false, scope: false }, + { method: 'GET', path: '/all', description: 'a route on all connections', auth: false, scope: false }, + { method: 'GET', path: '/api', description: 'api routes', auth: false, scope: false }, + { method: 'POST', path: '/apost/{foo}/comment/{another}', description: '', auth: false, scope: false }, + { method: 'GET', path: '/hi', description: '', auth: 'findme', scope: '!tester3' }, + { method: 'DELETE', path: '/post/{id}', description: '', auth: false, scope: false } + ] + }], + selectionScopeResult: [{ + routes: [ + { method: 'GET', path: '/', description: 'main index', auth: false, scope: false }, + { method: 'GET', path: '/all', description: 'a route on all connections', auth: false, scope: false }, + { method: 'GET', path: '/api', description: 'api routes', auth: false, scope: false }, + { method: 'POST', path: '/apost/{foo}/comment/{another}', description: '', auth: false, scope: false }, + { method: 'GET', path: '/hi', description: '', auth: 'findme', scope: 'tester2' }, { method: 'DELETE', path: '/post/{id}', description: '', auth: false, scope: false } ] }], @@ -120,10 +150,26 @@ internals.prepareServer = async function (options) { } }); - const authOptions = options.authType ? { - strategy: 'findme', - scope: ['tester'] - } : false; + let authOptions = false; + if (options.authType) { + authOptions = { + strategy: 'findme' + }; + switch (options.scopeType) { + case 'required': + authOptions.scope = ['+tester1']; + break; + case 'selection': + authOptions.scope = ['tester2']; + break; + case 'forbidden': + authOptions.scope = ['!tester3']; + break; + default: + authOptions.scope = ['+tester1', 'tester2', '!tester3']; + break; + } + } plugin.route({ method: 'GET', @@ -245,7 +291,7 @@ describe('routes', () => { expect(text).to.match(/hi.*findme/); }); - it('gets route information with scope', async () => { + it('gets route information with all scope', async () => { const blippOptions = { showAuth: true, @@ -265,6 +311,67 @@ describe('routes', () => { expect(text).to.match(/hi.*findme/); }); + it('gets route information with required scope', async () => { + + const blippOptions = { + showAuth: true, + showScope: true, + showStart: false + }; + + const server = await internals.prepareServer({ blippOptions, authType: 'findme', scopeType: 'required' }); + + const info = server.plugins[Pkg.name].info(); + delete info[0].uri; + expect(info).to.equal(internals.requiredScopeResult); + + const text = server.plugins[Pkg.name].text(); + expect(text).to.match(/none.*main index/); + expect(text).to.match(/none.*api routes/); + expect(text).to.match(/hi.*findme/); + }); + + it('gets route information with selection scope', async () => { + + const blippOptions = { + showAuth: true, + showScope: true, + showStart: false + }; + + const server = await internals.prepareServer({ blippOptions, authType: 'findme', scopeType: 'selection' }); + + const info = server.plugins[Pkg.name].info(); + delete info[0].uri; + expect(info).to.equal(internals.selectionScopeResult); + + const text = server.plugins[Pkg.name].text(); + expect(text).to.match(/none.*main index/); + expect(text).to.match(/none.*api routes/); + expect(text).to.match(/hi.*findme/); + }); + + it('gets route information with forbidden scope', async () => { + + const blippOptions = { + showAuth: true, + showScope: true, + showStart: false + }; + + const server = await internals.prepareServer({ blippOptions, authType: 'findme', scopeType: 'forbidden' }); + + const info = server.plugins[Pkg.name].info(); + delete info[0].uri; + expect(info).to.equal(internals.forbiddenScopeResult); + + const text = server.plugins[Pkg.name].text(); + expect(text).to.match(/none.*main index/); + expect(text).to.match(/none.*api routes/); + expect(text).to.match(/hi.*findme/); + }); + + it('gets route information with default', async () => { const blippOptions = {