FoxToPhone 1.2beta3. Improved detection of errors with authentication. Allow the management of several accounts

This commit is contained in:
amla70
2011-08-04 15:09:24 +00:00
parent 11ae8e6ba9
commit b497fd22d5
12 changed files with 294 additions and 38 deletions

View File

@@ -10,7 +10,7 @@
</stringbundleset> </stringbundleset>
<popupset id="mainPopupSet"> <popupset id="mainPopupSet">
<menupopup id="sendtophoneContextMenu" onpopupshowing="sendtophone.initPopup();"> <menupopup id="sendtophoneContextMenu" onpopupshowing="if (event.target == this) sendtophone.initPopup();">
<menuitem label="&sendtophoneContextSendClipboard.label;" <menuitem label="&sendtophoneContextSendClipboard.label;"
accesskey="&sendtophoneContextSendClipboard.accesskey;" accesskey="&sendtophoneContextSendClipboard.accesskey;"
oncommand="sendtophone.sendClipboard()" id="sendtophoneContextMenuSendClipboard"/> oncommand="sendtophone.sendClipboard()" id="sendtophoneContextMenuSendClipboard"/>
@@ -23,8 +23,12 @@
<menu label="&sendtophoneProtocols.label;"> <menu label="&sendtophoneProtocols.label;">
<menupopup id="menu_Protocols" onpopupshowing="sendtophone.onOptionsShowing(this)"> <menupopup id="menu_Protocols" onpopupshowing="sendtophone.onOptionsShowing(this)">
<menuitem type="checkbox" id="marketcheck" label="market:" oncommand="sendtophone.onToggleOption(this)" option="market"/> <menuitem type="checkbox" id="marketcheck" label="market:" oncommand="sendtophone.onToggleOption(this)" option="market"/>
<menuitem type="checkbox" id="smscheck" label="sms:" oncommand="sendtophone.onToggleOption(this)" option="sms"/> <menuitem type="checkbox" id="smscheck" label="sms:" oncommand="sendtophone.onToggleOption(this)" option="sms"/>
<menuitem type="checkbox" id="telcheck" label="tel:" oncommand="sendtophone.onToggleOption(this)" option="tel"/> <menuitem type="checkbox" id="telcheck" label="tel:" oncommand="sendtophone.onToggleOption(this)" option="tel"/>
</menupopup>
</menu>
<menu label="&sendtophonePhoneAccounts.label;">
<menupopup id="sendtophoneContextMenuAccountsPane" onpopupshowing="sendtophone.fillAccountsMenu(this)">
</menupopup> </menupopup>
</menu> </menu>
<menuitem label="&sendtophoneContextLogout.label;" <menuitem label="&sendtophoneContextLogout.label;"

View File

