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);
