Skip to content

Commit 80de86c

Browse files
AndrewLaneflovilmart
authored andcommitted
Implement Janrain Capture and Janrain Engage auth provider (#2436)
* Janrain engage auth provider * Modeled after the existing providers in /src/authDataManager/ and also after https://github.com/janrain/Janrain-Sample-Code/blob/master/widget-examples/server.js * See also: http://developers.janrain.com/overview/social-login/identity-providers/user-profile-data/#normalized-user-profile-data * Janrain capture auth provider * Modeled after the existing providers in /src/authDataManager/ * See also: https://docs.janrain.com/api/registration/entity/#entity * Janrain engage auth provider * Modeled after the existing providers in /src/authDataManager/ and also after https://github.com/janrain/Janrain-Sample-Code/blob/master/widget-examples/server.js * See also: http://developers.janrain.com/overview/social-login/identity-providers/user-profile-data/#normalized-user-profile-data * Janrain capture auth provider * Modeled after the existing providers in /src/authDataManager/ * See also: https://docs.janrain.com/api/registration/entity/#entity * Adding missing newlines at EOF
1 parent a5a1729 commit 80de86c

File tree

4 files changed

+127
-2
lines changed

4 files changed

+127
-2
lines changed

spec/OAuth.spec.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ describe('OAuth', function() {
137137
})
138138
});
139139

140-
["facebook", "github", "instagram", "google", "linkedin", "meetup", "twitter"].map(function(providerName){
140+
["facebook", "github", "instagram", "google", "linkedin", "meetup", "twitter", "janrainengage", "janraincapture"].map(function(providerName){
141141
it("Should validate structure of "+providerName, (done) => {
142142
var provider = require("../src/authDataManager/"+providerName);
143143
jequal(typeof provider.validateAuthData, "function");

src/authDataManager/index.js

+5-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ let github = require("./github");
77
let twitter = require("./twitter");
88
let spotify = require("./spotify");
99
let digits = require("./twitter"); // digits tokens are validated by twitter
10+
let janrainengage = require("./janrainengage");
11+
let janraincapture = require("./janraincapture");
1012

1113
let anonymous = {
1214
validateAuthData: () => {
@@ -27,7 +29,9 @@ let providers = {
2729
twitter,
2830
spotify,
2931
anonymous,
30-
digits
32+
digits,
33+
janrainengage,
34+
janraincapture
3135
}
3236

3337
module.exports = function(oauthOptions = {}, enableAnonymousUsers = true) {

src/authDataManager/janraincapture.js

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
// Helper functions for accessing the Janrain Capture API.
2+
var https = require('https');
3+
var Parse = require('parse/node').Parse;
4+
var querystring = require('querystring');
5+
6+
// Returns a promise that fulfills iff this user id is valid.
7+
function validateAuthData(authData, options) {
8+
return request(options.janrain_capture_host, authData.access_token)
9+
.then((data) => {
10+
//successful response will have a "stat" (status) of 'ok' and a result node that stores the uuid, because that's all we asked for
11+
//see: https://docs.janrain.com/api/registration/entity/#entity
12+
if (data && data.stat == 'ok' && data.result == authData.id) {
13+
return;
14+
}
15+
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Janrain capture auth is invalid for this user.');
16+
});
17+
}
18+
19+
// Returns a promise that fulfills iff this app id is valid.
20+
function validateAppId() {
21+
//no-op
22+
return Promise.resolve();
23+
}
24+
25+
// A promisey wrapper for api requests
26+
function request(host, access_token) {
27+
28+
var query_string_data = querystring.stringify({
29+
'access_token': access_token,
30+
'attribute_name': 'uuid' // we only need to pull the uuid for this access token to make sure it matches
31+
});
32+
33+
return new Promise(function(resolve, reject) {
34+
https.get({
35+
host: host,
36+
path: '/entity?' + query_string_data
37+
}, function(res) {
38+
var data = '';
39+
res.on('data', function(chunk) {
40+
data += chunk;
41+
});
42+
res.on('end', function () {
43+
resolve(JSON.parse(data));
44+
});
45+
}).on('error', function(e) {
46+
reject('Failed to validate this access token with Janrain capture.');
47+
});
48+
});
49+
}
50+
51+
module.exports = {
52+
validateAppId: validateAppId,
53+
validateAuthData: validateAuthData
54+
};

src/authDataManager/janrainengage.js

+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
// Helper functions for accessing the Janrain Engage API.
2+
var https = require('https');
3+
var Parse = require('parse/node').Parse;
4+
var querystring = require('querystring');
5+
6+
// Returns a promise that fulfills iff this user id is valid.
7+
function validateAuthData(authData, options) {
8+
return request(options.api_key, authData.auth_token)
9+
.then((data) => {
10+
//successful response will have a "stat" (status) of 'ok' and a profile node with an identifier
11+
//see: http://developers.janrain.com/overview/social-login/identity-providers/user-profile-data/#normalized-user-profile-data
12+
if (data && data.stat == 'ok' && data.profile.identifier == authData.id) {
13+
return;
14+
}
15+
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Janrain engage auth is invalid for this user.');
16+
});
17+
}
18+
19+
// Returns a promise that fulfills iff this app id is valid.
20+
function validateAppId() {
21+
//no-op
22+
return Promise.resolve();
23+
}
24+
25+
// A promisey wrapper for api requests
26+
function request(api_key, auth_token) {
27+
28+
var post_data = querystring.stringify({
29+
'token': auth_token,
30+
'apiKey': api_key,
31+
'format': 'json'
32+
});
33+
34+
var post_options = {
35+
host: 'rpxnow.com',
36+
path: '/api/v2/auth_info',
37+
method: 'POST',
38+
headers: {
39+
'Content-Type': 'application/x-www-form-urlencoded',
40+
'Content-Length': post_data.length
41+
}
42+
};
43+
44+
return new Promise(function (resolve, reject) {
45+
// Create the post request.
46+
var post_req = https.request(post_options, function (res) {
47+
var data = '';
48+
res.setEncoding('utf8');
49+
// Append data as we receive it from the Janrain engage server.
50+
res.on('data', function (d) {
51+
data += d;
52+
});
53+
// Once we have all the data, we can parse it and return the data we want.
54+
res.on('end', function () {
55+
resolve(JSON.parse(data));
56+
});
57+
});
58+
59+
post_req.write(post_data);
60+
post_req.end();
61+
});
62+
}
63+
64+
module.exports = {
65+
validateAppId: validateAppId,
66+
validateAuthData: validateAuthData
67+
};

0 commit comments

Comments
 (0)