@@ -46,10 +46,123 @@ let foxToPhonePreferences =
document.getElementById("hboxFileServerUrl").hidden = ( fileserverMenuList.value != 'Custom'); document.getElementById("hboxFileServerUrl").hidden = ( fileserverMenuList.value != 'Custom');
window.sizeToContent(); // Accounts
var accountsList = document.getElementById("accountsList");
// Clear all the items
while (accountsList.getRowCount() >0)
accountsList.removeItemAt(0);
this.prefs = Components.classes["@mozilla.org/preferences-service;1"]
.getService(Components.interfaces.nsIPrefService)
.getBranch("extensions.sendtophone.") ;
var accounts = this.prefs.getCharPref("accounts").split(";");
for (var i=0; i<accounts.length ; i++)
{
var account = accounts[i];
var title = this.prefs.getCharPref( account + ".title" );
accountsList.appendItem( title, account );
}
window.sizeToContent();
},
getString: function(name)
{
if (!this.strings)
{
this.strings = Components.classes["@mozilla.org/intl/stringbundle;1"]
.getService(Components.interfaces.nsIStringBundleService)
.createBundle("chrome://sendtophone/locale/overlay.properties");
}
return this.strings.GetStringFromName(name);
},
onAccountSelected: function() {
var accountsList = document.getElementById("accountsList"),
count = accountsList.selectedCount;
document.getElementById("btnRenameAccount").disabled = (count === 0);
document.getElementById("btnRemoveAccount").disabled = ((count === 0) || (accountsList.getRowCount()==1));
},
addAccount: function() {
var n=1,
accounts = this.prefs.getCharPref("accounts"),
accountsArray = accounts.split(";");
while (accountsArray.indexOf("account" + n)>=0)
n++;
var input = {value:"Phone " + n};
if (Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
.getService(Components.interfaces.nsIPromptService)
.prompt( null, this.getString("SendToPhoneTitle"), this.getString("PhoneAccountPromptAdd"), input, null, {value: false}))
{
var account = "account" + n;
this.prefs.setCharPref( account + ".title", input.value);
this.prefs.setCharPref( "accounts", accounts + ";" + account );
document.getElementById("accountsList").appendItem( input.value, account );
}
},
renameAccount: function() {
var accountsList = document.getElementById("accountsList");
for (var i= accountsList.selectedItems.length-1; i>=0; i--)
{
var item = accountsList.selectedItems[i],
input = {value:item.label},
ok = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
.getService(Components.interfaces.nsIPromptService)
.prompt( null, this.getString("SendToPhoneTitle"), this.getString("PhoneAccountPromptRename"), input, null, {value: false});
if (!ok)
return;
item.label = input.value;
this.prefs.setCharPref( item.value + ".title", input.value);
}
},
removeAccount: function() {
var accountsList = document.getElementById("accountsList"),
removedAccount = "",
accounts = [],
i;
for (i = accountsList.selectedItems.length-1; i>=0; i--)
{
var item = accountsList.selectedItems[i],
title = item.label;
if (!Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
.getService(Components.interfaces.nsIPromptService)
.confirm( null, this.getString("SendToPhoneTitle"), this.getString("PhoneAccountPromptRemove") + "\r\n" + title))
return;
removedAccount = item.value;
accountsList.removeItemAt( accountsList.getIndexOfItem( item ) );
this.prefs.deleteBranch( removedAccount );
}
for(i=0; i<accountsList.itemCount; i++)
{
var item = accountsList.getItemAtIndex( i );
accounts.push( item.value );
}
this.prefs.setCharPref( "accounts", accounts.join(";"));
if (this.prefs.getCharPref("currentAccount")==removedAccount)
{
if (typeof sendtophoneCore == "undefined")
Components.utils.import("resource://sendtophone/sendtophone.js");
sendtophoneCore.setCurrentAccount( accounts[0] );
}
} }
} ; } ;
this.addEventListener("load", function () {foxToPhonePreferences.load(); }, false); this.addEventListener("load", function () {foxToPhonePreferences.load(); }, false);

View File

