UNPKG

5.38 kBJavaScriptView Raw
1/****************
2 * IMPORTS
3 */
4
5var util = require('util')
6var OAuth2Strategy = require('passport-oauth2')
7var InternalOAuthError = require('passport-oauth2').InternalOAuthError
8
9/**
10 * `Strategy` constructor.
11 *
12 * The Google authentication strategy authenticates requests by delegating to
13 * Google using the OAuth 2.0 protocol.
14 *
15 * Applications must supply a `verify` callback which accepts an `accessToken`,
16 * `refreshToken` and service-specific `profile`, and then calls the `done`
17 * callback supplying a `user`, which should be set to `false` if the
18 * credentials are not valid. If an exception occured, `err` should be set.
19 *
20 * Options:
21 * - `clientId` your Google application's client id
22 * - `clientSecret` your Google application's client secret
23 * - `callbackURL` URL to which Google will redirect the user after granting authorizationin your Google Application
24 *
25 * Examples:
26 *
27 * passport.use(new GoogleDriveStrategy({
28 * clientID: '123-456-789',
29 * clientSecret: 'shhh-its-a-secret'
30 * callbackURL: 'https://www.example.net/auth/google-drive/callback'
31 * },
32 * function(accessToken, refreshToken, profile, done) {
33 * User.findOrCreate(..., function (err, user) {
34 * done(err, user);
35 * });
36 * }
37 * ));
38 *
39 * @param {Object} options
40 * @param {Function} verify
41 * @api public
42 */
43
44function GoogleDriveStrategy (options, verify) {
45 options = options || {};
46 options.authorizationURL = options.authorizationURL || 'https://accounts.google.com/o/oauth2/auth'
47 options.tokenURL = options.tokenURL || 'https://accounts.google.com/o/oauth2/token'
48
49 OAuth2Strategy.call(this, options, verify)
50 this.name = 'google-drive'
51}
52
53/**
54 * Inherit from `OAuth2Strategy`.
55 */
56
57util.inherits(GoogleDriveStrategy, OAuth2Strategy)
58
59/**
60 * Retrieve user profile from Google Drive.
61 *
62 * This function constructs a normalized profile, with the following properties:
63 *
64 * - `provider` always set to `google-drive`
65 * - `id`
66 * - etc..
67 *
68 * @param {String} accessToken
69 * @param {Function} done
70 * @api protected
71 */
72
73GoogleDriveStrategy.prototype.authenticate = function (req, options) {
74 options || (options = {})
75
76 var oldHint = options.loginHint
77 options.loginHint = req.query.login_hint
78 OAuth2Strategy.prototype.authenticate.call(this, req, options)
79 options.loginHint = oldHint
80}
81
82GoogleDriveStrategy.prototype.userProfile = function (accessToken, done) {
83
84 this._oauth2.get('https://www.googleapis.com/drive/v2/about', accessToken, function (err, body, res) {
85
86 if (err) {
87 return done(new InternalOAuthError('failed to fetch user profile', err))
88 }
89 try {
90 var json = JSON.parse(body)
91
92 var profile = { provider: 'google-drive' }
93 profile.id = 'drive-' + json.user.permissionId
94 profile.displayName = json.user.displayName
95 profile.name = json.name
96
97 if (json.user.emailAddress) {
98 profile.email = json.user.emailAddress
99 }
100 if (json.user.picture) {
101 profile.picture = json.user.picture.url
102 }
103 profile.quotaBytesTotal = json.quotaBytesTotal || 0
104 profile.quotaBytesUsed = json.quotaBytesUsed || 0
105 profile.quotaBytesUsedAggregate = json.quotaBytesUsedAggregate || 0
106 profile.quotaBytesUsedInTrash = json.quotaBytesUsedInTrash || 0
107 profile.quotaType = json.quotaType || ''
108
109 profile._raw = body
110 profile._json = json
111
112 done(null, profile)
113 }
114 catch (e) {
115 done(e)
116 }
117 })
118}
119
120GoogleDriveStrategy.prototype.authorizationParams = function (options) {
121 var params = {}
122 if (options.accessType) {
123 params['access_type'] = options.accessType
124 }
125 if (options.approvalPrompt) {
126 params['approval_prompt'] = options.approvalPrompt
127 }
128 if (options.prompt) {
129 // This parameter is undocumented in Google's official documentation.
130 // However, it was detailed by Breno de Medeiros (who works at Google) in
131 // this Stack Overflow answer:
132 // http://stackoverflow.com/questions/14384354/force-google-account-chooser/14393492#14393492
133 params['prompt'] = options.prompt
134 }
135 if (options.loginHint) {
136 // This parameter is derived from OpenID Connect, and supported by Google's
137 // OAuth 2.0 endpoint.
138 // https://github.com/jaredhanson/passport-google-oauth/pull/8
139 // https://bitbucket.org/openid/connect/commits/970a95b83add
140 params['login_hint'] = options.loginHint
141 }
142 if (options.userID) {
143 // Undocumented, but supported by Google's OAuth 2.0 endpoint. Appears to
144 // be equivalent to `login_hint`.
145 params['user_id'] = options.userID
146 }
147 if (options.hostedDomain || options.hd) {
148 // This parameter is derived from Google's OAuth 1.0 endpoint, and (although
149 // undocumented) is supported by Google's OAuth 2.0 endpoint was well.
150 // https://developers.google.com/accounts/docs/OAuth_ref
151 params['hd'] = options.hostedDomain || options.hd
152 }
153 return params
154}
155
156/**
157 * Expose `Strategy`.
158 */
159
160module.exports = GoogleDriveStrategy