summaryrefslogtreecommitdiffstats
path: root/application/basilisk/components/migration/EdgeProfileMigrator.js
diff options
context:
space:
mode:
Diffstat (limited to 'application/basilisk/components/migration/EdgeProfileMigrator.js')
-rw-r--r--application/basilisk/components/migration/EdgeProfileMigrator.js425
1 files changed, 0 insertions, 425 deletions
diff --git a/application/basilisk/components/migration/EdgeProfileMigrator.js b/application/basilisk/components/migration/EdgeProfileMigrator.js
deleted file mode 100644
index 5020fa2a7..000000000
--- a/application/basilisk/components/migration/EdgeProfileMigrator.js
+++ /dev/null
@@ -1,425 +0,0 @@
-/* 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 { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
-
-Cu.import("resource://gre/modules/osfile.jsm"); /* globals OS */
-Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/Task.jsm");
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("resource:///modules/MigrationUtils.jsm"); /* globals MigratorPrototype */
-Cu.import("resource:///modules/MSMigrationUtils.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils",
- "resource://gre/modules/PlacesUtils.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "ESEDBReader",
- "resource:///modules/ESEDBReader.jsm");
-
-Cu.importGlobalProperties(["URL"]);
-
-const kEdgeRegistryRoot = "SOFTWARE\\Classes\\Local Settings\\Software\\" +
- "Microsoft\\Windows\\CurrentVersion\\AppContainer\\Storage\\" +
- "microsoft.microsoftedge_8wekyb3d8bbwe\\MicrosoftEdge";
-const kEdgeDatabasePath = "AC\\MicrosoftEdge\\User\\Default\\DataStore\\Data\\";
-
-XPCOMUtils.defineLazyGetter(this, "gEdgeDatabase", function() {
- let edgeDir = MSMigrationUtils.getEdgeLocalDataFolder();
- if (!edgeDir) {
- return null;
- }
- edgeDir.appendRelativePath(kEdgeDatabasePath);
- if (!edgeDir.exists() || !edgeDir.isReadable() || !edgeDir.isDirectory()) {
- return null;
- }
- let expectedLocation = edgeDir.clone();
- expectedLocation.appendRelativePath("nouser1\\120712-0049\\DBStore\\spartan.edb");
- if (expectedLocation.exists() && expectedLocation.isReadable() && expectedLocation.isFile()) {
- expectedLocation.normalize();
- return expectedLocation;
- }
- // We used to recurse into arbitrary subdirectories here, but that code
- // went unused, so it likely isn't necessary, even if we don't understand
- // where the magic folders above come from, they seem to be the same for
- // everyone. Just return null if they're not there:
- return null;
-});
-
-/**
- * Get rows from a table in the Edge DB as an array of JS objects.
- *
- * @param {String} tableName the name of the table to read.
- * @param {String[]|function} columns a list of column specifiers
- * (see ESEDBReader.jsm) or a function that
- * generates them based on the database
- * reference once opened.
- * @param {function} filterFn a function that is called for each row.
- * Only rows for which it returns a truthy
- * value are included in the result.
- * @param {nsIFile} dbFile the database file to use. Defaults to
- * the main Edge database.
- * @returns {Array} An array of row objects.
- */
-function readTableFromEdgeDB(tableName, columns, filterFn, dbFile = gEdgeDatabase) {
- let database;
- let rows = [];
- try {
- let logFile = dbFile.parent;
- logFile.append("LogFiles");
- database = ESEDBReader.openDB(dbFile.parent, dbFile, logFile);
-
- if (typeof columns == "function") {
- columns = columns(database);
- }
-
- let tableReader = database.tableItems(tableName, columns);
- for (let row of tableReader) {
- if (filterFn(row)) {
- rows.push(row);
- }
- }
- } catch (ex) {
- Cu.reportError("Failed to extract items from table " + tableName + " in Edge database at " +
- dbFile.path + " due to the following error: " + ex);
- // Deliberately make this fail so we expose failure in the UI:
- throw ex;
- } finally {
- if (database) {
- ESEDBReader.closeDB(database);
- }
- }
- return rows;
-}
-
-function EdgeTypedURLMigrator() {
-}
-
-EdgeTypedURLMigrator.prototype = {
- type: MigrationUtils.resourceTypes.HISTORY,
-
- get _typedURLs() {
- if (!this.__typedURLs) {
- this.__typedURLs = MSMigrationUtils.getTypedURLs(kEdgeRegistryRoot);
- }
- return this.__typedURLs;
- },
-
- get exists() {
- return this._typedURLs.size > 0;
- },
-
- migrate(aCallback) {
- let typedURLs = this._typedURLs;
- let places = [];
- for (let [urlString, time] of typedURLs) {
- let uri;
- try {
- uri = Services.io.newURI(urlString);
- if (["http", "https", "ftp"].indexOf(uri.scheme) == -1) {
- continue;
- }
- } catch (ex) {
- Cu.reportError(ex);
- continue;
- }
-
- // Note that the time will be in microseconds (PRTime),
- // and Date.now() returns milliseconds. Places expects PRTime,
- // so we multiply the Date.now return value to make up the difference.
- let visitDate = time || (Date.now() * 1000);
- places.push({
- uri,
- visits: [{ transitionType: Ci.nsINavHistoryService.TRANSITION_TYPED,
- visitDate}]
- });
- }
-
- if (places.length == 0) {
- aCallback(typedURLs.size == 0);
- return;
- }
-
- MigrationUtils.insertVisitsWrapper(places, {
- ignoreErrors: true,
- ignoreResults: true,
- handleCompletion(updatedCount) {
- aCallback(updatedCount > 0);
- }
- });
- },
-};
-
-function EdgeReadingListMigrator(dbOverride) {
- this.dbOverride = dbOverride;
-}
-
-EdgeReadingListMigrator.prototype = {
- type: MigrationUtils.resourceTypes.BOOKMARKS,
-
- get db() { return this.dbOverride || gEdgeDatabase },
-
- get exists() {
- return !!this.db;
- },
-
- migrate(callback) {
- this._migrateReadingList(PlacesUtils.bookmarks.menuGuid).then(
- () => callback(true),
- ex => {
- Cu.reportError(ex);
- callback(false);
- }
- );
- },
-
- _migrateReadingList: Task.async(function*(parentGuid) {
- if (yield ESEDBReader.dbLocked(this.db)) {
- throw new Error("Edge seems to be running - its database is locked.");
- }
- let columnFn = db => {
- let columns = [
- {name: "URL", type: "string"},
- {name: "Title", type: "string"},
- {name: "AddedDate", type: "date"}
- ];
-
- // Later versions have an IsDeleted column:
- let isDeletedColumn = db.checkForColumn("ReadingList", "IsDeleted");
- if (isDeletedColumn && isDeletedColumn.dbType == ESEDBReader.COLUMN_TYPES.JET_coltypBit) {
- columns.push({name: "IsDeleted", type: "boolean"});
- }
- return columns;
- };
-
- let filterFn = row => {
- return !row.IsDeleted;
- };
-
- let readingListItems = readTableFromEdgeDB("ReadingList", columnFn, filterFn, this.db);
- if (!readingListItems.length) {
- return;
- }
-
- let destFolderGuid = yield this._ensureReadingListFolder(parentGuid);
- let bookmarks = [];
- for (let item of readingListItems) {
- let dateAdded = item.AddedDate || new Date();
- // Avoid including broken URLs:
- try {
- new URL(item.URL);
- } catch (ex) {
- continue;
- }
- bookmarks.push({ url: item.URL, title: item.Title, dateAdded });
- }
- yield MigrationUtils.insertManyBookmarksWrapper(bookmarks, destFolderGuid);
- }),
-
- _ensureReadingListFolder: Task.async(function*(parentGuid) {
- if (!this.__readingListFolderGuid) {
- let folderTitle = MigrationUtils.getLocalizedString("importedEdgeReadingList");
- let folderSpec = {type: PlacesUtils.bookmarks.TYPE_FOLDER, parentGuid, title: folderTitle};
- this.__readingListFolderGuid = (yield MigrationUtils.insertBookmarkWrapper(folderSpec)).guid;
- }
- return this.__readingListFolderGuid;
- }),
-};
-
-function EdgeBookmarksMigrator(dbOverride) {
- this.dbOverride = dbOverride;
-}
-
-EdgeBookmarksMigrator.prototype = {
- type: MigrationUtils.resourceTypes.BOOKMARKS,
-
- get db() { return this.dbOverride || gEdgeDatabase },
-
- get TABLE_NAME() { return "Favorites" },
-
- get exists() {
- if (!("_exists" in this)) {
- this._exists = !!this.db;
- }
- return this._exists;
- },
-
- migrate(callback) {
- this._migrateBookmarks().then(
- () => callback(true),
- ex => {
- Cu.reportError(ex);
- callback(false);
- }
- );
- },
-
- _migrateBookmarks: Task.async(function*() {
- if (yield ESEDBReader.dbLocked(this.db)) {
- throw new Error("Edge seems to be running - its database is locked.");
- }
- let {toplevelBMs, toolbarBMs} = this._fetchBookmarksFromDB();
- if (toplevelBMs.length) {
- let parentGuid = PlacesUtils.bookmarks.menuGuid;
- if (!MigrationUtils.isStartupMigration) {
- parentGuid = yield MigrationUtils.createImportedBookmarksFolder("Edge", parentGuid);
- }
- yield MigrationUtils.insertManyBookmarksWrapper(toplevelBMs, parentGuid);
- }
- if (toolbarBMs.length) {
- let parentGuid = PlacesUtils.bookmarks.toolbarGuid;
- if (!MigrationUtils.isStartupMigration) {
- parentGuid = yield MigrationUtils.createImportedBookmarksFolder("Edge", parentGuid);
- }
- yield MigrationUtils.insertManyBookmarksWrapper(toolbarBMs, parentGuid);
- }
- }),
-
- _fetchBookmarksFromDB() {
- let folderMap = new Map();
- let columns = [
- {name: "URL", type: "string"},
- {name: "Title", type: "string"},
- {name: "DateUpdated", type: "date"},
- {name: "IsFolder", type: "boolean"},
- {name: "IsDeleted", type: "boolean"},
- {name: "ParentId", type: "guid"},
- {name: "ItemId", type: "guid"}
- ];
- let filterFn = row => {
- if (row.IsDeleted) {
- return false;
- }
- if (row.IsFolder) {
- folderMap.set(row.ItemId, row);
- }
- return true;
- };
- let bookmarks = readTableFromEdgeDB(this.TABLE_NAME, columns, filterFn, this.db);
- let toplevelBMs = [], toolbarBMs = [];
- for (let bookmark of bookmarks) {
- let bmToInsert;
- // Ignore invalid URLs:
- if (!bookmark.IsFolder) {
- try {
- new URL(bookmark.URL);
- } catch (ex) {
- Cu.reportError(`Ignoring ${bookmark.URL} when importing from Edge because of exception: ${ex}`);
- continue;
- }
- bmToInsert = {
- dateAdded: bookmark.DateUpdated || new Date(),
- title: bookmark.Title,
- url: bookmark.URL,
- };
- } else /* bookmark.IsFolder */ {
- // Ignore the favorites bar bookmark itself.
- if (bookmark.Title == "_Favorites_Bar_") {
- continue;
- }
- if (!bookmark._childrenRef) {
- bookmark._childrenRef = [];
- }
- bmToInsert = {
- title: bookmark.Title,
- type: PlacesUtils.bookmarks.TYPE_FOLDER,
- dateAdded: bookmark.DateUpdated || new Date(),
- children: bookmark._childrenRef,
- };
- }
-
- if (!folderMap.has(bookmark.ParentId)) {
- toplevelBMs.push(bmToInsert);
- } else {
- let parent = folderMap.get(bookmark.ParentId);
- if (parent.Title == "_Favorites_Bar_") {
- toolbarBMs.push(bmToInsert);
- continue;
- }
- if (!parent._childrenRef) {
- parent._childrenRef = [];
- }
- parent._childrenRef.push(bmToInsert);
- }
- }
- return {toplevelBMs, toolbarBMs};
- },
-};
-
-function EdgeProfileMigrator() {
- this.wrappedJSObject = this;
-}
-
-EdgeProfileMigrator.prototype = Object.create(MigratorPrototype);
-
-EdgeProfileMigrator.prototype.getBookmarksMigratorForTesting = function(dbOverride) {
- return new EdgeBookmarksMigrator(dbOverride);
-};
-
-EdgeProfileMigrator.prototype.getReadingListMigratorForTesting = function(dbOverride) {
- return new EdgeReadingListMigrator(dbOverride);
-};
-
-EdgeProfileMigrator.prototype.getResources = function() {
- let resources = [
- new EdgeBookmarksMigrator(),
- MSMigrationUtils.getCookiesMigrator(MSMigrationUtils.MIGRATION_TYPE_EDGE),
- new EdgeTypedURLMigrator(),
- new EdgeReadingListMigrator(),
- ];
- let windowsVaultFormPasswordsMigrator =
- MSMigrationUtils.getWindowsVaultFormPasswordsMigrator();
- windowsVaultFormPasswordsMigrator.name = "EdgeVaultFormPasswords";
- resources.push(windowsVaultFormPasswordsMigrator);
- return resources.filter(r => r.exists);
-};
-
-EdgeProfileMigrator.prototype.getLastUsedDate = function() {
- // Don't do this if we don't have a single profile (see the comment for
- // sourceProfiles) or if we can't find the database file:
- if (this.sourceProfiles !== null || !gEdgeDatabase) {
- return Promise.resolve(new Date(0));
- }
- let logFilePath = OS.Path.join(gEdgeDatabase.parent.path, "LogFiles", "edb.log");
- let dbPath = gEdgeDatabase.path;
- let cookieMigrator = MSMigrationUtils.getCookiesMigrator(MSMigrationUtils.MIGRATION_TYPE_EDGE);
- let cookiePaths = cookieMigrator._cookiesFolders.map(f => f.path);
- let datePromises = [logFilePath, dbPath, ...cookiePaths].map(path => {
- return OS.File.stat(path).catch(() => null).then(info => {
- return info ? info.lastModificationDate : 0;
- });
- });
- datePromises.push(new Promise(resolve => {
- let typedURLs = new Map();
- try {
- typedURLs = MSMigrationUtils.getTypedURLs(kEdgeRegistryRoot);
- } catch (ex) {}
- let times = [0, ...typedURLs.values()];
- resolve(Math.max.apply(Math, times));
- }));
- return Promise.all(datePromises).then(dates => {
- return new Date(Math.max.apply(Math, dates));
- });
-};
-
-/* Somewhat counterintuitively, this returns:
- * - |null| to indicate "There is only 1 (default) profile" (on win10+)
- * - |[]| to indicate "There are no profiles" (on <=win8.1) which will avoid using this migrator.
- * See MigrationUtils.jsm for slightly more info on how sourceProfiles is used.
- */
-EdgeProfileMigrator.prototype.__defineGetter__("sourceProfiles", function() {
- let isWin10OrHigher = Services.vc.compare(Services.sysinfo.getProperty("version"), "10") >= 0;
- return isWin10OrHigher ? null : [];
-});
-
-EdgeProfileMigrator.prototype.__defineGetter__("sourceLocked", function() {
- // There is an exclusive lock on some databases. Assume they are locked for now.
- return true;
-});
-
-
-EdgeProfileMigrator.prototype.classDescription = "Edge Profile Migrator";
-EdgeProfileMigrator.prototype.contractID = "@mozilla.org/profile/migrator;1?app=browser&type=edge";
-EdgeProfileMigrator.prototype.classID = Components.ID("{62e8834b-2d17-49f5-96ff-56344903a2ae}");
-
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory([EdgeProfileMigrator]);