Skip to content

Commit d63c910

Browse files
committed
Clean up authorization params.
1 parent 7b7b97a commit d63c910

File tree

2 files changed

+217
-24
lines changed

2 files changed

+217
-24
lines changed

lib/oauth2.js

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -131,59 +131,62 @@ Strategy.prototype.userProfile = function(accessToken, done) {
131131
*/
132132
Strategy.prototype.authorizationParams = function(options) {
133133
var params = {};
134+
135+
// https://developers.google.com/identity/protocols/OAuth2WebServer
134136
if (options.accessType) {
135137
params['access_type'] = options.accessType;
136138
}
137-
if (options.approvalPrompt) {
138-
params['approval_prompt'] = options.approvalPrompt;
139-
}
140139
if (options.prompt) {
141-
// This parameter is undocumented in Google's official documentation.
142-
// However, it was detailed by Breno de Medeiros (who works at Google) in
143-
// this Stack Overflow answer:
144-
// http://stackoverflow.com/questions/14384354/force-google-account-chooser/14393492#14393492
145140
params['prompt'] = options.prompt;
146141
}
147142
if (options.loginHint) {
148-
// This parameter is derived from OpenID Connect, and supported by Google's
149-
// OAuth 2.0 endpoint.
150-
// https://github.com/jaredhanson/passport-google-oauth/pull/8
151-
// https://bitbucket.org/openid/connect/commits/970a95b83add
152143
params['login_hint'] = options.loginHint;
153144
}
154-
if (options.userID) {
155-
// Undocumented, but supported by Google's OAuth 2.0 endpoint. Appears to
156-
// be equivalent to `login_hint`.
157-
params['user_id'] = options.userID;
145+
if (options.includeGrantedScopes) {
146+
params['include_granted_scopes'] = true;
158147
}
148+
149+
// https://developers.google.com/identity/protocols/OpenIDConnect
150+
if (options.display) {
151+
// Specify what kind of display consent screen to display to users.
152+
// https://developers.google.com/accounts/docs/OpenIDConnect#authenticationuriparameters
153+
params['display'] = options.display;
154+
}
155+
156+
// Google Apps for Work
159157
if (options.hostedDomain || options.hd) {
160158
// This parameter is derived from Google's OAuth 1.0 endpoint, and (although
161159
// undocumented) is supported by Google's OAuth 2.0 endpoint was well.
162160
// https://developers.google.com/accounts/docs/OAuth_ref
163161
params['hd'] = options.hostedDomain || options.hd;
164162
}
165-
if (options.display) {
166-
// Specify what kind of display consent screen to display to users.
167-
// https://developers.google.com/accounts/docs/OpenIDConnect#authenticationuriparameters
168-
params['display'] = options.display;
169-
}
163+
164+
// Google+
170165
if (options.requestVisibleActions) {
171166
// Space separated list of allowed app actions
172167
// as documented at:
173168
// https://developers.google.com/+/web/app-activities/#writing_an_app_activity_using_the_google_apis_client_libraries
174169
// https://developers.google.com/+/api/moment-types/
175170
params['request_visible_actions'] = options.requestVisibleActions;
176171
}
172+
173+
// OpenID 2.0 migration
177174
if (options.openIDRealm) {
178175
// This parameter is needed when migrating users from Google's OpenID 2.0 to OAuth 2.0
179176
// https://developers.google.com/accounts/docs/OpenID?hl=ja#adjust-uri
180177
params['openid.realm'] = options.openIDRealm;
181178
}
182-
if (options.includeGrantedScopes) {
183-
// For use of this parameter:
184-
// https://developers.google.com/identity/protocols/OAuth2WebServer
185-
params['include_granted_scopes'] = true;
179+
180+
// Undocumented
181+
if (options.approvalPrompt) {
182+
params['approval_prompt'] = options.approvalPrompt;
183+
}
184+
if (options.userID) {
185+
// Undocumented, but supported by Google's OAuth 2.0 endpoint. Appears to
186+
// be equivalent to `login_hint`.
187+
params['user_id'] = options.userID;
186188
}
189+
187190
return params;
188191
}
189192

test/strategy.test.js

Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,194 @@ describe('Strategy', function() {
1818
});
1919
})
2020

21+
describe('constructed with undefined options', function() {
22+
it('should throw', function() {
23+
expect(function() {
24+
var strategy = new GoogleStrategy(undefined, function(){});
25+
}).to.throw(Error);
26+
});
27+
})
28+
29+
describe('authorization request with documented parameters', function() {
30+
var strategy = new GoogleStrategy({
31+
clientID: 'ABC123',
32+
clientSecret: 'secret'
33+
}, function() {});
34+
35+
36+
var url;
37+
38+
before(function(done) {
39+
chai.passport.use(strategy)
40+
.redirect(function(u) {
41+
url = u;
42+
done();
43+
})
44+
.req(function(req) {
45+
req.session = {};
46+
})
47+
.authenticate({ prompt: 'select_account', loginHint: 'john@mail.com', accessType: 'offline' });
48+
});
49+
50+
it('should be redirected', function() {
51+
expect(url).to.equal('https://accounts.google.com/o/oauth2/v2/auth?access_type=offline&prompt=select_account&login_hint=john%40mail.com&response_type=code&redirect_uri=&client_id=ABC123');
52+
});
53+
}); // authorization request with documented parameters
54+
55+
describe('authorization request with incremental authorization parameters', function() {
56+
var strategy = new GoogleStrategy({
57+
clientID: 'ABC123',
58+
clientSecret: 'secret'
59+
}, function() {});
60+
61+
62+
var url;
63+
64+
before(function(done) {
65+
chai.passport.use(strategy)
66+
.redirect(function(u) {
67+
url = u;
68+
done();
69+
})
70+
.req(function(req) {
71+
req.session = {};
72+
})
73+
.authenticate({ scope: [ 'https://www.googleapis.com/auth/drive.file' ], includeGrantedScopes: true });
74+
});
75+
76+
it('should be redirected', function() {
77+
expect(url).to.equal('https://accounts.google.com/o/oauth2/v2/auth?include_granted_scopes=true&response_type=code&redirect_uri=&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive.file&client_id=ABC123');
78+
});
79+
}); // authorization request with incremental authorization parameters
80+
81+
describe('authorization request with Google Apps for Work parameters', function() {
82+
var strategy = new GoogleStrategy({
83+
clientID: 'ABC123',
84+
clientSecret: 'secret'
85+
}, function() {});
86+
87+
88+
var url;
89+
90+
before(function(done) {
91+
chai.passport.use(strategy)
92+
.redirect(function(u) {
93+
url = u;
94+
done();
95+
})
96+
.req(function(req) {
97+
req.session = {};
98+
})
99+
.authenticate({ hostedDomain: 'example.com' });
100+
});
101+
102+
it('should be redirected', function() {
103+
expect(url).to.equal('https://accounts.google.com/o/oauth2/v2/auth?hd=example.com&response_type=code&redirect_uri=&client_id=ABC123');
104+
});
105+
}); // authorization request with Google Apps for Work parameters
106+
107+
describe('authorization request with Google Apps for Work parameters, in abbreviated form', function() {
108+
var strategy = new GoogleStrategy({
109+
clientID: 'ABC123',
110+
clientSecret: 'secret'
111+
}, function() {});
112+
113+
114+
var url;
115+
116+
before(function(done) {
117+
chai.passport.use(strategy)
118+
.redirect(function(u) {
119+
url = u;
120+
done();
121+
})
122+
.req(function(req) {
123+
req.session = {};
124+
})
125+
.authenticate({ hd: 'example.com' });
126+
});
127+
128+
it('should be redirected', function() {
129+
expect(url).to.equal('https://accounts.google.com/o/oauth2/v2/auth?hd=example.com&response_type=code&redirect_uri=&client_id=ABC123');
130+
});
131+
}); // authorization request with Google Apps for Work parameters, in abbreviated form
132+
133+
describe('authorization request with Google+ parameters', function() {
134+
var strategy = new GoogleStrategy({
135+
clientID: 'ABC123',
136+
clientSecret: 'secret'
137+
}, function() {});
138+
139+
140+
var url;
141+
142+
before(function(done) {
143+
chai.passport.use(strategy)
144+
.redirect(function(u) {
145+
url = u;
146+
done();
147+
})
148+
.req(function(req) {
149+
req.session = {};
150+
})
151+
.authenticate({ requestVisibleActions: 'http://schema.org/AddAction http://schema.org/ReviewAction' });
152+
});
153+
154+
it('should be redirected', function() {
155+
expect(url).to.equal('https://accounts.google.com/o/oauth2/v2/auth?request_visible_actions=http%3A%2F%2Fschema.org%2FAddAction%20http%3A%2F%2Fschema.org%2FReviewAction&response_type=code&redirect_uri=&client_id=ABC123');
156+
});
157+
}); // authorization request with Google+ parameters
158+
159+
describe('authorization request with OpenID 2.0 migration parameters', function() {
160+
var strategy = new GoogleStrategy({
161+
clientID: 'ABC123',
162+
clientSecret: 'secret'
163+
}, function() {});
164+
165+
166+
var url;
167+
168+
before(function(done) {
169+
chai.passport.use(strategy)
170+
.redirect(function(u) {
171+
url = u;
172+
done();
173+
})
174+
.req(function(req) {
175+
req.session = {};
176+
})
177+
.authenticate({ openIDRealm: 'http://www.example.com/' });
178+
});
179+
180+
it('should be redirected', function() {
181+
expect(url).to.equal('https://accounts.google.com/o/oauth2/v2/auth?openid.realm=http%3A%2F%2Fwww.example.com%2F&response_type=code&redirect_uri=&client_id=ABC123');
182+
});
183+
}); // authorization request with OpenID 2.0 migration parameters
184+
185+
describe('authorization request with undocumented parameters', function() {
186+
var strategy = new GoogleStrategy({
187+
clientID: 'ABC123',
188+
clientSecret: 'secret'
189+
}, function() {});
190+
191+
192+
var url;
193+
194+
before(function(done) {
195+
chai.passport.use(strategy)
196+
.redirect(function(u) {
197+
url = u;
198+
done();
199+
})
200+
.req(function(req) {
201+
req.session = {};
202+
})
203+
.authenticate({ approvalPrompt: 'none', userID: '1' });
204+
});
205+
206+
it('should be redirected', function() {
207+
expect(url).to.equal('https://accounts.google.com/o/oauth2/v2/auth?approval_prompt=none&user_id=1&response_type=code&redirect_uri=&client_id=ABC123');
208+
});
209+
}); // authorization request with undocumented parameters
210+
21211
});

0 commit comments

Comments
 (0)