@@ -15,7 +15,7 @@
<preference id="extensions.sendtophone.fileServerUrl" name="extensions.sendtophone.fileServerUrl" type="string"/> <preference id="extensions.sendtophone.fileServerUrl" name="extensions.sendtophone.fileServerUrl" type="string"/>
</preferences> </preferences>
<groupbox style="padding:1em;" label="ProtocolsGroup"> <groupbox style="padding:1em;">
<caption label="&sendtophoneProtocols.label;"/> <caption label="&sendtophoneProtocols.label;"/>
<checkbox preference="extensions.sendtophone.protocols.market" <checkbox preference="extensions.sendtophone.protocols.market"
@@ -30,7 +30,38 @@
label="tel:" /> label="tel:" />
</groupbox> </groupbox>
<groupbox style="padding:1em; min-height:10em;" label="FileServer"> <groupbox style="padding:1em;">
<caption label="&sendtophonePhoneAccounts.label;"/>
<description style="width:400px; height:2em;">
&sendtophonePhoneAccounts.description;
</description>
<hbox>
<listbox id="accountsList" flex="1" style="height: 8em; "
seltype="single"
onselect="foxToPhonePreferences.onAccountSelected();"
>
</listbox>
<vbox align="end">
<button id="btnAddAccount"
icon="add" label="&sendtophonePhoneAccounts.add;"
oncommand="foxToPhonePreferences.addAccount();"/>
<button id="btnRenameAccount" disabled="true"
label="&sendtophonePhoneAccounts.rename;"
oncommand="foxToPhonePreferences.renameAccount();"/>
<button id="btnRemoveAccount" disabled="true"
icon="remove" label="&sendtophonePhoneAccounts.remove;"
oncommand="foxToPhonePreferences.removeAccount();"/>
</vbox>
</hbox>
</groupbox>
<groupbox style="padding:1em; min-height:10em;">
<caption label="&sendtophoneFileTransfers.label;" /> <caption label="&sendtophoneFileTransfers.label;" />
<hbox align="center"> <hbox align="center">
<label value="&sendtophoneFileServer.label;" <label value="&sendtophoneFileServer.label;"
@@ -45,7 +76,7 @@
</menupopup> </menupopup>
</menulist> </menulist>
<description style="width: 300px;height:3em;" id="foxtophoneDisclaimer"> <description style="width:300px; height:3em;" id="foxtophoneDisclaimer">
&sendtophoneFileServer.Disclaimer; &sendtophoneFileServer.Disclaimer;
</description> </description>
</hbox> </hbox>

View File

