This page documents how to perform custom actions with Firefox Sync via JavaScript.
All of the in this page must be executed in a chrome-privileged console. To access a chrome-privileged console, open an about page (like about:about) then open a Web Console via the Web Developer menu.
Tabs from Other Computers
This snippet shows how to load all tabs from other computers.
Components.utils.import("resource://services-sync/main.js"); // Obtain a reference to the main Firefox window. let mainWindow = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor) .getInterface(Components.interfaces.nsIWebNavigation) .QueryInterface(Components.interfaces.nsIDocShellTreeItem) .rootTreeItem .QueryInterface(Components.interfaces.nsIInterfaceRequestor) .getInterface(Components.interfaces.nsIDOMWindow); // Obtain a reference to Sync's Tabs "engine." let tabsEngine = Weave.Service.engineManager.get("tabs"); // Iterate over each client having data. for each (let client in tabsEngine.getAllClients()) { for each (let tab in client.tabs) { let url = tab.urlHistory[0]; // Load the tab via the tabbed browser API. mainWindow.gBrowser.addTab(url); } }
Partially corrupt a server
Components.utils.import("resource://services-sync/main.js"); Components.utils.import("resource://services-sync/resource.js"); function deletePath(path) { let resource = new Resource(Weave.Service.storageURL + path); resource.setHeader("X-Confirm-Delete", "1"); return resource.delete(); } // Delete meta/global: deletePath("meta/global"); // Delete keys: deletePath("crypto/keys"); // Delete server: deletePath("");
Corrupt a single engine on the server
let ENGINE = "bookmarks"; Components.utils.import("resource://services-sync/main.js"); Components.utils.import("resource://services-sync/resource.js"); Components.utils.import("resource://services-sync/util.js"); let r = new Resource(Weave.Service.storageURL + "meta/global"); let g = r.get(); let envelope = JSON.parse(g); let payload = JSON.parse(envelope.payload); payload.engines[ENGINE].syncID = Weave.Utils.makeGUID(); // Or any other GUID you like. payload.engines[ENGINE].version = 0; // Or any other version number you like. envelope.payload = JSON.stringify(payload); r.put(JSON.stringify(envelope));
Generate new keys
// Clients always wipe the server when they generate new keys. Components.utils.import("resource://services-sync/main.js"); Weave.Service._freshStart(); // If you want to do it without wiping the server (which will cause corruption!): Weave.Service.generateNewSymmetricKeys();
Print out a list of large bookmark records
// Change '1000' as appropriate. Components.utils.import("resource://services-sync/engines.js"); Components.utils.import("resource://services-sync/engines/bookmarks.js"); let bme = Weave.Service.engineManager.get("bookmarks"); let ids = Object.keys(bme._store.getAllIDs()); for each (let id in ids) { let record = bme._store.createRecord(id, "bookmarks"); let len = record.toString().length; if (len > 1000) { console.log("ID: " + id + ", len = " + len + ", " + record.title); } }
Print an alphabetically sorted list of members of a collection
Components.utils.import("resource://services-sync/main.js"); Components.utils.import("resource://services-sync/resource.js"); let ids = JSON.parse(new Resource(Weave.Service.storageURL + "bookmarks").get()); for each (let id in ids.sort()) { console.log(" " + id); }
Get a count of the number of members of a collection on the server
let collection = "passwords"; Components.utils.import("resource://services-sync/main.js"); Components.utils.import("resource://services-sync/resource.js"); JSON.parse(new Resource(Weave.Service.storageURL + collection).get()).length;
Dump the cleartext of each record in a collection to the console.
let collection = "forms"; Components.utils.import("resource://services-sync/main.js"); Components.utils.import("resource://services-sync/record.js"); let recordType = Weave.Engines.get(collection)._recordObj; let coll = new Collection(Weave.Service.storageURL + collection, recordType); coll.full = true; coll.recordHandler = function(item) { item.collection = collection; item.decrypt(); console.log(item.cleartext); }; coll.get();
Print an individual record
let collection = "history"; let id = "GUID_GOES_HERE"; Components.utils.import("resource://services-sync/main.js"); Components.utils.import("resource://services-sync/record.js"); let recordType = Weave.Engines.get(collection)._recordObj; let coll = new Collection(Weave.Service.storageURL + collection, recordType); coll.full = true; coll.ids = [id]; coll.recordHandler = function(item) { item.collection = collection; item.decrypt(); console.log(item.cleartext); }; coll.get();
Count types of bookmark records
Components.utils.import("resource://services-sync/main.js"); Components.utils.import("resource://services-sync/record.js"); let deleted = 0; let items = {}; let collection = "bookmarks"; let recordType = Weave.Engines.get(collection)._recordObj; let coll = new Collection(Weave.Service.storageURL + collection, recordType); coll.full = true; coll.limit = null; coll.recordHandler = function(item) { item.collection = collection; item.decrypt(); if (item.deleted) { deleted++; } else { items[item.type] = 1 + (items[item.type] || 0); } }; coll.get(); console.log("Deleted: " + deleted + ", " + JSON.stringify(items));
Get a log from XUL Fennec
- View about:sync-log.
- Long-tap the log in question. Choose "Save Link".
- Open a mail client. Click Attach.
- Choose "File Manager" as the handler.
- Navigate to "Downloads", pick correct file.
Watch live Sync logs
- Set services.sync.log.appender.console to Trace.
Bump meta/global's modified time
Components.utils.import("resource://services-sync/main.js"); Components.utils.import("resource://services-sync/resource.js"); function getPath(path) { let r = new Resource(Weave.Service.storageURL + path); let g = r.get(); return [g, r]; }; let [g, r] = getPath("meta/global"); r.put(g);
Delete and restore a record
Components.utils.import("resource://services-sync/main.js"); Components.utils.import("resource://services-sync/resource.js"); Components.utils.import("resource://services-sync/record.js"); // For example: let id = "iASOkUOZpIxZ" let collection = "bookmarks"; let resource = new Resource(Weave.Service.storageURL + collection + "/" + id); let del = new CryptoWrapper(collection, id); del.deleted = true; del.encrypt(); // Save the old value. let old = resource.get(); // Delete. resource.put(del); // Restore the old value. resource.put(old);