Skip to content

Instantly share code, notes, and snippets.

@cat-in-136
Last active August 29, 2015 14:23
Show Gist options
  • Save cat-in-136/1997af6354b7b0222e4c to your computer and use it in GitHub Desktop.
Save cat-in-136/1997af6354b7b0222e4c to your computer and use it in GitHub Desktop.
Study for connecting Firefox Sync Server from web/Firefox OS App.
module.exports = function (grunt) {
grunt.initConfig({
browserify: {
dist: {
files: {
"bundle.js": "index.js"
},
options: {
require: [
"p-promise",
"sjcl",
"xhr2",
"p-promise",
"./node_modules/fxa-js-client/client/FxAccountClient.js",
"./node_modules/fxa-js-client/client/lib/credentials",
"./node_modules/fxa-js-client/client/lib/errors",
"./node_modules/fxa-js-client/client/lib/hawk",
"./node_modules/fxa-js-client/client/lib/hawkCredentials",
"./node_modules/fxa-js-client/client/lib/hkdf",
"./node_modules/fxa-js-client/client/lib/pbkdf2",
"./node_modules/fxa-js-client/client/lib/request"
]
}
}
}
});
grunt.loadNpmTasks('grunt-browserify');
grunt.registerTask("compile", [
"browserify:dist"
]);
grunt.registerTask("default", [
"compile"
]);
};
"use strict";
// Replace with your Firefox Account email and password bellow:
var email = "";
var password = '';
var jwcrypto = require("browserid-crypto");
require("browserid-crypto/lib/algs/ds");
var P = require("p-promise");
var FxAccountsClient = require("fxa-js-client");
var XMLHttpRequest = require("xhr2");
var createHash = require("create-hash");
var hawk = require("hawk");
(function () {
var deferred = P.defer();
var output = {};
var fxaServerUrl = "https://api.accounts.firefox.com/v1";
var fxClient = new FxAccountsClient(fxaServerUrl, { xhr: XMLHttpRequest });
fxClient.signIn(email, password, {keys: true}).then(function (creds) {
output.creds = creds;
return fxClient.accountKeys(creds.keyFetchToken, creds.unwrapBKey);
}).then(function (result) {
output.creds.kB = result.kB;
output.creds.kA = result.kA;
console.log(output.creds);
deferred.resolve({fxClient: fxClient, creds: output.creds});
});
return deferred.promise;
})().then(function(v) {
var fxClient = v.fxClient;
var creds = v.creds;
var deferred = P.defer();
jwcrypto.generateKeypair({algorithm: "DS", keysize: 256}, function (err, keypair) {
if (err) {
deferred.reject(err);
} else {
console.log(keypair.publicKey.serialize());
console.log(keypair.secretKey.serialize());
fxClient.certificateSign(creds.sessionToken, keypair.publicKey.toSimpleObject(), 60*60*1000).then(function(cert) {
if (cert) {
deferred.resolve({creds: creds, keypair: keypair, cert: cert});
} else {
deferred.reject();
}
}, function (err) {
deferred.reject(err);
});
}
});
return deferred.promise;
}, console.error).then(function (v) {
var creds = v.creds;
var keypair = v.keypair;
var cert = v.cert;
var deferred = P.defer();
var clientState = createHash("sha256").update(
Buffer(creds.kB, "hex") // syncKey
).digest().slice(0, 16).toString("hex");
jwcrypto.assertion.sign({
}, {
issuer: "https://api.accounts.firefox.com/v1",
expiresAt: new Date() + 60 * 1000,
issuedAt: new Date().valueOf(),
audience: "https://token.services.mozilla.com"
},
keypair.secretKey,
function (err, signedObject) {
if (err) {
deferred.reject(err);
} else {
var backedAssertion = jwcrypto.cert.bundle([cert.cert], signedObject);
console.log({assertion: backedAssertion});
deferred.resolve({clientState: clientState, assertion: backedAssertion});
}
});
return deferred.promise;
}, console.error).then(function (v) {
var clientState = v.clientState;
var assertion = v.assertion;
var deferred = P.defer();
var client = new XMLHttpRequest({mozSystem: true});
client.open("GET", "https://token.services.mozilla.com/1.0/sync/1.5");
client.setRequestHeader("Authorization", "BrowserID " + assertion);
client.setRequestHeader("X-Client-State", clientState);
client.setRequestHeader("Accept", "application/json");
client.onload = function () {
console.log(client.responseText);
var creds_token = JSON.parse(client.responseText);
deferred.resolve({creds_token: creds_token});
};
client.onerror = function () {
console.error(client.responseText);
deferred.reject();
}
client.send();
return deferred.promise;
}, console.error).then(function (v) {
var creds_token = v.creds_token;
var deferred = P.defer();
var uri = creds_token.api_endpoint + "/storage/bookmarks";
var authHeader = hawk.client.header(uri, "GET", {
credentials: {
id: creds_token.id,
key: creds_token.key,
algorithm: creds_token.hashalg
},
contentType: "application/json"
});
var client = new XMLHttpRequest({mozSystem: true});
client.open("GET", uri);
client.setRequestHeader("authorization", authHeader.field);
client.onload = function () {
console.log(client.responseText);
deferred.resolve({creds_token: creds_token});
};
client.onerror = function () {
console.error(client.responseText);
deferred.reject();
}
client.send();
return deferred.promise;
}, console.error).done();
{
"name": "fx-sync-web-client",
"version": "0.0.0",
"description": "Study for connecting Firefox Sync Server from web/Firefox OS App.",
"main": "index.js",
"scripts": {
"build": "grunt compile",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": {
"name": "@cat_in_136",
"url": "https://twitter.com/cat_in_136/"
},
"license": "MIT",
"repository": {
"type" : "git",
"url" : "https://gist.github.com/1997af6354b7b0222e4c.git"
},
"dependencies": {
"browserid-crypto": "~0.7.0",
"p-promise": "~0.5.0",
"xhr2": "~0.1.2",
"fxa-js-client": "~0.1.27",
"create-hash": "~1.1.1",
"hawk": "~3.1.0",
"sjcl": "~1.0.3"
},
"devDependencies": {
"browserify": "~10.2.4",
"grunt-cli": "~0.1.13",
"grunt": "~0.4.5",
"grunt-browserify": "~3.8.0"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment