Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
node_modules
*.swp
*.sh
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,18 @@ $ npm install libbeacon

## Example
```js
var beacon = new Libbeacon();
beacon.login('username', 'password', function(err, success) {
beacon.get('Jobs/1', {}, function(error, data) {
console.log(data);
}
const libbeacon = require('libbeacon')(client_id, client_secret, 'preview');
libbeacon.login('username', 'password').then((api) => {
api.get('Messages/')
}, (error) => {
// fail
});
```

## Tests
```bash
$ npm install
$ BEACON_USERNAME='user' BEACON_PASSWORD='pass' npm test
$ IDENTITY_CLIENT_ID='' IDENTITY_CLIENT_SECRET='' BEACON_USERNAME='user' BEACON_PASSWORD='pass' npm test
```

## License
Expand Down
27 changes: 27 additions & 0 deletions example.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
const libbeacon = require("./lib/main.js"); // require('libbeacon');

if(!process.env.IDENTITY_CLIENT_ID || !process.env.IDENTITY_CLIENT_SECRET) {
assert.fail("Must set IDENTITY_CLIENT_ID and IDENTITY_CLIENT_SECRET");
}

const env = "BEACON_ENV" in process.env ? process.env.BEACON_ENV : 'prod'

const api = libbeacon(
process.env.IDENTITY_CLIENT_ID,
process.env.IDENTITY_CLIENT_SECRET,
env
);

if(!process.env.BEACON_USERNAME || !process.env.BEACON_PASSWORD) {
assert.fail("Must set BEACON_USERNAME and BEACON_PASSWORD");
}

const client = api.login(
process.env.BEACON_USERNAME,
process.env.BEACON_PASSWORD
).then((client) => {
const promise = client.get('Jobs/1', {}).then((data) => {
console.log(data);
});
});

43 changes: 43 additions & 0 deletions lib/auth.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
const oauth2 = require('simple-oauth2');
const c = require('./constants');
const debug = require('debug')('libbeacon:auth');

module.exports = function(
client_id, client_secret, environment='prod',
) {
const credentials = {
client: {
id: client_id,
secret: client_secret,
},
auth: {
tokenHost: c.environments[environment].identity_url,
tokenPath: '/core/connect/token',
authorizePath: '/core/connect/authorize',
},
};

const api = oauth2.create(credentials);

return {
getToken: (username, password) => {
return new Promise((resolve, reject) => {
const tokenConfig = {
username: username,
password: password,
scope: c.environments[environment].oauth_scope,
};

api.ownerPassword.getToken(tokenConfig)
.then((result) => {
debug('Successful auth: ', result);
resolve(api.accessToken.create(result));
})
.catch((error) => {
debug('Auth fail: ', error);
reject(Error('Access token error: ' + error.message));
});
});
},
};
};
111 changes: 111 additions & 0 deletions lib/client.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
const c = require('./constants');
const Request = require('request');
const _ = require('underscore');
const debug = require('debug')('libbeacon:client');


class Client {
constructor(token, environment) {
debug('Initialize Client with token: ', token);
this._token = token;
this.environment = environment;
const userAgent = "libbeacon/" + c.version + " (github.com/SESMembers/libbeacon)";
this._request = Request.defaults({
rejectUnauthorized: false,
timeout: 30000,
headers: {
"User-Agent": userAgent,
"Authorization": this.authHeader,
},
});
}

get authHeader() {
return 'Bearer ' +this._token.token.access_token;
}

get path() {
return c.environments[this.environment].api_url + 'Api/v1/'
}

get(path, opts) {
return new Promise((resolve, reject) => {
debug('Get request for ' + path);
var options = _.defaults(_.clone(opts) || {}, {
headers: {}, // make sure headers is an empty obj if not passed
});
options.url = this.path + path;

debug('Making request with args: ', options);
var req = this._request(options, function(error, response, body) {
if(error) {
debug('Error in HTTP request: ' + response);
reject(new Error('Error in HTTP request: ' + response));
return;
}
if(response.statusCode === 403 || response.statusCode === 401) {
reject(new Error("unauthorized"));
return;
}
if(response.statusCode != 200) {
debug('Non-200 HTTP status code: ' + response.statusCode);
reject(new Error('Non-200 HTTP status code: ' + response.statusCode));
return;
}
try {
var data = JSON.parse(body);
} catch(e) {
debug(options.url);
debug('Could not parse response: ' + body);
reject(new Error('Could not parse the API response'));
return;
}
resolve(data);
});
});
}

getPagedResults(path, opts, cb) {
if(!_.isFunction(cb))
throw new Error('Callback not specified');
this.getPagedResultsPage(path, opts, 1, cb);
}

getPagedResultsPage(path, opts, page, cb) {
// cb(error, finished, data)
var self = this;
var options = _.defaults(_.clone(opts) || {}, {
qs: {}, // make sure qs is an empty obj if not passed
});
var totalItemsKey = 'TotalItems';
if(options.totalItemsKey) {
totalItemsKey = options.totalItemsKey;
delete options.totalItemsKey;
}
options.qs['PageIndex'] = page;
const promise = this.get(path, options)
.then((data) => {
var bad = false;
bad = 'CurrentPage' in data ? bad : true;
bad = 'PageSize' in data ? bad : true;
bad = totalItemsKey in data ? bad : true;
bad = 'Results' in data ? bad : true;
if(bad) {
cb && cb('Received data that does not contain page information');
return;
}
if(data[totalItemsKey] > data['CurrentPage'] * data['PageSize']) {
cb && cb(null, false, data['Results']);
self.getPagedResultsPage(path, opts, page+1, cb);
}
else {
cb && cb(null, true, data['Results']);
}
})
.catch((error) => {
cb && cb(error);
});
}
}

module.exports = Client;
19 changes: 19 additions & 0 deletions lib/constants.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
const package = require('../package.json');

module.exports = {
version: package.version,
environments: {
prod: {
api_url: 'https://apibeacon.ses.nsw.gov.au/',
beacon_url: 'https://beacon.ses.nsw.gov.au/',
identity_url: 'https://identity.ses.nsw.gov.au/',
oauth_scope: 'beaconApi profile',
},
preview: {
api_url: 'https://apipreviewbeacon.ses.nsw.gov.au/',
beacon_url: 'https://previewbeacon.ses.nsw.gov.au/',
identity_url: 'https://identitypreview.ses.nsw.gov.au/',
oauth_scope: 'beaconApi profile',
},
}
}
Loading