Socket
Socket
Sign inDemoInstall

facebook-sdk

Package Overview
Dependencies
Maintainers
0
Versions
11
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

facebook-sdk - npm Package Compare versions

Comparing version 0.2.5 to 0.2.6

docs/api.md

48

example/connect.js
var connect = require('connect'),
fbsdk = require('facebook-sdk');
fbsdk = require('facebook-sdk');
var port = 3000;
connect()
.use(connect.favicon())
.use(fbsdk.facebook({
appId : 'YOUR APP ID',
secret : 'YOUR API SECRET'
}))
.use(function(req, res, next) {
if (req.facebook.getSession()) {
res.end('<a href="' + req.facebook.getLogoutUrl() + '">Logout</a>');
// get my graph api information
req.facebook.api('/me', function(me) {
console.log(me);
});
} else {
res.end('<a href="' + req.facebook.getLoginUrl() + '">Login</a>');
}
})
.listen(3000);
.use(connect.favicon())
.use(fbsdk.facebook({
appId : 'YOUR APP ID',
secret : 'YOUR APP SECRET'
}))
.use(function(req, res, next) {
if (req.facebook.getSession()) {
// get my graph api information
req.facebook.api('/me', function(me) {
console.log(me);
});
res.end('<a href="' + req.facebook.getLogoutUrl() + '">Logout</a>');
} else {
res.end('<a href="' + req.facebook.getLoginUrl() + '">Login</a>');
}
})
.listen(port);
console.log('Listening for http requests on port ' + port);

@@ -18,7 +18,7 @@ /**

var crypto = require('crypto'),
http = require('http'),
https = require('https'),
querystring = require('querystring'),
URL = require('url'),
util = require('util');
http = require('http'),
https = require('https'),
querystring = require('querystring'),
URL = require('url'),
util = require('util');

@@ -29,66 +29,66 @@ /**

var FacebookApiException = function(result) {
this.result = result;
this.result = result;
this.error = true;
this.code = result.error_code ? result.error_code : 0;
this.error = true;
this.code = result.error_code ? result.error_code : 0;
if (result.error_description) {
// OAuth 2.0 Draft 10 style
this.message = result.error_description;
} else if (result.error && result.error.message) {
// OAuth 2.0 Draft 00 style
this.message = result.error.message;
} else if (result.error_msg) {
// Rest server style
this.message = result.error_msg;
} else {
this.message = 'Unknown Error. Check getResult()';
}
if (result.error_description) {
// OAuth 2.0 Draft 10 style
this.message = result.error_description;
} else if (result.error && result.error.message) {
// OAuth 2.0 Draft 00 style
this.message = result.error.message;
} else if (result.error_msg) {
// Rest server style
this.message = result.error_msg;
} else {
this.message = 'Unknown Error. Check getResult()';
}
};
FacebookApiException.prototype = {
// The result from the API server that represents the exception information.
result: null,
// The result from the API server that represents the exception information.
result: null,
/**
* Return the associated result object returned by the API server.
*
* @return {Object} the result from the API server
*/
getResult: function() {
return this.result;
},
/**
* Return the associated result object returned by the API server.
*
* @return {Object} the result from the API server
*/
getResult: function() {
return this.result;
},
/**
* Returns the associated type for the error. This will default to
* 'Exception' when a type is not available.
*
* @return {String}
*/
getType: function() {
if (this.result.error) {
error = this.result.error;
if (typeof error == 'string') {
// OAuth 2.0 Draft 10 style
return error;
} else if (error.type) {
// OAuth 2.0 Draft 00 style
return error.type;
}
}
return 'Exception';
},
/**
* Returns the associated type for the error. This will default to
* 'Exception' when a type is not available.
*
* @return {String}
*/
getType: function() {
if (this.result.error) {
error = this.result.error;
if (typeof error == 'string') {
// OAuth 2.0 Draft 10 style
return error;
} else if (error.type) {
// OAuth 2.0 Draft 00 style
return error.type;
}
}
return 'Exception';
},
/**
* To make debugging easier.
*
* @return {String} the string representation of the error
*/
toString: function() {
str = this.getType() + ': ';
if (this.code != 0) {
str += this.code + ': ';
}
return str + this.message;
}
/**
* To make debugging easier.
*
* @return {String} the string representation of the error
*/
toString: function() {
str = this.getType() + ': ';
if (this.code != 0) {
str += this.code + ': ';
}
return str + this.message;
}
};

@@ -112,22 +112,22 @@

var Facebook = exports.facebook = exports.Facebook = function(config) {
var facebook;
if (this instanceof Facebook) {
// instantiation using the 'new' operator
facebook = this;
} else {
// connect style middleware function
// TODO: this should also function as a Facebook object, add prototype
facebook = function(req, res, next) {
req.facebook = new Facebook(config);
req.facebook.request = req;
req.facebook.response = res;
next();
};
}
var facebook;
if (this instanceof Facebook) {
// instantiation using the 'new' operator
facebook = this;
} else {
// connect style middleware function
// TODO: this should also function as a Facebook object, add prototype
facebook = function(req, res, next) {
req.facebook = new Facebook(config);
req.facebook.request = req;
req.facebook.response = res;
next();
};
}
for (var i in config) {
facebook[i] = config[i];
}
return facebook;
for (var i in config) {
facebook[i] = config[i];
}
return facebook;
};

@@ -137,771 +137,767 @@

