diff --git a/.gitignore b/.gitignore
index 1823f2e57..b0346bd65 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,3 +3,5 @@
.\#*
/node_modules
/var
+/rpmbuild
+
diff --git a/ChangeLog b/ChangeLog
index 1fae26146..4afca93de 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+train-2011.10.27:
+ * link fixing ('need help?' to point to SUMO): #378
+ * unit tests repaired: #469 (broken in fix to #82)
+ * improve handling of network errors: #448
+ * improve styling and language of email confirmation page: #349
+ * logging improvements: #455
+ * RPM generation script created (for installation of browserid on redhat [moz prod] boxes): #478
+ * SCHEMA CHANGES to improve database performance and scalability: #480
+ * change the health check call from '/ping.txt' to '/__heartbeat__': #481
+ * remove application level network timeouts (let the network stack do its job, the user can cancel if they get sick of it): #485
+ * improve messaging for unsupported browsers: #273, #484
+ * developer documentation improvements: #496
+
train-2011.10.20:
* android < 3.0 now supported: #461
* properly set assertion expiration time to when they expire, not when they're issued: #433, #457, #458
diff --git a/DEPLOYMENT.md b/DEPLOYMENT.md
index 07fe7cb6e..1e8b7b606 100644
--- a/DEPLOYMENT.md
+++ b/DEPLOYMENT.md
@@ -156,16 +156,16 @@ post update hook, annotated to help you follow along:
### 5. get node servers running
At this point, pushing code to gitolite will cause /home/browserid/code to be updated. Now
-we need to get the servers running! Manually we can verify that the servers will run.
+we need to get the servers running! Manually we can verify that the servers will run.
For the browser id server:
- cd /home/browserid/code/browserid && sudo -u www-data ./run.js
+ cd /home/browserid/code/browserid && sudo -u www-data ./run.js
And for the verifier:
- cd /home/browserid/code/verifier && sudo -u www-data ./run.js
+ cd /home/browserid/code/verifier && sudo -u www-data ./run.js
-Now let's set up [monit] to restart the node.js servers:
+Now let's set up [monit] to restart the node.js servers:
1. install monit: `sudo apt-get install monit`
2. enable monit by editing `/etc/default/monit`
@@ -181,7 +181,7 @@ include /etc/monit.d/*
#!/bin/bash
-/usr/local/bin/node $1 > $(dirname $1)/error.log 2>&1 &
+/usr/local/bin/node $1 > $(dirname $1)/error.log 2>&1 &
5. create a file to run the verifier at `/etc/monit.d/verifier`:
@@ -192,7 +192,7 @@ check host verifier with address 127.0.0.1
as uid "www-data" and gid "www-data"
stop program = "/usr/bin/pkill -f '/usr/local/bin/node /home/browserid/code/verifier/run.js'"
if failed port 62800 protocol HTTP
- request /ping.txt
+ request /__heartbeat__
with timeout 10 seconds
then restart
@@ -205,7 +205,7 @@ check host browserid.org with address 127.0.0.1
as uid "www-data" and gid "www-data"
stop program = "/usr/bin/pkill -f '/usr/local/bin/node /home/browserid/code/browserid/run.js'"
if failed port 62700 protocol HTTP
- request /ping.txt
+ request /__heartbeat__
with timeout 10 seconds
then restart
diff --git a/README.md b/README.md
index 9ecb6efd1..908b6ea4a 100644
--- a/README.md
+++ b/README.md
@@ -23,10 +23,12 @@ or changes will be made.
2. Boot up the VM:
- $ cd browserid
- $ vagrant up
- $ vagrant ssh
- vagrant@lucid32:browserid$ node ./run.js
+```
+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.
diff --git a/browserid.spec b/browserid.spec
new file mode 100644
index 000000000..368194a57
--- /dev/null
+++ b/browserid.spec
@@ -0,0 +1,45 @@
+%define _rootdir /opt/browserid
+
+Name: browserid-server
+Version: 0.2011.10.13
+Release: 1%{?dist}
+Summary: BrowserID server
+Packager: Pete Fritchman
+Group: Development/Libraries
+License: MPL 1.1+/GPL 2.0+/LGPL 2.1+
+URL: https://github.com/mozilla/browserid
+Source0: %{name}.tar.gz
+BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
+AutoReqProv: no
+Requires: openssl nodejs
+BuildRequires: gcc-c++ git jre make npm openssl-devel
+
+%description
+browserid server & web home for browserid.org
+
+%prep
+%setup -q -n browserid
+
+%build
+npm install
+export PATH=$PWD/node_modules/.bin:$PATH
+(cd browserid && ./compress.sh)
+git log -1 --oneline > browserid/static/ver.txt
+
+%install
+rm -rf %{buildroot}
+mkdir -p %{buildroot}%{_rootdir}
+for f in browserid libs node_modules verifier *.json *.js; do
+ cp -rp $f %{buildroot}%{_rootdir}/$dir
+done
+
+%clean
+rm -rf %{buildroot}
+
+%files
+%defattr(-,root,root,-)
+%{_rootdir}
+
+%changelog
+* Tue Oct 18 2011 Pete Fritchman
+- Initial version
diff --git a/browserid/app.js b/browserid/app.js
index a0f26efc2..6f661ee7c 100644
--- a/browserid/app.js
+++ b/browserid/app.js
@@ -45,6 +45,7 @@ express = require('express'),
secrets = require('../libs/secrets.js'),
db = require('./lib/db.js'),
configuration = require('../libs/configuration.js'),
+heartbeat = require('../libs/heartbeat.js'),
substitution = require('../libs/substitute.js');
metrics = require("../libs/metrics.js"),
logger = require("../libs/logging.js").logger;
@@ -79,11 +80,16 @@ function router(app) {
metrics.userEntry(req);
res.render('dialog.ejs', {
title: 'A Better Way to Sign In',
- layout: false,
+ layout: 'dialog_layout.ejs',
+ useJavascript: true,
production: configuration.get('use_minified_resources')
});
});
+ app.get("/unsupported_dialog", function(req,res) {
+ res.render('unsupported_dialog.ejs', {layout: 'dialog_layout.ejs', useJavascript: false});
+ });
+
// simple redirects (internal for now)
app.get('/register_iframe', internal_redirector('/dialog/register_iframe.html',true));
@@ -102,9 +108,6 @@ function router(app) {
res.render('index.ejs', {title: 'A Better Way to Sign In', fullpage: true});
});
- // BA removed .html URLs. If we have 404s,
- // we should set up some redirects
-
app.get("/signup", function(req, res) {
res.render('signup.ejs', {title: 'Sign Up', fullpage: false});
});
@@ -141,7 +144,7 @@ function router(app) {
REDIRECTS = {
"/manage": "/",
"/users": "/",
- "/users/": "/",
+ "/users/": "/",
"/primaries" : "/developers",
"/primaries/" : "/developers",
"/developers" : "https://github.com/mozilla/browserid/wiki/How-to-Use-BrowserID-on-Your-Site"
@@ -160,6 +163,9 @@ function router(app) {
// register all the WSAPI handlers
wsapi.setup(app);
+ // setup health check / heartbeat
+ heartbeat.setup(app);
+
// the public key
app.get("/pk", function(req, res) {
res.json(ca.PUBLIC_KEY.toSimpleObject());
diff --git a/browserid/lib/db_mysql.js b/browserid/lib/db_mysql.js
index 06bd219bf..9a7dbc838 100644
--- a/browserid/lib/db_mysql.js
+++ b/browserid/lib/db_mysql.js
@@ -49,6 +49,7 @@
*
*
* +------ staged ----------+
+ * |*int id |
* |*string secret |
* | bool new_acct |
* | string existing |
@@ -67,10 +68,28 @@ var client = undefined;
// may get defined at open() time causing a database to be dropped upon connection closing.
var drop_on_close = undefined;
+// If you change these schemas, please notify
const schemas = [
- "CREATE TABLE IF NOT EXISTS user ( id INTEGER AUTO_INCREMENT PRIMARY KEY, passwd VARCHAR(64) );",
- "CREATE TABLE IF NOT EXISTS email ( id INTEGER AUTO_INCREMENT PRIMARY KEY, user INTEGER, INDEX(user), address VARCHAR(255) UNIQUE, INDEX(address) );",
- "CREATE TABLE IF NOT EXISTS staged ( secret VARCHAR(48) PRIMARY KEY, new_acct BOOL, existing VARCHAR(255), email VARCHAR(255) UNIQUE, INDEX(email), ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP);"
+ "CREATE TABLE IF NOT EXISTS user (" +
+ "id BIGINT AUTO_INCREMENT PRIMARY KEY," +
+ "passwd CHAR(64) NOT NULL" +
+ ") ENGINE=InnoDB;",
+
+ "CREATE TABLE IF NOT EXISTS email (" +
+ "id BIGINT AUTO_INCREMENT PRIMARY KEY," +
+ "user BIGINT NOT NULL," +
+ "address VARCHAR(255) UNIQUE NOT NULL," +
+ "FOREIGN KEY user_fkey (user) REFERENCES user(id)" +
+ ") ENGINE=InnoDB;",
+
+ "CREATE TABLE IF NOT EXISTS staged (" +
+ "id BIGINT AUTO_INCREMENT PRIMARY KEY," +
+ "secret CHAR(48) UNIQUE NOT NULL," +
+ "new_acct BOOL NOT NULL," +
+ "existing VARCHAR(255)," +
+ "email VARCHAR(255) UNIQUE NOT NULL," +
+ "ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL" +
+ ") ENGINE=InnoDB;",
];
// log an unexpected database error
@@ -111,37 +130,39 @@ exports.open = function(cfg, cb) {
}
// now create the databse
- client.query("CREATE DATABASE IF NOT EXISTS " + database, function(err) {
- if (err) {
- logUnexpectedError(err);
- cb(err);
- return;
- }
- client.useDatabase(database, function(err) {
+ if (cfg.create_schema || cfg.unit_test) {
+ client.query("CREATE DATABASE IF NOT EXISTS " + database, function(err) {
if (err) {
logUnexpectedError(err);
cb(err);
return;
}
+ client.useDatabase(database, function(err) {
+ if (err) {
+ logUnexpectedError(err);
+ cb(err);
+ return;
+ }
- // now create tables
- function createNextTable(i) {
- if (i < schemas.length) {
- client.query(schemas[i], function(err) {
- if (err) {
- logUnexpectedError(err);
- cb(err);
- } else {
- createNextTable(i+1);
- }
- });
- } else {
- cb();
+ // now create tables
+ function createNextTable(i) {
+ if (i < schemas.length) {
+ client.query(schemas[i], function(err) {
+ if (err) {
+ logUnexpectedError(err);
+ cb(err);
+ } else {
+ createNextTable(i+1);
+ }
+ });
+ } else {
+ cb();
+ }
}
- }
- createNextTable(0);
+ createNextTable(0);
+ });
});
- });
+ };
};
exports.close = function(cb) {
diff --git a/browserid/lib/wsapi.js b/browserid/lib/wsapi.js
index 9cd1bf8b0..9c75fdbfc 100644
--- a/browserid/lib/wsapi.js
+++ b/browserid/lib/wsapi.js
@@ -278,7 +278,7 @@ function setup(app) {
db.gotVerificationSecret(req.body.token, hash, function(err, email) {
if (err) {
- logger.error("error completing the verification: " + err);
+ logger.warn("couldn't complete email verification: " + err);
resp.json({ success: false });
} else {
// FIXME: not sure if we want to do this (ba)
@@ -360,7 +360,7 @@ function setup(app) {
app.post('/wsapi/complete_email_addition', checkParams(["token"]), function(req, resp) {
db.gotVerificationSecret(req.body.token, undefined, function(e) {
if (e) {
- logger.error("error completing the verification: " + e);
+ logger.warn("couldn't complete email verification: " + e);
resp.json({ success: false });
} else {
resp.json({ success: true });
diff --git a/browserid/static/css/style.css b/browserid/static/css/style.css
index 9023ebbcb..20c2e610d 100644
--- a/browserid/static/css/style.css
+++ b/browserid/static/css/style.css
@@ -21,30 +21,24 @@ body {
overflow-y: scroll;
}
-/*header {
- border-top: 4px solid #333;
- background-color: #333;
- padding: 0 20% 0 20%;
- margin: 0;
- background: #008;
- height: 230px;
- color #fff;
- min-width: 800px;
- display: block;
+/* for floats */
+.cf:after {
+ content: ".";
+ display: block;
+ clear: both;
+ visibility: hidden;
+ line-height: 0;
+ height: 0;
}
-footer {
- background-color: #F1F1F1;
- border-top: 2px solid #ddd;
- margin: 0;
- margin-top: 100px;
- padding: 0;
- height: 200px;
- font-size: 1.1em;
- display: block;
+html[xmlns] .cf {
+ display: block;
+}
+
+* html .cf {
+ height: 1%;
}
-*/
.sans {
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
}
@@ -115,11 +109,6 @@ hr {
display: none;
}
-/*
-.authenticated #content {
- display: block;
-}
-*/
#about {
font-family: 'Droid Serif', Georgia, serif;
font-size: 14px;
@@ -623,7 +612,7 @@ h1 {
display: inline-block;
}
-#signUpForm {
+#signUpForm, #congrats {
padding: 20px;
background-color: rgba(0,0,0,0.035);
@@ -656,33 +645,6 @@ h1 {
float: left;
}
-a.forgot {
- color: #888784;
- text-shadow: 1px 1px 0 rgba(255, 255, 255, 0.5);
- font-size: 11px;
-}
-
-.notifications {
- list-style-type: none;
-}
-
-.notifications > .notification {
- margin-top: 20px;
- padding: 5px;
- line-height: 16px;
- -webkit-border-radius: 3px;
- -moz-border-radius: 3px;
- -o-border-radius: 3px;
- border-radius: 3px;
- display: none;
- text-align: center;
-}
-
-.notifications .notification.error {
- color: red;
- background-color: rgba(255,0,0,0.25);
-}
-
#signUpForm .red {
color: red;
}
@@ -748,6 +710,64 @@ a.forgot {
float: right;
}
+#signUpForm .error {
+ margin-top: 20px;
+ color: red;
+ background-color: rgba(255,0,0,0.25);
+ padding: 5px;
+ line-height: 16px;
+
+ -webkit-border-radius: 3px;
+ -moz-border-radius: 3px;
+ -o-border-radius: 3px;
+ border-radius: 3px;
+}
+
+
+#congrats #siteinfo, #congrats {
+ display: none;
+}
+
+#congrats p {
+ color: #62615F;
+ display: block;
+ text-shadow: 1px 1px 0 rgba(255, 255, 255, 0.5);
+}
+
+#congrats .website {
+ display: block;
+ text-align: center;
+}
+
+
+a.forgot {
+ color: #888784;
+ text-shadow: 1px 1px 0 rgba(255, 255, 255, 0.5);
+ font-size: 11px;
+}
+
+.notifications {
+ list-style-type: none;
+}
+
+.notifications > .notification {
+ margin-top: 20px;
+ padding: 5px;
+ line-height: 16px;
+ -webkit-border-radius: 3px;
+ -moz-border-radius: 3px;
+ -o-border-radius: 3px;
+ border-radius: 3px;
+ display: none;
+ text-align: center;
+}
+
+.notifications .notification.error {
+ color: red;
+ background-color: rgba(255,0,0,0.25);
+}
+
+
#header {
position: absolute;
top: 0;
@@ -830,172 +850,3 @@ a.forgot {
color: #aaa;
}
-
-/* for floats */
-.cf:after {
- content: ".";
- display: block;
- clear: both;
- visibility: hidden;
- line-height: 0;
- height: 0;
-}
-
-html[xmlns] .cf {
- display: block;
-}
-
-* html .cf {
- height: 1%;
-}
-
-#signUpFormWrap {
- margin: 122px 160px;
-}
-
-#signUpFormWrap a.signUpIn {
- color: #549FDC;
- text-shadow: 1px 1px 0 rgba(255, 255, 255, 0.5);
-}
-
-#signUpFormWrap a.space {
- margin: 10px 20px 0;
- display: inline-block;
-}
-
-#signUpForm,
-#congrats {
- padding: 20px;
- background-color: rgba(0,0,0,0.035);
-
- -webkit-border-radius: 5px;
- -moz-border-radius: 5px;
- -o-border-radius: 5px;
- border-radius: 5px;
-}
-
-#congrats {
- display: none;
-}
-
-#congrats p {
- color: #62615F;
- display: block;
- text-shadow: 1px 1px 0 rgba(255, 255, 255, 0.5);
-}
-
-#signUpForm label/*,
-#signUpForm p.hint*/ {
- display: block;
- color: #62615F;
- text-shadow: 1px 1px 0 rgba(255,255,255,0.5);
-}
-
-/*
-
-#signUpForm p.hint {
- margin: -20px -20px 20px;
- padding: 10px 20px 10px 45px;
- background-color: rgba(0,0,0,0.05);
- background-repeat: no-repeat;
- background-position: 20px center;
- color: #222;
-
- -webkit-border-radius: 5px 5px 0 0;
- -moz-border-radius: 5px 5px 0 0;
- -o-border-radius: 5px 5px 0 0;
- border-radius: 5px 5px 0 0;
-}
-*/
-#signUpForm label.half,
-.half {
- width: 50%;
- display: inline-block;
- float: left;
-}
-
-a.forgot {
- color: #888784;
- text-shadow: 1px 1px 0 rgba(255, 255, 255, 0.5);
- font-size: 11px;
-}
-
-#signUpForm .error {
- margin-top: 20px;
- color: red;
- background-color: rgba(255,0,0,0.25);
- padding: 5px;
- line-height: 16px;
-
- -webkit-border-radius: 3px;
- -moz-border-radius: 3px;
- -o-border-radius: 3px;
- border-radius: 3px;
-}
-
-#signUpForm .red {
- color: red;
-}
-
-#signUpForm input[type=email],
-#signUpForm input[type=password] {
- width: 100%;
- font-size: 14px;
- padding: 5px;
- border-width: 1px;
- border-style: solid;
- border-color: #A3A29D #C6C3B4 #C6C3B4 #A3A29D;
- outline: none;
-
- -webkit-border-radius: 3px;
- -moz-border-radius: 3px;
- -o-border-radius: 3px;
- border-radius: 3px;
-
- -webkit-box-shadow: 1px 1px 0 rgba(255,255,255,0.5);
- -moz-box-shadow: 1px 1px 0 rgba(255,255,255,0.5);
- -o-box-shadow: 1px 1px 0 rgba(255,255,255,0.5);
- box-shadow: 1px 1px 0 rgba(255,255,255,0.5);
-}
-
-#signUpForm input[type=email]:focus,
-#signUpForm input[type=password]:focus {
- border: 1px solid #549FDC;
-
- -webkit-border-radius: 0;
- -moz-border-radius: 0;
- -o-border-radius: 0;
- border-radius: 0;
-
- -webkit-box-shadow: 0 0 0 1px #549FDC inset;
- -moz-box-shadow: 0 0 0 1px #549FDC inset;
- -o-box-shadow: 0 0 0 1px #549FDC inset;
- box-shadow: 0 0 0 1px #549FDC inset;
-}
-
-#signUpForm .submit {
- height: 28px;
-}
-
-#signUpForm .remember {
- display: inline-block;
- line-height: 28px;
-}
-
-#signUpForm .remember .checkAlign {
- float: left;
-}
-
-#signUpForm .remember label {
- margin-left: 5px;
- float: left;
-}
-
-#signUpForm .create {
- font-size: 14px;
- height: 28px;
- padding: 0 10px;
- float: right;
-}
-
-
diff --git a/browserid/static/dialog/controllers/authenticate_controller.js b/browserid/static/dialog/controllers/authenticate_controller.js
index 0054f37c3..84632f5f3 100644
--- a/browserid/static/dialog/controllers/authenticate_controller.js
+++ b/browserid/static/dialog/controllers/authenticate_controller.js
@@ -40,6 +40,7 @@
var ANIMATION_TIME = 250,
bid = BrowserID,
user = bid.User,
+ errors = bid.Errors,
validation = bid.Validation,
lastEmail = "";
@@ -60,7 +61,7 @@
else {
createUserState.call(self);
}
- });
+ }, self.getErrorDialog(errors.isEmailRegistered));
}
function createUser(el, event) {
@@ -83,7 +84,7 @@
else {
// XXX can't register this email address.
}
- }, self.getErrorDialog(bid.Errors.createAccount));
+ }, self.getErrorDialog(errors.createUser));
}
function authenticate(el, event) {
@@ -106,10 +107,7 @@
} else {
bid.Tooltip.showTooltip("#cannot_authenticate");
}
- },
- self.getErrorDialog(bid.Errors.authentication)
- );
-
+ }, self.getErrorDialog(errors.authenticate));
}
function resetPassword(el, event) {
@@ -122,9 +120,7 @@
self.close("reset_password", {
email: email
});
- }, function() {
- // XXX TODO error screen!
- });
+ }, self.getErrorDialog(errors.requestPasswordReset));
}
function animateSwap(fadeOutSelector, fadeInSelector, callback) {
diff --git a/browserid/static/dialog/controllers/dialog_controller.js b/browserid/static/dialog/controllers/dialog_controller.js
index 491d983fa..49560e08d 100644
--- a/browserid/static/dialog/controllers/dialog_controller.js
+++ b/browserid/static/dialog/controllers/dialog_controller.js
@@ -42,33 +42,40 @@
(function() {
"use strict";
- var user = BrowserID.User;
+ var bid = BrowserID,
+ user = bid.User,
+ errors = bid.Errors,
+ offline = false;
PageController.extend("Dialog", {}, {
init: function(el) {
var self=this;
- //this.element.show();
// keep track of where we are and what we do on success and error
self.onsuccess = null;
self.onerror = null;
setupChannel(self);
self.stateMachine();
+
},
getVerifiedEmail: function(origin_url, onsuccess, onerror) {
- this.onsuccess = onsuccess;
- this.onerror = onerror;
+ var self=this;
+ self.onsuccess = onsuccess;
+ self.onerror = onerror;
+
+ if('onLine' in navigator && !navigator.onLine) {
+ self.doOffline();
+ return;
+ }
user.setOrigin(origin_url);
-
- // get the cleaned origin.
$("#sitename").text(user.getHostname());
- this.doCheckAuth();
+ self.doCheckAuth();
- var self=this;
$(window).bind("unload", function() {
+ bid.Storage.setStagedOnBehalfOf("");
self.doCancel();
});
},
@@ -78,7 +85,15 @@
var self=this,
hub = OpenAjax.hub,
el = this.element;
-
+
+ hub.subscribe("offline", function(msg, info) {
+ self.doOffline();
+ });
+
+ hub.subscribe("xhrError", function(msg, info) {
+ //self.doXHRError(info);
+ // XXX how are we going to handle this?
+ });
hub.subscribe("user_staged", function(msg, info) {
self.doConfirmUser(info.email);
@@ -100,7 +115,7 @@
});
hub.subscribe("assertion_generated", function(msg, info) {
- if(info.assertion !== null) {
+ if (info.assertion !== null) {
self.doAssertionGenerated(info.assertion);
}
else {
@@ -138,6 +153,15 @@
},
+ doOffline: function() {
+ this.renderError("wait.ejs", errors.offline);
+ offline = true;
+ },
+
+ doXHRError: function(info) {
+ if (!offline) this.renderError("wait.ejs", errors.offline);
+ },
+
doConfirmUser: function(email) {
this.confirmEmail = email;
@@ -150,7 +174,7 @@
doCancel: function() {
var self=this;
- if(self.onsuccess) {
+ if (self.onsuccess) {
self.onsuccess(null);
}
},
@@ -182,7 +206,8 @@
doEmailConfirmed: function() {
var self=this;
// yay! now we need to produce an assertion.
- user.getAssertion(this.confirmEmail, self.doAssertionGenerated.bind(self));
+ user.getAssertion(this.confirmEmail, self.doAssertionGenerated.bind(self),
+ self.getErrorDialog(errors.getAssertion));
},
doAssertionGenerated: function(assertion) {
@@ -195,16 +220,16 @@
},
doNotMe: function() {
- user.logoutUser(this.doAuthenticate.bind(this));
+ var self=this;
+ user.logoutUser(self.doAuthenticate.bind(self), self.getErrorDialog(errors.logoutUser));
},
syncEmails: function() {
var self = this;
user.syncEmails(self.doPickEmail.bind(self),
- self.getErrorDialog(BrowserID.Errors.signIn));
+ self.getErrorDialog(errors.signIn));
},
-
doCheckAuth: function() {
var self=this;
user.checkAuthenticationAndSync(function onSuccess() {},
@@ -215,7 +240,7 @@
self.doAuthenticate();
}
},
- self.getErrorDialog(BrowserID.Errors.checkAuthentication));
+ self.getErrorDialog(errors.checkAuthentication));
}
});
diff --git a/browserid/static/dialog/controllers/page_controller.js b/browserid/static/dialog/controllers/page_controller.js
index f3031469a..01ddbb26a 100644
--- a/browserid/static/dialog/controllers/page_controller.js
+++ b/browserid/static/dialog/controllers/page_controller.js
@@ -48,6 +48,8 @@
var me=this,
bodyTemplate = options.bodyTemplate,
bodyVars = options.bodyVars,
+ errorTemplate = options.errorTemplate,
+ errorVars = options.errorVars,
waitTemplate = options.waitTemplate,
waitVars = options.waitVars;
@@ -60,6 +62,10 @@
me.renderWait(waitTemplate, waitVars);
}
+ if(errorTemplate) {
+ me.renderError(errorTemplate, errorVars);
+ }
+
// XXX move all of these, bleck.
$("form").bind("submit", me.onSubmit.bind(me));
$("#cancel").click(me.onCancel.bind(me));
@@ -95,12 +101,12 @@
renderWait: function(body, body_vars) {
this.renderTemplates("#wait", body, body_vars);
- $("body").removeClass("error").removeClass("form").addClass("waiting");
- $("#wait").stop().css('opacity', 1).hide().fadeIn(ANIMATION_TIME);
+ $("body").removeClass("error").removeClass("form").addClass("waiting").css('opacity', 1);
+ $("#wait").stop().hide().fadeIn(ANIMATION_TIME);
},
- renderError: function(error_vars) {
- this.renderTemplates("#error", "wait.ejs", error_vars);
+ renderError: function(body, body_vars) {
+ this.renderTemplates("#error", body, body_vars);
$("body").removeClass("waiting").removeClass("form").addClass("error");
$("#error").stop().css('opacity', 1).hide().fadeIn(ANIMATION_TIME);
},
@@ -144,7 +150,7 @@
*/
getErrorDialog: function(info) {
var self=this;
- return self.renderError.bind(self, info);
+ return self.renderError.bind(self, "wait.ejs", info);
},
onCancel: function(event) {
diff --git a/browserid/static/dialog/controllers/pickemail_controller.js b/browserid/static/dialog/controllers/pickemail_controller.js
index 43e23513b..1b3679c13 100644
--- a/browserid/static/dialog/controllers/pickemail_controller.js
+++ b/browserid/static/dialog/controllers/pickemail_controller.js
@@ -40,6 +40,7 @@
var ANIMATION_TIME = 250,
bid = BrowserID,
user = bid.User,
+ errors = bid.Errors,
body = $("body"),
animationComplete = body.innerWidth() < 640,
assertion;
@@ -109,13 +110,13 @@
var self=this;
user.getAssertion(email, function(assert) {
assertion = assert || null;
- tryClose.call(self);
- });
+ startAnimation.call(self);
+ }, self.getErrorDialog(errors.getAssertion));
}
function startAnimation() {
+ var self=this;
if(!animationComplete) {
- var self=this;
$("#signIn").animate({"width" : "685px"}, "slow", function () {
// post animation
body.delay(500).animate({ "opacity" : "0.5"}, "fast", function () {
@@ -124,6 +125,9 @@
});
});
}
+ else {
+ tryClose.call(self);
+ }
}
@@ -134,9 +138,7 @@
var valid = checkEmail.call(self, email);
if (valid) {
-// self.doWait(bid.Wait.generateKey);
getAssertion.call(self, email);
- startAnimation.call(self);
}
}
@@ -168,7 +170,7 @@
bid.Tooltip.showTooltip("#could_not_add");
});
}
- });
+ }, self.getErrorDialog(errors.isEmailRegistered));
}
diff --git a/browserid/static/dialog/css/m.css b/browserid/static/dialog/css/m.css
index 49f4a5613..9ddb605ea 100644
--- a/browserid/static/dialog/css/m.css
+++ b/browserid/static/dialog/css/m.css
@@ -111,6 +111,19 @@
height: 250px;
}
-}
+ #error .vertical {
+ width: auto;
+ }
+ #error .vertical > div {
+ display: block;
+ height: auto;
+ padding: 10px;
+ }
+
+ #error #borderbox {
+ border-left: none;
+ padding: 0;
+ }
+
diff --git a/browserid/static/dialog/css/popup.css b/browserid/static/dialog/css/popup.css
index b1b54243f..441efacb3 100644
--- a/browserid/static/dialog/css/popup.css
+++ b/browserid/static/dialog/css/popup.css
@@ -18,6 +18,7 @@ body {
font-size: 13px;
line-height: 21px;
background-image: url('/i/bg.png');
+ color: #000;
}
@@ -118,16 +119,17 @@ section > .contents {
#wait, #error {
text-align: center;
- background-image: url("/i/bg.png");
}
#wait {
z-index: 1;
+ background-image: url("/i/bg.png");
}
#error {
display: none;
z-index: 2;
+ background-color: #fff;
}
#wait strong, #error strong {
@@ -135,10 +137,40 @@ section > .contents {
font-weight: bold;
}
-#error {
- z-index: 2;
+
+#error .vertical {
+ width: 630px;
+ margin: 0 auto;
+ display: block;
+}
+
+
+#error .vertical > div {
+ display: table-cell;
+ vertical-align: middle;
+ padding: 0 10px;
+ height: 250px;
+}
+
+#error #alternative a {
+ color: #549FDC;
+ text-decoration: underline;
+}
+
+#error #borderbox {
+ border-left: 1px solid #777;
+ padding: 20px 0;
}
+#error #borderbox img {
+ border: none;
+}
+
+#error #alternative .lighter {
+ color: #777;
+}
+
+
#formWrap {
background-color: #fff;
background-image: none;
diff --git a/browserid/static/dialog/qunit.html b/browserid/static/dialog/qunit.html
index 108cc60fd..7e8189f82 100644
--- a/browserid/static/dialog/qunit.html
+++ b/browserid/static/dialog/qunit.html
@@ -12,23 +12,31 @@
-
+
+
+
-
+
Content below here is test content that can be ignored
-
+
-
+
+
+
+
+
+
+
Cannot confirm
+
Cannot communicate
+
+
Hint
-
-