-
Notifications
You must be signed in to change notification settings - Fork 0
/
oauth2orize-google.js
142 lines (116 loc) · 3.57 KB
/
oauth2orize-google.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
"use strict";
var AuthorizationError = require("oauth2orize").AuthorizationError;
var request = require("request");
var objectAssign = require("object-assign");
// var getGoogleProfile = require('./oauth2orize-google-utils').getGoogleProfile;
module.exports = function(opts, issue) {
if (typeof opts === "function") {
issue = opts;
opts = null;
}
if (typeof issue !== "function") {
throw new Error(
"OAuth 2.0 password exchange middleware " + "requires an issue function."
);
}
opts = opts || {};
var userProperty = opts.userProperty || "user";
var separators = opts.scopeSeparator || " ";
var googleConfig = opts.googleConfig || {};
if (!Array.isArray(separators)) {
separators = [separators];
}
return function google(req, res, next) {
if (!req.body) {
return next(
new Error("Request body not parsed. " + "Use bodyParser middleware.")
);
}
// The `user` property of `req` holds the authenticated user. In the case
// of the token end-point, this property will contain the OAuth 2.0 client.
var client = req[userProperty];
var token = req.body.token;
var locale = req.body.locale;
var scope = req.body.scope;
if (!token) {
return next(
new AuthorizationError("Missing Google token!", "invalid_request")
);
}
// googleConfig.redirect_uri = req.get('origin') || googleConfig.redirect_uri
getGoogleProfile(token, locale, function(err, profile) {
if (err) {
return next(
new AuthorizationError(
err.message || "Could not get Google profile using provided token.",
"invalid_request"
)
);
}
// change google profile locale for our own locale:
profile.locale = locale;
if (scope) {
for (var i = 0, len = separators.length; i < len; i++) {
// Only separates on the first matching separator.
// This allows for a sort of separator "priority"
// (ie, favors spaces then fallback to commas).
var separated = scope.split(separators[i]);
if (separated.length > 1) {
scope = separated;
break;
}
}
if (!Array.isArray(scope)) {
scope = [scope];
}
}
var issued = function(err, accessToken, refreshToken, params) {
if (err) {
return next(err);
}
if (!accessToken) {
return next(
new AuthorizationError(
"Permissions was not granted.",
"invalid_grant"
)
);
}
var json = { access_token: accessToken };
if (refreshToken) {
json["refresh_token"] = refreshToken;
}
if (params) {
objectAssign(json, params);
}
json["token_type"] = json["token_type"] || "bearer";
json = JSON.stringify(json);
res.setHeader("Content-Type", "application/json");
res.setHeader("Cache-Control", "no-store");
res.setHeader("Pragma", "no-cache");
res.end(json);
};
issue(client, profile, scope, issued);
});
};
};
function getGoogleProfile(accessToken, locale, cb) {
request(
{
url:
"https://www.googleapis.com/oauth2/v3/userinfo?access_token=" +
accessToken,
json: true
},
function(err, res, body) {
if (err) {
return cb(err);
}
if (body && body.error) {
var msg = body.error.message || "Could not get Google profile.";
return cb(new Error(msg));
}
cb(null, body);
}
);
}