summaryrefslogtreecommitdiffstats
path: root/application/palemoon/components/migration/ChromeProfileMigrator.js
diff options
context:
space:
mode:
Diffstat (limited to 'application/palemoon/components/migration/ChromeProfileMigrator.js')
-rw-r--r--application/palemoon/components/migration/ChromeProfileMigrator.js463
1 files changed, 0 insertions, 463 deletions
diff --git a/application/palemoon/components/migration/ChromeProfileMigrator.js b/application/palemoon/components/migration/ChromeProfileMigrator.js
deleted file mode 100644
index 61955fbb4..000000000
--- a/application/palemoon/components/migration/ChromeProfileMigrator.js
+++ /dev/null
@@ -1,463 +0,0 @@
-/* -*- Mode: js; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
- * vim: sw=2 ts=2 sts=2 et */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cu = Components.utils;
-const Cr = Components.results;
-
-const FILE_INPUT_STREAM_CID = "@mozilla.org/network/file-input-stream;1";
-
-const S100NS_FROM1601TO1970 = 0x19DB1DED53E8000;
-const S100NS_PER_MS = 10;
-
-const AUTH_TYPE = {
- SCHEME_HTML: 0,
- SCHEME_BASIC: 1,
- SCHEME_DIGEST: 2
-};
-
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/NetUtil.jsm");
-Cu.import("resource://gre/modules/FileUtils.jsm");
-Cu.import("resource:///modules/MigrationUtils.jsm");
-
-XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils",
- "resource://gre/modules/PlacesUtils.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "OSCrypto",
- "resource://gre/modules/OSCrypto.jsm");
-
-/**
- * Convert Chrome time format to Date object
- *
- * @param aTime
- * Chrome time
- * @return converted Date object
- * @note Google Chrome uses FILETIME / 10 as time.
- * FILETIME is based on same structure of Windows.
- */
-function chromeTimeToDate(aTime)
-{
- return new Date((aTime * S100NS_PER_MS - S100NS_FROM1601TO1970 ) / 10000);
-}
-
-/**
- * Insert bookmark items into specific folder.
- *
- * @param aFolderId
- * id of folder where items will be inserted
- * @param aItems
- * bookmark items to be inserted
- */
-function insertBookmarkItems(aFolderId, aItems)
-{
- for (let i = 0; i < aItems.length; i++) {
- let item = aItems[i];
-
- try {
- if (item.type == "url") {
- PlacesUtils.bookmarks.insertBookmark(aFolderId,
- NetUtil.newURI(item.url),
- PlacesUtils.bookmarks.DEFAULT_INDEX,
- item.name);
- } else if (item.type == "folder") {
- let newFolderId =
- PlacesUtils.bookmarks.createFolder(aFolderId,
- item.name,
- PlacesUtils.bookmarks.DEFAULT_INDEX);
-
- insertBookmarkItems(newFolderId, item.children);
- }
- } catch (e) {
- Cu.reportError(e);
- }
- }
-}
-
-
-function ChromeProfileMigrator() {
- let chromeUserDataFolder = FileUtils.getDir(
-#ifdef XP_WIN
- "LocalAppData", ["Google", "Chrome", "User Data"]
-#elifdef XP_MACOSX
- "ULibDir", ["Application Support", "Google", "Chrome"]
-#else
- "Home", [".config", "google-chrome"]
-#endif
- , false);
- this._chromeUserDataFolder = chromeUserDataFolder.exists() ?
- chromeUserDataFolder : null;
-}
-
-ChromeProfileMigrator.prototype = Object.create(MigratorPrototype);
-
-ChromeProfileMigrator.prototype.getResources =
- function Chrome_getResources(aProfile) {
- if (this._chromeUserDataFolder) {
- let profileFolder = this._chromeUserDataFolder.clone();
- profileFolder.append(aProfile.id);
- if (profileFolder.exists()) {
- let possibleResources = [GetBookmarksResource(profileFolder),
- GetHistoryResource(profileFolder),
- GetCookiesResource(profileFolder),
-#ifdef XP_WIN
- GetWindowsPasswordsResource(profileFolder)
-#endif
- ];
- return [r for each (r in possibleResources) if (r != null)];
- }
- }
- return [];
- };
-
-Object.defineProperty(ChromeProfileMigrator.prototype, "sourceProfiles", {
- get: function Chrome_sourceProfiles() {
- if ("__sourceProfiles" in this)
- return this.__sourceProfiles;
-
- if (!this._chromeUserDataFolder)
- return [];
-
- let profiles = [];
- try {
- // Local State is a JSON file that contains profile info.
- let localState = this._chromeUserDataFolder.clone();
- localState.append("Local State");
- if (!localState.exists())
- throw new Error("Chrome's 'Local State' file does not exist.");
- if (!localState.isReadable())
- throw new Error("Chrome's 'Local State' file could not be read.");
-
- let fstream = Cc[FILE_INPUT_STREAM_CID].createInstance(Ci.nsIFileInputStream);
- fstream.init(localState, -1, 0, 0);
- let inputStream = NetUtil.readInputStreamToString(fstream, fstream.available(),
- { charset: "UTF-8" });
- let info_cache = JSON.parse(inputStream).profile.info_cache;
- for (let profileFolderName in info_cache) {
- let profileFolder = this._chromeUserDataFolder.clone();
- profileFolder.append(profileFolderName);
- profiles.push({
- id: profileFolderName,
- name: info_cache[profileFolderName].name || profileFolderName,
- });
- }
- } catch (e) {
- Cu.reportError("Error detecting Chrome profiles: " + e);
- // If we weren't able to detect any profiles above, fallback to the Default profile.
- let defaultProfileFolder = this._chromeUserDataFolder.clone();
- defaultProfileFolder.append("Default");
- if (defaultProfileFolder.exists()) {
- profiles = [{
- id: "Default",
- name: "Default",
- }];
- }
- }
-
- // Only list profiles from which any data can be imported
- return this.__sourceProfiles = profiles.filter(function(profile) {
- let resources = this.getResources(profile);
- return resources && resources.length > 0;
- }, this);
- }
-});
-
-Object.defineProperty(ChromeProfileMigrator.prototype, "sourceHomePageURL", {
- get: function Chrome_sourceHomePageURL() {
- let prefsFile = this._chromeUserDataFolder.clone();
- prefsFile.append("Preferences");
- if (prefsFile.exists()) {
- // XXX reading and parsing JSON is synchronous.
- let fstream = Cc[FILE_INPUT_STREAM_CID].
- createInstance(Ci.nsIFileInputStream);
- fstream.init(file, -1, 0, 0);
- try {
- return JSON.parse(
- NetUtil.readInputStreamToString(fstream, fstream.available(),
- { charset: "UTF-8" })
- ).homepage;
- }
- catch(e) {
- Cu.reportError("Error parsing Chrome's preferences file: " + e);
- }
- }
- return "";
- }
-});
-
-function GetBookmarksResource(aProfileFolder) {
- let bookmarksFile = aProfileFolder.clone();
- bookmarksFile.append("Bookmarks");
- if (!bookmarksFile.exists())
- return null;
-
- return {
- type: MigrationUtils.resourceTypes.BOOKMARKS,
-
- migrate: function(aCallback) {
- NetUtil.asyncFetch(bookmarksFile, MigrationUtils.wrapMigrateFunction(
- function(aInputStream, aResultCode) {
- if (!Components.isSuccessCode(aResultCode))
- throw new Error("Could not read Bookmarks file");
-
- // Parse Chrome bookmark file that is JSON format
- let bookmarkJSON = NetUtil.readInputStreamToString(
- aInputStream, aInputStream.available(), { charset : "UTF-8" });
- let roots = JSON.parse(bookmarkJSON).roots;
- PlacesUtils.bookmarks.runInBatchMode({
- runBatched: function() {
- // Importing bookmark bar items
- if (roots.bookmark_bar.children &&
- roots.bookmark_bar.children.length > 0) {
- // Toolbar
- let parentId = PlacesUtils.toolbarFolderId;
- if (!MigrationUtils.isStartupMigration) {
- parentId = MigrationUtils.createImportedBookmarksFolder(
- "Chrome", parentId);
- }
- insertBookmarkItems(parentId, roots.bookmark_bar.children);
- }
-
- // Importing bookmark menu items
- if (roots.other.children &&
- roots.other.children.length > 0) {
- // Bookmark menu
- let parentId = PlacesUtils.bookmarksMenuFolderId;
- if (!MigrationUtils.isStartupMigration) {
- parentId = MigrationUtils.createImportedBookmarksFolder(
- "Chrome", parentId);
- }
- insertBookmarkItems(parentId, roots.other.children);
- }
- }
- }, null);
- }, aCallback));
- }
- };
-}
-
-function GetHistoryResource(aProfileFolder) {
- let historyFile = aProfileFolder.clone();
- historyFile.append("History");
- if (!historyFile.exists())
- return null;
-
- return {
- type: MigrationUtils.resourceTypes.HISTORY,
-
- migrate: function(aCallback) {
- let dbConn = Services.storage.openUnsharedDatabase(historyFile);
- let stmt = dbConn.createAsyncStatement(
- "SELECT url, title, last_visit_time, typed_count FROM urls WHERE hidden = 0");
-
- stmt.executeAsync({
- handleResult : function(aResults) {
- let places = [];
- for (let row = aResults.getNextRow(); row; row = aResults.getNextRow()) {
- try {
- // if having typed_count, we changes transition type to typed.
- let transType = PlacesUtils.history.TRANSITION_LINK;
- if (row.getResultByName("typed_count") > 0)
- transType = PlacesUtils.history.TRANSITION_TYPED;
-
- places.push({
- uri: NetUtil.newURI(row.getResultByName("url")),
- title: row.getResultByName("title"),
- visits: [{
- transitionType: transType,
- visitDate: chromeTimeToDate(
- row.getResultByName(
- "last_visit_time")) * 1000,
- }],
- });
- } catch (e) {
- Cu.reportError(e);
- }
- }
-
- try {
- PlacesUtils.asyncHistory.updatePlaces(places);
- } catch (e) {
- Cu.reportError(e);
- }
- },
-
- handleError : function(aError) {
- Cu.reportError("Async statement execution returned with '" +
- aError.result + "', '" + aError.message + "'");
- },
-
- handleCompletion : function(aReason) {
- dbConn.asyncClose();
- aCallback(aReason == Ci.mozIStorageStatementCallback.REASON_FINISHED);
- }
- });
- stmt.finalize();
- }
- };
-}
-
-function GetCookiesResource(aProfileFolder) {
- let cookiesFile = aProfileFolder.clone();
- cookiesFile.append("Cookies");
- if (!cookiesFile.exists())
- return null;
-
- return {
- type: MigrationUtils.resourceTypes.COOKIES,
-
- migrate: function(aCallback) {
- let dbConn = Services.storage.openUnsharedDatabase(cookiesFile);
- let stmt = dbConn.createAsyncStatement(
- "SELECT host_key, path, name, value, secure, httponly, expires_utc FROM cookies");
-
- stmt.executeAsync({
- handleResult : function(aResults) {
- for (let row = aResults.getNextRow(); row; row = aResults.getNextRow()) {
- let host_key = row.getResultByName("host_key");
- if (host_key.match(/^\./)) {
- // 1st character of host_key may be ".", so we have to remove it
- host_key = host_key.substr(1);
- }
-
- try {
- let expiresUtc =
- chromeTimeToDate(row.getResultByName("expires_utc")) / 1000;
- Services.cookies.add(host_key,
- row.getResultByName("path"),
- row.getResultByName("name"),
- row.getResultByName("value"),
- row.getResultByName("secure"),
- row.getResultByName("httponly"),
- false,
- parseInt(expiresUtc));
- } catch (e) {
- Cu.reportError(e);
- }
- }
- },
-
- handleError : function(aError) {
- Cu.reportError("Async statement execution returned with '" +
- aError.result + "', '" + aError.message + "'");
- },
-
- handleCompletion : function(aReason) {
- dbConn.asyncClose();
- aCallback(aReason == Ci.mozIStorageStatementCallback.REASON_FINISHED);
- },
- });
- stmt.finalize();
- }
- }
-}
-
-function GetWindowsPasswordsResource(aProfileFolder) {
- let loginFile = aProfileFolder.clone();
- loginFile.append("Login Data");
- if (!loginFile.exists())
- return null;
-
- return {
- type: MigrationUtils.resourceTypes.PASSWORDS,
-
- migrate(aCallback) {
- let dbConn = Services.storage.openUnsharedDatabase(loginFile);
- let stmt = dbConn.createAsyncStatement(`
- SELECT origin_url, action_url, username_element, username_value,
- password_element, password_value, signon_realm, scheme, date_created,
- times_used FROM logins WHERE blacklisted_by_user = 0`);
- let crypto = new OSCrypto();
- let utf8Converter = Cc["@mozilla.org/intl/utf8converterservice;1"].getService(Ci.nsIUTF8ConverterService);
-
- stmt.executeAsync({
- _rowToLoginInfo(row) {
- let loginInfo = {
- username: utf8Converter.convertURISpecToUTF8(row.getResultByName("username_value"), "UTF-8"),
- password: utf8Converter.convertURISpecToUTF8(
- crypto.decryptData(crypto.arrayToString(row.getResultByName("password_value")), null),
- "UTF-8"),
- hostName: NetUtil.newURI(row.getResultByName("origin_url")).prePath,
- submitURL: null,
- httpRealm: null,
- usernameElement: row.getResultByName("username_element"),
- passwordElement: row.getResultByName("password_element"),
- timeCreated: chromeTimeToDate(row.getResultByName("date_created") + 0).getTime(),
- timesUsed: row.getResultByName("times_used") + 0,
- };
-
- switch (row.getResultByName("scheme")) {
- case AUTH_TYPE.SCHEME_HTML:
- loginInfo.submitURL = NetUtil.newURI(row.getResultByName("action_url")).prePath;
- break;
- case AUTH_TYPE.SCHEME_BASIC:
- case AUTH_TYPE.SCHEME_DIGEST:
- // signon_realm format is URIrealm, so we need remove URI
- loginInfo.httpRealm = row.getResultByName("signon_realm")
- .substring(loginInfo.hostName.length + 1);
- break;
- default:
- throw new Error("Login data scheme type not supported: " +
- row.getResultByName("scheme"));
- }
-
- return loginInfo;
- },
-
- handleResult(aResults) {
- for (let row = aResults.getNextRow(); row; row = aResults.getNextRow()) {
- try {
- let loginInfo = this._rowToLoginInfo(row);
- let login = Cc["@mozilla.org/login-manager/loginInfo;1"].createInstance(Ci.nsILoginInfo);
-
- login.init(loginInfo.hostName, loginInfo.submitURL, loginInfo.httpRealm,
- loginInfo.username, loginInfo.password, loginInfo.usernameElement,
- loginInfo.passwordElement);
- login.QueryInterface(Ci.nsILoginMetaInfo);
- login.timeCreated = loginInfo.timeCreated;
- login.timeLastUsed = loginInfo.timeCreated;
- login.timePasswordChanged = loginInfo.timeCreated;
- login.timesUsed = loginInfo.timesUsed;
-
- // Add the login only if there's not an existing entry
- let logins = Services.logins.findLogins({}, login.hostname,
- login.formSubmitURL,
- login.httpRealm);
-
- // Bug 1187190: Password changes should be propagated depending on timestamps.
- if (!logins.some(l => login.matches(l, true))) {
- Services.logins.addLogin(login);
- }
- } catch (e) {
- Cu.reportError(e);
- }
- }
- },
-
- handleError(aError) {
- Cu.reportError("Async statement execution returned with '" +
- aError.result + "', '" + aError.message + "'");
- },
-
- handleCompletion(aReason) {
- dbConn.asyncClose();
- aCallback(aReason == Ci.mozIStorageStatementCallback.REASON_FINISHED);
- crypto.finalize();
- },
- });
- stmt.finalize();
- }
- };
-}
-
-ChromeProfileMigrator.prototype.classDescription = "Chrome Profile Migrator";
-ChromeProfileMigrator.prototype.contractID = "@mozilla.org/profile/migrator;1?app=browser&type=chrome";
-ChromeProfileMigrator.prototype.classID = Components.ID("{4cec1de4-1671-4fc3-a53e-6c539dc77a26}");
-
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory([ChromeProfileMigrator]);