Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

halfpenny

Package Overview
Dependencies
Maintainers
3
Versions
25
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

halfpenny - npm Package Compare versions

Comparing version 0.0.5 to 2.0.0

src/client-src-stub.js

41

package.json
{
"name": "halfpenny",
"version": "0.0.5",
"description": "Official javascript COINS API client. Nodejs and Browser compatible!",
"main": "build/halfpenny.bundle.js",
"version": "2.0.0",
"description": "Official javascript COINS API client. Not browser compatible!",
"main": "src/index.js",
"scripts": {
"test": "echo 'run integration tests in nodeapi'",
"test": "node src/test.js",
"preversion": "git checkout master && git pull && npm ls",

@@ -12,6 +12,5 @@ "publish-patch": "npm run preversion && npm version patch && git push origin master --tags && npm publish",

"publish-major": "npm run preversion && npm version major && git push origin master --tags && npm publish",
"lint": "grunt lint",
"validate": "npm ls",
"build": "grunt build",
"add-build-to-commit": "git add build/*"
"lint": "jscs",
"postlint": "jshint",
"validate": "npm ls"
},

@@ -29,25 +28,6 @@ "repository": {

"devDependencies": {
"babel-core": "^6.3.21",
"babel-loader": "^6.2.0",
"babel-plugin-transform-runtime": "^6.3.13",
"babel-preset-es2015": "^6.3.13",
"coins-grunt-env": "^1.0.2",
"grunt": "^0.4.5",
"grunt-contrib-jshint": "^0.11.3",
"grunt-env": "^0.4.4",
"grunt-exec": "^0.4.6",
"grunt-jscs": "^2.3.0",
"load-grunt-config": "^0.19.0",
"load-grunt-tasks": "^3.3.0",
"precommit-hook": "^3.0.0",
"time-grunt": "^1.2.2",
"webpack": "^1.12.4"
"axios": "0.9.1",
"dom-storage": "2.0.2"
},
"dependencies": {
"btoa": "^1.1.2",
"dom-storage": "^2.0.2",
"es6-object-assign": "^1.0.1",
"hawk": "^4.0.0",
"rename-keys": "^1.1.2"
},
"dependencies": {},
"pre-commit": [

@@ -57,5 +37,4 @@ "lint",

"test",
"build",
"add-build-to-commit"
]
}
# halfpenny // COINS API Javascript client
What is a [halfpenny](https://en.wikipedia.org/wiki/Halfpenny_(British_pre-decimal_coin)), anyway? Beyond an old-timey coin, halfpenny is the official javascript API client for the COINS platform.
What is a [halfpenny](https://en.wikipedia.org/wiki/Halfpenny_(British_pre-decimal_coin)), anyway? Beyond an old-timey coin (AKA a pence), halfpenny is the official javascript API client for the COINS platform.
## alpha warning
halfpenny is still in active development! it is not ready for public usage
halfpenny is still in active development! it is not ready for public usage!
### TODO:
* support UMD and browser compatibility.
* Auto-generate documentation from API client
## peer dependencies
### request
In order to keep the use of this client as flexible as possible, the client
needs to be initialized with a function that can be used to make XHR requests.
The client was designed to work with the [request](https://www.npmjs.com/package/request)
package, but it can be adapted to work with others (like browser-request, or xhr).
### axios
A HTTP request agent is required to retrieve the Client source code and to make
requests. Axios was chosen as that client in order to support both server and
browser environments.
## configuration
### localstorage
In order to persist data to disk, a localstorage interface is required. In the
browser, this means supplying `window.localStorage` in the browser, and using
`node-localstorage` or `dom-storage` on the server.
### basic configuration:
```
const request = require('request');
const Promise = require('bluebird');
const apiClientOptions = {
requestFn: Promise.promisify(request),
baseUrl: 'http://localhost:3000'
};j
const client = require('../sdk/index.js')(apiClientOptions);
```
## basic configuration:
*See examples*
The above configuration parameters are *required*.
**Note that the 'requestFn' must be promisified**
### advanced configuration
## How it works:
This client can use multiple request engines to make requests to the API. This
allows the COINS team to use the client for its integration tests as well as
for its browser application. Most of the configuration is centered around mapping
the parameters that the client will feed to the request engine. If you are using
*request* as your request engine, then there is no configuration needed. See
`nodeapi/test/utils/init-api-client` for an example of how to configure the
client to use *hapi server.injectThen*.
The source code for the client is auto-generated during the build process of the
API itself. The API then bundles and serves the source code from `/client/client.js`.
## usage
This package retrieves the bundled source code and evaluates it. The result is an
object with properties corresponding to each method exposed by an API endpoint
(e.g. `ScansApi.get()`).
Once you have a configured client, you can use the following methods to interact
with the COINS API:
## examples
### *{Promise}* = .auth.login(username, password)
```js
const agent = require('axios');
const DomStorage = require('dom-storage');
const store = new DomStorage('/path/to/file', {strict: true});
const apiClientOptions = {
xhrAgent: agent,
baseUrl: 'http://localhost:8800', // hostname:port of nodeapi service
store: store
};
const clientReady = require('halfpenny')(apiClientOptions)
.catch((err) => {
//whoops
});
Sends POST request to /auth/keys, and stores resulting credentials.
// login
clientReady.then((client) => {
return client.auth.login('username', 'password');
});
### *{Promise}* = .auth.logout(username, password)
// get scans
clientReady.then((client) => {
return client.ScansApi.get(null, 'M87100000')
});
```
Sends DELETE request to /auth/keys, and removes credentials.
### *{Promise}* = .getAuthCredentials()
Get the credentials currently stored.
### *{Promise}* = .setAuthCredentials(val)
Set the credentials stored: will overwrite if already set.
### *{Promise}* = .makeRequest(options, sign)
Takes a set of request options formatted for the *request* library, and
modifies the options according to the requestObjectMap before signing the
request (*if `sign !== false`*) and sending it.
# examples
See `nodeapi/test/integration/keys.js`
See `nodeapi/test/integration` for more

@@ -1,145 +0,72 @@

/* global Promise */
/**
* @module halfpenny
*/
var defaultBaseUrl = 'https://coins-api.mrn.org';
var defaultClientPath = '/api/client/client.js';
var assign = require('es6-object-assign').assign;
var hawk = require('hawk/lib/browser.js');
var renameKeys = require('rename-keys');
var storage = require('./utils/get-storage-engine.js');
var routes = require('./routes/index.js');
function evalClientSrc (src) {
// @TODO: verify hmac of src for security
return eval(src);
}
var hawkClientHeader = hawk.client.header;
var authKeyId = 'COINS_AUTH_CREDENTIALS';
var defaultConfig = require('./config-default.js');
var me = {};
function extractClientSrc(response) {
if (!response.data) {
throw new Error('Client source code invalid');
}
return response.data;
}
/**
* get the currently stored auth credentials
* @return {Promise} resolves to the credentials object
*/
var getAuthCredentials = function() {
return new Promise(function(resolve) {
resolve(JSON.parse(storage.getItem(authKeyId)));
});
};
function assertOptions(options) {
// validate options
if (!options.xhrAgent) {
throw new Error('Options must include an xhrAgent (e.g. axios)');
}
/**
* set auth credentials
* @param {object} val the credentials to be saved
* @return {Promise} resolves to an object containing the id and rev
*/
var setAuthCredentials = function(credentials) {
return new Promise(function(resolve) {
storage.setItem(authKeyId, JSON.stringify(credentials));
resolve(getAuthCredentials());
});
};
if (!options.store || !options.store.setItem || !options.store.getItem) {
throw new Error('Options must include a `store` (e.g. localstorage)');
}
/**
* generate the header expected by Hawk.
* Note that the url must include a protocol and hostname
* @param {string} url
* @param {string} method e.g. 'GET'
* @return {string} The hawk auth signature
*/
var generateHawkHeader = function(url, method) {
return me.getAuthCredentials()
.then(function(credentials) {
if (!credentials) {
throw new Error('No credentials found to sign with');
}
if (!options.baseUrl || options.baseUrl.indexOf('http') !== 0) {
throw new Error('Options must include a valid baseUrl');
}
return me.getHawkHeader(
url,
method,
{ credentials: credentials }
);
});
};
/**
* format requestObj for use by requestFn
* @param {object} requestObj the object to be passed to the requestFn
* @return {object} the object after mapping keys to new ones
*/
var formatRequestOptions = function(requestOptions) {
if (me.config.onPreFormatRequestOptions instanceof Function) {
requestOptions = me.config.onPreFormatRequestOptions(
requestOptions
);
if (
!options.clientUrl ||
options.clientUrl.indexOf(options.baseUrl) !== 0
) {
throw new Error('Options must include a valid clientUrl');
}
requestOptions.uri = [
me.config.baseUrl,
'/v' + me.config.version,
requestOptions.uri
].join('');
return options;
}
return renameKeys(requestOptions, function(key) {
return me.config.requestObjectMap[key] || key;
});
};
function getDefaults(_options) {
/**
* make a request using config.requestFn
* @param {object} options request options to be passed to requestFn
* @return {Promise} promise that resolves with the value of the response
*/
var makeRequest = function(options, sign) {
var formattedOptions = formatRequestOptions(options);
//shallow copy options
var options = Object.create(_options);
options.baseUrl = options.baseUrl || defaultBaseUrl;
options.clientUrl = options.baseUrl + defaultClientPath;
return options;
}
/**
* convenience function for sending the formatted request
* @return {Promise} resolves to the formatted response value
*/
var sendRequest = function() {
return me.config.requestFn(formattedOptions)
.then(me.config.formatResponseCallback);
function constructClient (options, clientFactory) {
var config = {
xhrAgent: options.xhrAgent,
store: options.store,
apiUrl: options.baseUrl
};
return clientFactory(config);
}
/**
* convenience function for adding a header property to the
* formattedOptions
* @param {object} header output from hawk.client.header();
* @return {null} nothing
*/
var addFormattedHeader = function(header) {
var headers = formattedOptions.headers || [];
headers.push({
name: 'Authorization',
value: header.field
});
formattedOptions.headers = me.config.formatRequestHeaders(headers);
return;
};
module.exports = function(_options) {
var options = getDefaults(_options);
assertOptions(options);
var masterPromise;
if (sign !== false) {
masterPromise = generateHawkHeader(
formattedOptions.url,
formattedOptions.method
)
.then(addFormattedHeader);
} else {
masterPromise = Promise.resolve();
}
return masterPromise.then(sendRequest);
return options.xhrAgent.get(options.clientUrl)
.then(extractClientSrc)
.then(evalClientSrc)
.then(constructClient.bind(null, options))
};
module.exports = function init(config) {
me.config = assign({}, defaultConfig, config);
me.getHawkHeader = hawkClientHeader;
me.generateHawkHeader = generateHawkHeader;
me.makeRequest = makeRequest;
me.setAuthCredentials = setAuthCredentials;
me.getAuthCredentials = getAuthCredentials;
me.auth = routes.authentication(me);
me.scans = routes.scans(me);
me.users = routes.users(me);
me.coinstac = {
consortia: routes.coinstac.consortia(me)
};
return me;
};
module.exports.getDefaults = getDefaults;
module.exports.assertOptions = assertOptions;
module.exports.evalClientSrc = evalClientSrc;
module.exports.extractClientSrc = extractClientSrc;
module.exports.constructClient = constructClient;
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc