From 0cbbb20a68703603d7573df40c669d4c782593ae Mon Sep 17 00:00:00 2001 From: Lloyd Hilaiel <lloyd@hilaiel.com> Date: Fri, 19 Aug 2011 02:07:31 +0300 Subject: [PATCH] lazy fetch csrf tokens in dialog immediately before a post request which requires them. fixes csrf race condition in beta and dev --- .../dialog/resources/browserid-network.js | 191 +++++++++--------- 1 file changed, 98 insertions(+), 93 deletions(-) diff --git a/browserid/static/dialog/resources/browserid-network.js b/browserid/static/dialog/resources/browserid-network.js index 005392e64..1dc8d52bb 100644 --- a/browserid/static/dialog/resources/browserid-network.js +++ b/browserid/static/dialog/resources/browserid-network.js @@ -36,36 +36,40 @@ * ***** END LICENSE BLOCK ***** */ "use strict"; var BrowserIDNetwork = (function() { - var Network = { - csrf: function(onSuccess) { + var csrf_token = undefined; + function withCSRF(cb) { + if (csrf_token) setTimeout(cb, 0); + else { $.get('/wsapi/csrf', {}, function(result) { - BrowserIDNetwork.csrf_token = result; - if(onSuccess) { - onSuccess(); - } + csrf_token = result; + cb(); }); - }, + } + } + var Network = { setOrigin: function(origin) { BrowserIDNetwork.origin = filterOrigin(origin); }, authenticate: function(email, password, onSuccess, onFailure) { - $.ajax({ - type: "POST", - url: '/wsapi/authenticate_user', - data: { - email: email, - pass: password, - csrf: BrowserIDNetwork.csrf_token - }, - success: function(status, textStatus, jqXHR) { - if(onSuccess) { - var authenticated = JSON.parse(status); - onSuccess(authenticated); - } - }, - error: onFailure + withCSRF(function() { + $.ajax({ + type: "POST", + url: '/wsapi/authenticate_user', + data: { + email: email, + pass: password, + csrf: csrf_token + }, + success: function(status, textStatus, jqXHR) { + if(onSuccess) { + var authenticated = JSON.parse(status); + onSuccess(authenticated); + } + }, + error: onFailure + }); }); }, @@ -82,17 +86,19 @@ var BrowserIDNetwork = (function() { }, logout: function(onSuccess) { - $.post("/wsapi/logout", { - csrf: BrowserIDNetwork.csrf_token - }, - function() { - BrowserIDNetwork.csrf(); - onSuccess(); + withCSRF(function() { + $.post("/wsapi/logout", { + csrf: csrf_token + }, + function() { + onSuccess(); + }); }); }, stageUser: function(email, password, keypair, onSuccess, onFailure) { - $.ajax({ + withCSRF(function() { + $.ajax({ type: "post", url: '/wsapi/stage_user', data: { @@ -100,26 +106,28 @@ var BrowserIDNetwork = (function() { pass: password, pubkey : keypair.pub, site : BrowserIDNetwork.origin, - csrf : BrowserIDNetwork.csrf_token + csrf : csrf_token }, success: onSuccess, error: onFailure }); - + }); }, addEmail: function(email, keypair, onSuccess, onFailure) { - $.ajax({ - type: 'POST', - url: '/wsapi/add_email', - data: { - email: email, - pubkey: keypair.pub, - site: BrowserIDNetwork.origin, - csrf: BrowserIDNetwork.csrf_token - }, - success: onSuccess, - error: onFailure + withCSRF(function() { + $.ajax({ + type: 'POST', + url: '/wsapi/add_email', + data: { + email: email, + pubkey: keypair.pub, + site: BrowserIDNetwork.origin, + csrf: csrf_token + }, + success: onSuccess, + error: onFailure + }); }); }, @@ -149,69 +157,66 @@ var BrowserIDNetwork = (function() { }, setKey: function(email, keypair, onSuccess, onError) { - $.ajax({ - type: 'POST', - url: '/wsapi/set_key', - data: { - email: email, - pubkey: keypair.pub, - csrf: BrowserIDNetwork.csrf_token - }, - success: onSuccess, - error: onError + withCSRF(function() { + $.ajax({ + type: 'POST', + url: '/wsapi/set_key', + data: { + email: email, + pubkey: keypair.pub, + csrf: csrf_token + }, + success: onSuccess, + error: onError + }); }); - }, syncEmails: function(issued_identities, onKeySyncSuccess, onKeySyncFailure, onSuccess, onFailure) { - $.ajax({ - type: "POST", - url: '/wsapi/sync_emails', - data: { - emails: issued_identities, - csrf: BrowserIDNetwork.csrf_token - }, - success: function(resp, textStatus, jqXHR) { - // first remove idenitites that the server doesn't know about - if (resp.unknown_emails) { - _(resp.unknown_emails).each(function(email_address) { + withCSRF(function() { + $.ajax({ + type: "POST", + url: '/wsapi/sync_emails', + data: { + emails: issued_identities, + csrf: csrf_token + }, + success: function(resp, textStatus, jqXHR) { + // first remove idenitites that the server doesn't know about + if (resp.unknown_emails) { + _(resp.unknown_emails).each(function(email_address) { removeEmail(email_address); }); - } - - // now let's begin iteratively re-keying the emails mentioned in the server provided list - var emailsToAdd = resp.key_refresh; - - function addNextEmail() { - if (!emailsToAdd || !emailsToAdd.length) { - onSuccess(); - return; } - // pop the first email from the list - var email = emailsToAdd.shift(); - var keypair = CryptoStubs.genKeyPair(); - - BrowserIDNetwork.setKey(email, keypair, function() { - // update emails list and commit to local storage, then go do the next email - onKeySyncSuccess(email, keypair); - addNextEmail(); - }, onKeySyncFailure); - } - - addNextEmail(); - }, - error: onFailure - } - ); - + // now let's begin iteratively re-keying the emails mentioned in the server provided list + var emailsToAdd = resp.key_refresh; + + function addNextEmail() { + if (!emailsToAdd || !emailsToAdd.length) { + onSuccess(); + return; + } + + // pop the first email from the list + var email = emailsToAdd.shift(); + var keypair = CryptoStubs.genKeyPair(); + + BrowserIDNetwork.setKey(email, keypair, function() { + // update emails list and commit to local storage, then go do the next email + onKeySyncSuccess(email, keypair); + addNextEmail(); + }, onKeySyncFailure); + } + addNextEmail(); + }, + error: onFailure + }); + }); } }; - $(function() { - Network.csrf(); - }); return Network; function filterOrigin(origin) { -- GitLab