Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fitbit provider #240

Merged
merged 5 commits into from Jul 16, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion API.md
Expand Up @@ -65,7 +65,7 @@ server.register(require('bell'), function (err) {
### Options

The `server.auth.strategy()` method requires the following strategy options:
- `provider` - the name of the third-party provider (`'auth0'`, `'bitbucket'`, `'dropbox'`, `'facebook'`, `'foursquare'`, `'github'`, `'google'`, `'instagram'`, `'linkedin'`, `'live'`, `'twitter'`, `'vk'`, `'arcgisonline'`, `'yahoo'`, `'nest'`, `'phabricator'`, `'office365'`, `'pinterest'`)
- `provider` - the name of the third-party provider (`'auth0'`, `'bitbucket'`, `'dropbox'`, `'facebook'`, `'fitbit'`, `'foursquare'`, `'github'`, `'google'`, `'instagram'`, `'linkedin'`, `'live'`, `'twitter'`, `'vk'`, `'arcgisonline'`, `'yahoo'`, `'nest'`, `'phabricator'`, `'office365'`, `'pinterest'`)
or an object containing a custom provider with the following:
- `protocol` - the authorization protocol used. Must be one of:
- `'oauth'` - OAuth 1.0a
Expand Down
19 changes: 19 additions & 0 deletions Providers.md
Expand Up @@ -127,6 +127,25 @@ credentials.profile = {
};
```

### Fitbit

[Provider Documentation](https://dev.fitbit.com/docs/oauth2/)

- `scope`: Defaults to `['activity', 'profile']`
- `config`: not applicable
- `auth`: https://www.fitbit.com/oauth2/authorize
- `token`: https://api.fitbit.com/oauth2/token

The default profile response will look like this:

```javascript
credentials.profile = {
id: profile.user.encodedId,
displayName: profile.user.displayName,
name: profile.user.fullName
};
```

### Foursquare

[Provider Documentation](https://developer.foursquare.com/overview/auth)
Expand Down
25 changes: 25 additions & 0 deletions lib/providers/fitbit.js
@@ -0,0 +1,25 @@
'use strict';

exports = module.exports = function (options) {

return {
protocol: 'oauth2',
useParamsAuth: false,
auth: 'https://www.fitbit.com/oauth2/authorize',
token: 'https://api.fitbit.com/oauth2/token',
scope: ['activity','profile'], //see https://dev.fitbit.com/docs/oauth2/#scope
profile: function (credentials, params, get, callback) {

get('https://api.fitbit.com/1/user/-/profile.json', null, (profile) => {

credentials.profile = {
id: profile.user.encodedId,
displayName: profile.user.displayName,
name: profile.user.fullName
};

return callback();
});
}
};
};
1 change: 1 addition & 0 deletions lib/providers/index.js
Expand Up @@ -5,6 +5,7 @@ exports = module.exports = {
bitbucket: require('./bitbucket'),
dropbox: require('./dropbox'),
facebook: require('./facebook'),
fitbit: require('./fitbit'),
foursquare: require('./foursquare'),
github: require('./github'),
gitlab: require('./gitlab'),
Expand Down
1 change: 1 addition & 0 deletions package.json
Expand Up @@ -15,6 +15,7 @@
"bitbucket",
"dropbox",
"facebook",
"fitbit",
"foursquare",
"github",
"gitlab",
Expand Down
92 changes: 92 additions & 0 deletions test/providers/fitbit.js
@@ -0,0 +1,92 @@
'use strict';

// Load modules

const Bell = require('../../');
const Code = require('code');
const Hapi = require('hapi');
const Hoek = require('hoek');
const Lab = require('lab');
const Mock = require('../mock');


// Test shortcuts

const lab = exports.lab = Lab.script();
const describe = lab.describe;
const it = lab.it;
const expect = Code.expect;


describe('fitbit', () => {

it('authenticates with mock', { parallel: false }, (done) => {

const mock = new Mock.V2();
mock.start((provider) => {

const server = new Hapi.Server();
server.connection({ host: 'localhost', port: 80 });
server.register(Bell, (err) => {

expect(err).to.not.exist();

const custom = Bell.providers.fitbit();
Hoek.merge(custom, provider);

const profile = {
user: {
encodedId: '1234',
displayName: 'Steve',
fullName: 'Steve Smith'
}
};

Mock.override('https://api.fitbit.com/1/user/-/profile.json', profile);

server.auth.strategy('custom', 'bell', {
password: 'cookie_encryption_password_secure',
isSecure: false,
clientId: 'fitbit',
clientSecret: 'secret',
provider: custom
});

server.route({
method: '*',
path: '/login',
config: {
auth: 'custom',
handler: function (request, reply) {

reply(request.auth.credentials);
}
}
});

server.inject('/login', (res) => {

const cookie = res.headers['set-cookie'][0].split(';')[0] + ';';
mock.server.inject(res.headers.location, (mockRes) => {

server.inject({ url: mockRes.headers.location, headers: { cookie: cookie } }, (response) => {

Mock.clear();

expect(response.result).to.equal({
provider: 'custom',
token: '456',
expiresIn: 3600,
refreshToken: undefined,
query: {},
profile: { id: '1234', displayName: 'Steve', name: 'Steve Smith' }
});

mock.stop(done);
});
});
});
});
});
});
});