├── .editorconfig ├── .gitignore ├── .travis.yml ├── README.md ├── index.js ├── package.json └── test.js /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig helps developers define and maintain consistent 2 | # coding styles between different editors and IDEs 3 | # http://editorconfig.org 4 | 5 | root = true 6 | 7 | [*] 8 | 9 | # Change these settings to your own preference 10 | indent_style = space 11 | indent_size = 2 12 | 13 | # We recommend you to keep these unchanged 14 | end_of_line = lf 15 | charset = utf-8 16 | trim_trailing_whitespace = true 17 | insert_final_newline = true 18 | 19 | [*.md] 20 | trim_trailing_whitespace = false 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | node_modules 3 | .DS_Store 4 | .idea 5 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | 3 | node_js: 4 | - "4" 5 | - "6" 6 | - "7" 7 | - "node" 8 | 9 | sudo: false 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Build Status](https://travis-ci.org/justin-lovell/hapi-api-secret-key.svg?branch=master)](https://travis-ci.org/justin-lovell/hapi-api-secret-key) 2 | 3 | About 4 | ===== 5 | The use case that this HAPI plugin solves is simple: given a simple set of API keys, 6 | requests made to the routes marked as "api" should be protected with only the listed 7 | API keys. 8 | 9 | This allows the API to be hosted behind an API Manager so that key rotation may occur. 10 | 11 | 12 | Default Behavior 13 | ================ 14 | 1. API Secrets are usually loaded by the plugin with the following pseudo code: 15 | 16 | ```javascript 17 | var secrets = []; 18 | var curr; 19 | while (curr = process.env['API_KEY_' + (secrets.length + 1)]) { 20 | secrets.push(curr); 21 | } 22 | ``` 23 | 24 | 2. Callee's are responsible for providing the secret either 25 | by the query string or HTTP-header named "api-key" 26 | 27 | 3. Only the routes which have been decorated with "api" tag will 28 | be protected by this plugin. 29 | 30 | In summary, the `hapi-api-secret-key` has two modes which is determined whether 31 | or not secrets are supplied to the plugin. These behaviors are documented as below. 32 | 33 | | Secrets loaded? | Allow localhost access? | Allow remote access? | 34 | |-----------------|-------------------------|------------------------------------------------| 35 | | No | Yes | No | 36 | | Yes | No | Yes - only if supplied keys match a secret key | 37 | 38 | 39 | Quick Start 40 | =========== 41 | Simply install the package. 42 | 43 | ```bash 44 | npm install --save hapi-api-secret-key 45 | ``` 46 | 47 | Then configure your HAPI server to employ the plugin with the following configuration options 48 | 49 | ```javascript 50 | var server = new Hapi.Server(); 51 | 52 | server.register( 53 | // this is where you register all your HAPI plugins 54 | require('hapi-api-secret-key').plugin, 55 | function (err) { 56 | 57 | if (err) { 58 | throw err; 59 | } 60 | 61 | server.route({ 62 | method: 'GET', 63 | path: '/protected/{name}', 64 | handler: function (request, reply) { 65 | reply({ 66 | name: request.params.name 67 | }); 68 | }, 69 | config: { 70 | // we protect anything with the API tag by default 71 | tags: ['api'] 72 | } 73 | }); 74 | 75 | // below is standard start-up procedure of HAPI servers 76 | server.start(function(err) { 77 | 78 | if (err) { 79 | throw err; 80 | } 81 | 82 | console.log('Server running at:', server.info.uri); 83 | 84 | }); 85 | } 86 | ); 87 | ``` 88 | 89 | Options? 90 | -------- 91 | With the above example, there are simple options which could be injected 92 | into the plugin, namely. 93 | * Secrets 94 | * Fetching the user supplied token/secret 95 | * Which routes to protect 96 | 97 | 98 | ```javascript 99 | var server = new Hapi.Server(); 100 | 101 | // by default, the plugin behaves as the options below 102 | // however, you are able to selectively override the behavior 103 | // of each option 104 | var configOptions = { 105 | secrets: [ 106 | process.env['API_KEY_1'], 107 | process.env['API_KEY_2'] 108 | // and so on 109 | ], 110 | fetchUserApiKey: function (request) { 111 | return request.headers["api-key"] || request.query["api-key"]; 112 | }, 113 | shouldApplyApiFilter: function (request) { 114 | var tags = request.route.settings.tags; 115 | return tags && tags.indexOf('api') >= 0; 116 | } 117 | }; 118 | 119 | server.register( 120 | // this is where you register all your HAPI plugins 121 | { 122 | register: require('hapi-api-secret-key').plugin, 123 | options: configOptions 124 | }, 125 | function (err) { 126 | 127 | if (err) { 128 | throw err; 129 | } 130 | 131 | server.route({ 132 | method: 'GET', 133 | path: '/protected/{name}', 134 | handler: function (request, reply) { 135 | reply({ 136 | name: request.params.name 137 | }); 138 | }, 139 | config: { 140 | // we protect anything with the API tag by default 141 | tags: ['api'] 142 | } 143 | }); 144 | 145 | // below is standard start-up procedure of HAPI servers 146 | server.start(function(err) { 147 | 148 | if (err) { 149 | throw err; 150 | } 151 | 152 | console.log('Server running at:', server.info.uri); 153 | 154 | }); 155 | } 156 | ); 157 | ``` 158 | 159 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var Boom = require('boom'); 4 | 5 | const unauthorizedMessageText = 'The correct API Key was not provided by the client'; 6 | 7 | 8 | function loadApiKeysFromEnvironmentVariables() { 9 | var keys = []; 10 | 11 | var curr; 12 | while (curr = process.env['API_KEY_' + (keys.length + 1)]) { 13 | keys.push(curr); 14 | } 15 | 16 | return keys; 17 | } 18 | 19 | 20 | function createFetchUserApiKey() { 21 | return function fetchUserSuppliedUserApiKey(request) { 22 | return request.headers["api-key"] || request.query["api-key"]; 23 | } 24 | } 25 | 26 | function createDefaultShouldApplyApiKeyFiltering() { 27 | return function shouldApplyApiKeyFiltering(request) { 28 | var tags = request.route.settings.tags; 29 | return tags && tags.indexOf('api') >= 0; 30 | } 31 | } 32 | 33 | 34 | function createInterceptor(options) { 35 | var secrets = (options && options.secrets) || loadApiKeysFromEnvironmentVariables(); 36 | var fetchUserSuppliedSecret = options.fetchUserApiKey || createFetchUserApiKey(); 37 | var shouldApplyFilter = options.shouldApplyApiFilter || createDefaultShouldApplyApiKeyFiltering(); 38 | 39 | return function (request, reply) { 40 | if (!shouldApplyFilter(request)) { 41 | return reply.continue(); 42 | } 43 | 44 | var isLocalHost = request.info.hostname.toLowerCase() === 'localhost'; 45 | if (isLocalHost && (!secrets || !secrets.length)) { 46 | return reply.continue(); 47 | } 48 | 49 | var apiKey = fetchUserSuppliedSecret(request); 50 | if (secrets && secrets.indexOf(apiKey) >= 0) { 51 | return reply.continue(); 52 | } 53 | 54 | return reply(Boom.unauthorized(unauthorizedMessageText)); 55 | } 56 | } 57 | 58 | 59 | const plugin = { 60 | register: function (server, options, next) { 61 | 62 | server.ext('onPreAuth', createInterceptor(options)); 63 | next(); 64 | } 65 | }; 66 | 67 | plugin.register.attributes = { 68 | name: "hapi-api-secret-key", 69 | version: '1.1.0' 70 | }; 71 | 72 | module.exports = { 73 | plugin, 74 | messages: { 75 | unauthorized: unauthorizedMessageText 76 | } 77 | }; 78 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hapi-api-secret-key", 3 | "version": "1.1.0", 4 | "description": "Protect your API tagged routes with a simple set of known keys. Useful for locking down useage from API managers", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "mocha test.js" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/justin-lovell/hapi-api-secret-key.git" 12 | }, 13 | "keywords": [ 14 | "hapi", 15 | "api", 16 | "apim" 17 | ], 18 | "author": "Justin Lovell", 19 | "license": "MIT", 20 | "bugs": { 21 | "url": "https://github.com/justin-lovell/hapi-api-secret-key/issues" 22 | }, 23 | "homepage": "https://github.com/justin-lovell/hapi-api-secret-key#readme", 24 | "dependencies": { 25 | "boom": "^4.2.0" 26 | }, 27 | "devDependencies": { 28 | "hapi": "latest", 29 | "mocha": "latest" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | require('mocha'); 4 | var Assert = require('assert'); 5 | 6 | 7 | var Hapi = require('hapi'); 8 | 9 | var ProtectApiPlugin = require('./index'); 10 | 11 | 12 | describe('protect-api', function () { 13 | 14 | var ping123 = {method: 'GET', url: '/ping/123'}; 15 | var greetName = {method: 'GET', url: '/protected/name'}; 16 | 17 | 18 | function startServer(server, pluginOptions, done) { 19 | 20 | server.route({ 21 | method: 'GET', 22 | path: '/ping/{ping}', 23 | handler: function (request, reply) { 24 | reply({ 25 | pong: request.params.ping 26 | }) 27 | } 28 | }); 29 | 30 | server.route({ 31 | method: 'GET', 32 | path: '/protected/{name}', 33 | handler: function (request, reply) { 34 | reply({ 35 | name: request.params.name 36 | }); 37 | }, 38 | config: { 39 | tags: ['api'] 40 | } 41 | }); 42 | 43 | 44 | server.register( 45 | { 46 | register: ProtectApiPlugin.plugin, 47 | options: pluginOptions 48 | }, 49 | function () { 50 | server.start(done); 51 | } 52 | ); 53 | 54 | }; 55 | 56 | 57 | describe('when the configuration has not been set', function () { 58 | 59 | var remoteServer = null; 60 | var localhostServer = null; 61 | 62 | before(function (done) { 63 | remoteServer = new Hapi.Server(); 64 | remoteServer.connection({host: process.env.HOSTNAME}); 65 | 66 | startServer(remoteServer, null, done); 67 | } 68 | ); 69 | before(function (done) { 70 | localhostServer = new Hapi.Server(); 71 | localhostServer.connection({host: 'localhost'}); 72 | 73 | startServer(localhostServer, null, done); 74 | } 75 | ); 76 | 77 | after(function (done) { 78 | remoteServer.stop(done); 79 | }); 80 | after(function (done) { 81 | localhostServer.stop(done); 82 | }); 83 | 84 | 85 | describe('when accessing from localhost', function () { 86 | 87 | 88 | it('GET ' + greetName.url + ' | Respond pong:123 -> 200', function () { 89 | return localhostServer.inject(ping123) 90 | .then(function (response) { 91 | Assert.equal(response.statusCode, 200); 92 | Assert.equal(response.result.pong, '123'); 93 | }) 94 | }); 95 | 96 | it('GET ' + greetName.url + ' | Respond pong:123 -> 200', function () { 97 | return localhostServer.inject(greetName) 98 | .then(function (response) { 99 | Assert.equal(response.statusCode, 200); 100 | Assert.equal(response.result.name, 'name'); 101 | }); 102 | } 103 | ); 104 | 105 | }); 106 | 107 | 108 | describe('when accessing from remote server', function () { 109 | 110 | it('GET ' + greetName.url + ' | Respond pong:123 -> 200', function () { 111 | return remoteServer.inject(ping123) 112 | .then(function (response) { 113 | Assert.equal(response.statusCode, 200); 114 | Assert.equal(response.result.pong, '123'); 115 | }); 116 | } 117 | ); 118 | 119 | it('GET ' + greetName.url + ' | Respond pong:123 -> 401', function () { 120 | return remoteServer.inject(greetName) 121 | .then(function (response) { 122 | Assert.equal(response.statusCode, 401); 123 | Assert.equal(response.result.message, ProtectApiPlugin.messages.unauthorized); 124 | }); 125 | } 126 | ); 127 | 128 | }); 129 | 130 | }); 131 | 132 | 133 | describe('when the configuration has been set', function () { 134 | 135 | var remoteServer = null; 136 | var localhostServer = null; 137 | var configOptions = { 138 | secrets: ['secret', 'secret2'] 139 | }; 140 | 141 | before(function (done) { 142 | remoteServer = new Hapi.Server(); 143 | remoteServer.connection({host: process.env.HOSTNAME}); 144 | 145 | startServer(remoteServer, configOptions, done); 146 | } 147 | ); 148 | before(function (done) { 149 | localhostServer = new Hapi.Server(); 150 | localhostServer.connection({host: 'localhost'}); 151 | 152 | startServer(localhostServer, configOptions, done); 153 | } 154 | ); 155 | 156 | after(function (done) { 157 | remoteServer.stop(done) 158 | }); 159 | after(function (done) { 160 | localhostServer.stop(done) 161 | }); 162 | 163 | 164 | it('GET ' + greetName.url + '| Respond pong:123 -> 200', function () { 165 | return remoteServer.inject(ping123) 166 | .then(function (response) { 167 | Assert.equal(response.statusCode, 200); 168 | Assert.equal(response.result.pong, '123'); 169 | }) 170 | } 171 | ); 172 | 173 | 174 | describe('requests are made with the correct token set', function () { 175 | 176 | describe('when accessing from localhost', function () { 177 | 178 | it('GET ' + greetName.url + ' with HEADER | Respond pong:123 -> 200', function () { 179 | return localhostServer.inject(Object.assign({}, greetName, {headers: {'api-key': 'secret'}})) 180 | .then(function (response) { 181 | Assert.equal(response.statusCode, 200); 182 | Assert.equal(response.result.name, 'name'); 183 | }) 184 | } 185 | ); 186 | 187 | it('GET ' + greetName.url + '?api-key=secret | Respond pong:123 -> 200', function () { 188 | return localhostServer.inject(Object.assign({}, greetName, {url: greetName.url + '?api-key=secret'})) 189 | .then(function (response) { 190 | Assert.equal(response.statusCode, 200); 191 | Assert.equal(response.result.name, 'name'); 192 | }); 193 | } 194 | ); 195 | 196 | it('GET ' + greetName.url + '?api-key=secret2 | Respond pong:123 -> 200', function () { 197 | return localhostServer.inject(Object.assign({}, greetName, {url: greetName.url + '?api-key=secret2'})) 198 | .then(function (response) { 199 | Assert.equal(response.statusCode, 200); 200 | Assert.equal(response.result.name, 'name'); 201 | }); 202 | } 203 | ); 204 | 205 | } 206 | ); 207 | 208 | 209 | describe('when accessing from remote server', function () { 210 | 211 | it('GET ' + greetName.url + ' with HEADER | Respond pong:123 -> 200', function () { 212 | return localhostServer.inject(Object.assign({}, greetName, {headers: {'api-key': 'secret'}})) 213 | .then(function (response) { 214 | Assert.equal(response.statusCode, 200); 215 | Assert.equal(response.result.name, 'name'); 216 | }); 217 | }); 218 | 219 | it('GET ' + greetName.url + '?api-key=secret | Respond pong:123 -> 200', function () { 220 | return localhostServer.inject(Object.assign({}, greetName, {url: greetName.url + '?api-key=secret'})) 221 | .then(function (response) { 222 | Assert.equal(response.statusCode, 200); 223 | Assert.equal(response.result.name, 'name'); 224 | }); 225 | }); 226 | 227 | it('GET ' + greetName.url + '?api-key=secret2 | Respond pong:123 -> 200', function () { 228 | return localhostServer.inject(Object.assign({}, greetName, {url: greetName.url + '?api-key=secret2'})) 229 | .then(function (response) { 230 | Assert.equal(response.statusCode, 200); 231 | Assert.equal(response.result.name, 'name'); 232 | } 233 | ); 234 | }); 235 | 236 | }); 237 | 238 | }); 239 | 240 | 241 | describe('requests are made with the incorrect token set', function () { 242 | 243 | describe('when accessing from localhost', function () { 244 | 245 | it('GET ' + greetName.url + ' with HEADER | Respond pong:123 -> 401', function () { 246 | return localhostServer.inject(Object.assign({}, greetName, {headers: {'api-key': 'wrong'}})) 247 | .then(function (response) { 248 | Assert.equal(response.statusCode, 401); 249 | Assert.equal(response.result.message, ProtectApiPlugin.messages.unauthorized); 250 | }) 251 | }); 252 | 253 | it('GET ' + greetName.url + '?api-key=wrong | Respond pong:123 -> 401', function () { 254 | return localhostServer.inject(Object.assign({}, greetName, {url: greetName.url + '?api-key=wrong'})) 255 | .then(function (response) { 256 | Assert.equal(response.statusCode, 401); 257 | Assert.equal(response.result.message, ProtectApiPlugin.messages.unauthorized); 258 | }) 259 | }); 260 | 261 | }); 262 | 263 | 264 | describe('when accessing from remote server', function () { 265 | 266 | it('GET ' + greetName.url + ' with HEADER | Respond pong:123 -> 401', function () { 267 | return localhostServer.inject(Object.assign({}, greetName, {headers: {'api-key': 'wrong'}})) 268 | .then(function (response) { 269 | Assert.equal(response.statusCode, 401); 270 | Assert.equal(response.result.message, ProtectApiPlugin.messages.unauthorized); 271 | }) 272 | }); 273 | 274 | it('GET ' + greetName.url + '?api-key=wrong | Respond pong:123 -> 401', function () { 275 | return localhostServer.inject(Object.assign({}, greetName, {url: greetName.url + '?api-key=wrong'})) 276 | .then(function (response) { 277 | Assert.equal(response.statusCode, 401); 278 | Assert.equal(response.result.message, ProtectApiPlugin.messages.unauthorized); 279 | }) 280 | }); 281 | 282 | }); 283 | 284 | }); 285 | 286 | 287 | describe('requests are made without token set', function () { 288 | 289 | describe('when accessing from localhost', function () { 290 | 291 | it('GET ' + greetName.url + ' | Respond pong:123 -> 401', function () { 292 | return localhostServer.inject(greetName) 293 | .then(function (response) { 294 | Assert.equal(response.statusCode, 401); 295 | Assert.equal(response.result.message, ProtectApiPlugin.messages.unauthorized); 296 | }) 297 | }); 298 | 299 | }); 300 | 301 | 302 | describe('when accessing from remote server', function () { 303 | 304 | 305 | it('GET ' + greetName.url + ' | Respond pong:123 -> 401', function () { 306 | return remoteServer.inject(greetName) 307 | .then(function (response) { 308 | Assert.equal(response.statusCode, 401); 309 | Assert.equal(response.result.message, ProtectApiPlugin.messages.unauthorized); 310 | }) 311 | }); 312 | 313 | }); 314 | 315 | }); 316 | 317 | }); 318 | 319 | 320 | describe('when the process environment variables are set', function () { 321 | 322 | var remoteServer = null; 323 | var localhostServer = null; 324 | 325 | before(function () { 326 | process.env['API_KEY_1'] = 'secret'; 327 | process.env['API_KEY_2'] = 'secret2'; 328 | } 329 | ); 330 | before(function (done) { 331 | 332 | remoteServer = new Hapi.Server(); 333 | remoteServer.connection({host: process.env.HOSTNAME}); 334 | 335 | startServer(remoteServer, {}, done); 336 | 337 | } 338 | ); 339 | before(function (done) { 340 | 341 | localhostServer = new Hapi.Server(); 342 | localhostServer.connection({host: 'localhost'}); 343 | 344 | startServer(localhostServer, {}, done); 345 | 346 | } 347 | ); 348 | 349 | after(function (done) { 350 | 351 | remoteServer.stop(done); 352 | 353 | }); 354 | after(function (done) { 355 | 356 | localhostServer.stop(done); 357 | 358 | }); 359 | 360 | 361 | it('GET ' + greetName.url + '| Respond pong:123 -> 200', function () { 362 | return remoteServer.inject(ping123) 363 | .then(function (response) { 364 | Assert.equal(response.statusCode, 200); 365 | Assert.equal(response.result.pong, '123'); 366 | }) 367 | } 368 | ); 369 | 370 | 371 | describe('requests are made with the correct token set', function () { 372 | 373 | describe('when accessing from localhost', function () { 374 | 375 | it('GET ' + greetName.url + ' with HEADER | Respond pong:123 -> 200', function () { 376 | return localhostServer.inject(Object.assign({}, greetName, {headers: {'api-key': 'secret'}})) 377 | .then(function (response) { 378 | Assert.equal(response.statusCode, 200); 379 | Assert.equal(response.result.name, 'name'); 380 | }) 381 | } 382 | ); 383 | 384 | it('GET ' + greetName.url + '?api-key=secret | Respond pong:123 -> 200', function () { 385 | return localhostServer.inject(Object.assign({}, greetName, {url: greetName.url + '?api-key=secret'})) 386 | .then(function (response) { 387 | Assert.equal(response.statusCode, 200); 388 | Assert.equal(response.result.name, 'name'); 389 | }); 390 | } 391 | ); 392 | 393 | it('GET ' + greetName.url + '?api-key=secret2 | Respond pong:123 -> 200', function () { 394 | return localhostServer.inject(Object.assign({}, greetName, {url: greetName.url + '?api-key=secret2'})) 395 | .then(function (response) { 396 | Assert.equal(response.statusCode, 200); 397 | Assert.equal(response.result.name, 'name'); 398 | }); 399 | } 400 | ); 401 | 402 | } 403 | ); 404 | 405 | 406 | describe('when accessing from remote server', function () { 407 | 408 | it('GET ' + greetName.url + ' with HEADER | Respond pong:123 -> 200', function () { 409 | return localhostServer.inject(Object.assign({}, greetName, {headers: {'api-key': 'secret'}})) 410 | .then(function (response) { 411 | Assert.equal(response.statusCode, 200); 412 | Assert.equal(response.result.name, 'name'); 413 | }); 414 | }); 415 | 416 | it('GET ' + greetName.url + '?api-key=secret | Respond pong:123 -> 200', function () { 417 | return localhostServer.inject(Object.assign({}, greetName, {url: greetName.url + '?api-key=secret'})) 418 | .then(function (response) { 419 | Assert.equal(response.statusCode, 200); 420 | Assert.equal(response.result.name, 'name'); 421 | }); 422 | }); 423 | 424 | it('GET ' + greetName.url + '?api-key=secret2 | Respond pong:123 -> 200', function () { 425 | return localhostServer.inject(Object.assign({}, greetName, {url: greetName.url + '?api-key=secret2'})) 426 | .then(function (response) { 427 | Assert.equal(response.statusCode, 200); 428 | Assert.equal(response.result.name, 'name'); 429 | } 430 | ); 431 | }); 432 | 433 | }); 434 | 435 | }); 436 | 437 | 438 | describe('requests are made with the incorrect token set', function () { 439 | 440 | describe('when accessing from localhost', function () { 441 | 442 | it('GET ' + greetName.url + ' with HEADER | Respond pong:123 -> 401', function () { 443 | return localhostServer.inject(Object.assign({}, greetName, {headers: {'api-key': 'wrong'}})) 444 | .then(function (response) { 445 | Assert.equal(response.statusCode, 401); 446 | Assert.equal(response.result.message, ProtectApiPlugin.messages.unauthorized); 447 | }) 448 | }); 449 | 450 | it('GET ' + greetName.url + '?api-key=wrong | Respond pong:123 -> 401', function () { 451 | return localhostServer.inject(Object.assign({}, greetName, {url: greetName.url + '?api-key=wrong'})) 452 | .then(function (response) { 453 | Assert.equal(response.statusCode, 401); 454 | Assert.equal(response.result.message, ProtectApiPlugin.messages.unauthorized); 455 | }) 456 | }); 457 | 458 | }); 459 | 460 | 461 | describe('when accessing from remote server', function () { 462 | 463 | it('GET ' + greetName.url + ' with HEADER | Respond pong:123 -> 401', function () { 464 | return localhostServer.inject(Object.assign({}, greetName, {headers: {'api-key': 'wrong'}})) 465 | .then(function (response) { 466 | Assert.equal(response.statusCode, 401); 467 | Assert.equal(response.result.message, ProtectApiPlugin.messages.unauthorized); 468 | }) 469 | }); 470 | 471 | it('GET ' + greetName.url + '?api-key=wrong | Respond pong:123 -> 401', function () { 472 | return localhostServer.inject(Object.assign({}, greetName, {url: greetName.url + '?api-key=wrong'})) 473 | .then(function (response) { 474 | Assert.equal(response.statusCode, 401); 475 | Assert.equal(response.result.message, ProtectApiPlugin.messages.unauthorized); 476 | }) 477 | }); 478 | 479 | }); 480 | 481 | }); 482 | 483 | 484 | describe('requests are made without token set', function () { 485 | 486 | describe('when accessing from localhost', function () { 487 | 488 | it('GET ' + greetName.url + ' | Respond pong:123 -> 401', function () { 489 | return localhostServer.inject(greetName) 490 | .then(function (response) { 491 | Assert.equal(response.statusCode, 401); 492 | Assert.equal(response.result.message, ProtectApiPlugin.messages.unauthorized); 493 | }) 494 | }); 495 | 496 | }); 497 | 498 | 499 | describe('when accessing from remote server', function () { 500 | 501 | 502 | it('GET ' + greetName.url + ' | Respond pong:123 -> 401', function () { 503 | return remoteServer.inject(greetName) 504 | .then(function (response) { 505 | Assert.equal(response.statusCode, 401); 506 | Assert.equal(response.result.message, ProtectApiPlugin.messages.unauthorized); 507 | }) 508 | }); 509 | 510 | }); 511 | 512 | }); 513 | 514 | }); 515 | 516 | 517 | }); 518 | 519 | 520 | --------------------------------------------------------------------------------