// The Application ID.
appId: null,
// The Application ID.
appId: null,
// The Application API Secret.
secret: null,
// The Application API Secret.
secret: null,
// Url of the app
siteUrl: null,
// Url of the app
siteUrl: null,
// http.ServerRequest for initializing the session
request: null,
// http.ServerRequest for initializing the session
request: null,
// http.ServerResponse for writing the session cookie
response: null,
// http.ServerResponse for writing the session cookie
response: null,
// Base domain for the Cookie.
domain: '',
// Base domain for the Cookie.
domain: '',
// Indicates if the CURL based @ syntax for file uploads is enabled.
fileUpload: false,
// Indicates if the CURL based @ syntax for file uploads is enabled.
fileUpload: false,
// Milliseconds for connection with Facebook's servers to be established
// TODO: connectTimeout: 10000,
// Milliseconds for transmition of data from Facebook to complete
timeout: 60000,
// Milliseconds for connection with Facebook's servers to be established
// TODO: connectTimeout: 10000,
// Milliseconds for transmition of data from Facebook to complete
timeout: 60000,
// The active user session, if one is available.
_session: null,
// The active user session, if one is available.
_session: null,
// The data from the signed_request token.
_signedRequest: null,
// The data from the signed_request token.
_signedRequest: null,
// Indicates that we already loaded the session as best as we could.
_sessionLoaded: false,
// Indicates that we already loaded the session as best as we could.
_sessionLoaded: false,
// List of query parameters that get automatically dropped when rebuilding the current URL
DROP_QUERY_PARAMS: [
'session',
'signed_request'
],
// List of query parameters that get automatically dropped when rebuilding the current URL
DROP_QUERY_PARAMS: [
'session',
'signed_request'
],
// Map of aliases to Facebook domains
DOMAIN_MAP: {
api : 'https://api.facebook.com/',
api_read : 'https://api-read.facebook.com/',
graph : 'https://graph.facebook.com/',
www : 'https://www.facebook.com/'
},
// Map of aliases to Facebook domains
DOMAIN_MAP: {
api : 'https://api.facebook.com/',
api_video: 'https://api-video.facebook.com/',
api_read : 'https://api-read.facebook.com/',
graph : 'https://graph.facebook.com/',
www : 'https://www.facebook.com/'
},
/**
* Get the data from a signed_request token
*
* @return {Object}
*/
getSignedRequest: function() {
if (!this._signedRequest && this.request) {
var parse = URL.parse(this.request.url, true);
if (parse.query.signed_request) {
this._signedRequest = this._parseSignedRequest(parse.query.signed_request);
}
}
return this._signedRequest;
},
/**
* Get the data from a signed_request token
*
* @return {Object}
*/
getSignedRequest: function() {
if (!this._signedRequest && this.request) {
var parse = URL.parse(this.request.url, true);
if (parse.query.signed_request) {
this._signedRequest = this._parseSignedRequest(parse.query.signed_request);
}
}
return this._signedRequest;
},
/**
* Set the Session.
*
* @param {Object} session the session
* @param {boolean} write_cookie indicate if a cookie should be written. ignored if no response object.
*/
setSession: function(session, write_cookie) {
write_cookie = write_cookie === undefined ? true : write_cookie;
session = this._validateSessionObject(session);
this._sessionLoaded = true;
this._session = session;
if (write_cookie) {
this._setCookieFromSession(session);
}
return this;
},
/**
* Set the Session.
*
* @param {Object} session the session
* @param {boolean} write_cookie indicate if a cookie should be written. ignored if no response object.
*/
setSession: function(session, write_cookie) {
write_cookie = write_cookie === undefined ? true : write_cookie;
session = this._validateSessionObject(session);
this._sessionLoaded = true;
this._session = session;
if (write_cookie) {
this._setCookieFromSession(session);
}
return this;
},
/**
* Get the session object. This will automatically look for a signed session
* sent via the signed_request, Cookie or Query Parameters if needed.
*
* @return {Object} the session
*/
getSession: function() {
if (!this._sessionLoaded) {
var session = null;
var write_cookie = true;
/**
* Get the session object. This will automatically look for a signed session
* sent via the signed_request, Cookie or Query Parameters if needed.
*
* @return {Object} the session
*/
getSession: function() {
if (!this._sessionLoaded) {
var session = null;
var write_cookie = true;
// try loading session from signed_request in request
signedRequest = this.getSignedRequest();
if (signedRequest) {
// sig is good, use the signedRequest
session = this._createSessionFromSignedRequest(signedRequest);
}
// try loading session from signed_request in request
signedRequest = this.getSignedRequest();
if (signedRequest) {
// sig is good, use the signedRequest
session = this._createSessionFromSignedRequest(signedRequest);
}
// try loading session from request
// TODO: this works from querystring requests, make it work with POST, PUT and DELETE data (aka express support)
if (!session && this.request) {
var parse = URL.parse(this.request.url, true);
if (parse.query.session) {
session = JSON.parse(parse.query.session);
session = this._validateSessionObject(session);
}
}
// try loading session from request
// TODO: this works from querystring requests, make it work with POST, PUT and DELETE data (aka express support)
if (!session && this.request) {
var parse = URL.parse(this.request.url, true);
if (parse.query.session) {
session = JSON.parse(parse.query.session);
session = this._validateSessionObject(session);
}
}
// try loading session from cookie if necessary
if (!session && this.request) {
var cookie = this._getSessionCookie();
if (cookie) {
var cookie = cookie.replace(/^"*|"*$/g, '');
session = querystring.parse(cookie);
session = this._validateSessionObject(session);
// write only if we need to delete a invalid session cookie
write_cookie = !session;
}
}
// try loading session from cookie if necessary
if (!session && this.request) {
var cookie = this._getSessionCookie();
if (cookie) {
var cookie = cookie.replace(/^"*|"*$/g, '');
session = querystring.parse(cookie);
session = this._validateSessionObject(session);
// write only if we need to delete a invalid session cookie
write_cookie = !session;
}
}
this.setSession(session, write_cookie);
}
this.setSession(session, write_cookie);
}
return this._session;
},
return this._session;
},
// TODO: make this work with express cookies
// TODO: this cookie parsing may still not be quite right, consult the RFC or just use connect
_getSessionCookie: function() {
if (!this.request.headers.cookie) {
return;
}
var cookieName = this._getSessionCookieName();
var cookies = {};
this.request.headers.cookie.split(';').forEach(function(cookie) {
var split = cookie.indexOf('=');
if (split > 0) {
cookies[cookie.substr(0, split).trim()] = querystring.unescape(cookie.substr(split + 1)).trim();
}
});
return cookies[cookieName];
},
// TODO: make this work with express cookies
// TODO: this cookie parsing may still not be quite right, consult the RFC or just use connect
_getSessionCookie: function() {
if (!this.request.headers.cookie) {
return;
}
var cookieName = this._getSessionCookieName();
var cookies = {};
this.request.headers.cookie.split(';').forEach(function(cookie) {
var split = cookie.indexOf('=');
if (split > 0) {
cookies[cookie.substr(0, split).trim()] = querystring.unescape(cookie.substr(split + 1)).trim();
}
});
return cookies[cookieName];
},
/**
* Get the UID from the session.
*
* @return {String} the UID if available
*/
getUser: function() {
session = this.getSession();
return session ? session.uid : null;
},
/**
* Get the UID from the session.
*
* @return {String} the UID if available
*/
getUser: function() {
session = this.getSession();
return session ? session.uid : null;
},
/**
* Gets a OAuth access token.
*
* @return {String} the access token
*/
getAccessToken: function() {
session = this.getSession();
// either user session signed, or app signed
if (session) {
return session.access_token;
} else {
return this.appId +'|'+ this.secret;
}
},
/**
* Gets a OAuth access token.
*
* @return {String} the access token
*/
getAccessToken: function() {
session = this.getSession();
// either user session signed, or app signed
if (session) {
return session.access_token;
} else {
return this.appId +'|'+ this.secret;
}
},
/**
* Get a Login URL for use with redirects. By default, full page redirect is
* assumed. If you are using the generated URL with a window.open() call in
* JavaScript, you can pass in display=popup as part of the params.
*
* The parameters (optional):
* - next: the url to go to after a successful login
* - cancel_url: the url to go to after the user cancels
* - req_perms: comma separated list of requested extended perms
* - display: can be "page" (default, full page) or "popup"
*
* @param {Object} params provide custom parameters
* @return {String} the URL for the login flow
*/
getLoginUrl: function(params) {
params = params || {};
currentUrl = this._getCurrentUrl();
/**
* Get a Login URL for use with redirects. By default, full page redirect is
* assumed. If you are using the generated URL with a window.open() call in
* JavaScript, you can pass in display=popup as part of the params.
*
* The parameters (optional):
* - next: the url to go to after a successful login
* - cancel_url: the url to go to after the user cancels
* - req_perms: comma separated list of requested extended perms
* - display: can be "page" (default, full page) or "popup"
*
* @param {Object} params provide custom parameters
* @return {String} the URL for the login flow
*/
getLoginUrl: function(params) {
params = params || {};
currentUrl = this._getCurrentUrl();
var defaults = {
api_key : this.appId,
cancel_url : currentUrl,
display : 'page',
fbconnect : 1,
next : currentUrl,
return_session : 1,
session_version : 3,
v : '1.0'
};
for (var i in defaults) {
params[i] = params[i] || defaults[i];
}
var defaults = {
api_key : this.appId,
cancel_url : currentUrl,
display : 'page',
fbconnect : 1,
next : currentUrl,
return_session : 1,
session_version : 3,
v : '1.0'
};
for (var i in defaults) {
params[i] = params[i] || defaults[i];
}
return this._getUrl('www', 'login.php', params);
},
return this._getUrl('www', 'login.php', params);
},
/**
* Get a Logout URL suitable for use with redirects.
*
* The parameters:
* - next: the url to go to after a successful logout
*
* @param {Object} params provide custom parameters
* @return {String} the URL for the logout flow
*/
getLogoutUrl: function(params) {
params = params || {};
/**
* Get a Logout URL suitable for use with redirects.
*
* The parameters:
* - next: the url to go to after a successful logout
*
* @param {Object} params provide custom parameters
* @return {String} the URL for the logout flow
*/
getLogoutUrl: function(params) {
params = params || {};
var defaults = {
next : this._getCurrentUrl(),
access_token : this.getAccessToken()
};
for (var i in defaults) {
params[i] = params[i] || defaults[i];
}
var defaults = {
next : this._getCurrentUrl(),
access_token : this.getAccessToken()
};
for (var i in defaults) {
params[i] = params[i] || defaults[i];
}
return this._getUrl('www', 'logout.php', params);
},
return this._getUrl('www', 'logout.php', params);
},
/**
* Get a login status URL to fetch the status from facebook.
*
* The parameters:
* - ok_session: the URL to go to if a session is found
* - no_session: the URL to go to if the user is not connected
* - no_user: the URL to go to if the user is not signed into facebook
*
* @param {Object} params provide custom parameters
* @return {String} the URL for the logout flow
*/
getLoginStatusUrl: function(params) {
params = params || {};
/**
* Get a login status URL to fetch the status from facebook.
*
* The parameters:
* - ok_session: the URL to go to if a session is found
* - no_session: the URL to go to if the user is not connected
* - no_user: the URL to go to if the user is not signed into facebook
*
* @param {Object} params provide custom parameters
* @return {String} the URL for the logout flow
*/
getLoginStatusUrl: function(params) {
params = params || {};
var defaults = {
api_key : this.appId,
no_session : this._getCurrentUrl(),
no_user : this._getCurrentUrl(),
ok_session : this._getCurrentUrl(),
session_version : 3
};
for (var i in defaults) {
params[i] = params[i] || defaults[i];
}
var defaults = {
api_key : this.appId,
no_session : this._getCurrentUrl(),
no_user : this._getCurrentUrl(),
ok_session : this._getCurrentUrl(),
session_version : 3
};
for (var i in defaults) {
params[i] = params[i] || defaults[i];
}
return this._getUrl('www', 'extern/login_status.php', params);
},
return this._getUrl('www', 'extern/login_status.php', params);
},
/**
* Make an API call.
*/
api: function(/* polymorphic */) {
if (typeof arguments[0] == 'object') {
this._restserver.apply(this, arguments);
} else {
this._graph.apply(this, arguments);
}
},
/**
* Make an API call.
*/
api: function(/* polymorphic */) {
if (typeof arguments[0] == 'object') {
this._restserver.apply(this, arguments);
} else {
this._graph.apply(this, arguments);
}
},
/**
* Invoke the old restserver.php endpoint.
*
* @param {Object} params method call object
* @param {Function( object )} callback to send the decoded response object
*/
_restserver: function(params, callback) {
// generic application level parameters
params.api_key = this.appId;
params.format = 'json-strings';
/**
* Invoke the old restserver.php endpoint.
*
* @param {Object} params method call object
* @param {Function( object )} callback to send the decoded response object
*/
_restserver: function(params, callback) {
// generic application level parameters
params.api_key = this.appId;
params.format = 'json-strings';
this._oauthRequest(
this._getApiUrl(params.method),
params,
function(result) {
result = JSON.parse(result);
if (result && result.error_code) {
result = new FacebookApiException(result);
}
callback(result);
},
callback
);
},
this._oauthRequest(
this._getApiUrl(params.method),
params,
function(result) {
result = JSON.parse(result);
if (result && result.error_code) {
result = new FacebookApiException(result);
}
callback(result);
},
callback
);
},
/**
* Invoke the Graph API.
*
* @param {String} path the path (required)
* @param {String} method the http method (default 'GET')
* @param {Object} params the query/post data
* @param {Function( object )} callback to send the decoded response object
*/
_graph: function(path, method, params, callback) {
var self = this;
/**
* Invoke the Graph API.
*
* @param {String} path the path (required)
* @param {String} method the http method (default 'GET')
* @param {Object} params the query/post data
* @param {Function( object )} callback to send the decoded response object
*/
_graph: function(path, method, params, callback) {
var self = this;
if (typeof method != 'string') {
callback = params;
params = method || {};
method = params.method || 'GET';
}
if (typeof params == 'function') {
callback = params;
params = {};
}
params.method = method;
if (typeof method != 'string') {
callback = params;
params = method || {};
method = params.method || 'GET';
}
if (typeof params == 'function') {
callback = params;
params = {};
}
params.method = method;
this._oauthRequest(
this._getUrl('graph', path),
params,
function(result) {
result = JSON.parse(result);
if (result && result.error) {
var result = new FacebookApiException(result);
switch (result.getType()) {
// OAuth 2.0 Draft 00 style
case 'OAuthException':
// OAuth 2.0 Draft 10 style
case 'invalid_token':
self.setSession(null);
}
}
callback && callback(result);
},
callback
);
},
this._oauthRequest(
this._getUrl('graph', path),
params,
function(result) {
result = JSON.parse(result);
if (result && result.error) {
var result = new FacebookApiException(result);
switch (result.getType()) {
case 'OAuthException': // OAuth 2.0 Draft 00 style
case 'invalid_token': // OAuth 2.0 Draft 10 style
// TODO: test and check if headers have alread been sent
try {
self.setSession(null);
} catch (err) {
console.log(err);
}
}
}
callback && callback(result);
},
callback
);
},
/**
* Make a OAuth Request
*
* @param {String} path the path (required)
* @param {Object} params the query/post data
* @param {Function( string )} success to send the raw response string
* @param {Function( FacebookApiException )} error to send the error on failure
*/
_oauthRequest: function(url, params, success, error) {
if (!params.access_token) {
params.access_token = this.getAccessToken();
}
/**
* Make a OAuth Request
*
* @param {String} path the path (required)
* @param {Object} params the query/post data
* @param {Function( string )} success to send the raw response string
* @param {Function( FacebookApiException )} error to send the error on failure
*/
_oauthRequest: function(url, params, success, error) {
if (!params.access_token) {
params.access_token = this.getAccessToken();
}
// json encode all params values that are not strings
// TODO: untested
for (var key in params) {
if (typeof params[key] == 'object') {
params[key] = JSON.stringify(params[key]);
}
}
// json encode all params values that are not strings
// TODO: untested
for (var key in params) {
if (typeof params[key] == 'object') {
params[key] = JSON.stringify(params[key]);
}
}
this._makeRequest(url, params, success, error);
},
this._makeRequest(url, params, success, error);
},
/**
* Makes an HTTP request. This method can be overriden by subclasses if
* developers want to do fancier things or use something other than curl to
* make the request.
*
* @param {String} url the URL to make the request to
* @param {Object} params the parameters to use for the POST body
* @param {Function( string )} success callback to send the raw response data
* @param {Function{ FacebookApiException }} error callback to send an error object
*/
_makeRequest: function(url, params, success, error) {
var parts = URL.parse(url);
/**
* Makes an HTTP request. This method can be overriden by subclasses if
* developers want to do fancier things or use something other than curl to
* make the request.
*
* @param {String} url the URL to make the request to
* @param {Object} params the parameters to use for the POST body
* @param {Function( string )} success callback to send the raw response data
* @param {Function{ FacebookApiException }} error callback to send an error object
*/
_makeRequest: function(url, params, success, error) {
var parts = URL.parse(url);
var protocol = http;
var port = 80;
if (parts.protocol == 'https:') {
protocol = https;
port = 443;
}
var protocol = http;
var port = 80;
if (parts.protocol == 'https:') {
protocol = https;
port = 443;
}
var options = {
host: parts.hostname,
port: parts.port ? parts.port : port,
path: parts.pathname,
method: 'POST'
};
var options = {
host: parts.hostname,
port: parts.port ? parts.port : port,
path: parts.pathname,
method: 'POST'
};
// TODO: header 'Expect: 100-continue'? This was a part of the original curl makeRequest
// TODO: header 'Expect: 100-continue'? This was a part of the original curl makeRequest
var request = protocol.request(options, function(result) {
result.setEncoding('utf8');
var request = protocol.request(options, function(result) {
result.setEncoding('utf8');
var body = '';
result.on('data', function(chunk) {
body += chunk;
});
var body = '';
result.on('data', function(chunk) {
body += chunk;
});
result.on('end', function() {
clearTimeout(timeout);
success(body);
});
});
result.on('end', function() {
clearTimeout(timeout);
success(body);
});
});
// TODO?
// if (this.useFileUploadSupport()) {
// opts[CURLOPT_POSTFIELDS] = params;
// } else {
// opts[CURLOPT_POSTFIELDS] = http_build_query(params, null, '&');
// }
request.write(querystring.stringify(params));
request.end();
// TODO?
// if (this.useFileUploadSupport()) {
// opts[CURLOPT_POSTFIELDS] = params;
// } else {
// opts[CURLOPT_POSTFIELDS] = http_build_query(params, null, '&');
// }
request.write(querystring.stringify(params));
request.end();
var timeout = setTimeout(function() {
request.abort();
var e = new FacebookApiException({
error_code : 28 /* CURLE_OPERATION_TIMEDOUT */,
error : {
message : 'timeout',
type : 'CurlException'
}
});
error && error(e);
}, this.timeout);
},
var timeout = setTimeout(function() {
request.abort();
var e = new FacebookApiException({
error_code : 28 /* CURLE_OPERATION_TIMEDOUT */,
error : {
message : 'timeout',
type : 'CurlException'
}
});
error && error(e);
}, this.timeout);
},
/**
* The name of the Cookie that contains the session.
*
* @return {String} the cookie name
*/
_getSessionCookieName: function() {
return 'fbs_' + this.appId;
},
/**
* The name of the Cookie that contains the session.
*
* @return {String} the cookie name
*/
_getSessionCookieName: function() {
return 'fbs_' + this.appId;
},
/**
* Set a JS Cookie based on the _passed in_ session. It does not use the
* currently stored session -- you need to explicitly pass it in.
*
* @param {Object} session the session to use for setting the cookie
*/
_setCookieFromSession: function(session) {
if (!this.response) {
return;
}
/**
* Set a JS Cookie based on the _passed in_ session. It does not use the
* currently stored session -- you need to explicitly pass it in.
*
* @param {Object} session the session to use for setting the cookie
*/
_setCookieFromSession: function(session) {
if (!this.response) {
return;
}
var cookieName = this._getSessionCookieName();
var value = 'deleted';
var expires = new Date(Date.now() - 3600000);
var domain = this.domain;
if (session) {
value = '"' + querystring.stringify(session) + '"';
if (session.base_domain) {
domain = session.base_domain;
}
expires = new Date(session.expires * 1000);
}
// prepend dot if a domain is found
if (domain) {
domain = '.' + domain;
}
// if an existing cookie is not set, we dont need to delete it
// TODO: how do we know the cookie does not exist?
//if (value == 'deleted' && empty(_COOKIE[cookieName])) {
// return;
//}
// TODO: is this relevant for node.js?
//if (headers_sent()) {
// this._errorLog('Could not set cookie. Headers already sent.');
//} else {
this._setCookie(cookieName, value, expires, '/', domain);
//}
},
var cookieName = this._getSessionCookieName();
var value = 'deleted';
var expires = new Date(Date.now() - 3600000);
var domain = this.domain;
if (session) {
value = '"' + querystring.stringify(session) + '"';
if (session.base_domain) {
domain = session.base_domain;
}
expires = new Date(session.expires * 1000);
}
// prepend dot if a domain is found
if (domain) {
domain = '.' + domain;
}
// if an existing cookie is not set, we dont need to delete it
// TODO: how do we know the cookie does not exist?
//if (value == 'deleted' && empty(_COOKIE[cookieName])) {
// return;
//}
// TODO: is this relevant for node.js?
//if (headers_sent()) {
// this._errorLog('Could not set cookie. Headers already sent.');
//} else {
this._setCookie(cookieName, value, expires, '/', domain);
//}
},
/**
* Set the cookie in the http response.
*
* @param {String} name of cookie
* @param {String} value of cookie
* @param {Date} expires the date the cookie should expire
* @param {String} path under which the cookie should be available
* @param {String} domain of sites where the cookie should be available
*/
_setCookie: function(name, value, expires, path, domain) {
// TODO: express support
var cookie = querystring.escape(name) + '=' + querystring.escape(value);
if (expires) {
cookie += '; expires=' + expires.toUTCString();
}
if (path) {
cookie += '; path=' + path;
}
if (domain) {
cookie += '; domain=' + domain;
}
this.response.setHeader('Set-Cookie', cookie);
},
/**
* Set the cookie in the http response.
*
* @param {String} name of cookie
* @param {String} value of cookie
* @param {Date} expires the date the cookie should expire
* @param {String} path under which the cookie should be available
* @param {String} domain of sites where the cookie should be available
*/
_setCookie: function(name, value, expires, path, domain) {
// TODO: express support
var cookie = querystring.escape(name) + '=' + querystring.escape(value);
if (expires) {
cookie += '; expires=' + expires.toUTCString();
}
if (path) {
cookie += '; path=' + path;
}
if (domain) {
cookie += '; domain=' + domain;
}
this.response.setHeader('Set-Cookie', cookie);
},
/**
* Validates a session_version=3 style session object.
*
* @param {Object} session the session object
* @return {Object} the session object if it validates, null otherwise
*/
_validateSessionObject: function(session) {
// make sure some essential fields exist
if (session &&
session.uid &&
session.access_token &&
session.sig) {
// validate the signature
session_without_sig = {};
for (var key in session) {
if (key != 'sig') {
session_without_sig[key] = session[key];
}
}
expected_sig = this._generateSignature(
session_without_sig,
this.secret
);
if (session.sig != expected_sig) {
this._errorLog('Got invalid session signature in cookie.');
session = null;
}
// check expiry time
} else {
session = null;
}
return session;
},
/**
* Validates a session_version=3 style session object.
*
* @param {Object} session the session object
* @return {Object} the session object if it validates, null otherwise
*/
_validateSessionObject: function(session) {
// make sure some essential fields exist
if (session &&
session.uid &&
session.access_token &&
session.sig) {
expected_sig = this._generateSignature(session, this.secret);
if (session.sig != expected_sig) {
this._errorLog('Got invalid session signature in cookie.');
session = null;
}
// check expiry time
} else {
session = null;
}
return session;
},
/**
* Returns something that looks like our JS session object from the
* signed token's data
*
* TODO: Nuke this once the login flow uses OAuth2
*
* @param {Object} data the output of getSignedRequest
* @return {Object} Something that will work as a session
*/
_createSessionFromSignedRequest: function(data) {
if (!data.oauth_token) {
return null;
}
/**
* Returns something that looks like our JS session object from the
* signed token's data
*
* TODO: Nuke this once the login flow uses OAuth2
*
* @param {Object} data the output of getSignedRequest
* @return {Object} Something that will work as a session
*/
_createSessionFromSignedRequest: function(data) {
if (!data.oauth_token) {
return null;
}
session = {
uid : data.user_id,
access_token : data.oauth_token,
expires : data.expires
};
session = {
uid : data.user_id,
access_token : data.oauth_token,
expires : data.expires
};
// put a real sig, so that validateSignature works
session.sig = this._generateSignature(
session,
this.secret
);
// put a real sig, so that validateSignature works
session.sig = this._generateSignature(session, this.secret);
return session;
},
return session;
},
/**
* Parses a signed_request and validates the signature.
* Then saves it in this.signed_data
*
* @param {String} signed_request A signed token
* @return {Object} the payload inside it or null if the sig is wrong
*/
_parseSignedRequest: function(signed_request) {
var split = signed_request.split('.', 2);
if (split.length != 2) {
return null;
}
var encoded_sig = split[0];
var payload = split[1];
/**
* Parses a signed_request and validates the signature.
* Then saves it in this.signed_data
*
* @param {String} signed_request A signed token
* @return {Object} the payload inside it or null if the sig is wrong
*/
_parseSignedRequest: function(signed_request) {
var split = signed_request.split('.', 2);
if (split.length != 2) {
return null;
}
var encoded_sig = split[0];
var payload = split[1];
// decode the data
sig = this._base64UrlDecode(encoded_sig);
data = JSON.parse(this._base64UrlDecode(payload));
// decode the data
sig = this._base64UrlDecode(encoded_sig);
data = JSON.parse(this._base64UrlDecode(payload));
if (data.algorithm.toUpperCase() !== 'HMAC-SHA256') {
this._errorLog('Unknown algorithm. Expected HMAC-SHA256');
return null;
}
if (data.algorithm.toUpperCase() !== 'HMAC-SHA256') {
this._errorLog('Unknown algorithm. Expected HMAC-SHA256');
return null;
}
// check sig
var hmac = crypto.createHmac('sha256', this.secret);
hmac.update(payload);
expected_sig = hmac.digest();
if (sig !== expected_sig) {
this._errorLog('Bad Signed JSON signature!');
return null;
}
// check sig
var hmac = crypto.createHmac('sha256', this.secret);
hmac.update(payload);
expected_sig = hmac.digest();
if (sig !== expected_sig) {
this._errorLog('Bad Signed JSON signature!');
return null;
}
return data;
},
return data;
},
/**
* Build the URL for api given parameters.
*
* @param {String} method the method name.
* @return {String} the URL for the given parameters
*/
_getApiUrl: function(method) {
const READ_ONLY_CALLS = {
'admin.getallocation' : 1,
'admin.getappproperties' : 1,
'admin.getbannedusers' : 1,
'admin.getlivestreamvialink' : 1,
'admin.getmetrics' : 1,
'admin.getrestrictioninfo' : 1,
'application.getpublicinfo' : 1,
'auth.getapppublickey' : 1,
'auth.getsession' : 1,
'auth.getsignedpublicsessiondata' : 1,
'comments.get' : 1,
'connect.getunconnectedfriendscount' : 1,
'dashboard.getactivity' : 1,
'dashboard.getcount' : 1,
'dashboard.getglobalnews' : 1,
'dashboard.getnews' : 1,
'dashboard.multigetcount' : 1,
'dashboard.multigetnews' : 1,
'data.getcookies' : 1,
'events.get' : 1,
'events.getmembers' : 1,
'fbml.getcustomtags' : 1,
'feed.getappfriendstories' : 1,
'feed.getregisteredtemplatebundlebyid' : 1,
'feed.getregisteredtemplatebundles' : 1,
'fql.multiquery' : 1,
'fql.query' : 1,
'friends.arefriends' : 1,
'friends.get' : 1,
'friends.getappusers' : 1,
'friends.getlists' : 1,
'friends.getmutualfriends' : 1,
'gifts.get' : 1,
'groups.get' : 1,
'groups.getmembers' : 1,
'intl.gettranslations' : 1,
'links.get' : 1,
'notes.get' : 1,
'notifications.get' : 1,
'pages.getinfo' : 1,
'pages.isadmin' : 1,
'pages.isappadded' : 1,
'pages.isfan' : 1,
'permissions.checkavailableapiaccess' : 1,
'permissions.checkgrantedapiaccess' : 1,
'photos.get' : 1,
'photos.getalbums' : 1,
'photos.gettags' : 1,
'profile.getinfo' : 1,
'profile.getinfooptions' : 1,
'stream.get' : 1,
'stream.getcomments' : 1,
'stream.getfilters' : 1,
'users.getinfo' : 1,
'users.getloggedinuser' : 1,
'users.getstandardinfo' : 1,
'users.hasapppermission' : 1,
'users.isappuser' : 1,
'users.isverified' : 1,
'video.getuploadlimits' : 1
};
var name = 'api';
if (READ_ONLY_CALLS[method.toLowerCase()]) {
name = 'api_read';
}
return this._getUrl(name, 'restserver.php');
},
/**
* Build the URL for api given parameters.
*
* @param {String} method the method name.
* @return {String} the URL for the given parameters
*/
_getApiUrl: function(method) {
const READ_ONLY_CALLS = {
'admin.getallocation' : 1,
'admin.getappproperties' : 1,
'admin.getbannedusers' : 1,
'admin.getlivestreamvialink' : 1,
'admin.getmetrics' : 1,
'admin.getrestrictioninfo' : 1,
'application.getpublicinfo' : 1,
'auth.getapppublickey' : 1,
'auth.getsession' : 1,
'auth.getsignedpublicsessiondata' : 1,
'comments.get' : 1,
'connect.getunconnectedfriendscount' : 1,
'dashboard.getactivity' : 1,
'dashboard.getcount' : 1,
'dashboard.getglobalnews' : 1,
'dashboard.getnews' : 1,
'dashboard.multigetcount' : 1,
'dashboard.multigetnews' : 1,
'data.getcookies' : 1,
'events.get' : 1,
'events.getmembers' : 1,
'fbml.getcustomtags' : 1,
'feed.getappfriendstories' : 1,
'feed.getregisteredtemplatebundlebyid' : 1,
'feed.getregisteredtemplatebundles' : 1,
'fql.multiquery' : 1,
'fql.query' : 1,
'friends.arefriends' : 1,
'friends.get' : 1,
'friends.getappusers' : 1,
'friends.getlists' : 1,
'friends.getmutualfriends' : 1,
'gifts.get' : 1,
'groups.get' : 1,
'groups.getmembers' : 1,
'intl.gettranslations' : 1,
'links.get' : 1,
'notes.get' : 1,
'notifications.get' : 1,
'pages.getinfo' : 1,
'pages.isadmin' : 1,
'pages.isappadded' : 1,
'pages.isfan' : 1,
'permissions.checkavailableapiaccess' : 1,
'permissions.checkgrantedapiaccess' : 1,
'photos.get' : 1,
'photos.getalbums' : 1,
'photos.gettags' : 1,
'profile.getinfo' : 1,
'profile.getinfooptions' : 1,
'stream.get' : 1,
'stream.getcomments' : 1,
'stream.getfilters' : 1,
'users.getinfo' : 1,
'users.getloggedinuser' : 1,
'users.getstandardinfo' : 1,
'users.hasapppermission' : 1,
'users.isappuser' : 1,
'users.isverified' : 1,
'video.getuploadlimits' : 1
};
var name = 'api';
method = method.toLowerCase();
if (READ_ONLY_CALLS[method]) {
name = 'api_read';
} else if (method === 'video.upload') {
name = 'api_video';
}
return this._getUrl(name, 'restserver.php');
},
/**
* Build the URL for given domain alias, path and parameters.
*
* @param {String} name the name of the domain
* @param {String} path optional path (without a leading slash)
* @param {Object} params optional query parameters
* @return {String} the URL for the given parameters
*/
_getUrl: function(name, path, params) {
var url = this.DOMAIN_MAP[name];
if (path) {
if (path[0] === '/') {
path = path.substr(1);
}
url += path;
}
if (params) {
url += '?' + querystring.stringify(params);
}
return url;
},
/**
* Build the URL for given domain alias, path and parameters.
*
* @param {String} name the name of the domain
* @param {String} path optional path (without a leading slash)
* @param {Object} params optional query parameters
* @return {String} the URL for the given parameters
*/
_getUrl: function(name, path, params) {
var url = this.DOMAIN_MAP[name];
if (path) {
if (path[0] === '/') {
path = path.substr(1);
}
url += path;
}
if (params) {
url += '?' + querystring.stringify(params);
}
return url;
},
/**
* Returns the Current URL, stripping it of known FB parameters that should
* not persist.
*
* @return {String} the current URL
*/
_getCurrentUrl: function() {
if (this.siteUrl) {
var site = URL.parse(this.siteUrl);
} else if (this.request && this.request.headers.host) {
var site = {
protocol: 'http:', // TODO: can we detect this?
host: this.request.headers.host
};
} else {
throw new Error('No host or siteUrl available');
}
var url = URL.parse(this.request.url, true);
/**
* Returns the Current URL, stripping it of known FB parameters that should
* not persist.
*
* @return {String} the current URL
*/
_getCurrentUrl: function() {
if (this.siteUrl) {
var site = URL.parse(this.siteUrl);
} else if (this.request && this.request.headers.host) {
var site = {
protocol: this.request.connection.encrypted ? 'https:' : 'http:',
host: this.request.headers.host
};
} else {
throw new Error('No host or siteUrl available');
}
var url = URL.parse(this.request.url, true);
// drop known fb params
this.DROP_QUERY_PARAMS.forEach(function(key) {
delete url.query[key];
});
// drop known fb params
this.DROP_QUERY_PARAMS.forEach(function(key) {
delete url.query[key];
});
var currentUrl = site.protocol + '//' + site.host + url.pathname;
if (url.query) {
currentUrl += '?' + querystring.stringify(url.query);
}
var currentUrl = site.protocol + '//' + site.host + url.pathname;
if (url.query) {
currentUrl += '?' + querystring.stringify(url.query);
}
return currentUrl;
},
return currentUrl;
},
/**
* Generate a signature for the given params and secret.
*
* @param {Object} params the parameters to sign
* @param {String} secret the secret to sign with
* @return {String} the generated signature
*/
_generateSignature: function(params, secret) {
var md5 = crypto.createHash('md5');
Object.keys(params).sort().forEach(function(key) {
md5.update(key + '=' + params[key]);
});
md5.update(secret);
return md5.digest('hex');
},
/**
* Generate a signature for the given params and secret.
*
* @param {Object} params the parameters to sign
* @param {String} secret the secret to sign with
* @return {String} the generated signature
*/
_generateSignature: function(params, secret) {
var md5 = crypto.createHash('md5');
Object.keys(params).sort().forEach(function(key) {
if (key !== 'sig') {
md5.update(key + '=' + params[key]);
}
});
md5.update(secret);
return md5.digest('hex');
},
/**
* Prints to the error log if you aren't in command line mode.
*
* @param {String} msg log message
*/
_errorLog: function(msg) {
console.log(msg);
},
/**
* Prints to the error log if you aren't in command line mode.
*
* @param {String} msg log message
*/
_errorLog: function(msg) {
console.log(msg);
},
/**
* Base64 encoding that doesn't need to be urlencode()ed.
* Exactly the same as base64_encode except it uses
* - instead of +
* _ instead of /
*
* @param {String} input base64UrlEncodeded string
* @param {String} decoded
*/
_base64UrlDecode: function(input) {
var buffer = new Buffer(input.replace('-', '+').replace('_', '/'), 'base64');
return buffer.toString('binary');
}
/**
* Base64 encoding that doesn't need to be urlencode()ed.
* Exactly the same as base64_encode except it uses
* - instead of +
* _ instead of /
*
* @param {String} input base64UrlEncodeded string
* @param {String} decoded
*/
_base64UrlDecode: function(input) {
var buffer = new Buffer(input.replace('-', '+').replace('_', '/'), 'base64');
return buffer.toString('binary');
}
};
{
"name": "facebook-sdk",
"description": "A full port of Facebook's PHP SDK library",
"keywords": ["facebook", "sdk", "graph", "api", "connect", "canvas"],
"version": "0.2.5",
"author": "Christopher Johnson <tenorviol@yahoo.com> (http://github.com/tenorviol)",
"repository" : {
"type" : "git",
"url" : "git://github.com/tenorviol/node-facebook-sdk.git"
},
"directories" : {
"lib" : "./lib"
},
"licenses" : [
{ "type" : "Apache License, Version 2.0", "url" : "http://www.apache.org/licenses/LICENSE-2.0.html" }
],
"main": "lib/facebook",
"engines": { "node" : ">= 0.4" }
"name": "facebook-sdk",
"description": "A full port of Facebook's PHP SDK library",
"keywords": ["facebook", "sdk", "graph", "api", "connect", "canvas"],
"version": "0.2.6",
"author": "Christopher Johnson <tenorviol@yahoo.com> (http://github.com/tenorviol)",
"repository" : {
"type" : "git",
"url" : "git://github.com/tenorviol/node-facebook-sdk.git"
},
"directories" : {
"lib" : "./lib"
},
"licenses" : [
{ "type" : "Apache License, Version 2.0", "url" : "http://www.apache.org/licenses/LICENSE-2.0.html" }
],
"main": "lib/facebook",
"engines": { "node" : ">= 0.4" }
}

