Comparing version 1.1.0 to 1.1.1
@@ -0,1 +1,6 @@ | ||
## v1.1.1 (Mar 10, 2014): | ||
* Fix web browser client login sequence to work in mobile safari | ||
## v1.1.0 (Feb 19, 2014): | ||
@@ -2,0 +7,0 @@ |
@@ -24,2 +24,6 @@ /*global process */ | ||
tasks: ['build'] | ||
}, | ||
jsdoc: { | ||
files: ["lib/**/*.js" ], | ||
tasks: ['jsdoc'] | ||
} | ||
@@ -26,0 +30,0 @@ }, |
/** | ||
* | ||
* @file Browser client connection management class | ||
* @author Shinichi Tomita <shinichi.tomita@gmail.com> | ||
*/ | ||
@@ -17,22 +18,21 @@ var events = require('events'), | ||
var top = (screen.height/2)-(h/2); | ||
return window.open(url, null, 'toolbar=no,status=no,menubar=no,width='+w+',height='+h+',top='+top+',left='+left); | ||
return window.open(url, null, 'location=yes,toolbar=no,status=no,menubar=no,width='+w+',height='+h+',top='+top+',left='+left); | ||
} | ||
/** | ||
* @private | ||
*/ | ||
function checkCallbackResponse(w) { | ||
var params; | ||
if (isSameOrigin(w)) { | ||
if (w.location.hash) { | ||
params = qs.parse(w.location.hash.substring(1)); | ||
if (params.access_token) { | ||
return { success: true, body: params }; | ||
} | ||
} else if (w.location.search) { | ||
params = qs.parse(w.location.search.substring(1)); | ||
if (params.error) { | ||
return { success: false, error: params }; | ||
} | ||
function handleCallbackResponse() { | ||
var res = checkCallbackResponse(); | ||
var state = localStorage.getItem('jsforce_state'); | ||
if (res && state && res.body.state === state) { | ||
localStorage.removeItem('jsforce_state'); | ||
var states = state.split('.'); | ||
var prefix = states[0], promptType = states[1]; | ||
var cli = new Client(prefix); | ||
if (res.success) { | ||
cli._storeTokens(res.body); | ||
location.hash = ''; | ||
} else { | ||
cli._storeError(res.body); | ||
} | ||
if (promptType === 'popup') { window.close(); } | ||
return true; | ||
} | ||
@@ -44,8 +44,15 @@ } | ||
*/ | ||
function isSameOrigin(w) { | ||
return location.origin ? | ||
location.origin === w.location.origin : | ||
(location.hostname === w.location.hostname && | ||
location.port === w.location.port && | ||
location.protocol === w.location.protocol); | ||
function checkCallbackResponse() { | ||
var params; | ||
if (window.location.hash) { | ||
params = qs.parse(window.location.hash.substring(1)); | ||
if (params.access_token) { | ||
return { success: true, body: params }; | ||
} | ||
} else if (window.location.search) { | ||
params = qs.parse(window.location.search.substring(1)); | ||
if (params.error) { | ||
return { success: false, body: params }; | ||
} | ||
} | ||
} | ||
@@ -58,6 +65,7 @@ | ||
/** | ||
* | ||
* @class | ||
* @todo add document | ||
*/ | ||
var Client = function() { | ||
this._prefix = 'sf' + clientIdx++; | ||
var Client = function(prefix) { | ||
this._prefix = prefix || 'jsforce' + clientIdx++; | ||
this.connection = null; | ||
@@ -72,2 +80,3 @@ }; | ||
Client.prototype.init = function(config) { | ||
if (handleCallbackResponse()) { return; } | ||
this.config = config; | ||
@@ -97,4 +106,12 @@ this.connection = new Connection(config); | ||
var self = this; | ||
this._prompt(options, callback); | ||
}; | ||
Client.prototype._prompt = function(options, callback) { | ||
var self = this; | ||
var oauth2 = new OAuth2(options); | ||
var state = Math.random().toString(36).substring(2); | ||
var rand = Math.random().toString(36).substring(2); | ||
var state = [ this._prefix, "popup", rand ].join('.'); | ||
localStorage.setItem("jsforce_state", state); | ||
var authzUrl = oauth2.getAuthorizationUrl({ | ||
@@ -105,24 +122,32 @@ response_type: 'token', | ||
}); | ||
var size = options.popup || {}; | ||
var w = popupWin(authzUrl, size.width || 912, size.height || 513); | ||
var size = options.size || {}; | ||
var pw = popupWin(authzUrl, size.width || 912, size.height || 513); | ||
if (!pw) { | ||
state = [ this._prefix, "redirect", rand ].join('.'); | ||
localStorage.setItem("jsforce_state", state); | ||
authzUrl = oauth2.getAuthorizationUrl({ | ||
response_type: 'token', | ||
scope : options.scope, | ||
state: state | ||
}); | ||
location.href = authzUrl; | ||
return; | ||
} | ||
self._removeTokens(); | ||
var pid = setInterval(function() { | ||
try { | ||
if (w.closed) { | ||
if (!pw || pw.closed) { | ||
clearInterval(pid); | ||
callback(null, { status: 'cancel' }); | ||
} else { | ||
var res = checkCallbackResponse(w); | ||
w.close(); | ||
clearInterval(pid); | ||
if (res.success && res.body.state === state) { | ||
self._storeTokens(res.body); | ||
self.connection.initialize({ | ||
accessToken: res.body.access_token, | ||
instanceUrl: res.body.instance_url | ||
}); | ||
var tokens = self._getTokens(); | ||
if (tokens) { | ||
self.connection.initialize(tokens); | ||
self.emit('connect', self.connection); | ||
callback(null, { status: 'connect', body: res.body }); | ||
} else if (!res.success) { | ||
var error = new Error(res.error.error + ": " + res.error.error_description); | ||
callback(error); | ||
callback(null, { status: 'connect' }); | ||
} else { | ||
var err = self._getError(); | ||
if (err) { | ||
callback(new Error(err.error + ": " + err.error_description)); | ||
} else { | ||
callback(null, { status: 'cancel' }); | ||
} | ||
} | ||
@@ -188,2 +213,20 @@ } | ||
/** | ||
* @private | ||
*/ | ||
Client.prototype._getError = function() { | ||
try { | ||
var err = JSON.parse(localStorage.getItem(this._prefix + '_error')); | ||
localStorage.removeItem(this._prefix + '_error'); | ||
return err; | ||
} catch(e) {} | ||
}; | ||
/** | ||
* @private | ||
*/ | ||
Client.prototype._storeError = function(err) { | ||
localStorage.setItem(this._prefix + '_error', JSON.stringify(err)); | ||
}; | ||
/** | ||
* | ||
@@ -190,0 +233,0 @@ */ |
/*global process */ | ||
/** | ||
* @file Command line interface for JSforce | ||
* @author Shinichi Tomita <shinichi.tomita@gmail.com> | ||
*/ | ||
var http = require('http'), | ||
@@ -18,3 +22,3 @@ url = require('url'), | ||
/** | ||
* | ||
* @private | ||
*/ | ||
@@ -52,3 +56,3 @@ function start() { | ||
/** | ||
* | ||
* @private | ||
*/ | ||
@@ -64,3 +68,3 @@ function getCurrentConnection() { | ||
/** | ||
* | ||
* @private | ||
*/ | ||
@@ -85,3 +89,3 @@ function saveCurrentConnection() { | ||
/** | ||
* | ||
* @private | ||
*/ | ||
@@ -133,3 +137,3 @@ function connect(name, options, callback) { | ||
/** | ||
* | ||
* @private | ||
*/ | ||
@@ -160,3 +164,3 @@ function loginByPassword(username, password, retry, callback) { | ||
/** | ||
* | ||
* @private | ||
*/ | ||
@@ -174,3 +178,3 @@ function disconnect(name) { | ||
/** | ||
* | ||
* @private | ||
*/ | ||
@@ -212,3 +216,3 @@ function authorize(clientName, callback) { | ||
/** | ||
* | ||
* @private | ||
*/ | ||
@@ -242,3 +246,3 @@ function waitCallback(serverUrl, state, callback) { | ||
/** | ||
* | ||
* @private | ||
*/ | ||
@@ -292,3 +296,3 @@ function register(clientName, clientConfig, callback) { | ||
/** | ||
* | ||
* @private | ||
*/ | ||
@@ -304,3 +308,3 @@ function listConnections() { | ||
/** | ||
* | ||
* @private | ||
*/ | ||
@@ -312,3 +316,3 @@ function getConnectionNames() { | ||
/** | ||
* | ||
* @private | ||
*/ | ||
@@ -320,3 +324,3 @@ function getClientNames() { | ||
/** | ||
* | ||
* @private | ||
*/ | ||
@@ -332,3 +336,3 @@ function promptMessage(message, callback) { | ||
/** | ||
* | ||
* @private | ||
*/ | ||
@@ -344,3 +348,3 @@ function promptPassword(message, callback) { | ||
/** | ||
* | ||
* @private | ||
*/ | ||
@@ -355,5 +359,4 @@ function promptConfirm(message, callback) { | ||
/** | ||
* | ||
*/ | ||
/* ------------------------------------------------------------------------- */ | ||
module.exports = { | ||
@@ -360,0 +363,0 @@ start: start, |
/*global process */ | ||
/** | ||
* | ||
* @file Registry for connection information, cached in local file system | ||
* @author Shinichi Tomita <shinichi.tomita@gmail.com> | ||
*/ | ||
@@ -12,5 +13,3 @@ var fs = require('fs'), | ||
/** | ||
* @private | ||
*/ | ||
/* */ | ||
var registryConfig = {}; | ||
@@ -117,5 +116,4 @@ try { | ||
/** | ||
* | ||
*/ | ||
/* ------------------------------------------------------------------------- */ | ||
module.exports = { | ||
@@ -122,0 +120,0 @@ getConnection: getConnection, |
@@ -5,2 +5,3 @@ /*global process, global */ | ||
* @author Shinichi Tomita <shinichi.tomita@gmail.com> | ||
* @private | ||
*/ | ||
@@ -37,3 +38,3 @@ var stream = require('stream'), | ||
/** | ||
* | ||
* @private | ||
*/ | ||
@@ -115,3 +116,3 @@ function injectAfter(replServer, method, afterFn) { | ||
/** | ||
* | ||
* @private | ||
*/ | ||
@@ -179,3 +180,3 @@ var Repl = module.exports = function(cli, replModule) { | ||
/** | ||
* | ||
* @private | ||
*/ | ||
@@ -182,0 +183,0 @@ Repl.prototype._defineAdditionalCommands = function(replServer) { |
@@ -6,5 +6,4 @@ /*global process, Sfdc */ | ||
/** | ||
* | ||
*/ | ||
/* */ | ||
var nodeRequest = require('request'), | ||
@@ -44,2 +43,3 @@ xhrRequest = require('./browser/request'), | ||
* @class | ||
* @protected | ||
*/ | ||
@@ -83,3 +83,5 @@ var Transport = module.exports = function() {}; | ||
* | ||
* @class | ||
* @class Transport~ProxyTransport | ||
* @protected | ||
* @extends Transport | ||
* @param {String} proxyUrl - AJAX Proxy server URL | ||
@@ -96,2 +98,3 @@ */ | ||
* | ||
* @method Transport~ProxyTransport#httpRequest | ||
* @param {Object} params - HTTP request | ||
@@ -98,0 +101,0 @@ * @param {Callback.<Object>} [callback] - Calback Function |
@@ -13,3 +13,3 @@ { | ||
"homepage": "http://github.com/jsforce/jsforce", | ||
"version": "1.1.0", | ||
"version": "1.1.1", | ||
"repository": { | ||
@@ -16,0 +16,0 @@ "type": "git", |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
2476703
31650