diff --git a/browserid/static/dialog/controllers/authenticate_controller.js b/browserid/static/dialog/controllers/authenticate_controller.js
new file mode 100644
index 0000000000000000000000000000000000000000..7d5eb7f35826aba8dd78b19b7ed663a68af0ec48
--- /dev/null
+++ b/browserid/static/dialog/controllers/authenticate_controller.js
@@ -0,0 +1,43 @@
+(function() {
+  "use strict";
+
+  PageController.extend("Authenticate", {}, {
+      init: function() {
+        this._super({
+          bodyTemplate: "authenticate.ejs",
+          bodyVars: {
+            sitename: BrowserIDNetwork.origin
+          },
+          footerTemplate: "bottom-signin.ejs",
+          footerVars: {}
+        });
+      },
+
+      validate: function() {
+        var email = $("#email_input").val();
+        var pass = $("#password_input").val();
+
+        return true;
+      },
+
+      submit: function() {
+        var email = $("#email_input").val();
+        var pass = $("#password_input").val();
+
+        var self = this;
+        BrowserIDNetwork.authenticate(email, pass, function(authenticated) {
+          if (!authenticated) {
+            self.find("#nosuchaccount").hide().fadeIn(400);
+          } else {
+              self.doWait(BrowserIDWait.authentication);
+              self.publish("authenticate:authenticated");
+          }
+        }, function(resp) {
+          self.runErrorDialog(BrowserIDErrors.authentication);
+          self.publish("cancel");
+        });
+        
+      }
+  });
+
+}());
diff --git a/browserid/static/dialog/controllers/dialog_controller.js b/browserid/static/dialog/controllers/dialog_controller.js
index 6f7b0c6f160cdfe43978eb636bbbed3fe413ab93..1aed5d65a95a72c722b66a265cabcbe1a328bcbc 100644
--- a/browserid/static/dialog/controllers/dialog_controller.js
+++ b/browserid/static/dialog/controllers/dialog_controller.js
@@ -37,24 +37,6 @@ $.Controller("Dialog", {}, {
     "#suggest_signin click": function(event) {
       this.doAuthenticate();
     },
-      
-    "#signin click": function(event) {
-      var email = $("#email_input").val();
-      var pass = $("#password_input").val();
-
-      var self = this;
-
-      BrowserIDNetwork.authenticate(email, pass, function(authenticated) {
-        if (!authenticated) {
-          self.find("#nosuchaccount").hide().fadeIn(400);
-        } else {
-          self.doWait(BrowserIDWait.authentication);
-          self.syncIdentities();
-        }
-      }, function(resp) {
-        runErrorDialog(BrowserIDErrors.authentication);
-      });
-    },
 
     "#pickemail click": function(event) {
       var email = $("#identities input:checked").val();
@@ -186,9 +168,15 @@ $.Controller("Dialog", {}, {
     },
 
     doAuthenticate: function() {
-      this.renderTemplates("authenticate.ejs", {sitename: BrowserIDNetwork.origin},
-                           "bottom-signin.ejs", {});
-
+      var el = this.element, self=this;
+      el.authenticate();
+      OpenAjax.hub.subscribe("authenticate:authenticated", function() {
+        el.authenticate('destroy');
+        self.syncIdentities();
+      });
+      OpenAjax.hub.subscribe("cancel", function() {
+        el.authenticate('destroy');
+      });
     },
       
     doCreate: function() {
diff --git a/browserid/static/dialog/controllers/page_controller.js b/browserid/static/dialog/controllers/page_controller.js
new file mode 100644
index 0000000000000000000000000000000000000000..68b7829b519550748e219225ba5f853b0ead75af
--- /dev/null
+++ b/browserid/static/dialog/controllers/page_controller.js
@@ -0,0 +1,86 @@
+/*jshint browser:true, jQuery: true, forin: true, laxbreak:true */                                             
+/*global Channel:true, CryptoStubs:true, alert:true, errorOut:true, setupChannel:true, getEmails:true, clearEmails: true, console: true, _: true, pollTimeout: true, addEmail: true, removeEmail:true, BrowserIDNetwork: true, BrowserIDWait:true, BrowserIDErrors: true, runErrorDialog:true */ 
+//
+// a JMVC controller for the browserid dialog
+//
+
+(function() {
+"use strict";
+
+  $.Controller.extend("PageController", {
+    }, {
+    init: function(options) {
+      var bodyTemplate = options.bodyTemplate;
+      var bodyVars = options.bodyVars;
+      var footerTemplate = options.footerTemplate;
+      var footerVars = options.footerVars;
+
+      this.renderTemplates(bodyTemplate, bodyVars, footerTemplate, footerVars);
+      $('form').bind("submit", this.onSubmit.bind(this));
+    },
+
+    renderTemplates: function(body, body_vars, footer, footer_vars) {
+      if (body) {
+        var bodyHtml = $.View("//dialog/views/" + body, body_vars);
+        $('#dialog').html(bodyHtml).hide().fadeIn(300, function() {
+          $('#dialog input').eq(0).focus(); 
+        });
+      }
+
+      if (footer) {
+        var footerHtml = $.View("//dialog/views/" + footer, footer_vars);
+        $('#bottom-bar').html(footerHtml);
+      }
+      setupEnterKey();
+    },
+
+    onSubmit: function(event) {
+      event.stopPropagation();
+      event.preventDefault();
+      if(this.validate()) {
+        this.submit();
+      }
+    },
+
+    validate: function() {
+      return true;
+    },
+
+    submit: function() {
+      this.publish("submit");
+    },
+
+    doWait: function(info) {
+      this.renderTemplates("wait.ejs", {title: info.message, message: info.description});
+    },
+
+    runErrorDialog: function(info) {
+      $(".dialog").hide();
+
+      $("#error_dialog div.title").text(info.message);
+      $("#error_dialog div.content").text(info.description);
+
+      $("#back").hide();
+      $("#cancel").hide();
+      $("#submit").show().unbind('click').click(function() {
+      }).text("Close");
+
+      $("#error_dialog").fadeIn(500);
+    },
+
+    "#cancel click": function() {
+      this.publish("cancel");
+    }
+
+  });
+
+  function setupEnterKey() {
+    $("input").keyup(function(e) {
+      if(e.which == 13) {
+        e.preventDefault();
+        $('.submit').click();
+      }
+    });
+  }
+
+}());
diff --git a/browserid/static/dialog/dialog.js b/browserid/static/dialog/dialog.js
index 71ed5782ffa70eccd9b210ab2d1f58cb719e51a9..eee2d76fbf639e36be37cb82e7582a63e88d096d 100644
--- a/browserid/static/dialog/dialog.js
+++ b/browserid/static/dialog/dialog.js
@@ -20,7 +20,9 @@ steal.plugins(
 
 	.models()						// loads files in models folder 
 
-	.controllers('dialog')					// loads files in controllers folder
+	.controllers('dialog',
+               'page',
+               'authenticate')					// loads files in controllers folder
 
 	.views('authenticate.ejs',
            'addemail.ejs',
diff --git a/browserid/static/dialog/style.css b/browserid/static/dialog/style.css
index 2612391d98bf3653b06cae42f1f79fcda8a8d263..5dcca5f8791910d31d180f6eb4d6db0fd1003ea9 100644
--- a/browserid/static/dialog/style.css
+++ b/browserid/static/dialog/style.css
@@ -54,7 +54,7 @@ span.sitename, span.email {
     font-size: .7em;
 }
 
-#bottom-bar button {
+#bottom-bar button, #bottom-bar input[type=submit] {
     height: 25px;
     border: 1px solid rgb(145, 145, 145);
     -moz-border-radius: 4px;
@@ -69,11 +69,11 @@ span.sitename, span.email {
     z-index: 0;
 }
 
-#bottom-bar button.righty {
+#bottom-bar button.righty, #bottom-bar input[type=submit].righty {
     float: right;
 }
 
-#bottom-bar button.action {
+#bottom-bar button.action, #bottom-bar input[type=submit] {
     background-color: rgb(0,128,211);
     color: #fff;
     font-weight: bold;
diff --git a/browserid/static/dialog/views/body.ejs b/browserid/static/dialog/views/body.ejs
index b2952fe21134287a155a77a177fe39fa730d00bb..7b17ff10777bde550932a82b8babc700b22e9474 100644
--- a/browserid/static/dialog/views/body.ejs
+++ b/browserid/static/dialog/views/body.ejs
@@ -6,11 +6,13 @@
   <div id="labs_logo" class="sprite"></div>
 </header>
 
-<div id="dialog" class="dialog">
-</div>
+<form action=""> <!-- using the form element to hook into with js -->
+  <div id="dialog" class="dialog">
+  </div>
 
-<div id="bottom-bar">
-</div>
+  <div id="bottom-bar">
+  </div>
+</form>
 
 <footer id="terms">
     BrowserID is a <a target="_blank" href="http://mozillalabs.org">Mozilla Labs</a> service.
diff --git a/browserid/static/dialog/views/bottom-signin.ejs b/browserid/static/dialog/views/bottom-signin.ejs
index f069d5033a3d9daf7826300cd74efcdbcb4d81c3..1c235718f4f8afa0cecf608791aa7cc18b5543af 100644
--- a/browserid/static/dialog/views/bottom-signin.ejs
+++ b/browserid/static/dialog/views/bottom-signin.ejs
@@ -1,2 +1,2 @@
-  <button id="signin" class="righty action submit">Sign In</button>
+  <input type="submit" id="signin" class="righty action submit" name="submit" value="Sign In"/ >
   <button id="cancel" class="righty">Cancel</button>