1 /* ***** BEGIN LICENSE BLOCK ***** 2 * Version: MPL 1.1/GPL 2.0/LGPL 2.1 3 * 4 * The contents of this file are subject to the Mozilla Public License Version 5 * 1.1 (the "License"); you may not use this file except in compliance with 6 * the License. You may obtain a copy of the License at 7 * http://www.mozilla.org/MPL/ 8 * 9 * Software distributed under the License is distributed on an "AS IS" basis, 10 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 11 * for the specific language governing rights and limitations under the 12 * License. 13 * 14 * The Original Code is gContactSync. 15 * 16 * The Initial Developer of the Original Code is 17 * Josh Geenen <gcontactsync@pirules.org>. 18 * Portions created by the Initial Developer are Copyright (C) 2010 19 * the Initial Developer. All Rights Reserved. 20 * 21 * Contributor(s): 22 * 23 * Alternatively, the contents of this file may be used under the terms of 24 * either the GNU General Public License Version 2 or later (the "GPL"), or 25 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), 26 * in which case the provisions of the GPL or the LGPL are applicable instead 27 * of those above. If you wish to allow use of your version of this file only 28 * under the terms of either the GPL or the LGPL, and not to allow others to 29 * use your version of this file under the terms of the MPL, indicate your 30 * decision by deleting the provisions above and replace them with the notice 31 * and other provisions required by the GPL or the LGPL. If you do not delete 32 * the provisions above, a recipient may use your version of this file under 33 * the terms of any one of the MPL, the GPL or the LGPL. 34 * 35 * ***** END LICENSE BLOCK ***** */ 36 37 if (!com) var com = {}; // A generic wrapper variable 38 // A wrapper for all GCS functions and variables 39 if (!com.gContactSync) com.gContactSync = {}; 40 41 window.addEventListener("load", 42 /** Initializes the MessengerOverlay class when the window has finished loading */ 43 function gCS_mainOverlayLoadListener(e) { 44 // introduce a slight delay before initializing to let FileIO load in TB 2 45 setTimeout(com.gContactSync.MessengerOverlay.initialize, 100); 46 }, 47 false); 48 49 /** 50 * The main overlay removes old log files and logs basic information about 51 * the version of gContactSync and Thunderbird. 52 * Also resets the needRestart pref to false. 53 * @class 54 */ 55 com.gContactSync.MessengerOverlay = { 56 /** 57 * The original SetBusyCursor function that throws exceptions after 58 * gContactSync synchronizes from messenger.xul. 59 */ 60 mOriginalSetBusyCursor: null, 61 /** 62 * Initializes the MessengerOverlay class. 63 * This consists of setting the needRestart pref to false, removing the old 64 * log file, and logging basic TB and gContactSync information. 65 */ 66 initialize: function MessengerOverlay_initialize() { 67 // reset the needRestart pref 68 com.gContactSync.Preferences.setSyncPref("needRestart", false); 69 // remove the old log file 70 if (com.gContactSync.FileIO.mLogFile && com.gContactSync.FileIO.mLogFile.exists()) { 71 com.gContactSync.FileIO.mLogFile.remove(false); // delete the old log file 72 } 73 74 // override SetBusyCursor to wrap it in a try/catch block as it and 75 // this add-on do not get along... 76 com.gContactSync.MessengerOverlay.mOriginalSetBusyCursor = SetBusyCursor; 77 SetBusyCursor = com.gContactSync.MessengerOverlay.SetBusyCursor; 78 79 // log some basic system and application info 80 com.gContactSync.LOGGER.LOG("Loading gContactSync at " + new Date()); 81 com.gContactSync.LOGGER.LOG(" * Version is: " + 82 com.gContactSync.getVersionString()); 83 com.gContactSync.LOGGER.LOG(" * Last version was: " + 84 com.gContactSync.getVersionString(true)); 85 com.gContactSync.LOGGER.LOG(" * User Agent: " + 86 navigator.userAgent + "\n"); 87 com.gContactSync.Preferences.setSyncPref("lastVersionMajor", 88 com.gContactSync.versionMajor); 89 com.gContactSync.Preferences.setSyncPref("lastVersionMinor", 90 com.gContactSync.versionMinor); 91 com.gContactSync.Preferences.setSyncPref("lastVersionRelease", 92 com.gContactSync.versionRelease); 93 com.gContactSync.Preferences.setSyncPref("lastVersionSuffix", 94 com.gContactSync.versionSuffix); 95 com.gContactSync.Preferences.setSyncPref("synchronizing", false); 96 com.gContactSync.MessengerOverlay.checkAuthentication(); // check if the Auth token is valid 97 if (com.gContactSync.Preferences.mSyncPrefs.overrideGetCardForEmail.value) { 98 try { 99 com.gContactSync.MessengerOverlay.originalGetCardForEmail = getCardForEmail; 100 getCardForEmail = com.gContactSync.MessengerOverlay.getCardForEmail; 101 } catch (e) {} 102 } 103 }, 104 /** 105 * Calls the original SetBusyCursor() function from mailCore.js wrapped in a 106 * try/catch block. For some unknown reason, gContactSync causes 107 * SetBusyCursor to fail after a synchronization with an update from 108 * messenger.xul. 109 * See Bug 22801 for more details. 110 */ 111 SetBusyCursor: function MessengerOverlay_SetBusyCursor() { 112 try { 113 com.gContactSync.MessengerOverlay.mOriginalSetBusyCursor.apply(this, arguments); 114 } 115 catch (e) { 116 com.gContactSync.LOGGER.LOG_WARNING("SetBusyCursor failed", e); 117 } 118 }, 119 /** 120 * Returns an object with the first card and AB found with the given e-mail 121 * address. 122 * This is used to also search the ThirdEmail and FourthEmail properties as 123 * added by gContactSync. 124 * 125 * @param aEmail {string} The e-mail address to search for. 126 * 127 * @returns {object} An object with the AB and contact, if found. 128 * The object has 2 properties: book, containing the AB; and 129 * card, containing the contact. Both are null if no contact 130 * was found with the given e-mail address, or if the e-mail 131 * address was empty. 132 */ 133 getCardForEmail: function MessengerOverlay_getCardForEmail(aEmail) { 134 var result = { book: null, card: null }; 135 136 // abmanager should always exist as the original function doesn't exist in 137 // TB 2 (or Seamonkey 2) 138 if (!aEmail || !Components.classes["@mozilla.org/abmanager;1"]) { 139 return result; 140 } 141 142 var abs = Components.classes["@mozilla.org/abmanager;1"] 143 .getService(Components.interfaces.nsIAbManager) 144 .directories; 145 146 while (abs.hasMoreElements()) { 147 var ab = abs.getNext() 148 .QueryInterface(Components.interfaces.nsIAbDirectory); 149 try { 150 // Search the original PrimaryEmail and SecondEmail fields 151 var card = ab.cardForEmailAddress(aEmail); 152 // Search ThirdEmail 153 if (!card) { 154 card = ab.getCardFromProperty("ThirdEmail", aEmail, false); 155 } 156 // Search FourthEmail 157 if (!card) { 158 card = ab.getCardFromProperty("FourthEmail", aEmail, false); 159 } 160 // If a card was found somewhere, setup result 161 if (card) { 162 result.book = ab; 163 result.card = card; 164 // used in case ContactPhotos is installed 165 try { 166 com.ContactPhotos.mCurrentAb = ab; 167 com.ContactPhotos.mCurrentContact = card; 168 } catch (e) {} 169 return result; 170 } 171 } 172 catch (ex) {} 173 } 174 return result; 175 }, 176 /** 177 * Checks to see whether or not there is an authentication token in the login 178 * manager. If so, it begins a sync. If not, it shows the login prompt. 179 */ 180 checkAuthentication: function MessengerOverlay_checkAuthentication() { 181 if (com.gContactSync.gdata.isAuthValid()) { 182 if (com.gContactSync.MessengerOverlay.mUsername) { 183 var name = com.gContactSync.Preferences.mSyncPrefs.addressBookName.value; 184 var ab = com.gContactSync.GAbManager.getGAb(com.gContactSync.GAbManager.getAbByName(name)); 185 ab.savePref("Username", com.gContactSync.MessengerOverlay.mUsername); 186 ab.setLastSyncDate(0); 187 com.gContactSync.Sync.begin(); 188 } 189 else { 190 com.gContactSync.Sync.schedule(com.gContactSync.Preferences.mSyncPrefs.initialDelayMinutes.value * 60000); 191 } 192 return; 193 } 194 com.gContactSync.Overlay.setStatusBarText(com.gContactSync.StringBundle.getStr("notAuth")); 195 com.gContactSync.MessengerOverlay.promptLogin(); 196 }, 197 /** 198 * Prompts the user to enter his or her Google username and password and then 199 * gets an authentication token to store and use. 200 */ 201 promptLogin: function MessengerOverlay_promptLogin() { 202 var prompt = Components.classes["@mozilla.org/embedcomp/prompt-service;1"] 203 .getService(Components.interfaces.nsIPromptService) 204 .promptUsernameAndPassword; 205 var username = {}; 206 var password = {}; 207 // opens a username/password prompt 208 var ok = prompt(window, com.gContactSync.StringBundle.getStr("loginTitle"), 209 com.gContactSync.StringBundle.getStr("loginText"), username, password, null, 210 {value: false}); 211 if (!ok) 212 return false; 213 214 // This is a primitive way of validating an e-mail address, but Google takes 215 // care of the rest. It seems to allow getting an auth token w/ only the 216 // username, but returns an error when trying to do anything w/ that token 217 // so this makes sure it is a full e-mail address. 218 if (username.value.indexOf("@") < 1) { 219 com.gContactSync.alertError(com.gContactSync.StringBundle.getStr("invalidEmail")); 220 return com.gContactSync.MessengerOverlay.promptLogin(); 221 } 222 223 // fix the username before authenticating 224 username.value = com.gContactSync.fixUsername(username.value); 225 var body = com.gContactSync.gdata.makeAuthBody(username.value, password.value); 226 var httpReq = new com.gContactSync.GHttpRequest("authenticate", null, null, body); 227 // if it succeeds and Google returns the auth token, store it and then start 228 // a new sync 229 httpReq.mOnSuccess = function authSuccess(httpReq) { 230 com.gContactSync.MessengerOverlay.login(username.value, 231 httpReq.responseText.split("\n")[2]); 232 }; 233 // if it fails, alert the user and prompt them to try again 234 httpReq.mOnError = function authError(httpReq) { 235 com.gContactSync.alertError(com.gContactSync.StringBundle.getStr('authErr')); 236 com.gContactSync.LOGGER.LOG_ERROR('Authentication Error - ' + 237 httpReq.status, 238 httpReq.responseText); 239 com.gContactSync.MessengerOverlay.promptLogin(); 240 }; 241 // if the user is offline, alert them and quit 242 httpReq.mOnOffline = com.gContactSync.Sync.mOfflineFunction; 243 httpReq.send(); 244 return true; 245 }, 246 /** 247 * Stores the given auth token in the login manager and starts the setup 248 * window that will begin the first synchronization when closed. 249 * @param aAuthToken {string} The authentication token to store. 250 */ 251 login: function MessengerOverlay_login(aUsername, aAuthToken) { 252 com.gContactSync.LoginManager.addAuthToken(aUsername, 'GoogleLogin ' + aAuthToken); 253 com.gContactSync.Overlay.setStatusBarText(com.gContactSync.StringBundle.getStr("initialSetup")); 254 var setup = window.open("chrome://gcontactsync/content/FirstLogin.xul", 255 "SetupWindow", 256 "chrome,resizable=yes,scrollbars=no,status=no"); 257 com.gContactSync.MessengerOverlay.mUsername = aUsername; 258 // when the setup window loads, set its onunload property to begin a sync 259 setup.onload = function onloadListener() { 260 setup.onunload = function onunloadListener() { 261 com.gContactSync.MessengerOverlay.checkAuthentication(); 262 }; 263 }; 264 } 265 }; 266