Permalink
Browse files

integrating train 2011.09.22

  • Loading branch information...
2 parents aefe662 + 85aa2ab commit 34bbdd1cf49cac0dac17a0a2f64f1e53f02efdce @lloyd lloyd committed Sep 29, 2011
Showing 376 changed files with 67,217 additions and 11,832 deletions.
View
@@ -1,3 +0,0 @@
-[submodule "lib/doctest"]
- path = lib/doctest
- url = git@github.com:ianb/doctestjs
View
@@ -1,3 +1,20 @@
+train-2011.09.22:
+ * migrate to browserid signed certificates rather than keypairs where browserid hosts the public key: https://github.com/mozilla/browserid/issues?milestone=6
+ * IE9 support
+ * partial IE8 support (not yet usable, several small remaining bugs, and abysmal performance)
+ * development harness (./run.js) now respects an IP_ADDRESS env var to bind to a specific address (other than 127.0.0.1)
+ * improved first-time development experience: `git clone && cd browserid && npm install && npm run`
+ * initial support for running locally under virtualbox via vagrant: issue #261 (thanks ozten!)
+ * (fix 2011.09.23) fix race condition between relay iframe and window introduced with IE9 support. issue #287
+ * (fix 2011.09.23) fix blank popup on second sigin invocation in same session in FFX: issue #286
+ * (fix 2011.09.23) explicitly disable caching for /wsapi calls, prevents unwanted caching of CSRF and friends. issue #294
+
+train-2011.09.01:
+ * /ws_api/set_key always returns returns value instead of HTTP 204 response: #219
+ * update javascript mvc to 3.1.0.
+ * major interframe/window communication change using a hidden relay iframe to facilitate IE: #97(still open)
+ * link colors on browserid.org are consistent: #227
+
train-2011.08.25:
* created command line load generation tool and performance analysis work: #125
* beginning unit/functional tests for front end: #183
View
@@ -12,24 +12,50 @@ This repository contains several distinct things related to BrowserID:
* **the browserid.org website** - the templates, css, and javascript that make up the visible part of browserid.org
* **the javascript/HTML dialog & include library** - this is include.js and the code that it includes, the bit that someone using browserid will include.
+## Quick Start Virtual Machine
+
+We've prepared a VM so you can test/hack/have fun with BrowserID without modifying your local computer (too much). Skip to the next section "Dependencies", for detailed instructions to install this codebase locally, instead of using Vagrant.
+
+1. Install [Vagrant](http://vagrantup.com/docs/getting-started/index.html).
+
+This does add ruby, ruby-gems, and VirtualBox to your local desktop computer. No other software
+or changes will be made.
+
+2. Boot up the VM:
+
+ $ cd browserid
+ $ vagrant up
+ $ vagrant ssh
+ vagrant@lucid32:browserid$ node ./run.js
+
+`vagrant up` will take a while. Go get a cup of coffee. This is because it downloads the 500MB VM.
+
+You can now browse to http://localhost:10001 and http://localhost:10002.
+
+Any changes to the source code on your local computer are immediately mirrored in the VM.
+
+Handy for dev and QA tasks, but if you want to install from scratch...
+
## Dependencies
Here's the software you'll need installed:
* node.js (>= 0.4.5): http://nodejs.org/
* npm: http://npmjs.org/
* Several node.js 3rd party libraries - see `package.json` for details
+* browserify which will be installed globally.
+* git, g++
## Getting started:
-1. install node
-2. run `npm install` to installed 3rd party libraries into `node_modules`
-3. run the top level *run.js* script: `node ./run.js`
+1. install node and npm
+3. run `npm install` to install 3rd party libraries and generate keys
+3. run `npm start` to start the servers locally
4. visit the demo application ('rp') in your web browser (url output on the console at runtime)
## Testing
-Unit tests can be run by invoking `test.sh` at the top level, and you
+Unit tests can be run by invoking `npm test` at the top level, and you
should run them often. Like before committing code. To fully test
the code you should install mysql and have a well permissions `test`
user (can create and drop databases). If you don't have mysql installed,
View
@@ -0,0 +1,25 @@
+Vagrant::Config.run do |config|
+
+ config.vm.box = "lucid32_2.box"
+ config.vm.box_url = "http://people.mozilla.org/~aking/browserid/lucid32_2.box"
+
+ # name vagrant desktop
+ config.vm.forward_port("readme", 10000, 10000)
+ config.vm.forward_port("verifier", 10001, 10001)
+ config.vm.forward_port("server", 10002, 10002)
+
+
+
+ # Increase vagrant's patience during hang-y CentOS bootup
+ # see: https://github.com/jedi4ever/veewee/issues/14
+ config.ssh.max_tries = 50
+ config.ssh.timeout = 300
+
+ # nfs needs to be explicitly enabled to run.
+
+ config.vm.share_folder("v-root", "/home/vagrant/browserid", ".")
+
+ # Add to /etc/hosts: 33.33.33.27 dev.browserid.org
+ config.vm.network "33.33.33.27"
+
+end
View
@@ -38,8 +38,8 @@ fs = require('fs'),
path = require('path'),
url = require('url'),
wsapi = require('./lib/wsapi.js'),
+ca = require('./lib/ca.js'),
httputils = require('./lib/httputils.js'),
-webfinger = require('./lib/webfinger.js'),
sessions = require('connect-cookie-session'),
express = require('express'),
secrets = require('../libs/secrets.js'),
@@ -57,8 +57,10 @@ db.open(configuration.get('database'));
const COOKIE_SECRET = secrets.hydrateSecret('browserid_cookie', configuration.get('var_path'));
const COOKIE_KEY = 'browserid_state';
-function internal_redirector(new_url) {
+function internal_redirector(new_url, suppress_noframes) {
return function(req, resp, next) {
+ if (suppress_noframes)
+ resp.removeHeader('x-frame-options');
req.url = new_url;
return next();
};
@@ -83,7 +85,18 @@ function router(app) {
});
// simple redirects (internal for now)
- app.get('/register_iframe', internal_redirector('/dialog/register_iframe.html'));
+ app.get('/register_iframe', internal_redirector('/dialog/register_iframe.html',true));
+
+ // Used for a relay page for communication.
+ app.get("/relay", function(req,res, next) {
+ // Allow the relay to be run within a frame
+ res.removeHeader('x-frame-options');
+ res.render('relay.ejs', {
+ layout: false,
+ production: configuration.get('use_minified_resources')
+ });
+ });
+
app.get('/', function(req,res) {
res.render('index.ejs', {title: 'A Better Way to Sign In', fullpage: true});
@@ -120,12 +133,22 @@ function router(app) {
// register all the WSAPI handlers
wsapi.setup(app);
- app.get('/users/:identity.xml', function(req, resp, next) {
- webfinger.renderUserPage(req.params.identity, function (resultDocument) {
- if (resultDocument === undefined) {
- httputils.fourOhFour(resp, "I don't know anything about: " + req.params.identity + "\n");
+ // the public key
+ app.get("/pk", function(req, res) {
+ res.json(ca.PUBLIC_KEY.toSimpleObject());
+ });
+
+ // vep bundle of JavaScript
+ app.get("/vepbundle", function(req, res) {
+ fs.readFile(__dirname + "/../node_modules/jwcrypto/vepbundle.js", function(error, content) {
+ if (error) {
+ res.writeHead(500);
+ res.end("oops");
+ console.log(error);
} else {
- httputils.xmlResponse(resp, resultDocument);
+ res.writeHead(200, {'Content-Type': 'text/javascript'});
+ res.write(content);
+ res.end();
}
});
});
@@ -149,7 +172,7 @@ exports.setup = function(server) {
// over SSL?
var overSSL = (configuration.get('scheme') == 'https');
-
+
server.use(express.cookieParser());
var cookieSessionMiddleware = sessions({
@@ -160,19 +183,22 @@ exports.setup = function(server) {
httpOnly: true,
// IMPORTANT: we allow users to go 1 weeks on the same device
// without entering their password again
- maxAge: (7 * 24 * 60 * 60 * 1000),
+ maxAge: (7 * 24 * 60 * 60 * 1000),
secure: overSSL
}
});
- // cookie sessions
+ // cookie sessions && cache control
server.use(function(req, resp, next) {
// cookie sessions are only applied to calls to /wsapi
// as all other resources can be aggressively cached
// by layers higher up based on cache control headers.
// the fallout is that all code that interacts with sessions
// should be under /wsapi
if (/^\/wsapi/.test(req.url)) {
+ // explicitly disallow caching on all /wsapi calls (issue #294)
+ resp.setHeader('Cache-Control', 'no-cache, max-age=0');
+
// we set this parameter so the connect-cookie-session
// sends the cookie even though the local connection is HTTP
// (the load balancer does SSL)
@@ -196,14 +222,14 @@ exports.setup = function(server) {
var denied = false;
if (!/^\/wsapi/.test(req.url)) { // post requests only allowed to /wsapi
denied = true;
- logger.warn("CSRF validation failure: POST only allowed to /wsapi urls. not '" + req.url + "'");
+ logger.warn("CSRF validation failure: POST only allowed to /wsapi urls. not '" + req.url + "'");
}
if (req.session === undefined) { // there must be a session
denied = true;
- logger.warn("CSRF validation failure: POST calls to /wsapi require an active session");
+ logger.warn("CSRF validation failure: POST calls to /wsapi require an active session");
}
-
+
// the session must have a csrf token
if (typeof req.session.csrf !== 'string') {
denied = true;
View
@@ -32,13 +32,19 @@ cd dialog
$UGLIFY < production.js > production.min.js
mv production.min.js production.js
+cd ../relay
+cat ../dialog/resources/jschannel.js relay.js > production.js
+$UGLIFY < production.js > production.min.js
+mv production.min.js production.js
+
+
echo ''
echo '****Building BrowserID.org HTML, CSS, and JS****'
echo ''
cd ../js
# re-minimize everything together
-cat jquery-1.6.2.min.js ../dialog/resources/underscore-min.js ../dialog/resources/browserid-network.js ../dialog/resources/browserid-identities.js ../dialog/resources/storage.js browserid.js > lib.js
+cat jquery-1.6.2.min.js json2.js ../dialog/resources/underscore-min.js ../dialog/resources/storage.js ../dialog/resources/browserid-network.js ../dialog/resources/browserid-identities.js browserid.js > lib.js
$UGLIFY < lib.js > lib.min.js
cd ../css
@@ -1,5 +1,3 @@
-#!/usr/local/bin/node
-
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
@@ -20,6 +18,7 @@
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
+ * Ben Adida <benadida@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@@ -35,40 +34,50 @@
*
* ***** END LICENSE BLOCK ***** */
-const fs = require("fs");
-const jwt = require("./jwt.js");
-const idassertion = require("./idassertion.js");
+// certificate authority
+
+var jwcert = require('jwcrypto/jwcert'),
+ jwk = require('jwcrypto/jwk'),
+ jws = require('jwcrypto/jws'),
+ configuration = require('../../libs/configuration'),
+ secrets = require('../../libs/secrets'),
+ path = require("path"),
+ fs = require("fs");
-function futureDate()
-{
- var d = new Date();
- var future = new Date(d.getTime() + 1000 * 60 * 5);
- return future;
+var HOSTNAME = configuration.get('hostname');
+
+function parsePublicKey(serializedPK) {
+ return jwk.PublicKey.deserialize(serializedPK);
}
-function makeAssertion(email, validUntil, audience, privateKeyData)
-{
- var payload = {};
- payload["email"] = email;
- payload["valid-until"] = validUntil;
- payload["audience"] = audience;
-
- var token = new jwt.WebToken(JSON.stringify(payload), JSON.stringify({alg:"RS256"}));
- var signed = token.serialize(privateKeyData);
- return signed;
+function parseCert(serializedCert) {
+ var cert = new jwcert.JWCert();
+ cert.parse(serializedCert);
+ return cert;
}
-if (process.argv.length < 5) {
- console.log("Usage: node make_assertion.js <identity-address> <private-key-filename> <audience-hostname>");
- process.exit();
+function certify(email, publicKey, expiration) {
+ if (expiration == null)
+ throw "expiration cannot be null";
+ return new jwcert.JWCert(HOSTNAME, expiration, publicKey, {email: email}).sign(secrets.SECRET_KEY);
}
-var address = process.argv[2];
-var privateKey = process.argv[3];
-var audience = process.argv[4];
-var privateKeyData;
+function verifyChain(certChain, cb) {
+ // raw certs
+ return jwcert.JWCert.verifyChain(
+ certChain, new Date(),
+ function(issuer, next) {
+ // for now we only do browserid.org issued keys
+ if (issuer != HOSTNAME)
+ return next(null);
+
+ next(secrets.PUBLIC_KEY);
+ }, cb);
+}
-// Read the private key:
-privateKeyData = fs.readFileSync(privateKey);
-var a = makeAssertion(address, futureDate(), audience, privateKeyData.toString());
-console.log(a);
+// exports, not the key stuff
+exports.certify = certify;
+exports.verifyChain = verifyChain;
+exports.parsePublicKey = parsePublicKey;
+exports.parseCert = parseCert;
+exports.PUBLIC_KEY = secrets.PUBLIC_KEY;
View
@@ -96,13 +96,11 @@ exports.onReady = function(f) {
'emailKnown',
'isStaged',
'emailsBelongToSameAccount',
- 'addKeyToEmail',
'stageUser',
'stageEmail',
'gotVerificationSecret',
'checkAuth',
- 'getSyncResponse',
- 'pubkeysForEmail',
+ 'listEmails',
'removeEmail',
'cancelAccount'
].forEach(function(fn) {
Oops, something went wrong.

0 comments on commit 34bbdd1

Please sign in to comment.