Skip to content

Commit

Permalink
Add new useHttp option to module (#2)
Browse files Browse the repository at this point in the history
* Add `useHttp` option.  Will inform the authentication specification on whether to expect the authentication service to use HTTPS or HTTP.
  • Loading branch information
rgwozdz committed May 29, 2018
1 parent 575e700 commit a011ea0
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 7 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
All notable changes to this project will be documented in this file.
This project adheres to [Semantic Versioning](http://semver.org/).

## Unreleased
## Added
* new option `useHttp`. Must be a boolean. This will get added verbatim to the result of authenticationSpecification function

## [1.0.0] - 2018-05-22
### Added
* Initial release of an authentication plugin for Koop that leverages a file-based user-store.
Expand Down
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,12 @@ Finally, create a JSON file store. This should be an array of objects with prop
| userStoreFilePath | <code>string</code> | path to the JSON file containing the array of username/password objects |
| options | <code>object</code> | options object |
| options.tokenExpirationMinutes | <code>integer</code> | minutes until token expires (default 60) |
| options.useHttp | <code>boolean</code> | pass the `useHttp` boolean flag as part of the authenticationSpecification function result|

## Special considerations for use with [koop-ouput-geoservices](https://github.com/koopjs/koop-output-geoservices)
[koop-ouput-geoservices](https://github.com/koopjs/koop-output-geoservices) assumes that token-services occur over HTTPS. For development purposes you may wish to allow authentication to occur of HTTP. This can be done two different ways. You can add the `useHttp` option when configuring the module, which will be passed on in the result of `authenticationSpecification()` calls.

let auth = require('@koopjs/auth-direct-file')('pass-in-your-secret', `${__dirname}/user-store.json`, { useHttp: true })
koop.register(auth)

Alternatively, you can set an environment variable `KOOP_AUTH_HTTP=true`. Either of these approaches inform [koop-ouput-geoservices](https://github.com/koopjs/koop-output-geoservices) to use `http` as the protocol of the `tokenServicesUrl`.
20 changes: 14 additions & 6 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
const fs = require('fs')
const jwt = require('jsonwebtoken')
const validateCredentials = require('./validate-credentials')
const TOKEN_EXPIRATION_MINTUES = 60
const TOKEN_EXPIRATION_MINUTES = 60
let _useHttp
let _tokenExpirationMinutes
let _secret
let _userStoreFilePath
Expand All @@ -12,6 +13,7 @@ let _userStoreFilePath
* @param {string} userStoreFilePath - file path of user store JSON file
* @param {object} options
* @param {integer} options.tokenExpirationMinutes - number of minutes until token expires
* @param {boolean} options.useHttp - direct consumers of authenticationSpecifcation to use HTTP instead of HTTPS
*/
function auth (secret, userStoreFilePath, options = {}) {
// Throw error if user-store file does not exist
Expand All @@ -21,10 +23,15 @@ function auth (secret, userStoreFilePath, options = {}) {

_secret = secret
_userStoreFilePath = userStoreFilePath
_tokenExpirationMinutes = options.tokenExpirationMinutes || TOKEN_EXPIRATION_MINTUES

// Ensure the useHttp option is a boolean and default to false
if (options.useHttp && typeof options.useHttp !== 'boolean') throw new Error(`"useHttp" must be a boolean`)
_useHttp = options.useHttp || false

// Ensure token expiration is an integer greater than 5
if (!Number.isInteger(_tokenExpirationMinutes) || _tokenExpirationMinutes < 5) throw new Error(`"tokenExpirationMinutes" must be an integer >= 5`)
if (options.tokenExpirationMinutes && (!Number.isInteger(options.tokenExpirationMinutes) || options.tokenExpirationMinutes < 5)) throw new Error(`"tokenExpirationMinutes" must be an integer >= 5`)

_tokenExpirationMinutes = options.tokenExpirationMinutes || TOKEN_EXPIRATION_MINUTES

return {
type: 'auth',
Expand All @@ -40,10 +47,11 @@ function auth (secret, userStoreFilePath, options = {}) {
*/
function getAuthenticationSpecification (providerNamespace) {
return function authenticationSpecification () {
return {
return Object.assign({
provider: providerNamespace,
secured: true
}
secured: true,
useHttp: _useHttp
})
}
}

Expand Down
29 changes: 28 additions & 1 deletion test/auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,36 @@ test('authenticationSpecifiction', t => {
t.equals(result.provider, providerMock.name)
})

test('tokenExpirationMinutes - invalid setting', t => {
test('authSpecOptions - useHttp: true', t => {
t.plan(3)
let optionAuth = require('../src')(secret, path.join(__dirname, '/fixtures/user-store.json'), {useHttp: true})
let authenticationSpecification = optionAuth.getAuthenticationSpecification(providerMock.name)
let result = authenticationSpecification()
t.equals(result.secured, true)
t.equals(result.provider, providerMock.name)
t.equals(result.useHttp, true)
})

test('authSpecOptions - useHttp: false', t => {
t.plan(3)
let optionAuth = require('../src')(secret, path.join(__dirname, '/fixtures/user-store.json'), {useHttp: false})
let authenticationSpecification = optionAuth.getAuthenticationSpecification(providerMock.name)
let result = authenticationSpecification()
t.equals(result.secured, true)
t.equals(result.provider, providerMock.name)
t.equals(result.useHttp, false)
})

test('tokenExpirationMinutes - invalid "tokenExpirationMinutes" setting', t => {
t.plan(1)
t.throws(function () {
require('../src')(secret, path.join(__dirname, '/fixtures/user-store.json'), {tokenExpirationMinutes: -1})
}, /"tokenExpirationMinutes" must be an integer >= 5/)
})

test('tokenExpirationMinutes - invalid "useHttp" setting', t => {
t.plan(1)
t.throws(function () {
require('../src')(secret, path.join(__dirname, '/fixtures/user-store.json'), {useHttp: 'string-value'})
}, /"useHttp" must be a boolean/)
})

0 comments on commit a011ea0

Please sign in to comment.