diff --git a/example/rp/index.html b/example/rp/index.html index 4cff0e90686b3ce95b7667ed7f7f88e4ca0988f6..9eb54b10869eceb66b082c507ed73ac345c6b516 100644 --- a/example/rp/index.html +++ b/example/rp/index.html @@ -126,7 +126,6 @@ navigator.id.addEventListener('logout', function(event) { }); navigator.id.addEventListener('loginCanceled', function(event) { -alert(""); var txt = 'got event at ' + (new Date).toString(); $(".loginCanceledEvents > pre").text(txt); }); @@ -145,7 +144,7 @@ $(document).ready(function() { }); }); - // explicitly trigger events at document ready + // explicitly trigger events at document load navigator.id.setLoggedInUser(null); }); diff --git a/lib/db/mysql.js b/lib/db/mysql.js index 2931097bcde0d45dd58fdeef5265e1c1524a2a6f..19a6aa4ff01375917223f96af897e89d60817de5 100644 --- a/lib/db/mysql.js +++ b/lib/db/mysql.js @@ -118,7 +118,6 @@ exports.open = function(cfg, cb) { logger.debug("connecting to database: " + database); options.database = database; client = mysql.createClient(options); - client.ping(function(err) { logger.debug("connection to database " + (err ? ("fails: " + err) : "established")); cb(err); diff --git a/resources/static/communication_iframe/start.js b/resources/static/communication_iframe/start.js index 386ca965ebb036038498164264af023583456e91..1737dff674794a001ea1698c17f90c1d7f8127a4 100644 --- a/resources/static/communication_iframe/start.js +++ b/resources/static/communication_iframe/start.js @@ -6,7 +6,8 @@ (function() { var bid = BrowserID, network = bid.Network, - user = bid.User; + user = bid.User, + storage = bid.Storage; network.init(); @@ -25,28 +26,31 @@ } } - chan.bind("getPersistentAssertion", function(trans, params) { - setRemoteOrigin(trans.origin); + var loggedInUser = undefined; - trans.delayReturn(true); + // one of two events will cause us to begin checking to + // see if an event shall be emitted - either an explicit + // loggedInUser event or page load. + chan.bind("loggedInUser", function(trans, email) { + loggedInUser = email; + }); - user.getPersistentSigninAssertion(function(rv) { - trans.complete(rv); - }, function() { - trans.error(); + chan.bind("loaded", function(trans, params) { + setRemoteOrigin(trans.origin); + + user.getSilentAssertion(loggedInUser, function(email, assertion) { + if (email && assertion) chan.notify({ method: 'login', params: assertion }); + else chan.notify({ method: 'logout' }); + }, function(err) { + chan.notify({ method: 'logout' }); }); + + trans.complete(); }); chan.bind("logout", function(trans, params) { setRemoteOrigin(trans.origin); - - trans.delayReturn(true); - - user.clearPersistentSignin(function(rv) { - trans.complete(rv); - }, function() { - trans.error(); - }); + storage.setLoggedIn(remoteOrigin, false); + trans.complete(); }); }()); - diff --git a/resources/static/css/style.css b/resources/static/css/style.css index e2c74432efbaf327f993f5b19397d1f99fa7a50a..cab5f6f6f370ed8554dd055e3509186c942069f5 100644 --- a/resources/static/css/style.css +++ b/resources/static/css/style.css @@ -655,20 +655,6 @@ h1 { height: 28px; } -#signUpForm .remember { - display: inline-block; - line-height: 28px; -} - -#signUpForm .remember .checkAlign { - float: left; -} - -#signUpForm .remember label { - margin-left: 5px; - float: left; -} - #signUpForm .error { margin-top: 20px; color: red; diff --git a/resources/static/dialog/controllers/pick_email.js b/resources/static/dialog/controllers/pick_email.js index 87a311462475ff78ceae1e4d588dc969a60d5825..3a352f19d60e757caf362bacb00539a9b96568a5 100644 --- a/resources/static/dialog/controllers/pick_email.js +++ b/resources/static/dialog/controllers/pick_email.js @@ -51,10 +51,6 @@ BrowserID.Modules.PickEmail = (function() { var origin = user.getOrigin(); storage.site.set(origin, "email", email); - if (self.allowPersistent) { - storage.site.set(origin, "remember", $("#remember").is(":checked")); - } - self.close("email_chosen", { email: email }); } } @@ -90,14 +86,11 @@ BrowserID.Modules.PickEmail = (function() { options = options || {}; - self.allowPersistent = options.allow_persistent; dom.addClass("body", "pickemail"); self.renderDialog("pick_email", { identities: getSortedIdentities(), siteemail: storage.site.get(origin, "email"), - allow_persistent: options.allow_persistent || false, - remember: storage.site.get(origin, "remember") || false, privacy_url: options.privacyURL, tos_url: options.tosURL }); diff --git a/resources/static/dialog/css/m.css b/resources/static/dialog/css/m.css index 08b24fe3105acd15ac6dc8915ee5e52af9e22fd4..f3e6dc32525b26460c9cf42e990e374fc336b81d 100644 --- a/resources/static/dialog/css/m.css +++ b/resources/static/dialog/css/m.css @@ -139,10 +139,8 @@ margin-bottom: 20px; } - label[for=remember] { - display: block; - font-size: 15px; - margin-bottom: 25px; + .form_section { + margin-top: 20px; } #content, .form_section, .inputs, .vertical { diff --git a/resources/static/dialog/css/popup.css b/resources/static/dialog/css/popup.css index d3765789e63f85d99d05c94960e50bbb8b3a7c33..1c198c0824b04f7d5dbffe78b6ee663e17aa38d8 100644 --- a/resources/static/dialog/css/popup.css +++ b/resources/static/dialog/css/popup.css @@ -372,11 +372,6 @@ footer { display: none; } -label[for=remember] { - display: inline-block; - margin-bottom: 10px; -} - a.emphasize { background-color: #F0EFED; color: #4E4E4E; diff --git a/resources/static/dialog/resources/internal_api.js b/resources/static/dialog/resources/internal_api.js index 70d81219a29c5a626d17fa7f18bbfde5dea62678..6285f8cb788357cf7ac11f80b46b76d82f309840 100644 --- a/resources/static/dialog/resources/internal_api.js +++ b/resources/static/dialog/resources/internal_api.js @@ -27,7 +27,7 @@ } user.checkAuthentication(function onComplete(authenticated) { - if(authenticated) { + if (authenticated) { storage.site.set(origin, "remember", true); } diff --git a/resources/static/dialog/resources/state.js b/resources/static/dialog/resources/state.js index a955170a02bc17f24994a7dc9b72602efaecdc95..8ccc31247d5f596ba37d337c9f2e369c4ecb1b2b 100644 --- a/resources/static/dialog/resources/state.js +++ b/resources/static/dialog/resources/state.js @@ -37,7 +37,6 @@ BrowserID.State = (function() { info = info || {}; self.hostname = info.hostname; - self.allowPersistent = !!info.allowPersistent; self.privacyURL = info.privacyURL; self.tosURL = info.tosURL; requiredEmail = info.requiredEmail; @@ -70,6 +69,7 @@ BrowserID.State = (function() { var authenticated = info.authenticated; if (requiredEmail) { + self.email = requiredEmail; startState("doAuthenticateWithRequiredEmail", { email: requiredEmail, privacyURL: self.privacyURL, @@ -97,6 +97,7 @@ BrowserID.State = (function() { }); subscribe("user_confirmed", function() { + self.email = self.stagedEmail; startState("doEmailConfirmed", { email: self.stagedEmail} ); }); @@ -165,7 +166,6 @@ BrowserID.State = (function() { subscribe("pick_email", function() { startState("doPickEmail", { origin: self.hostname, - allow_persistent: self.allowPersistent, privacyURL: self.privacyURL, tosURL: self.tosURL }); @@ -177,6 +177,8 @@ BrowserID.State = (function() { var email = info.email, idInfo = storage.getEmail(email); + self.email = email; + function oncomplete() { complete(info.complete); } @@ -245,6 +247,7 @@ BrowserID.State = (function() { subscribe("assertion_generated", function(msg, info) { self.success = true; if (info.assertion !== null) { + bid.Storage.setLoggedIn(user.getOrigin(), self.email); startState("doAssertionGenerated", info.assertion); } else { diff --git a/resources/static/dialog/views/pick_email.ejs b/resources/static/dialog/views/pick_email.ejs index be2fdd3fae2d01aadfb975af222eeedfaa79154d..a9dbdae0af95ae247065e29a8b318bfa83185357 100644 --- a/resources/static/dialog/views/pick_email.ejs +++ b/resources/static/dialog/views/pick_email.ejs @@ -23,28 +23,18 @@ <div class="submit add cf"> - <% if (allow_persistent) { %> - <label for="remember" class="selectable"> - <input type="checkbox" id="remember" name="remember" <% if (remember) { %> checked="checked" <% } %> /> - <%= gettext('Always sign in using this email') %> - </label> - <% } %> - - <% if (privacy_url && tos_url) { %> - <p> -<%= format( - gettext('By clicking %s, you confirm that you accept this site\'s <a %s>Terms of Use</a> and <a %s>Privacy Policy</a>.'), - [ gettext('sign in'), - format(' href="%s" target="_new"', [tos_url]), - format(' href="%s" target="_new"', [privacy_url]) - ]) %> - </p> - <p> - <% } %> - <button id="signInButton"><%= gettext('sign in') %></button> <% if (privacy_url && tos_url) { %> + <p class="tospp"> + <%= format( + gettext('By clicking %s, you confirm that you accept this site\'s <a %s>Terms of Use</a> and <a %s>Privacy Policy</a>.'), + [ gettext('sign in'), + format(' href="%s" target="_new"', [tos_url]), + format(' href="%s" target="_new"', [privacy_url]) + ]) %> </p> <% } %> + + <button id="signInButton"><%= gettext('sign in') %></button> + <br style="clear: both" /> </div> </div> - diff --git a/resources/static/include_js/include.js b/resources/static/include_js/include.js index 0aa5b545828d04e2466f073e873f31d9ec6706fb..d1b12fd75ba82a5cb16f651b88c966574e63cd26 100644 --- a/resources/static/include_js/include.js +++ b/resources/static/include_js/include.js @@ -979,7 +979,17 @@ iframe.style.display = "none"; doc.body.appendChild(iframe); iframe.src = ipServer + "/communication_iframe"; - commChan = Channel.build({window: iframe.contentWindow, origin: ipServer, scope: "mozid_ni"}); + commChan = Channel.build({ + window: iframe.contentWindow, + origin: ipServer, + scope: "mozid_ni", + onReady: function() { + // once the channel is set up, we'll fire a loaded message. this is the + // cutoff point where we'll say if 'setLoggedInUser' was not called before + // this point, then it wont be called (XXX: optimize and improve me) + commChan.call({ method: 'loaded', success: function(){}, error: function() {} }); + } + }); commChan.bind('logout', function(trans, params) { emitEvent('logout'); @@ -992,11 +1002,10 @@ } navigator.id.addEventListener = function(type, listener/*, useCapture */) { - // 1. allocate iframe if it is not allocated + // allocate iframe if it is not allocated _open_hidden_iframe(); - // 2. add event to listeners table if it's not there already - // XXX: should we throw or silently ignore? + // add event to listeners table if it's not there already if (!listeners[type]) throw "unsupported event type: '" + type + "'"; // is the function already registered? @@ -1009,14 +1018,21 @@ navigator.id.removeEventListener = function(type, listener/*, useCapture */) { if (!useCapture) useCapture = false; - // 1. remove event from listeners table + // remove event from listeners table + var i; + for (i = 0; i < listeners[type].length; i++) { + if (listeners[type][i] === listener) break; + } + if (i < listeners[type][i] === listener) { + listeners[type].splice(i, 1); + } }; navigator.id.logout = function() { - // 1. allocate iframe if it is not allocated + // allocate iframe if it is not allocated _open_hidden_iframe(); - // 2. send logout message + // send logout message commChan.notify({ method: 'logout', params: email }); }; diff --git a/resources/static/shared/storage.js b/resources/static/shared/storage.js index 40288033af84e75d874a8fc4f677bd31b1649d8a..0e7cfa0deb376f79c80130579555d354528f7d75 100644 --- a/resources/static/shared/storage.js +++ b/resources/static/shared/storage.js @@ -159,7 +159,6 @@ BrowserID.Storage = (function() { } } - function managePageGet(key) { var allInfo = JSON.parse(storage.managePage || "{}"); return allInfo[key]; @@ -176,6 +175,22 @@ BrowserID.Storage = (function() { delete allInfo[key]; storage.managePage = JSON.stringify(allInfo); } + + function setLoggedIn(origin, email) { + var allInfo = JSON.parse(storage.loggedIn || "{}"); + if (email) allInfo[origin] = email; + else delete allInfo[origin]; + storage.loggedIn = JSON.stringify(allInfo); + } + function getLoggedIn(origin) { + var allInfo = JSON.parse(storage.loggedIn || "{}"); + return allInfo[origin]; + } + function watchLoggedIn(origin, callback) { + throw "not yet implemented"; + } + + return { /** * Add an email address and optional key pair. @@ -242,6 +257,24 @@ BrowserID.Storage = (function() { remove: managePageRemove }, + /** set logged in state for a site + * @param {string} origin - the site to set logged in state for + * @param {string} email - the email that the user is logged in with or falsey if login state should be cleared + */ + setLoggedIn: setLoggedIn, + + /** check if the user is logged into a site + * @param {string} origin - the site to set check the logged in state of + * @returns the email with which the user is logged in + */ + getLoggedIn: getLoggedIn, + + /** watch for changes in the logged in state of a page + * @param {string} origin - the site to watch the status of + * @param {function} callback - a callback to invoke when state changes + */ + watchLoggedIn: watchLoggedIn, + /** * Clear all stored data - email addresses, key pairs, temporary key pairs, * site/email associations. diff --git a/resources/static/shared/user.js b/resources/static/shared/user.js index d4a23aec70aacea814a0e07caa9c6b341bc52c08..2c2102cb0b57072177f66d245fb6a7b9f3698835 100644 --- a/resources/static/shared/user.js +++ b/resources/static/shared/user.js @@ -1046,27 +1046,27 @@ BrowserID.User = (function() { }, /** - * Get an assertion for the current domain, as long as the user has - * selected that they want the email/site remembered + * Get an assertion for the current domain if the user is signed into it * @method getPersistentSigninAssertion * @param {function} onComplete - called on completion. Called with an * assertion if successful, null otw. * @param {function} onFailure - called on XHR failure. */ - getPersistentSigninAssertion: function(onComplete, onFailure) { + getSilentAssertion: function(siteSpecifiedEmail, onComplete, onFailure) { User.checkAuthentication(function(authenticated) { if (authenticated) { - var remembered = storage.site.get(origin, "remember"); - var email = storage.site.get(origin, "email"); - if (remembered && email) { - User.getAssertion(email, origin, onComplete, onFailure); + var loggedInEmail = storage.getLoggedIn(origin); + if (loggedInEmail && siteSpecifiedEmail != loggedInEmail) { + User.getAssertion(loggedInEmail, origin, function(assertion) { + onComplete(loggedInEmail, assertion); + }, onFailure); } else if (onComplete) { - onComplete(null); + onComplete(loggedInEmail, null); } } else if (onComplete) { - onComplete(null); + onComplete(null, null); } }, onFailure); }, @@ -1078,10 +1078,10 @@ BrowserID.User = (function() { * a boolean, true if successful, false otw. * @param {function} onFailure - called on XHR failure. */ - clearPersistentSignin: function(onComplete, onFailure) { + logout: function(onComplete, onFailure) { User.checkAuthentication(function(authenticated) { if (authenticated) { - storage.site.set(origin, "remember", false); + storage.setLoggedIn(origin, false); if (onComplete) { onComplete(true); } @@ -1111,8 +1111,6 @@ BrowserID.User = (function() { onComplete(hasSecondary); } - - }; User.setOrigin(document.location.host);