Permalink
Browse files

integrating train 2011.09.29

  • Loading branch information...
2 parents 97e56cf + 0e77230 commit 13d9e8a2368c7093cda0107c5ec3138d2c66b18e @lloyd lloyd committed Oct 6, 2011
View
8 ChangeLog
@@ -1,3 +1,11 @@
+train-2011.09.29:
+ * shortly after dialog is spawned, we remove the four random chars in the fragment (aesthetic)
+ * fix bug where session duration had an upper bound of 7 days - the time the server was running: #310
+ * fix bug where a user could go longer than 1 week without re-authenticating: #309
+ * fix link on /developers page to verfier source: #326
+ * (merged 2011.10.04) fix issue where a wrong-set client clock could prevent login: #329
+ * (external fix in myfavoritebeer) IE9 support: #240
+
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
View
17 DEPLOYMENT.md
@@ -277,7 +277,22 @@ server {
}
</pre>
- 5. restart your webserver and you're all done: `sudo /etc/init.d/nginx restart
+ 5. restart your webserver: `sudo /etc/init.d/nginx restart
+
+### 6. set up log rotation
+
+create a file as root at `/etc/logrotate.d/browserid`:
+
+ /home/browserid/var/log/browserid.log /home/browserid/var/log/browserid-metrics.json /home/browserid/var/log/verifier.log /home/browserid/var/log/verifier-metrics.json {
+ daily
+ rotate 30
+ copytruncate
+ dateext
+ compress
+ dateformat -%Y-%m-%d
+ }
+
+Now your logfiles will be automatically rotated.
easy, right?
View
2 browserid/app.js
@@ -183,7 +183,7 @@ 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: configuration.get('authentication_duration_ms'),
secure: overSSL
}
});
View
5 browserid/lib/db_json.js
@@ -75,11 +75,6 @@ function flush() {
}
}
-// when should a key created right now expire?
-function getExpiryTime() {
- return ((new Date()).getTime() + (14 * 24 * 60 * 60 * 1000));
-}
-
// when unit_test is set in configuration, database should be
// ephemeral. which simply means we use a temp file and delete
// on close;
View
112 browserid/lib/wsapi.js
@@ -46,7 +46,8 @@ email = require('./email.js'),
bcrypt = require('bcrypt'),
crypto = require('crypto'),
logger = require('../../libs/logging.js').logger,
-ca = require('./ca.js');
+ca = require('./ca.js'),
+configuration = require('../../libs/configuration.js');
function checkParams(params) {
return function(req, resp, next) {
@@ -71,9 +72,37 @@ function checkParams(params) {
};
}
+// log a user out, clearing everything from their session except the csrf token
+function clearAuthenticatedUser(session) {
+ Object.keys(session).forEach(function(k) {
+ if (k !== 'csrf') delete session[k];
+ });
+}
+
+
+function setAuthenticatedUser(session, email) {
+ session.authenticatedUser = email;
+ session.authenticatedAt = new Date();
+}
+
function isAuthed(req) {
- var result= (req.session && typeof req.session.authenticatedUser === 'string');
- return result;
+ var who;
+ try {
+ if (req.session.authenticatedUser) {
+ if (!Date.parse(req.session.authenticatedAt) > 0) throw "bad timestamp";
+ if (new Date() - new Date(req.session.authenticatedAt) >
+ configuration.get('authentication_duration_ms'))
+ {
+ throw "expired";
+ }
+ who = req.session.authenticatedUser;
+ }
+ } catch(e) {
+ logger.debug("Session authentication has expired:", e);
+ clearAuthenticatedUser(req.session);
+ }
+
+ return who;
}
// turned this into a proper middleware
@@ -86,18 +115,9 @@ function checkAuthed(req, resp, next) {
}
function setup(app) {
- // log a user out, clearing everything from their session except the csrf token
- function clearAuthenticatedUser(session) {
- Object.keys(session).forEach(function(k) {
- if (k !== 'csrf') delete session[k];
- });
- }
-
- // return the CSRF token
- // IMPORTANT: this should be safe because it's only readable by same-origin code
- // but we must be careful that this is never a JSON structure that could be hijacked
- // by a third party
- app.get('/wsapi/csrf', function(req, res) {
+ // return the CSRF token, authentication status, and current server time (for assertion signing)
+ // IMPORTANT: this is safe because it's only readable by same-origin code
+ app.get('/wsapi/session_context', function(req, res) {
if (typeof req.session == 'undefined') {
req.session = {};
}
@@ -109,10 +129,35 @@ function setup(app) {
logger.debug("NEW csrf token created: " + req.session.csrf);
}
- res.write(req.session.csrf);
- res.end();
- });
+ var auth_status = false;
+ function sendResponse() {
+ res.write(JSON.stringify({
+ csrf_token: req.session.csrf,
+ server_time: (new Date()).getTime(),
+ authenticated: auth_status
+ }));
+ res.end();
+ };
+
+ // if they're authenticated for an email address that we don't know about,
+ // then we should purge the stored cookie
+ if (!isAuthed(req)) {
+ logger.debug("user is not authenticated");
+ sendResponse();
+ } else {
+ db.emailKnown(req.session.authenticatedUser, function (known) {
+ if (!known) {
+ logger.debug("user is authenticated with an email that doesn't exist in the database");
+ clearAuthenticatedUser(req.session);
+ } else {
+ logger.debug("user is authenticated");
+ auth_status = true;
+ }
+ sendResponse();
+ });
+ }
+ });
/* checks to see if an email address is known to the server
* takes 'email' as a GET argument */
@@ -141,7 +186,7 @@ function setup(app) {
}
// bcrypt the password
- bcrypt.gen_salt(10, function (err, salt) {
+ bcrypt.gen_salt(configuration.get('bcrypt_work_factor'), function (err, salt) {
if (err) {
winston.error("error generating salt with bcrypt: " + err);
return resp.json(false);
@@ -221,7 +266,7 @@ function setup(app) {
db.checkAuth(v.email, function(hash) {
if (hash === v.hash) {
delete req.session.pendingVerification;
- req.session.authenticatedUser = v.email;
+ setAuthenticatedUser(req.session, v.email);
resp.json('complete');
} else {
resp.json('pending');
@@ -246,7 +291,9 @@ function setup(app) {
}
if (success) {
if (!req.session) req.session = {};
- req.session.authenticatedUser = req.body.email;
+ setAuthenticatedUser(req.session, req.body.email);
+
+ // if the work factor has changed, update the hash here
}
resp.json(success);
});
@@ -305,34 +352,15 @@ function setup(app) {
// same account, we certify the key
// we certify it for a day for now
var expiration = new Date();
- expiration.setTime(new Date().valueOf() + (24*3600*1000));
+ expiration.setTime(new Date().valueOf() + configuration.get('certificate_validity_ms'));
var cert = ca.certify(req.body.email, pk, expiration);
-
+
resp.writeHead(200, {'Content-Type': 'text/plain'});
resp.write(cert);
resp.end();
});
});
- app.get('/wsapi/am_authed', function(req,resp) {
- // if they're authenticated for an email address that we don't know about,
- // then we should purge the stored cookie
- if (!isAuthed(req)) {
- logger.debug("user is not authenticated");
- resp.json(false);
- } else {
- db.emailKnown(req.session.authenticatedUser, function (known) {
- if (!known) {
- logger.debug("user is authenticated with an email that doesn't exist in the database");
- clearAuthenticatedUser(req.session);
- } else {
- logger.debug("user is authenticated");
- }
- resp.json(known);
- });
- }
- });
-
app.post('/wsapi/logout', function(req, resp) {
clearAuthenticatedUser(req.session);
resp.json('ok');
View
48 browserid/static/dialog/resources/browserid-identities.js
@@ -51,20 +51,23 @@ var BrowserIDIdentities = (function() {
}
}
- function getIssuedIdentities() {
+ "use strict";
+ // remove identities that are no longer valid
+ function cleanupIdentities() {
var emails = storage.getEmails();
var issued_identities = {};
prepareDeps();
_(emails).each(function(email_obj, email_address) {
try {
email_obj.pub = jwk.PublicKey.fromSimpleObject(email_obj.pub);
} catch (x) {
- delete emails[email_address];
+ storage.removeEmail(email_address);
+ return;
}
// no cert? reset
if (!email_obj.cert) {
- delete emails[email_address];
+ storage.removeEmail(email_address);
} else {
try {
// parse the cert
@@ -74,18 +77,15 @@ var BrowserIDIdentities = (function() {
// check if needs to be reset, if it expires in 5 minutes
var diff = cert.expires.valueOf() - new Date().valueOf();
if (diff < 300000)
- delete emails[email_address];
+ storage.removeEmail(email_address);
} catch (e) {
// error parsing the certificate! Maybe it's of an old/different
// format? just delete it.
try { console.log("error parsing cert for", email_address ,":", e); } catch(e2) { }
- delete emails[email_address];
storage.removeEmail(email_address);
}
}
});
-
- return emails;
}
function removeUnknownIdentities(unknown_emails) {
@@ -116,7 +116,8 @@ var BrowserIDIdentities = (function() {
* @param {function} [onFailure] - Called on failure.
*/
syncIdentities: function(onSuccess, onFailure) {
- var issued_identities = getIssuedIdentities();
+ cleanupIdentities();
+ var issued_identities = Identities.getStoredIdentities();
// FIXME for certs
@@ -379,21 +380,24 @@ var BrowserIDIdentities = (function() {
* @param {function} [onFailure] - Called on failure.
*/
getIdentityAssertion: function(email, onSuccess, onFailure) {
- var storedID = Identities.getStoredIdentities()[email],
- assertion;
-
- if (storedID) {
- // parse the secret key
- prepareDeps();
- var sk = jwk.SecretKey.fromSimpleObject(storedID.priv);
- var tok = new jwt.JWT(null, new Date(), network.origin);
- assertion = vep.bundleCertsAndAssertion([storedID.cert], tok.sign(sk));
- }
-
- if (onSuccess) {
- onSuccess(assertion);
- }
+ // we use the current time from the browserid servers
+ // to avoid issues with clock drift on user's machine.
+ network.serverTime(function(serverTime) {
+ var storedID = Identities.getStoredIdentities()[email],
+ assertion;
+
+ if (storedID) {
+ // parse the secret key
+ prepareDeps();
+ var sk = jwk.SecretKey.fromSimpleObject(storedID.priv);
+ var tok = new jwt.JWT(null, serverTime, network.origin);
+ assertion = vep.bundleCertsAndAssertion([storedID.cert], tok.sign(sk));
+ }
+ if (onSuccess) {
+ onSuccess(assertion);
+ }
+ }, onFailure);
},
/**
View
101 browserid/static/dialog/resources/browserid-network.js
@@ -38,14 +38,21 @@ var BrowserIDNetwork = (function() {
"use strict";
var csrf_token;
+ var server_time;
+ var auth_status;
- function withCSRF(cb) {
- if (csrf_token) setTimeout(cb, 0);
+ function withContext(cb) {
+ if (typeof auth_status === 'boolean' && csrf_token !== undefined) setTimeout(cb, 0);
else {
- $.get('/wsapi/csrf', {}, function(result) {
- csrf_token = result;
+ $.get('/wsapi/session_context', {}, function(result) {
+ csrf_token = result.csrf_token;
+ server_time = {
+ remote: result.server_time,
+ local: (new Date()).getTime()
+ };
+ auth_status = result.authenticated;
cb();
- }, 'html');
+ }, 'json');
}
}
@@ -72,7 +79,7 @@ var BrowserIDNetwork = (function() {
* @param {function} [onFailure] - called on XHR failure
*/
authenticate: function(email, password, onSuccess, onFailure) {
- withCSRF(function() {
+ withContext(function() {
$.ajax({
type: "POST",
url: '/wsapi/authenticate_user',
@@ -83,8 +90,19 @@ var BrowserIDNetwork = (function() {
},
success: function(status, textStatus, jqXHR) {
if (onSuccess) {
- var authenticated = JSON.parse(status);
- onSuccess(authenticated);
+ try {
+ var authenticated = JSON.parse(status);
+
+ if (typeof authenticated !== 'boolean') throw status;
+
+ // at this point we know the authentication status of the
+ // session, let's set it to perhaps save a network request
+ // (to fetch session context).
+ auth_status = authenticated;
+ onSuccess(authenticated);
+ } catch (e) {
+ onFailure("unexpected server response: " + e);
+ }
}
},
error: onFailure
@@ -100,15 +118,16 @@ var BrowserIDNetwork = (function() {
* @param {function} [onFailure] - called on XHR failure.
*/
checkAuth: function(onSuccess, onFailure) {
- $.ajax({
- url: '/wsapi/am_authed',
- success: function(status, textStatus, jqXHR) {
- var authenticated = JSON.parse(status);
- onSuccess(authenticated);
- },
- error: onFailure
- });
-
+ function returnAuthStatus() {
+ try {
+ if (typeof auth_status !== 'boolean') throw "can't get authentication status!";
+ onSuccess(auth_status);
+ } catch(e) {
+ onFailure(e.toString());
+ }
+ }
+ if (typeof auth_status !== 'boolean') withContext(returnAuthStatus);
+ else setTimeout(returnAuthStatus, 0);
},
/**
@@ -117,12 +136,17 @@ var BrowserIDNetwork = (function() {
* @param {function} [onSuccess] - called on completion
*/
logout: function(onSuccess) {
- withCSRF(function() {
+ withContext(function() {
$.post("/wsapi/logout", {
csrf: csrf_token
- }, function() {
- csrf_token = undefined;
- withCSRF(function() {
+ }, function(result) {
+ // assume the logout request is successful and
+ // log the user out. There is no need to reset the
+ // CSRF token.
+ // FIXME: we should return a confirmation that the
+ // user was successfully logged out.
+ auth_status = false;
+ withContext(function() {
if (onSuccess) {
onSuccess();
}
@@ -143,7 +167,7 @@ var BrowserIDNetwork = (function() {
* @param {function} [onFailure] - Called on XHR failure.
*/
stageUser: function(email, password, onSuccess, onFailure) {
- withCSRF(function() {
+ withContext(function() {
$.ajax({
type: "post",
url: '/wsapi/stage_user',
@@ -189,7 +213,7 @@ var BrowserIDNetwork = (function() {
* @param {function} [onSuccess] - called whenever complete.
*/
cancelUser: function(onSuccess) {
- withCSRF(function() {
+ withContext(function() {
$.post("/wsapi/account_cancel", {"csrf": csrf_token}, function(result) {
if (onSuccess) {
onSuccess();
@@ -206,7 +230,7 @@ var BrowserIDNetwork = (function() {
* @param {function} [onFailure] - Called on XHR failure.
*/
addEmail: function(email, onSuccess, onFailure) {
- withCSRF(function() {
+ withContext(function() {
$.ajax({
type: 'POST',
url: '/wsapi/add_email',
@@ -251,7 +275,7 @@ var BrowserIDNetwork = (function() {
* @param {function} [onFailure] - Called on XHR failure.
*/
removeEmail: function(email, onSuccess, onFailure) {
- withCSRF(function() {
+ withContext(function() {
$.ajax({
type: 'POST',
url: '/wsapi/remove_email',
@@ -288,7 +312,7 @@ var BrowserIDNetwork = (function() {
* @method certKey
*/
certKey: function(email, pubkey, onSuccess, onError) {
- withCSRF(function() {
+ withContext(function() {
$.ajax({
type: 'POST',
url: '/wsapi/cert_key',
@@ -314,8 +338,31 @@ var BrowserIDNetwork = (function() {
success: onSuccess,
error: onFailure
});
+ },
+
+ /**
+ * Get the current time on the server in the form of a
+ * date object.
+ *
+ * Note: this function will perform a network request if
+ * during this session /wsapi/session_context has not
+ * been called.
+ *
+ * @method serverTime
+ */
+ serverTime: function(onSuccess, onFailure) {
+ function calcAndReturn() {
+ try {
+ if (!server_time) throw "can't get server time!";
+ var offset = (new Date()).getTime() - server_time.local;
+ onSuccess(new Date(offset + server_time.remote));
+ } catch(e) {
+ onFailure(e.toString());
+ }
+ }
+ if (!server_time) withContext(calcAndReturn);
+ else setTimeout(calcAndReturn, 0);
}
-
};
return Network;
View
4 browserid/static/dialog/resources/channel.js
@@ -118,7 +118,7 @@
// navigation, which would cause us to not find our parent window.
// issue #295
var relay = getRPRelay();
-
+
function onsuccess(rv) {
// Get the relay here so that we ensure that the calling window is still
// open and we aren't causing a problem.
@@ -137,6 +137,8 @@
registerWithRelayFrame(function(origin) {
controller.getVerifiedEmail(origin, onsuccess, onerror);
});
+
+ window.location.hash = '';
};
}());
View
29 browserid/static/dialog/test/qunit/browserid-identities_unit_test.js
@@ -39,12 +39,16 @@
* "testuser@testuser.com" with the password "testuser"
*/
var jwk = require("./jwk");
+var jwcert = require("./jwcert");
steal.plugins("jquery", "funcunit/qunit").then("/dialog/resources/browserid-identities", function() {
// I generated these locally, they are used nowhere else.
- var pubkey = {"algorithm":"RS","value":"-----BEGIN PUBLIC KEY-----\nMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAIPEB6mvbW4GHA5tYJ7CJbNU6CkDLfZa\nyv91CsC5TQ88oOQ7+63ispPJQGQxUgP4/QA3LObUX/eKF08VS9rlFm8CAwEAAQ==\n-----END PUBLIC KEY-----\n"};
+ var pubkey = {"algorithm":"RS","n":"56063028070432982322087418176876748072035482898334811368408525596198252519267108132604198004792849077868951906170812540713982954653810539949384712773390200791949565903439521424909576832418890819204354729217207360105906039023299561374098942789996780102073071760852841068989860403431737480182725853899733706069","e":"65537"};
- var privkey = {"algorithm":"RS","value":"-----BEGIN RSA PRIVATE KEY-----\nMIIBOgIBAAJBAIPEB6mvbW4GHA5tYJ7CJbNU6CkDLfZayv91CsC5TQ88oOQ7+63i\nspPJQGQxUgP4/QA3LObUX/eKF08VS9rlFm8CAwEAAQJBAIGeU/9rL9W8strKY/Ko\nf9eynZLCqvMeC3VS2JoPbqueBirCJSYNjGd70TXQ4MPzYWx8PsR3VrLQnWH8DWUk\n/hECIQDVWmkDM1vZUzQecHZkaRN8okv+Q3M6PL5qwy0GKCvqeQIhAJ4arGLARNWm\nidxGsJ0IPhtLyvcbNoDTU5rnx8LP/84nAiAUcpLH7L8rx+6h0DN4kh18/2z7FGnR\ntgql3sjM40K6OQIgBvKlILHSVJE8/bEdkckK8agjAzju7DpdMjF9VdJOK4ECIF2L\nSctl4hhZRUWzBN+sfuYEQTD8cc6svjBwlnEwJE9I\n-----END RSA PRIVATE KEY-----\n"};
+ var privkey = {"algorithm":"RS","n":"56063028070432982322087418176876748072035482898334811368408525596198252519267108132604198004792849077868951906170812540713982954653810539949384712773390200791949565903439521424909576832418890819204354729217207360105906039023299561374098942789996780102073071760852841068989860403431737480182725853899733706069","e":"65537","d":"786150156350274055174913976906933968265264030754683486390396799104417261473770120296370873955240982995278496143719986037141619777024457729427415826765728988003471373990098269492312035966334999128083733012526716409629032119935282516842904344253703738413658199885458117908331858717294515041118355034573371553"};
+
+ // this cert is meaningless, but it has the right format
+ var random_cert = "eyJhbGciOiJSUzEyOCJ9.eyJpc3MiOiJpc3N1ZXIuY29tIiwiZXhwIjoxMzE2Njk1MzY3NzA3LCJwdWJsaWMta2V5Ijp7ImFsZ29yaXRobSI6IlJTIiwibiI6IjU2MDYzMDI4MDcwNDMyOTgyMzIyMDg3NDE4MTc2ODc2NzQ4MDcyMDM1NDgyODk4MzM0ODExMzY4NDA4NTI1NTk2MTk4MjUyNTE5MjY3MTA4MTMyNjA0MTk4MDA0NzkyODQ5MDc3ODY4OTUxOTA2MTcwODEyNTQwNzEzOTgyOTU0NjUzODEwNTM5OTQ5Mzg0NzEyNzczMzkwMjAwNzkxOTQ5NTY1OTAzNDM5NTIxNDI0OTA5NTc2ODMyNDE4ODkwODE5MjA0MzU0NzI5MjE3MjA3MzYwMTA1OTA2MDM5MDIzMjk5NTYxMzc0MDk4OTQyNzg5OTk2NzgwMTAyMDczMDcxNzYwODUyODQxMDY4OTg5ODYwNDAzNDMxNzM3NDgwMTgyNzI1ODUzODk5NzMzNzA2MDY5IiwiZSI6IjY1NTM3In0sInByaW5jaXBhbCI6eyJlbWFpbCI6InRlc3R1c2VyQHRlc3R1c2VyLmNvbSJ9fQ.aVIO470S_DkcaddQgFUXciGwq2F_MTdYOJtVnEYShni7I6mqBwK3fkdWShPEgLFWUSlVUtcy61FkDnq2G-6ikSx1fUZY7iBeSCOKYlh6Kj9v43JX-uhctRSB2pI17g09EUtvmb845EHUJuoowdBLmLa4DSTdZE-h4xUQ9MsY7Ik";
var credentialsValid, unknownEmails, keyRefresh, syncValid, userEmails;
var netStub = {
@@ -81,7 +85,7 @@ steal.plugins("jquery", "funcunit/qunit").then("/dialog/resources/browserid-iden
certKey: function(email, pubkey, onSuccess, onFailure) {
if (syncValid) {
- onSuccess("foocert");
+ onSuccess(random_cert);
}
else {
onFailure();
@@ -108,6 +112,10 @@ steal.plugins("jquery", "funcunit/qunit").then("/dialog/resources/browserid-iden
onSuccess();
},
+ serverTime: function(onSuccess) {
+ onSuccess(new Date());
+ },
+
logout: function(onSuccess) {
credentialsValid = false;
onSuccess();
@@ -418,7 +426,6 @@ steal.plugins("jquery", "funcunit/qunit").then("/dialog/resources/browserid-iden
BrowserIDStorage.clearEmails();
userEmails = {"testuser@testuser.com": {}};
BrowserIDStorage.addEmail("testuser@testuser.com", {});
-
BrowserIDIdentities.syncIdentities(function onSuccess() {
var identities = BrowserIDIdentities.getStoredIdentities();
ok("testuser@testuser.com" in identities, "Our new email is added");
@@ -432,9 +439,9 @@ steal.plugins("jquery", "funcunit/qunit").then("/dialog/resources/browserid-iden
test("syncIdentities with identities preloaded and one to add", function() {
BrowserIDStorage.clearEmails();
- BrowserIDStorage.addEmail("testuser@testuser.com", {pubkey: pubkey, cert: "1234"});
- userEmails = {"testuser@testuser.com": {pubkey: pubkey, cert: "1234"},
- "testuser2@testuser.com": {pubkey: pubkey, cert: "1234"}};
+ BrowserIDStorage.addEmail("testuser@testuser.com", {pubkey: pubkey, cert: random_cert});
+ userEmails = {"testuser@testuser.com": {pubkey: pubkey, cert: random_cert},
+ "testuser2@testuser.com": {pubkey: pubkey, cert: random_cert}};
BrowserIDIdentities.syncIdentities(function onSuccess() {
var identities = BrowserIDIdentities.getStoredIdentities();
@@ -450,10 +457,10 @@ steal.plugins("jquery", "funcunit/qunit").then("/dialog/resources/browserid-iden
test("syncIdentities with identities preloaded and one to remove", function() {
BrowserIDStorage.clearEmails();
- BrowserIDStorage.addEmail("testuser@testuser.com", {pub: pubkey, cert: "1234"});
- BrowserIDStorage.addEmail("testuser2@testuser.com", {pub: pubkey, cert: "1234"});
- userEmails = {"testuser@testuser.com": { pub: pubkey, cert: "1234"}};
-
+ BrowserIDStorage.addEmail("testuser@testuser.com", {pub: pubkey, cert: random_cert});
+ BrowserIDStorage.addEmail("testuser2@testuser.com", {pub: pubkey, cert: random_cert});
+ userEmails = {"testuser@testuser.com": { pub: pubkey, cert: random_cert}};
+
BrowserIDIdentities.syncIdentities(function onSuccess() {
var identities = BrowserIDIdentities.getStoredIdentities();
ok("testuser@testuser.com" in identities, "Our old email address is still there");
View
19 browserid/static/dialog/test/qunit/browserid-network_test.js
@@ -91,13 +91,13 @@ steal.plugins("jquery", "funcunit/qunit").then("/dialog/resources/browserid-netw
test("logout->checkAuth: are we really logged out?", function() {
BrowserIDNetwork.authenticate("testuser@testuser.com", "testuser", function onSuccess(authenticated) {
- BrowserIDNetwork.logout(function onSuccess(authenticated) {
+ BrowserIDNetwork.logout(function onSuccess() {
BrowserIDNetwork.checkAuth(function onSuccess(authenticated) {
start();
equal(false, authenticated, "after logout, we are not authenticated");
- }, function onFailure() {
+ }, function onFailure(err) {
start();
- ok(false, "checkAuth failure");
+ ok(false, "checkAuth failure", err);
});
});
});
@@ -151,4 +151,17 @@ steal.plugins("jquery", "funcunit/qunit").then("/dialog/resources/browserid-netw
test("cancelUser", function() {
equal(typeof BrowserIDNetwork.cancelUser, "function", "what a ridiculously stupid test");
});
+
+ test("serverTime", function() {
+ BrowserIDNetwork.serverTime(function onSuccess(time) {
+ var diff = (new Date()) - time;
+ equal(Math.abs(diff) < 100, true, "server time and local time should be less than 100ms different (is " + diff + "ms different)");
+ start();
+ }, function onfailure() {
+ start();
+ });
+
+ stop();
+ });
+
});
View
6 browserid/tests/password-length-test.js
@@ -56,9 +56,13 @@ email.setInterceptor(function(email, site, secret) { });
suite.addBatch({
"get csrf token": {
- topic: wsapi.get('/wsapi/csrf'),
+ topic: wsapi.get('/wsapi/session_context'),
"works": function (r, err) {
assert.equal(typeof r.body, 'string');
+ var v = JSON.parse(r.body);
+ assert.equal(typeof v, 'object');
+ assert.equal(typeof v.csrf_token, 'string');
+ assert.equal(typeof v.server_time, 'number');
}
}
});
View
8 browserid/tests/registration-status-wsapi-test.js
@@ -136,10 +136,10 @@ suite.addBatch({
suite.addBatch({
"after successful registration": {
- topic: wsapi.get("/wsapi/am_authed"),
+ topic: wsapi.get("/wsapi/session_context"),
"we're authenticated": function (r, err) {
assert.strictEqual(r.code, 200);
- assert.strictEqual(JSON.parse(r.body), true);
+ assert.strictEqual(JSON.parse(r.body).authenticated, true);
},
"but we can easily clear cookies on the client to change that!": function(r, err) {
wsapi.clearCookies();
@@ -149,10 +149,10 @@ suite.addBatch({
suite.addBatch({
"after clearing cookies": {
- topic: wsapi.get("/wsapi/am_authed"),
+ topic: wsapi.get("/wsapi/session_context"),
"we're NOT authenticated": function (r, err) {
assert.strictEqual(r.code, 200);
- assert.strictEqual(JSON.parse(r.body), false);
+ assert.strictEqual(JSON.parse(r.body).authenticated, false);
}
}
});
View
10 libs/configuration.js
@@ -70,7 +70,10 @@ g_configs.production = {
database: {
driver: "mysql",
user: 'browserid'
- }
+ },
+ bcrypt_work_factor: 12,
+ authentication_duration_ms: (7 * 24 * 60 * 60 * 1000),
+ certificate_validity_ms: (24 * 60 * 60 * 1000)
};
// beta (diresworb.org) the only difference from production
@@ -91,7 +94,10 @@ g_configs.local = {
email_to_console: true, // don't send email, just dump verification URLs to console.
use_minified_resources: false,
var_path: path.join(__dirname, "..", "var"),
- database: { driver: "json" }
+ database: { driver: "json" },
+ bcrypt_work_factor: g_configs.production.bcrypt_work_factor,
+ authentication_duration_ms: g_configs.production.authentication_duration_ms,
+ certificate_validity_ms: g_configs.production.certificate_validity_ms
};
// test environments are variations on local
View
13 libs/wsapi_client.js
@@ -112,10 +112,15 @@ exports.get = function(cfg, path, context, getArgs, cb) {
function withCSRF(cfg, context, cb) {
if (context.csrf) cb(context.csrf);
else {
- exports.get(cfg, '/wsapi/csrf', context, undefined, function(r) {
- if (r.code === 200 && typeof r.body === 'string')
- context.csrf = r.body;
- cb(context.csrf);
+ exports.get(cfg, '/wsapi/session_context', context, undefined, function(r) {
+ try {
+ if (r.code !== 200) throw 'http error';
+ context.csrf = JSON.parse(r.body).csrf_token;
+ cb(context.csrf);
+ } catch(e) {
+ console.log('error getting csrf token: ', e);
+ cb();
+ }
});
}
}
View
2 package.json
@@ -16,7 +16,7 @@
, "uglify-js": "1.0.6"
, "JSONSelect": "0.2.1"
, "winston" : "0.3.3"
- , "connect-cookie-session" : "0.0.1"
+ , "connect-cookie-session" : "https://github.com/lloyd/connect-cookie-session/tarball/367b780"
, "mysql" : "0.9.2"
, "optimist" : "0.2.6"
, "qs" : "0.3.1"
View
2 scripts/migrate_to_certs.sql
@@ -1,2 +0,0 @@
-DROP TABLE pubkey;
-ALTER TABLE staged DROP COLUMN pubkey;

0 comments on commit 13d9e8a

Please sign in to comment.