/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ /* vim: set 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/. */ /* * Migrates from a Firefox SelectableProfile in a lossy manner in order to * clean up a user's profile. Data is only migrated where the benefits outweigh * the potential problems caused by importing undesired/invalid configurations * from the source profile. */ import { MigrationUtils } from "resource:///modules/MigrationUtils.sys.mjs"; import { SelectableProfileService } from "resource:///modules/profiles/SelectableProfileService.sys.mjs"; import { FirefoxProfileMigrator } from "resource:///modules/FirefoxProfileMigrator.sys.mjs"; /** * Firefox SelectableProfile migrator. Currently, this class only does * "pave over" migrations, where various parts of an old profile overwrite a * new profile. This is distinct from other migrators which attempt to import * old profile data into the existing profile. * * This migrator is what powers the "Profile Refresh" mechanism for * selectable profiles. */ export class FirefoxSelectableProfileMigrator extends FirefoxProfileMigrator { static get key() { return "firefox-selectable-profile"; } /** * Get all the profiles in the group. The group storeID is set environment * variable SELECTABLE_PROFILE_RESET_STORE_ID. * * @returns {Map} A map of available profiles * The key is the absolute profile path, the value is an object with some * profile information */ async getAllProfiles() { await SelectableProfileService.startupMigrationInit(); let availableProfiles = new Map(); let profiles = await SelectableProfileService.getAllProfiles(); for (let profile of profiles) { let rootDir = await profile.rootDir; if ( rootDir.exists() && rootDir.isReadable() && !rootDir.equals(MigrationUtils.profileStartup.directory) ) { availableProfiles.set(profile.path, { id: profile.path, name: profile.name, rootDir, }); } } return availableProfiles; } getResourcesInternal(sourceProfileDir, currentProfileDir) { let resources = super.getResourcesInternal( sourceProfileDir, currentProfileDir ); function savePrefs() { // If we've used the pref service to write prefs for the new profile, it's too // early in startup for the service to have a profile directory, so we have to // manually tell it where to save the prefs file. let newPrefsFile = currentProfileDir.clone(); newPrefsFile.append("prefs.js"); Services.prefs.savePrefFile(newPrefsFile); } let types = MigrationUtils.resourceTypes; let profiles = { name: "profiles", type: types.OTHERDATA, migrate: async aCallback => { try { const storeID = Services.env.get("SELECTABLE_PROFILE_RESET_STORE_ID"); if (storeID) { Services.prefs.setStringPref("toolkit.profiles.storeID", storeID); Services.prefs.setBoolPref("browser.profiles.enabled", true); Services.prefs.setBoolPref("browser.profiles.created", true); } savePrefs(); } catch { aCallback(false); return; } aCallback(true); }, }; let allResources = resources.concat([profiles].filter(r => r)); return allResources; } }