@@ -18,3 +18,3 @@ [node.js Facebook SDK](https://github.com/tenorviol/node-facebook-sdk)

npm install facebook-sdk
npm install facebook-sdk

@@ -28,26 +28,26 @@ Use as connect middleware

var connect = require('connect'),
fbsdk = require('facebook-sdk');
connect()
.use(fbsdk.facebook({
appId : 'YOUR APP ID',
secret : 'YOUR API SECRET'
}))
.use(function(req, res, next) {
if (req.facebook.getSession()) {
res.end('<a href="' + req.facebook.getLogoutUrl() + '">Logout</a>');
// get my graph api information
req.facebook.api('/me', function(me) {
console.log(me);
});
} else {
res.end('<a href="' + req.facebook.getLoginUrl() + '">Login</a>');
}
})
.listen(3000);
var connect = require('connect'),
fbsdk = require('facebook-sdk');
connect()
.use(fbsdk.facebook({
appId : 'YOUR APP ID',
secret : 'YOUR API SECRET'
}))
.use(function(req, res, next) {
if (req.facebook.getSession()) {
res.end('<a href="' + req.facebook.getLogoutUrl() + '">Logout</a>');
// get my graph api information
req.facebook.api('/me', function(me) {
console.log(me);
});
} else {
res.end('<a href="' + req.facebook.getLoginUrl() + '">Login</a>');
}
})
.listen(3000);

@@ -57,12 +57,12 @@ Stand alone usage

var fbsdk = require('facebook-sdk');
var facebook = new fbsdk.Facebook({
appId : 'YOUR APP ID',
secret : 'YOUR API SECRET'
});
facebook.api('/YOUR APP ID', function(data) {
console.log(data);
});
var fbsdk = require('facebook-sdk');
var facebook = new fbsdk.Facebook({
appId : 'YOUR APP ID',
secret : 'YOUR API SECRET'
});
facebook.api('/YOUR APP ID', function(data) {
console.log(data);
});

@@ -69,0 +69,0 @@ Tests

var connect = require('connect'),
http = require('http'),
fbsdk = require('../lib/facebook');
http = require('http'),
fbsdk = require('../lib/facebook');

@@ -9,8 +9,8 @@ var APP_ID = '117743971608120';

var VALID_EXPIRED_SESSION = {
access_token : '117743971608120|2.vdCKd4ZIEJlHwwtrkilgKQ__.86400.1281049200-1677846385|NF_2DDNxFBznj2CuwiwabHhTAHc.',
expires : '1281049200',
secret : 'u0QiRGAwaPCyQ7JE_hiz1w__',
session_key : '2.vdCKd4ZIEJlHwwtrkilgKQ__.86400.1281049200-1677846385',
sig : '7a9b063de0bef334637832166948dcad',
uid : '1677846385'
access_token : '117743971608120|2.vdCKd4ZIEJlHwwtrkilgKQ__.86400.1281049200-1677846385|NF_2DDNxFBznj2CuwiwabHhTAHc.',
expires : '1281049200',
secret : 'u0QiRGAwaPCyQ7JE_hiz1w__',
session_key : '2.vdCKd4ZIEJlHwwtrkilgKQ__.86400.1281049200-1677846385',
sig : '7a9b063de0bef334637832166948dcad',
uid : '1677846385'
};

@@ -22,31 +22,29 @@

exports.testFacebookMiddleware = function(test) {
var port = 3000;
connect()
.use(fbsdk.facebook({
appId: APP_ID,
secret: SECRET
}))
.use(connect.router(function(app) {
app.get('/', function(req, res, next) {
res.end();
var facebook = req.facebook;
test.equal(req, facebook.request);
test.equal(res, facebook.response);
test.deepEqual(VALID_EXPIRED_SESSION, facebook.getSession());
test.done();
});
}))
.listen(port, function() {
http.request({
host: 'localhost',
port: port,
path: '/',
headers: {
cookie: UNESCAPED_SESSION_COOKIE
}
}).end();
});
var port = 3000;
connect()
.use(fbsdk.facebook({
appId: APP_ID,
secret: SECRET
}))
.use(function(req, res, next) {
res.end();
var facebook = req.facebook;
test.equal(req, facebook.request);
test.equal(res, facebook.response);
test.deepEqual(VALID_EXPIRED_SESSION, facebook.getSession());
test.done();
})
.listen(port, function() {
http.request({
host: 'localhost',
port: port,
path: '/',
headers: {
cookie: UNESCAPED_SESSION_COOKIE
}
}).end();
});
};

@@ -18,5 +18,7 @@ /**

var fbsdk = require('../lib/facebook'),
http = require('http'),
querystring = require('querystring');
var Facebook = require('../lib/facebook').Facebook,
fs = require('fs'),
http = require('http'),
https = require('https'),
querystring = require('querystring');

@@ -30,8 +32,8 @@ var APP_ID = '117743971608120';

var VALID_EXPIRED_SESSION = {
access_token : '117743971608120|2.vdCKd4ZIEJlHwwtrkilgKQ__.86400.1281049200-1677846385|NF_2DDNxFBznj2CuwiwabHhTAHc.',
expires : '1281049200',
secret : 'u0QiRGAwaPCyQ7JE_hiz1w__',
session_key : '2.vdCKd4ZIEJlHwwtrkilgKQ__.86400.1281049200-1677846385',
sig : '7a9b063de0bef334637832166948dcad',
uid : '1677846385'
access_token : '117743971608120|2.vdCKd4ZIEJlHwwtrkilgKQ__.86400.1281049200-1677846385|NF_2DDNxFBznj2CuwiwabHhTAHc.',
expires : '1281049200',
secret : 'u0QiRGAwaPCyQ7JE_hiz1w__',
session_key : '2.vdCKd4ZIEJlHwwtrkilgKQ__.86400.1281049200-1677846385',
sig : '7a9b063de0bef334637832166948dcad',
uid : '1677846385'
};

@@ -48,79 +50,23 @@

exports.testConstructor = function(test) {
var facebook = new fbsdk.Facebook({
appId : APP_ID,
secret : SECRET
});
test.equal(facebook.appId, APP_ID, 'Expect the App ID to be set.');
test.equal(facebook.secret, SECRET, 'Expect the API secret to be set.');
test.ok(!facebook.cookieSupport, 'Expect Cookie support to be off.');
test.done();
var facebook = new Facebook({
appId : APP_ID,
secret : SECRET,
siteUrl: 'http://fbrell.com',
request: {},
response: {},
domain : 'fbrell.com',
fileUpload : true
});
test.equal(facebook.appId, APP_ID, 'Expect the App ID to be set.');
test.equal(facebook.secret, SECRET, 'Expect the API secret to be set.');
test.equal(facebook.siteUrl, 'http://fbrell.com');
test.ok(facebook.request);
test.ok(facebook.response);
test.equal(facebook.domain, 'fbrell.com');
test.ok(facebook.fileUpload);
test.done();
};
exports.testConstructorWithCookie = function(test) {
var facebook = new fbsdk.Facebook({
appId : APP_ID,
secret : SECRET,
cookie : true
});
test.equal(facebook.appId, APP_ID, 'Expect the App ID to be set.');
test.equal(facebook.secret, SECRET, 'Expect the API secret to be set.');
test.ok(facebook.cookie, 'Expect Cookie support to be on.');
test.done();
};
exports.testConstructorWithFileUpload = function(test) {
var facebook = new fbsdk.Facebook({
appId : APP_ID,
secret : SECRET,
fileUpload : true
});
test.equal(facebook.appId, APP_ID, 'Expect the App ID to be set.');
test.equal(facebook.secret, SECRET, 'Expect the API secret to be set.');
test.ok(facebook.fileUpload, 'Expect file upload support to be on.');
test.done();
};
exports.testSetAppId = function(test) {
var facebook = new fbsdk.Facebook({
appId : APP_ID,
secret : SECRET
});
facebook.appId = 'dummy';
test.equal(facebook.appId, 'dummy', 'Expect the App ID to be dummy.');
test.done();
};
exports.testSetAPISecret = function(test) {
var facebook = new fbsdk.Facebook({
appId : APP_ID,
secret : SECRET
});
facebook.secret = 'dummy';
test.equal(facebook.secret, 'dummy', 'Expect the API secret to be dummy.');
test.done();
};
exports.testDefaultBaseDomain = function(test) {
var facebook = new fbsdk.Facebook({
appId : APP_ID,
secret : SECRET,
domain : 'fbrell.com'
});
test.equal(facebook.domain, 'fbrell.com');
test.done();
};
exports.testSetCookieSupport = function(test) {
var facebook = new fbsdk.Facebook({
appId : APP_ID,
secret : SECRET
});
test.ok(!facebook.cookie, 'Expect Cookie support to be off.');
facebook.cookie = true;
test.ok(facebook.cookie, 'Expect Cookie support to be on.');
test.done();
};
// exports.testIgnoreDeleteSetCookie = function(test) {
// var facebook = new fbsdk.Facebook({
// var facebook = new Facebook({
// appId : APP_ID,

@@ -136,72 +82,60 @@ // secret : SECRET,

exports.testSetFileUploadSupport = function(test) {
var facebook = new fbsdk.Facebook({
appId : APP_ID,
secret : SECRET
});
test.ok(!facebook.fileUploadSupport, 'Expect file upload support to be off.');
facebook.fileUploadSupport = true;
test.ok(facebook.fileUploadSupport, 'Expect file upload support to be on.');
test.done();
};
exports.testSetNullSession = function(test) {
var facebook = new fbsdk.Facebook({
appId : APP_ID,
secret : SECRET
});
facebook.setSession(null);
test.ok(facebook.getSession() === null, 'Expect null session back.');
test.done();
var facebook = new Facebook({
appId : APP_ID,
secret : SECRET
});
facebook.setSession(null);
test.ok(facebook.getSession() === null, 'Expect null session back.');
test.done();
};
exports.testNonUserAccessToken = function(test) {
var facebook = new fbsdk.Facebook({
appId : APP_ID,
secret : SECRET,
cookie : true
});
test.ok(facebook.getAccessToken() == APP_ID+'|'+SECRET, 'Expect appId|secret.');
test.done();
var facebook = new Facebook({
appId : APP_ID,
secret : SECRET
});
test.ok(facebook.getAccessToken() == APP_ID+'|'+SECRET, 'Expect appId|secret.');
test.done();
};
exports.testSetSession = function(test) {
test.expect(4);
// the setSession below should call this response.setHeader method
var response = {
setHeader: function(name, value) {
// setting the session sets the cookie (copied from a php-sdk instance)
test.equal(name, 'Set-Cookie');
test.equal(value, SESSION_COOKIE+'; expires=Thu, 05 Aug 2010 23:00:00 GMT; path=/; domain=.foo.com');
}
};
var facebook = new fbsdk.Facebook({
appId : APP_ID,
secret : SECRET,
response : response,
domain : 'foo.com'
});
facebook.setSession(VALID_EXPIRED_SESSION);
test.ok(facebook.getUser() == VALID_EXPIRED_SESSION.uid, 'Expect uid back.');
test.ok(facebook.getAccessToken() == VALID_EXPIRED_SESSION.access_token, 'Expect access token back.');
test.done();
test.expect(4);
// the setSession below should call this response.setHeader method
var response = {
setHeader: function(name, value) {
// setting the session sets the cookie (copied from a php-sdk instance)
test.equal(name, 'Set-Cookie');
test.equal(value, SESSION_COOKIE+'; expires=Thu, 05 Aug 2010 23:00:00 GMT; path=/; domain=.foo.com');
}
};
var facebook = new Facebook({
appId : APP_ID,
secret : SECRET,
response : response,
domain : 'foo.com'
});
facebook.setSession(VALID_EXPIRED_SESSION);
test.ok(facebook.getUser() == VALID_EXPIRED_SESSION.uid, 'Expect uid back.');
test.ok(facebook.getAccessToken() == VALID_EXPIRED_SESSION.access_token, 'Expect access token back.');
test.done();
};
exports.testGetSession = function(test) {
// regression test: the cookie we set should be getSession-able
var request = {
url: '/',
headers: {
cookie: SESSION_COOKIE
}
};
var facebook = new fbsdk.Facebook({
appId : APP_ID,
secret : SECRET,
request: request
});
test.deepEqual(facebook.getSession(), VALID_EXPIRED_SESSION);
test.done();
// regression test: the cookie we set should be getSession-able
var request = {
url: '/',
headers: {
cookie: SESSION_COOKIE
}
};
var facebook = new Facebook({
appId : APP_ID,
secret : SECRET,
request: request
});
test.deepEqual(facebook.getSession(), VALID_EXPIRED_SESSION);
test.done();
};

@@ -211,214 +145,212 @@

exports.testGetSessionUnescaped = function(test) {
// regression test: the cookie we set should be getSession-able
var request = {
url: '/',
headers: {
cookie: UNESCAPED_SESSION_COOKIE
}
};
var facebook = new fbsdk.Facebook({
appId : APP_ID,
secret : SECRET,
request: request
});
test.deepEqual(facebook.getSession(), VALID_EXPIRED_SESSION);
test.done();
// regression test: the cookie we set should be getSession-able
var request = {
url: '/',
headers: {
cookie: UNESCAPED_SESSION_COOKIE
}
};
var facebook = new Facebook({
appId : APP_ID,
secret : SECRET,
request: request
});
test.deepEqual(facebook.getSession(), VALID_EXPIRED_SESSION);
test.done();
};
exports.testGetSessionFromCookie = function(test) {
var cookieName = 'fbs_' + APP_ID;
var session = VALID_EXPIRED_SESSION;
var cookie = {};
cookie[cookieName] = querystring.stringify(session);
var cookieName = 'fbs_' + APP_ID;
var session = VALID_EXPIRED_SESSION;
var cookie = {};
cookie[cookieName] = querystring.stringify(session);
var options = {
headers: { Cookie: querystring.stringify(cookie) }
};
httpServerTest(options, function(request, response) {
var facebook = new fbsdk.Facebook({
appId : APP_ID,
secret : SECRET,
cookie : true,
request : request
});
test.deepEqual(facebook.getSession(), session, 'Expect session back.');
test.done();
});
var options = {
headers: { Cookie: querystring.stringify(cookie) }
};
httpServerTest(options, function(request, response) {
var facebook = new Facebook({
appId : APP_ID,
secret : SECRET,
request : request
});
test.deepEqual(facebook.getSession(), session, 'Expect session back.');
test.done();
});
};
exports.testInvalidGetSessionFromCookie = function(test) {
var cookieName = 'fbs_' + APP_ID;
var session = clone(VALID_EXPIRED_SESSION);
session.uid = 'make me invalid';
var cookie = {};
cookie[cookieName] = querystring.stringify(session);
var cookieName = 'fbs_' + APP_ID;
var session = clone(VALID_EXPIRED_SESSION);
session.uid = 'make me invalid';
var cookie = {};
cookie[cookieName] = querystring.stringify(session);
var options = {
headers: { Cookie: querystring.stringify(cookie) }
};
httpServerTest(options, function(request, response) {
var facebook = new fbsdk.Facebook({
appId : APP_ID,
secret : SECRET,
cookie : true,
request : request
});
test.ok(facebook.getSession() === null, 'Expect no session back.');
test.done();
});
var options = {
headers: { Cookie: querystring.stringify(cookie) }
};
httpServerTest(options, function(request, response) {
var facebook = new Facebook({
appId : APP_ID,
secret : SECRET,
request : request
});
test.ok(facebook.getSession() === null, 'Expect no session back.');
test.done();
});
};
exports.testSessionFromQueryString = function(test) {
var options = {
path: '/?' + querystring.stringify({ session: JSON.stringify(VALID_EXPIRED_SESSION) })
};
httpServerTest(options, function(request, response) {
var facebook = new fbsdk.Facebook({
appId : APP_ID,
secret : SECRET,
request : request
});
test.equal(facebook.getUser(), VALID_EXPIRED_SESSION.uid, 'Expect uid back.');
test.done();
});
var options = {
path: '/?' + querystring.stringify({ session: JSON.stringify(VALID_EXPIRED_SESSION) })
};
httpServerTest(options, function(request, response) {
var facebook = new Facebook({
appId : APP_ID,
secret : SECRET,
request : request
});
test.equal(facebook.getUser(), VALID_EXPIRED_SESSION.uid, 'Expect uid back.');
test.done();
});
};
exports.testInvalidSessionFromQueryString = function(test) {
var qs = {
fb_sig_in_iframe : 1,
fb_sig_user : '1677846385',
fb_sig_session_key : '2.NdKHtYIuB0EcNSHOvqAKHg__.86400.1258092000-1677846385',
fb_sig_ss : 'AdCOu5nhDiexxRDLwZfqnA__',
fb_sig : '1949f256171f37ecebe00685ce33bf17'
};
var options = {
path: '/?' + querystring.stringify(qs)
};
var qs = {
fb_sig_in_iframe : 1,
fb_sig_user : '1677846385',
fb_sig_session_key : '2.NdKHtYIuB0EcNSHOvqAKHg__.86400.1258092000-1677846385',
fb_sig_ss : 'AdCOu5nhDiexxRDLwZfqnA__',
fb_sig : '1949f256171f37ecebe00685ce33bf17'
};
var options = {
path: '/?' + querystring.stringify(qs)
};
httpServerTest(options, function(request, response) {
var facebook = new fbsdk.Facebook({
appId : APP_ID,
secret : SECRET,
request : request
});
test.equal(facebook.getUser(), null, 'Expect uid back.');
test.done();
});
httpServerTest(options, function(request, response) {
var facebook = new Facebook({
appId : APP_ID,
secret : SECRET,
request : request
});
test.equal(facebook.getUser(), null, 'Expect uid back.');
test.done();
});
};
exports.testGetUID = function(test) {
var facebook = new fbsdk.Facebook({
appId : APP_ID,
secret : SECRET
});
var session = VALID_EXPIRED_SESSION;
facebook.setSession(session);
test.equal(facebook.getUser(), session.uid, 'Expect dummy uid back.');
test.done();
var facebook = new Facebook({
appId : APP_ID,
secret : SECRET
});
var session = VALID_EXPIRED_SESSION;
facebook.setSession(session);
test.equal(facebook.getUser(), session.uid, 'Expect dummy uid back.');
test.done();
};
exports.testAPIWithoutSession = function(test) {
var facebook = new fbsdk.Facebook({
appId : APP_ID,
secret : SECRET
});
facebook.api({
method : 'fql.query',
query : 'SELECT name FROM user WHERE uid=4'
}, function(response) {
test.equal(response.length, 1, 'Expect one row back.');
test.equal(response[0].name, 'Mark Zuckerberg', 'Expect the name back.');
test.done();
});
var facebook = new Facebook({
appId : APP_ID,
secret : SECRET
});
facebook.api({
method : 'fql.query',
query : 'SELECT name FROM user WHERE uid=4'
}, function(response) {
test.equal(response.length, 1, 'Expect one row back.');
test.equal(response[0].name, 'Mark Zuckerberg', 'Expect the name back.');
test.done();
});
};
exports.testAPIWithSession = function(test) {
var facebook = new fbsdk.Facebook({
appId : APP_ID,
secret : SECRET
});
facebook.setSession(VALID_EXPIRED_SESSION);
var facebook = new Facebook({
appId : APP_ID,
secret : SECRET
});
facebook.setSession(VALID_EXPIRED_SESSION);
// this is strange in that we are expecting a session invalid error vs a
// signature invalid error. basically we're just making sure session based
// signing is working, not that the api call is returning data.
facebook.api({
method : 'fql.query',
query : 'SELECT name FROM profile WHERE id=4'
}, function(data) {
test.ok(data.error);
// this is strange in that we are expecting a session invalid error vs a
// signature invalid error. basically we're just making sure session based
// signing is working, not that the api call is returning data.
facebook.api({
method : 'fql.query',
query : 'SELECT name FROM profile WHERE id=4'
}, function(data) {
test.ok(data.error);
var msg = 'Exception: 190: Invalid OAuth 2.0 Access Token';
test.equal(data, msg, 'Expect the invalid session message.');
var msg = 'Exception: 190: Invalid OAuth 2.0 Access Token';
test.equal(data, msg, 'Expect the invalid session message.');
var result = data.getResult();
test.ok(typeof result == 'object', 'expect a result object');
test.equal(result.error_code, 190, 'expect code');
test.done();
});
var result = data.getResult();
test.ok(typeof result == 'object', 'expect a result object');
test.equal(result.error_code, 190, 'expect code');
test.done();
});
};
exports.testAPIGraphPublicData = function(test) {
var facebook = new fbsdk.Facebook({
appId : APP_ID,
secret : SECRET
});
var facebook = new Facebook({
appId : APP_ID,
secret : SECRET
});
facebook.api('/naitik', function(response) {
test.equal(response.id, '5526183', 'should get expected id.');
test.done();
});
facebook.api('/naitik', function(response) {
test.equal(response.id, '5526183', 'should get expected id.');
test.done();
});
// regression test: calling api w/o callback throws TypeError
facebook.api('/4');
// regression test: calling api w/o callback throws TypeError
facebook.api('/4');
};
exports.testGraphAPIWithSession = function(test) {
var facebook = new fbsdk.Facebook({
appId : APP_ID,
secret : SECRET
});
facebook.setSession(VALID_EXPIRED_SESSION);
var facebook = new Facebook({
appId : APP_ID,
secret : SECRET
});
facebook.setSession(VALID_EXPIRED_SESSION);
facebook.api('/me', function(data) {
test.ok(data.error);
// means the server got the access token
var msg = 'OAuthException: Error validating access token.';
test.equal(msg, data, 'Expect the invalid session message.');
// also ensure the session was reset since it was invalid
test.equal(facebook.getSession(), null, 'Expect the session to be reset.');
test.done();
});
facebook.api('/me', function(data) {
test.ok(data.error);
// means the server got the access token
var msg = 'OAuthException: Error validating access token.';
test.equal(msg, data, 'Expect the invalid session message.');
// also ensure the session was reset since it was invalid
test.equal(facebook.getSession(), null, 'Expect the session to be reset.');
test.done();
});
};
exports.testGraphAPIMethod = function(test) {
var facebook = new fbsdk.Facebook({
appId : APP_ID,
secret : SECRET
});
var facebook = new Facebook({
appId : APP_ID,
secret : SECRET
});
facebook.api('/naitik', 'DELETE', function(data) {
test.ok(data.error);
// ProfileDelete means the server understood the DELETE
var msg = 'OAuthException: An access token is required to request this resource.';
test.equal(msg, data, 'Expect the invalid session message.');
test.done();
});
facebook.api('/naitik', 'DELETE', function(data) {
test.ok(data.error);
// ProfileDelete means the server understood the DELETE
var msg = 'OAuthException: An access token is required to request this resource.';
test.equal(msg, data, 'Expect the invalid session message.');
test.done();
});
};
exports.testGraphAPIOAuthSpecError = function(test) {
var facebook = new fbsdk.Facebook({
appId : MIGRATED_APP_ID,
secret : MIGRATED_SECRET
});
var facebook = new Facebook({
appId : MIGRATED_APP_ID,
secret : MIGRATED_SECRET
});
facebook.api('/me', { client_id: MIGRATED_APP_ID }, function(data) {
test.ok(data.error);
// means the server got the access token
msg = 'invalid_request: An active access token must be used to query information about the current user.';
test.equal(msg, data, 'Expect the invalid session message.');
// also ensure the session was reset since it was invalid
test.equal(facebook.getSession(), null, 'Expect the session to be reset.');
test.done();
});
facebook.api('/me', { client_id: MIGRATED_APP_ID }, function(data) {
test.ok(data.error);
// means the server got the access token
msg = 'invalid_request: An active access token must be used to query information about the current user.';
test.equal(msg, data, 'Expect the invalid session message.');
// also ensure the session was reset since it was invalid
test.equal(facebook.getSession(), null, 'Expect the session to be reset.');
test.done();
});
};

@@ -428,3 +360,3 @@

//exports.testGraphAPIMethodOAuthSpecError = function(test) {
// var facebook = new fbsdk.Facebook({
// var facebook = new Facebook({
// appId : MIGRATED_APP_ID,

@@ -444,16 +376,16 @@ // secret : MIGRATED_SECRET

exports.testCurlFailure = function(test) {
var facebook = new fbsdk.Facebook({
appId : APP_ID,
secret : SECRET
});
var facebook = new Facebook({
appId : APP_ID,
secret : SECRET
});
// we dont expect facebook will ever return in 1ms
facebook.timeout = 1;
facebook.api('/naitik', function(data) {
test.ok(data.error);
var CURLE_OPERATION_TIMEDOUT = 28;
test.equal(CURLE_OPERATION_TIMEDOUT, data.code, 'expect timeout');
test.equal('CurlException', data.getType(), 'expect type');
test.done();
});
// we dont expect facebook will ever return in 1ms
facebook.timeout = 1;
facebook.api('/naitik', function(data) {
test.ok(data.error);
var CURLE_OPERATION_TIMEDOUT = 28;
test.equal(CURLE_OPERATION_TIMEDOUT, data.code, 'expect timeout');
test.equal('CurlException', data.getType(), 'expect type');
test.done();
});
};

@@ -463,309 +395,322 @@

exports.testGraphAPIWithOnlyParams = function(test) {
var facebook = new fbsdk.Facebook({
appId : APP_ID,
secret : SECRET
});
var facebook = new Facebook({
appId : APP_ID,
secret : SECRET
});
facebook.api('/' + APP_ID + '/insights', { limit:1 }, function(response) {
test.equal(1, response.data.length, 'should get one entry');
test.done();
});
facebook.api('/' + APP_ID + '/insights', { limit:1 }, function(response) {
test.equal(1, response.data.length, 'should get one entry');
test.done();
});
};
exports.testLoginURLDefaults = function(test) {
var options = {
path: '/examples'
};
httpServerTest(options, function(request, response) {
request.headers.host = 'fbrell.com';
var facebook = new fbsdk.Facebook({
appId : APP_ID,
secret : SECRET,
request: request
});
var encodedUrl = querystring.escape('http://fbrell.com/examples');
test.ok(facebook.getLoginUrl().indexOf(encodedUrl) >= 0, 'Expect the current url to exist.');
test.done();
});
var options = {
path: '/examples',
headers: { host : 'fbrell.com' }
};
httpServerTest(options, function(request, response) {
var facebook = new Facebook({
appId : APP_ID,
secret : SECRET,
request: request
});
var encodedUrl = querystring.escape('http://fbrell.com/examples');
test.ok(facebook.getLoginUrl().indexOf(encodedUrl) >= 0, 'Expect the current url to exist.');
test.done();
});
};
// The siteUrl option trumps the 'host' header
// TODO: deprecate this feature
exports.testLoginURLUsingSiteUrl = function(test) {
var options = {
path: '/examples'
};
httpServerTest(options, function(request, response) {
test.ok(request.headers.host != 'fbrell.com');
var facebook = new fbsdk.Facebook({
appId : APP_ID,
secret : SECRET,
siteUrl: 'http://fbrell.com',
request: request
});
var encodedUrl = querystring.escape('http://fbrell.com/examples');
test.ok(facebook.getLoginUrl().indexOf(encodedUrl) >= 0, 'Expect the current url to exist.');
test.done();
});
var options = {
path: '/examples'
};
httpServerTest(options, function(request, response) {
test.ok(request.headers.host != 'fbrell.com');
var facebook = new Facebook({
appId : APP_ID,
secret : SECRET,
siteUrl: 'http://fbrell.com',
request: request
});
var encodedUrl = querystring.escape('http://fbrell.com/examples');
test.ok(facebook.getLoginUrl().indexOf(encodedUrl) >= 0, 'Expect the current url to exist.');
test.done();
});
};
exports.testUnavailableLoginURLThrowsError = function(test) {
var facebook = new fbsdk.Facebook({
appId : APP_ID,
secret : SECRET
});
test.expect(1);
test['throws'](function() {
facebook.getLoginUrl();
});
test.done();
var facebook = new Facebook({
appId : APP_ID,
secret : SECRET
});
test.expect(1);
test['throws'](function() {
facebook.getLoginUrl();
});
test.done();
};
exports.testLoginURLDefaultsDropSessionQueryParam = function(test) {
var options = {
path: '/examples?session=xx42xx'
};
httpServerTest(options, function(request, response) {
request.headers.host = 'fbrell.com';
var facebook = new fbsdk.Facebook({
appId : APP_ID,
secret : SECRET,
request: request
});
var expectEncodedUrl = querystring.escape('http://fbrell.com/examples');
test.ok(facebook.getLoginUrl().indexOf(expectEncodedUrl) >= 0, 'Expect the current url to exist.');
test.ok(facebook.getLoginUrl().indexOf('xx42xx') == -1, 'Expect the session param to be dropped.');
test.done();
});
var options = {
path: '/examples?session=xx42xx',
headers: { host : 'fbrell.com' }
};
httpServerTest(options, function(request, response) {
var facebook = new Facebook({
appId : APP_ID,
secret : SECRET,
request: request
});
var expectEncodedUrl = querystring.escape('http://fbrell.com/examples');
test.ok(facebook.getLoginUrl().indexOf(expectEncodedUrl) >= 0, 'Expect the current url to exist.');
test.ok(facebook.getLoginUrl().indexOf('xx42xx') == -1, 'Expect the session param to be dropped.');
test.done();
});
};
exports.testLoginURLDefaultsDropSessionQueryParamButNotOthers = function(test) {
var options = {
path: '/examples?session=xx42xx&do_not_drop=xx43xx'
};
httpServerTest(options, function(request, response) {
request.headers.host = 'fbrell.com';
var facebook = new fbsdk.Facebook({
appId : APP_ID,
secret : SECRET,
request: request
});
var expectEncodedUrl = querystring.escape('http://fbrell.com/examples');
test.ok(facebook.getLoginUrl().indexOf('xx42xx') == -1, 'Expect the session param to be dropped.');
test.ok(facebook.getLoginUrl().indexOf('xx43xx') >= 0, 'Expect the do_not_drop param to exist.');
test.done();
});
var options = {
path: '/examples?session=xx42xx&do_not_drop=xx43xx',
headers: { host : 'fbrell.com' }
};
httpServerTest(options, function(request, response) {
var facebook = new Facebook({
appId : APP_ID,
secret : SECRET,
request: request
});
var expectEncodedUrl = querystring.escape('http://fbrell.com/examples');
test.ok(facebook.getLoginUrl().indexOf('xx42xx') == -1, 'Expect the session param to be dropped.');
test.ok(facebook.getLoginUrl().indexOf('xx43xx') >= 0, 'Expect the do_not_drop param to exist.');
test.done();
});
};
exports.testLoginURLCustomNext = function(test) {
var options = {
path: '/examples'
};
httpServerTest(options, function(request, response) {
request.headers.host = 'fbrell.com';
var facebook = new fbsdk.Facebook({
appId : APP_ID,
secret : SECRET,
request: request
});
var next = 'http://fbrell.com/custom';
var loginUrl = facebook.getLoginUrl({
next : next,
cancel_url : next
});
var currentEncodedUrl = querystring.escape('http://fbrell.com/examples');
var expectedEncodedUrl = querystring.escape(next);
test.ok(loginUrl.indexOf(expectedEncodedUrl) >= 0, 'Expect the custom url to exist.');
test.ok(loginUrl.indexOf(currentEncodedUrl) == -1, 'Expect the current url to not exist.');
test.done();
});
var options = {
path: '/examples',
headers: { host : 'fbrell.com' }
};
httpServerTest(options, function(request, response) {
var facebook = new Facebook({
appId : APP_ID,
secret : SECRET,
request: request
});
var next = 'http://fbrell.com/custom';
var loginUrl = facebook.getLoginUrl({
next : next,
cancel_url : next
});
var currentEncodedUrl = querystring.escape('http://fbrell.com/examples');
var expectedEncodedUrl = querystring.escape(next);
test.ok(loginUrl.indexOf(expectedEncodedUrl) >= 0, 'Expect the custom url to exist.');
test.ok(loginUrl.indexOf(currentEncodedUrl) == -1, 'Expect the current url to not exist.');
test.done();
});
};
exports.testLogoutURLDefaults = function(test) {
var options = {
path: '/examples'
};
httpServerTest(options, function(request, response) {
request.headers.host = 'fbrell.com';
var facebook = new fbsdk.Facebook({
appId : APP_ID,
secret : SECRET,
request: request
});
var encodedUrl = querystring.escape('http://fbrell.com/examples');
test.ok(facebook.getLogoutUrl().indexOf(encodedUrl) >= 0, 'Expect the current url to exist.');
test.done();
});
var options = {
path: '/examples',
headers: { host : 'fbrell.com' }
};
httpServerTest(options, function(request, response) {
var facebook = new Facebook({
appId : APP_ID,
secret : SECRET,
request: request
});
var encodedUrl = querystring.escape('http://fbrell.com/examples');
test.ok(facebook.getLogoutUrl().indexOf(encodedUrl) >= 0, 'Expect the current url to exist.');
test.done();
});
};
exports.testLoginStatusURLDefaults = function(test) {
var options = {
path: '/examples'
};
httpServerTest(options, function(request, response) {
request.headers.host = 'fbrell.com';
var facebook = new fbsdk.Facebook({
appId : APP_ID,
secret : SECRET,
request: request
});
var encodedUrl = querystring.escape('http://fbrell.com/examples');
test.ok(facebook.getLoginStatusUrl().indexOf(encodedUrl) >= 0, 'Expect the current url to exist.');
test.done();
});
var options = {
path: '/examples',
headers: { host : 'fbrell.com' }
};
httpServerTest(options, function(request, response) {
var facebook = new Facebook({
appId : APP_ID,
secret : SECRET,
request: request
});
var encodedUrl = querystring.escape('http://fbrell.com/examples');
test.ok(facebook.getLoginStatusUrl().indexOf(encodedUrl) >= 0, 'Expect the current url to exist.');
test.done();
});
};
exports.testLoginStatusURLCustom = function(test) {
var options = {
path: '/examples'
};
httpServerTest(options, function(request, response) {
request.headers.host = 'fbrell.com';
var facebook = new fbsdk.Facebook({
appId : APP_ID,
secret : SECRET,
request: request
});
var encodedUrl1 = querystring.escape('http://fbrell.com/examples');
var okUrl = 'http://fbrell.com/here1';
var encodedUrl2 = querystring.escape(okUrl);
var loginStatusUrl = facebook.getLoginStatusUrl({ ok_session: okUrl });
test.ok(loginStatusUrl.indexOf(encodedUrl1) >= 0, 'Expect the current url to exist.');
test.ok(loginStatusUrl.indexOf(encodedUrl2) >= 0, 'Expect the custom url to exist.');
test.done();
});
var options = {
path: '/examples',
headers: { host : 'fbrell.com' }
};
httpServerTest(options, function(request, response) {
var facebook = new Facebook({
appId : APP_ID,
secret : SECRET,
request: request
});
var encodedUrl1 = querystring.escape('http://fbrell.com/examples');
var okUrl = 'http://fbrell.com/here1';
var encodedUrl2 = querystring.escape(okUrl);
var loginStatusUrl = facebook.getLoginStatusUrl({ ok_session: okUrl });
test.ok(loginStatusUrl.indexOf(encodedUrl1) >= 0, 'Expect the current url to exist.');
test.ok(loginStatusUrl.indexOf(encodedUrl2) >= 0, 'Expect the custom url to exist.');
test.done();
});
};
exports.testNonDefaultPort = function(test) {
var options = {
path: '/examples'
};
httpServerTest(options, function(request, response) {
request.headers.host = 'fbrell.com:8080';
var facebook = new fbsdk.Facebook({
appId : APP_ID,
secret : SECRET,
request: request
});
var encodedUrl = querystring.escape('http://fbrell.com:8080/examples');
test.ok(facebook.getLoginUrl().indexOf(encodedUrl) >= 0, 'Expect the current url to exist.');
test.done();
});
var options = {
path: '/examples',
headers: { host : 'fbrell.com:8080' }
};
httpServerTest(options, function(request, response) {
var facebook = new Facebook({
appId : APP_ID,
secret : SECRET,
request: request
});
var encodedUrl = querystring.escape('http://fbrell.com:8080/examples');
test.ok(facebook.getLoginUrl().indexOf(encodedUrl) >= 0, 'Expect the current url to exist.');
test.done();
});
};
// TODO: currently it is only possible to do this with a siteUrl
exports.testSecureCurrentUrl = function(test) {
var options = {
path: '/examples'
};
httpServerTest(options, function(request, response) {
var facebook = new fbsdk.Facebook({
appId : APP_ID,
secret : SECRET,
siteUrl: 'https://fbrell.com/',
request: request
});
var encodedUrl = querystring.escape('https://fbrell.com/examples');
test.ok(facebook.getLoginUrl().indexOf(encodedUrl) >= 0, 'Expect the current url to exist.');
test.done();
});
var options = {
https: true,
path: '/examples',
headers: { host : 'fbrell.com' }
};
httpServerTest(options, function(request, response) {
var facebook = new Facebook({
appId : APP_ID,
secret : SECRET,
request: request
});
var encodedUrl = querystring.escape('https://fbrell.com/examples');
test.ok(facebook.getLoginUrl().indexOf(encodedUrl) >= 0, 'Expect the current url to exist.');
test.done();
});
};
// TODO: do this without siteUrl?
exports.testSecureCurrentUrlWithNonDefaultPort = function(test) {
var options = {
path: '/examples'
};
httpServerTest(options, function(request, response) {
var facebook = new fbsdk.Facebook({
appId : APP_ID,
secret : SECRET,
siteUrl: 'https://fbrell.com:8080/',
request: request
});
var encodedUrl = querystring.escape('https://fbrell.com:8080/examples');
test.ok(facebook.getLoginUrl().indexOf(encodedUrl) >= 0, 'Expect the current url to exist.');
test.done();
});
var options = {
https: true,
path: '/examples',
headers: { host : 'fbrell.com:8080' }
};
httpServerTest(options, function(request, response) {
var facebook = new Facebook({
appId : APP_ID,
secret : SECRET,
request: request
});
var encodedUrl = querystring.escape('https://fbrell.com:8080/examples');
test.ok(facebook.getLoginUrl().indexOf(encodedUrl) >= 0, 'Expect the current url to exist.');
test.done();
});
};
exports.testAppSecretCall = function(test) {
var facebook = new fbsdk.Facebook({
appId : APP_ID,
secret : SECRET
});
facebook.api('/' + APP_ID + '/insights', function(response) {
test.ok(response.data.length > 0, 'Expect some data back.');
test.done();
});
var facebook = new Facebook({
appId : APP_ID,
secret : SECRET
});
facebook.api('/' + APP_ID + '/insights', function(response) {
test.ok(response.data.length > 0, 'Expect some data back.');
test.done();
});
};
exports.testBase64UrlEncode = function(test) {
var input = 'Facebook rocks';
var output = 'RmFjZWJvb2sgcm9ja3M';
test.equal(fbsdk.Facebook.prototype._base64UrlDecode(output), input);
test.done();
var input = 'Facebook rocks';
var output = 'RmFjZWJvb2sgcm9ja3M';
test.equal(Facebook.prototype._base64UrlDecode(output), input);
test.done();
};
exports.testSignedToken = function(test) {
var facebook = new fbsdk.Facebook({
appId : APP_ID,
secret : SECRET
});
var payload = facebook._parseSignedRequest(VALID_SIGNED_REQUEST);
test.ok(payload, 'Expected token to parse');
var session = facebook._createSessionFromSignedRequest(payload);
test.equal(session.uid, VALID_EXPIRED_SESSION.uid);
test.equal(facebook.getSignedRequest(), null);
var facebook = new Facebook({
appId : APP_ID,
secret : SECRET
});
var payload = facebook._parseSignedRequest(VALID_SIGNED_REQUEST);
test.ok(payload, 'Expected token to parse');
var session = facebook._createSessionFromSignedRequest(payload);
test.equal(session.uid, VALID_EXPIRED_SESSION.uid);
test.equal(facebook.getSignedRequest(), null);
// test that the actual signed request equals the expected one
var options = {
path: '/?' + querystring.stringify({ signed_request: VALID_SIGNED_REQUEST })
};
httpServerTest(options, function(request, response) {
facebook.request = request;
test.deepEqual(facebook.getSignedRequest(), payload);
test.done();
});
// test that the actual signed request equals the expected one
var options = {
path: '/?' + querystring.stringify({ signed_request: VALID_SIGNED_REQUEST })
};
httpServerTest(options, function(request, response) {
facebook.request = request;
test.deepEqual(facebook.getSignedRequest(), payload);
test.done();
});
};
exports.testSignedTokenInQuery = function(test) {
var options = {
path: '/?' + querystring.stringify({ signed_request: VALID_SIGNED_REQUEST })
};
httpServerTest(options, function(request, response) {
var facebook = new fbsdk.Facebook({
appId : APP_ID,
secret : SECRET,
request : request
});
test.ok(facebook.getSession());
test.done();
});
var options = {
path: '/?' + querystring.stringify({ signed_request: VALID_SIGNED_REQUEST })
};
httpServerTest(options, function(request, response) {
var facebook = new Facebook({
appId : APP_ID,
secret : SECRET,
request : request
});
test.ok(facebook.getSession());
test.done();
});
};
exports.testNonTossedSignedtoken = function(test) {
var facebook = new fbsdk.Facebook({
appId : APP_ID,
secret : SECRET
});
var payload = facebook._parseSignedRequest(NON_TOSSED_SIGNED_REQUEST);
test.ok(payload, 'Expected token to parse');
var session = facebook._createSessionFromSignedRequest(payload);
test.ok(!session);
test.ok(!facebook.getSignedRequest());
var facebook = new Facebook({
appId : APP_ID,
secret : SECRET
});
var payload = facebook._parseSignedRequest(NON_TOSSED_SIGNED_REQUEST);
test.ok(payload, 'Expected token to parse');
var session = facebook._createSessionFromSignedRequest(payload);
test.ok(!session);
test.ok(!facebook.getSignedRequest());
// test an actual http signed request
var options = {
path: '/?' + querystring.stringify({ signed_request: NON_TOSSED_SIGNED_REQUEST })
};
httpServerTest(options, function(request, response) {
facebook.request = request;
test.deepEqual(facebook.getSignedRequest(), {algorithm : 'HMAC-SHA256'});
test.done();
});
// test an actual http signed request
var options = {
path: '/?' + querystring.stringify({ signed_request: NON_TOSSED_SIGNED_REQUEST })
};
httpServerTest(options, function(request, response) {
facebook.request = request;
test.deepEqual(facebook.getSignedRequest(), {algorithm : 'HMAC-SHA256'});
test.done();
});
};
exports.testVideoUpload = function(test) {
var facebook = new Facebook({
appId : APP_ID,
secret : SECRET
});
facebook.setSession(VALID_EXPIRED_SESSION);
var url = facebook._getApiUrl('video.upload');
test.ok(url.indexOf('//api-video.') >= 0, 'video.upload should go against api-video');
test.done();
};
// TODO: is it possible or necessary to support this?
// exports.testBundledCACert = function(test) {
// var facebook = new fbsdk.Facebook({
// var facebook = new Facebook({
// appId : APP_ID,

@@ -789,24 +734,35 @@ // secret : SECRET,

*/
function httpServerTest(options, test, result) {
options.host = 'localhost';
options.port = 8889;
options.path = options.path || '/';
function httpServerTest(options, test) {
var transport = options.https ? https : http;
options.host = 'localhost';
options.port = 8889;
options.path = options.path || '/';
// create a server to test an http request
var server = http.createServer(function(request, response) {
test(request, response);
response.end();
server.close();
});
server.listen(options.port, function() {
http.request(options, result).end();
});
if (options.https) {
var server = transport.createServer({
key: fs.readFileSync(__dirname + '/test_key.pem'),
cert: fs.readFileSync(__dirname + '/test_cert.pem')
});
} else {
var server = transport.createServer();
}
server.on('request', function(request, response) {
test(request, response);
response.end();
server.close();
});
server.listen(options.port, function() {
transport.request(options /* , response */ ).end();
});
}
function clone(object) {
var new_object = {};
for (var i in object) {
new_object[i] = object[i];
}
return new_object;
var new_object = {};
for (var i in object) {
new_object[i] = object[i];
}
return new_object;
}
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc