Skip to content

Commit f91b733

Browse files
committed
Add basic support for emails parsing
1 parent 504ebdb commit f91b733

File tree

4 files changed

+62
-5
lines changed

4 files changed

+62
-5
lines changed

example/backend/passport.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
'use strict';
22

33
var passport = require('passport'),
4-
BitbucketTokenStrategy = require('passport-bitbucket-token'),
4+
BitbucketTokenStrategy = require('../../lib/index'),
55
User = require('mongoose').model('User');
66

77
module.exports = function () {
88

99
passport.use(new BitbucketTokenStrategy({
1010
clientID: 'app-id',
1111
clientSecret: 'client-secret'
12+
apiVersion: '1.0',
13+
profileWithEmail: true
1214
},
1315
function (accessToken, refreshToken, profile, done) {
1416
User.upsertUser(accessToken, refreshToken, profile, function(err, user) {

example/backend/server.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ var generateToken = function (req, res, next) {
5757

5858
var sendToken = function (req, res) {
5959
res.setHeader('x-auth-token', req.token);
60-
res.status(200).send(req.auth);
60+
res.status(200).send(req.user);
6161
};
6262

6363
router.route('/auth/bitbucket')

src/index.js

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,11 @@ export default class BitbucketTokenStrategy extends OAuth2Strategy {
1515
super(options, verify);
1616

1717
this.name = 'bitbucket-token';
18-
this.apiVersion = options.apiVersion || '1.0';
18+
this._apiVersion = options.apiVersion || '1.0';
19+
this._profileWithEmail = options.profileWithEmail || false;
1920
this._accessTokenField = options.accessTokenField || 'access_token';
2021
this._refreshTokenField = options.refreshTokenField || 'refresh_token';
21-
this._profileURL = `https://api.bitbucket.org/${this.apiVersion}/user`;
22+
this._profileURL = `https://api.bitbucket.org/${this._apiVersion}/user`;
2223
this._clientSecret = options.clientSecret;
2324
this._passReqToCallback = options.passReqToCallback || false;
2425
this._oauth2.useAuthorizationHeaderforGET(true);
@@ -48,6 +49,31 @@ export default class BitbucketTokenStrategy extends OAuth2Strategy {
4849
});
4950
}
5051

52+
loadUserMail(accessToken, accountName, done) {
53+
const emailUrlPath = this._apiVersion === '2.0' ? 'https://api.bitbucket.org/2.0/user/emails' : `https://api.bitbucket.org/1.0/users/${accountName}/emails`;
54+
const emailUrl = uri.parse(emailUrlPath);
55+
56+
this._oauth2.get(emailUrl, accessToken, (error, body, res) => {
57+
if (error) return done(new InternalOAuthError('Failed to fetch user profile', error));
58+
59+
try {
60+
const json = JSON.parse(body);
61+
62+
return this._apiVersion === '2.0' ? this.parseV2Emails(json) : this.parseV1Emails(json);
63+
} catch (e) {
64+
done(e);
65+
}
66+
});
67+
}
68+
69+
parseV1Emails(body) {
70+
return body.map(email => {return { value: email.email, primary: email.primary, verified: email.active }; });
71+
}
72+
73+
parseV2Emails(body) {
74+
return body.values.map(email => { return {value: email.email, primary: email.is_primary, verified: email.is_confirmed}; });
75+
}
76+
5177
userProfile(accessToken, done) {
5278
let profileURL = uri.parse(this._profileURL);
5379

@@ -57,7 +83,11 @@ export default class BitbucketTokenStrategy extends OAuth2Strategy {
5783
try {
5884
const json = JSON.parse(body);
5985

60-
const profile = this.apiVersion === '1.0' ? this.parseV1Profile(json, body) : this.parseV2Profile(json, body);
86+
const profile = this._apiVersion === '1.0' ? this.parseV1Profile(json, body) : this.parseV2Profile(json, body);
87+
88+
if (this._profileWithEmail) {
89+
profile.emails = this.loadUserMail(accessToken, profile.username, done);
90+
}
6191

6292
done(null, profile);
6393
} catch (e) {

test/init-sequence.test.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ describe('BitbucketTokenStrategy:init', () => {
2727
assert.equal(strategy._accessTokenField, 'access_token');
2828
assert.equal(strategy._refreshTokenField, 'refresh_token');
2929
assert.equal(strategy._passReqToCallback, false);
30+
assert.equal(strategy._apiVersion, '1.0');
31+
assert.equal(strategy._profileWithEmail, false);
3032
});
3133

3234
it('Should changed property correctly', () => {
@@ -49,6 +51,8 @@ describe('BitbucketTokenStrategy:init', () => {
4951
assert.equal(strategy._accessTokenField, 'test_access_token');
5052
assert.equal(strategy._refreshTokenField, 'test_refresh_token');
5153
assert.equal(strategy._passReqToCallback, true);
54+
assert.equal(strategy._apiVersion, '1.0');
55+
assert.equal(strategy._profileWithEmail, false);
5256
});
5357

5458
it('Should change profile URL when API version is set to 2.0', () => {
@@ -72,6 +76,27 @@ describe('BitbucketTokenStrategy:init', () => {
7276
assert.equal(strategy._accessTokenField, 'test_access_token');
7377
assert.equal(strategy._refreshTokenField, 'test_refresh_token');
7478
assert.equal(strategy._passReqToCallback, true);
79+
assert.equal(strategy._apiVersion, '2.0');
80+
assert.equal(strategy._profileWithEmail, false);
81+
});
82+
83+
it('Should change value of profile with email to true', () => {
84+
let strategy = new BitbucketTokenStrategy({
85+
clientID: '123',
86+
clientSecret: '123',
87+
profileWithEmail: true
88+
}, () => {});
89+
90+
assert.equal(strategy.name, 'bitbucket-token');
91+
assert.equal(strategy._oauth2._useAuthorizationHeaderForGET, true);
92+
assert.equal(strategy._oauth2._accessTokenUrl, 'https://bitbucket.org/site/oauth2/access_token');
93+
assert.equal(strategy._oauth2._authorizeUrl, 'https://bitbucket.org/site/oauth2/authorize');
94+
assert.equal(strategy._profileURL,`https://api.bitbucket.org/1.0/user`);
95+
assert.equal(strategy._accessTokenField, 'access_token');
96+
assert.equal(strategy._refreshTokenField, 'refresh_token');
97+
assert.equal(strategy._passReqToCallback, false);
98+
assert.equal(strategy._apiVersion, '1.0');
99+
assert.equal(strategy._profileWithEmail, true);
75100
});
76101

77102
});

0 commit comments

Comments
 (0)