@@ -233,6 +233,36 @@ var sendtophone = {
return (/^(https?|market|tel|sms(to)?|mailto|ftp):/i).test( uri ); return (/^(https?|market|tel|sms(to)?|mailto|ftp):/i).test( uri );
}, },
fillAccountsMenu: function(menupopup)
{
var accounts = this.prefs.getCharPref("accounts").split(";"),
currentAccount = this.prefs.getCharPref('currentAccount');
while (menupopup.firstChild)
menupopup.removeChild(menupopup.firstChild);
for (var i=0; i<accounts.length ; i++)
{
var account = accounts[i],
title = this.prefs.getCharPref( account + '.title' );
var menuitem = document.createElement("menuitem");
menuitem.setAttribute("label", title);
menuitem.setAttribute("id", "sendtophone_" + account);
menuitem.setAttribute("type", "radio");
menuitem.setAttribute("name", "sendtophone_account");
if (currentAccount == account)
menuitem.setAttribute("checked", true);
// Select that account
menuitem.addEventListener("command", function(e) {
var id = e.target.getAttribute("id");
sendtophoneCore.setCurrentAccount( id.match(/_(.*)/)[1] );
}, false);
menupopup.appendChild(menuitem);
}
},
initPopup: function() initPopup: function()
{ {
var fileServerUrl = this.prefs.getCharPref( "fileServerUrl" ); var fileServerUrl = this.prefs.getCharPref( "fileServerUrl" );
@@ -241,6 +271,8 @@ var sendtophone = {
document.getElementById("sendtophoneContextMenuSendClipboard").disabled = !this.clipboardHasText(); document.getElementById("sendtophoneContextMenuSendClipboard").disabled = !this.clipboardHasText();
document.getElementById("sendtophoneContextMenuLogout").disabled = !sendtophoneCore.isLoggedIn();
// returning true will make the popup show // returning true will make the popup show
return true; return true;
}, },

View File

@@ -27,3 +27,8 @@
<!ENTITY sendtophoneFileServer.None "None"> <!ENTITY sendtophoneFileServer.None "None">
<!ENTITY sendtophoneFileServer.Custom "Custom"> <!ENTITY sendtophoneFileServer.Custom "Custom">
<!ENTITY sendtophoneFileServer.Disclaimer "Disclaimer: We (FoxToPhone developers) are not affiliated with any of the third party hosting services listed here. You should read their Terms Of Service before using them."> <!ENTITY sendtophoneFileServer.Disclaimer "Disclaimer: We (FoxToPhone developers) are not affiliated with any of the third party hosting services listed here. You should read their Terms Of Service before using them.">
<!ENTITY sendtophonePhoneAccounts.label "Phone accounts">
<!ENTITY sendtophonePhoneAccounts.description "If you are using several Google accounts with your devices, you can switch between them after creating them here.">
<!ENTITY sendtophonePhoneAccounts.add "Add new">
<!ENTITY sendtophonePhoneAccounts.rename "Rename">
<!ENTITY sendtophonePhoneAccounts.remove "Remove">

View File

@@ -21,3 +21,6 @@ qrContextMenu=Send "%s" to Android
FileUploadsDisabled=It's not possible to upload files to the phone. FileUploadsDisabled=It's not possible to upload files to the phone.
FileTooBig=The file is too big. FileTooBig=The file is too big.
videoTitle=Video Link videoTitle=Video Link
PhoneAccountPromptAdd=Please, write the name for the new account
PhoneAccountPromptRename=Please, write the new name for this account
PhoneAccountPromptRemove=Are you sure that you want to delete this account?

View File

@@ -27,3 +27,8 @@
<!ENTITY sendtophoneFileServer.None "Ninguno"> <!ENTITY sendtophoneFileServer.None "Ninguno">
<!ENTITY sendtophoneFileServer.Custom "Personalizado"> <!ENTITY sendtophoneFileServer.Custom "Personalizado">
<!ENTITY sendtophoneFileServer.Disclaimer "Aviso: Nosotros (los desarrolladores de Fox to Phone) no estamos relacionados con ninguno de los servidores de alojamiento mostrados aquí. Debes leer sus Terminos de Servicio antes de usarlos."> <!ENTITY sendtophoneFileServer.Disclaimer "Aviso: Nosotros (los desarrolladores de Fox to Phone) no estamos relacionados con ninguno de los servidores de alojamiento mostrados aquí. Debes leer sus Terminos de Servicio antes de usarlos.">
<!ENTITY sendtophonePhoneAccounts.label "Cuentas">
<!ENTITY sendtophonePhoneAccounts.description "Si usas varias cuentas de Google con tus aparatos, puedes cambiar entre ellas tras crearlas aquí.">
<!ENTITY sendtophonePhoneAccounts.add "Añadir">
<!ENTITY sendtophonePhoneAccounts.rename "Renombrar">
<!ENTITY sendtophonePhoneAccounts.remove "Quitar">

View File

@@ -21,3 +21,6 @@ qrContextMenu=Enviar "%s" a Android
FileUploadsDisabled=No se pueden enviar ficheros al teléfono. FileUploadsDisabled=No se pueden enviar ficheros al teléfono.
FileTooBig=El fichero que quiere enviar es demasiado grande. FileTooBig=El fichero que quiere enviar es demasiado grande.
videoTitle=Video Link videoTitle=Video Link
PhoneAccountPromptAdd=Por favor, escriba un nombre para la nueva cuenta
PhoneAccountPromptRename=Por favor, escriba el nuevo nombre para la cuenta
PhoneAccountPromptRemove=¿Está seguro de querer quitar esta cuenta?

View File

@@ -6,6 +6,9 @@ pref("extensions.sendtophone.proxyUrl", "http://foxtophone.com/f2p.php?link=");
pref("extensions.sendtophone.fileServerUrl", ""); pref("extensions.sendtophone.fileServerUrl", "");
pref("extensions.sendtophone.fileUploadMaxKb", 50000); pref("extensions.sendtophone.fileUploadMaxKb", 50000);
pref("extensions.sendtophone.SearchQR", 0); // 0: search and prompt, 1: search and launch automatically, 2: don't search pref("extensions.sendtophone.SearchQR", 0); // 0: search and prompt, 1: search and launch automatically, 2: don't search
pref("extensions.sendtophone.accounts", "account0");
pref("extensions.sendtophone.currentAccount", "account0");
pref("extensions.sendtophone.account0.title", "default");
pref("extensions.sendtophone.protocols.market", true); pref("extensions.sendtophone.protocols.market", true);
pref("extensions.sendtophone.protocols.sms", true); pref("extensions.sendtophone.protocols.sms", true);

View File

@@ -4,7 +4,7 @@
<em:id>sendtophone@martinezdelizarrondo.com</em:id> <em:id>sendtophone@martinezdelizarrondo.com</em:id>
<em:type>2</em:type> <em:type>2</em:type>
<em:name>Fox To Phone</em:name> <em:name>Fox To Phone</em:name>
<em:version>1.2beta2</em:version> <em:version>1.2beta3</em:version>
<em:creator>Alfonso &amp; Patrick</em:creator> <em:creator>Alfonso &amp; Patrick</em:creator>
<em:description>Send links to your Android 2.2 phone using the new C2DM service. Based on the ChromeToPhone extension.</em:description> <em:description>Send links to your Android 2.2 phone using the new C2DM service. Based on the ChromeToPhone extension.</em:description>

View File

@@ -71,7 +71,7 @@ function openTab(url, successUrl, callback)
* @return {ChromeExOAuth} An initialized ChromeExOAuth object. * @return {ChromeExOAuth} An initialized ChromeExOAuth object.
*/ */
var OAuthFactory = { var OAuthFactory = {
init : function(oauth_config) init : function(oauth_config, preferences)
{ {
var chromeExOAuth = new ChromeExOAuth( var chromeExOAuth = new ChromeExOAuth(
oauth_config['request_url'], oauth_config['request_url'],
@@ -91,22 +91,19 @@ var OAuthFactory = {
/* /*
LocalStorage isn't working for extensions LocalStorage isn't working for extensions
http://farter.users.sourceforge.net/blog/2011/03/07/using-localstorage-in-firefox-extensions-for-persistent-data-storage/ Use the preferences system with a branch for each account
*/ */
var url = oauth_config['scope']; chromeExOAuth.setPreferencesBranch(preferences);
var ios = Components.classes["@mozilla.org/network/io-service;1"]
.getService(Components.interfaces.nsIIOService);
var ssm = Components.classes["@mozilla.org/scriptsecuritymanager;1"]
.getService(Components.interfaces.nsIScriptSecurityManager);
var dsm = Components.classes["@mozilla.org/dom/storagemanager;1"]
.getService(Components.interfaces.nsIDOMStorageManager);
chromeExOAuth.localStorage = dsm.getLocalStorageForPrincipal(ssm.getCodebasePrincipal( ios.newURI(url, "", null) ) , ""); return chromeExOAuth;
return chromeExOAuth;
} }
}; };
ChromeExOAuth.prototype.setPreferencesBranch = function( branch ) {
this.prefs = Cc["@mozilla.org/preferences-service;1"]
.getService(Ci.nsIPrefService)
.getBranch(branch) ;
}
/** /**
* Constructor - no need to invoke directly, call initBackgroundPage instead. * Constructor - no need to invoke directly, call initBackgroundPage instead.
@@ -156,8 +153,8 @@ function ChromeExOAuth(url_request_token, url_auth_token, url_access_token,
* "logout" of the configured OAuth API. * "logout" of the configured OAuth API.
*/ */
ChromeExOAuth.prototype.clearTokens = function() { ChromeExOAuth.prototype.clearTokens = function() {
delete this.localStorage[this.key_token + encodeURI(this.oauth_scope)]; try { this.prefs.clearUserPref(this.key_token); } catch (e) {}
delete this.localStorage[this.key_token_secret + encodeURI(this.oauth_scope)]; try { this.prefs.clearUserPref(this.key_token_secret); } catch (e) {}
}; };
/** /**
@@ -414,7 +411,7 @@ ChromeExOAuth.addURLParam = function(url, key, value) {
* @param {String} token The token to store. * @param {String} token The token to store.
*/ */
ChromeExOAuth.prototype.setToken = function(token) { ChromeExOAuth.prototype.setToken = function(token) {
this.localStorage[this.key_token + encodeURI(this.oauth_scope)] = token; this.prefs.setCharPref(this.key_token, token);
}; };
/** /**
@@ -422,7 +419,9 @@ ChromeExOAuth.prototype.setToken = function(token) {
* @return {String} The stored token. * @return {String} The stored token.
*/ */
ChromeExOAuth.prototype.getToken = function() { ChromeExOAuth.prototype.getToken = function() {
return this.localStorage[this.key_token + encodeURI(this.oauth_scope)]; if (!this.prefs.prefHasUserValue(this.key_token))
return "";
return this.prefs.getCharPref(this.key_token);
}; };
/** /**
@@ -430,7 +429,7 @@ ChromeExOAuth.prototype.getToken = function() {
* @param {String} secret The secret to store. * @param {String} secret The secret to store.
*/ */
ChromeExOAuth.prototype.setTokenSecret = function(secret) { ChromeExOAuth.prototype.setTokenSecret = function(secret) {
this.localStorage[this.key_token_secret + encodeURI(this.oauth_scope)] = secret; this.prefs.setCharPref(this.key_token_secret, secret);
}; };
/** /**
@@ -438,12 +437,13 @@ ChromeExOAuth.prototype.setTokenSecret = function(secret) {
* @return {String} The stored secret. * @return {String} The stored secret.
*/ */
ChromeExOAuth.prototype.getTokenSecret = function() { ChromeExOAuth.prototype.getTokenSecret = function() {
return this.localStorage[this.key_token_secret + encodeURI(this.oauth_scope)]; if (!this.prefs.prefHasUserValue(this.key_token_secret))
return "";
return this.prefs.getCharPref(this.key_token_secret);
}; };
/** /**
* Starts an OAuth authorization flow for the current page. If a token exists, * Starts an OAuth authorization flow.
* no redirect is needed and the supplied callback is called immediately.
* If this method detects that a redirect has finished, it grabs the * If this method detects that a redirect has finished, it grabs the
* appropriate OAuth parameters from the URL and attempts to retrieve an * appropriate OAuth parameters from the URL and attempts to retrieve an
* access token. If no token exists and no redirect has happened, then * access token. If no token exists and no redirect has happened, then
@@ -454,14 +454,21 @@ ChromeExOAuth.prototype.getTokenSecret = function() {
* secret {String} The OAuth access token secret. * secret {String} The OAuth access token secret.
*/ */
ChromeExOAuth.prototype.initOAuthFlow = function(callback) { ChromeExOAuth.prototype.initOAuthFlow = function(callback) {
if (!this.hasToken()) {
// Clear any existing credentials as they have failed
this.clearTokens();
var request_params = { var request_params = {
'url_callback_param' : 'chromeexoauthcallback', 'url_callback_param' : 'chromeexoauthcallback',
'url_callback': this.callback_page 'url_callback': this.callback_page
} }
var self = this; var self = this;
this.getRequestToken(function(url) { this.getRequestToken(function(url, error) {
if (error)
{
callback(error);
return;
}
openTab( url, request_params.url_callback, function( url ) openTab( url, request_params.url_callback, function( url )
{ {
var params = ChromeExOAuth.getQueryStringParams( url ); var params = ChromeExOAuth.getQueryStringParams( url );
@@ -476,9 +483,6 @@ ChromeExOAuth.prototype.initOAuthFlow = function(callback) {
}); });
}, request_params); }, request_params);
} else {
callback(this.getToken(), this.getTokenSecret());
}
}; };
/** /**
@@ -547,7 +551,8 @@ ChromeExOAuth.prototype.onRequestToken = function(callback, xhr) {
} }
callback(url); callback(url);
} else { } else {
throw new Error("Fetching request token failed. Status " + xhr.status); // throw new Error("Fetching request token failed. Status " + xhr.status);
callback(null, "Fetching request token failed. Status " + xhr.status);
} }
} }
}; };

View File

@@ -53,6 +53,8 @@ var sendtophoneCore = {
if (typeof OAuthFactory == "undefined") if (typeof OAuthFactory == "undefined")
Components.utils.import("resource://sendtophone/OAuth.js"); Components.utils.import("resource://sendtophone/OAuth.js");
var currentAccount = this.prefs.getCharPref('currentAccount');
this.oauth = OAuthFactory.init({ this.oauth = OAuthFactory.init({
'request_url' : baseUrl + '/_ah/OAuthGetRequestToken', 'request_url' : baseUrl + '/_ah/OAuthGetRequestToken',
'authorize_url' : baseUrl + '/_ah/OAuthAuthorizeToken', 'authorize_url' : baseUrl + '/_ah/OAuthAuthorizeToken',
@@ -62,7 +64,16 @@ var sendtophoneCore = {
'scope' : baseUrl, 'scope' : baseUrl,
'app_name' : 'Fox To Phone', 'app_name' : 'Fox To Phone',
'callback_page': this.returnOAuthUrl 'callback_page': this.returnOAuthUrl
}); }, 'extensions.sendtophone.' + currentAccount + '.');
},
setCurrentAccount: function(account)
{
if (!this.prefs)
this.init();
this.prefs.setCharPref('currentAccount', account);
this.oauth.setPreferencesBranch('extensions.sendtophone.' + account + '.');
}, },
getString: function(name) getString: function(name)
@@ -112,7 +123,7 @@ var sendtophoneCore = {
.logStringMessage( text ); .logStringMessage( text );
}, },
processXHR: function(url, method, headers, data, callback) processXHR: function(url, method, headers, data, callback, errorCallback)
{ {
var req = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"] var req = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"]
.createInstance(Ci.nsIXMLHttpRequest); .createInstance(Ci.nsIXMLHttpRequest);
@@ -149,6 +160,11 @@ var sendtophoneCore = {
} }
else else
{ {
if (errorCallback)
{
errorCallback.call( sendtophoneCore, req);
return;
}
sendtophoneCore.alert(sendtophoneCore.getString("ErrorOnSend") + ' (status ' + req.status + ')\r\n' + body); sendtophoneCore.alert(sendtophoneCore.getString("ErrorOnSend") + ' (status ' + req.status + ')\r\n' + body);
} }
} }
@@ -274,11 +290,47 @@ var sendtophoneCore = {
} }
}, },
// Detect if the user is logged in
isLoggedIn: function()
{
if (!this.oauth)
this.init();
return (this.oauth.hasToken());
},
doLogin: function() doLogin: function()
{ {
this.popupNotification( this.getString("LoginRequired") ); this.popupNotification( this.getString("LoginRequired") );
//Open Google login page and close tab when done //Open Google login page and close tab when done
this.oauth.initOAuthFlow( function() {sendtophoneCore.loginSuccessful();} ); this.oauth.initOAuthFlow( function(error) {
var self = sendtophoneCore;
if (error)
{
// Try to guess if the domain might be blocked. Not bulletprof, but friendlier that stating anything about "request token"
if (error == "Fetching request token failed. Status 0")
{
var url = self.prefs.getCharPref( "appUrl" );
// The expected response isn't hardcoded here as we don't know what are the plans.
self.processXHR( url, "GET", null, "",
function(req) {
// Don't really know why the login failed.
self.alert( error );
},
function(req) {
if ( req.status == 0)
self.alert("Unable to connect with " + url + "\r\nCheck that it isn't blocked with a firewall");
else
self.alert( error );
});
}
else
self.alert(error);
return;
}
self.loginSuccessful();
} );
}, },
processSentData : function(body, req) processSentData : function(body, req)