PageRenderTime 28ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/primary/static/main.js

https://github.com/9kopb/browserid
JavaScript | 341 lines | 268 code | 39 blank | 34 comment | 33 complexity | be2436dc9a66b924cb86cc3499b4101a MD5 | raw file
  1. // this is the picker code! it runs in the identity provider's domain, and
  2. // fiddles the dom expressed by picker.html
  3. (function() {
  4. function refreshAuthStatus() {
  5. $.ajax({
  6. url: '/wsapi/current_username',
  7. success: function(status, textStatus, jqXHR) {
  8. var currentUsername = JSON.parse(jqXHR.responseText);
  9. if (!currentUsername) {
  10. $("#logged_out").show();
  11. } else {
  12. $("#username").text(currentUsername);
  13. $("#logged_in").show();
  14. }
  15. },
  16. error: function() {
  17. runErrorDialog(
  18. "serverError",
  19. "Error Communicating With Server!",
  20. "There was a technical problem while trying to log you in. Yucky!");
  21. }
  22. });
  23. }
  24. function runErrorDialog(code, title, message, onsuccess, onerror) {
  25. $(".dialog").hide();
  26. $("#error_dialog div.title").text(title);
  27. $("#error_dialog div.content").text(message);
  28. $("#back").hide();
  29. $("#cancel").hide();
  30. $("#submit").show().unbind('click').click(function() {
  31. onerror(code);
  32. }).text("Close");
  33. $("#error_dialog").fadeIn(500);
  34. }
  35. function runConfirmationDialog(username) {
  36. refreshAuthStatus();
  37. $("#welcome_address").text(username + "@primary.eyedee.me");
  38. $("#welcome_dialog").fadeIn(500);
  39. $("#create_welcome").show().unbind('click').click(function() {
  40. $("#welcome_dialog").fadeOut(500);
  41. });
  42. };
  43. function runCreateDialog() {
  44. $(".dialog").hide();
  45. $("#back").show().unbind('click').click(function() {
  46. runAuthenticateDialog(undefined);
  47. });
  48. $("#create_cancel").show().unbind('click').click(function() {
  49. onerror("canceled");
  50. });
  51. $("#create_submit").show().unbind('click').click(function() {
  52. // ignore the click if we're disabled
  53. if ($(this).hasClass('disabled')) return true;
  54. // now we need to actually try to stage the creation of this account.
  55. var username = $("#create_dialog input:eq(0)").val();
  56. var pass = $("#create_dialog input:eq(1)").val();
  57. // Go do it...
  58. $.ajax({
  59. url: '/wsapi/create_user?username=' + encodeURIComponent(username) + '&pass=' + encodeURIComponent(pass),
  60. success: function(result) {
  61. $(".dialog").hide();
  62. if (result) {
  63. // the server may have "normalized" our username, a success payload includes the actual
  64. // username registered
  65. username = result.username;
  66. $("#create_dialog input:eq(0)").val(username);
  67. runConfirmationDialog(username);
  68. try {
  69. navigator.id.registerVerifiedEmail(username + "@primary.eyedee.me", function(publicKey) {
  70. $.ajax({
  71. url: '/wsapi/add_key?pubkey=' + encodeURIComponent(publicKey),
  72. success: function() {
  73. // key is saved - we're done?
  74. },
  75. error: function() {
  76. }});
  77. }, function(error) {
  78. runErrorDialog(
  79. "serverError",
  80. "Error Registering Address!",
  81. "There was a technical problem while trying to register your address. Sorry.");
  82. });
  83. } catch (e) {
  84. alert("Whoops, unable to register verified email: " + e);
  85. }
  86. } else {
  87. runErrorDialog(
  88. "serverError",
  89. "Error Creating Account!",
  90. "There was a technical problem while trying to create your account. Sorry.");
  91. }
  92. },
  93. error: function() {
  94. runErrorDialog(
  95. "serverError",
  96. "Error Creating Account!",
  97. "There was a technical problem while trying to create your account. Yucky.");
  98. }
  99. });
  100. }).text("Continue").addClass("disabled");
  101. $("#create_dialog div.attention_lame").hide();
  102. $("#create_dialog div.attention_lame a").unbind('click').click(function() {
  103. var username = $("#create_dialog input:eq(0)").val();
  104. runAuthenticateDialog(username);
  105. });
  106. function checkInput() {
  107. $("#create_submit").removeClass("disabled");
  108. // check the username
  109. var email = $("#create_dialog input:eq(0)").val();
  110. $("#create_dialog div.note:eq(0)").empty();
  111. if (typeof email === 'string' && email.length) {
  112. var valid = checkedEmails[email];
  113. if (typeof valid === 'string') {
  114. // oh noes. we tried to check this email, but it failed. let's just not tell the
  115. // user anything, cause this is a non-critical issue
  116. } else if (typeof valid === 'boolean') {
  117. if (valid) {
  118. $("#create_dialog div.note:eq(0)").html($('<span class="good"/>').text("Username available!"));
  119. $("#create_dialog div.attention_lame").hide();
  120. } else {
  121. $("#create_dialog div.attention_lame").fadeIn(300);
  122. $("#create_dialog div.attention_lame span.email").text(email);
  123. $("#create_submit").addClass("disabled");
  124. }
  125. } else {
  126. // this is an email that needs to be checked!
  127. if (emailCheckState !== 'querying') {
  128. if (emailCheckState) window.clearTimeout(emailCheckState);
  129. emailCheckState = setTimeout(function() {
  130. emailCheckState = 'querying';
  131. var checkingNow = nextEmailToCheck;
  132. // bounce off the server and enter the 'querying' state
  133. $.ajax({
  134. url: '/wsapi/username_available?username=' + encodeURIComponent(checkingNow),
  135. success: function(data, textStatus, jqXHR) {
  136. checkedEmails[checkingNow] = !JSON.parse(data);
  137. emailCheckState = undefined;
  138. checkInput();
  139. }, error: function(jqXHR, textStatus, errorThrown) {
  140. // some kind of error was encountered. This is non-critical, we'll simply ignore it
  141. // and mark this email check as failed.
  142. checkedEmails[checkingNow] = "server failed";
  143. emailCheckState = undefined;
  144. checkInput();
  145. }
  146. });
  147. }, 700);
  148. } else {
  149. $("#create_dialog div.note:eq(0)").html($('<span class="warning"/>').text("Checking address"));
  150. }
  151. nextEmailToCheck = email;
  152. $("#create_submit").addClass("disabled");
  153. }
  154. } else {
  155. $("#create_submit").addClass("disabled");
  156. }
  157. // next let's check the password entry
  158. var pass = $("#create_dialog input:eq(1)").val();
  159. var match = pass === $("#create_dialog input:eq(2)").val();
  160. if (!match) {
  161. $("#create_submit").addClass("disabled");
  162. $("#create_dialog div.note:eq(1)").html($('<span class="bad"/>').text("Passwords different"));
  163. } else {
  164. if (!pass) {
  165. $("#create_submit").addClass("disabled");
  166. $("#create_dialog div.note:eq(1)").html($('<span class="bad"/>').text("Enter a password"));
  167. } else if (pass.length < 5) {
  168. $("#create_submit").addClass("disabled");
  169. $("#create_dialog div.note:eq(1)").html($('<span class="bad"/>').text("Password too short"));
  170. } else {
  171. $("#create_dialog div.note:eq(1)").html($('<span class="good"/>').text("Password OK"))
  172. }
  173. }
  174. }
  175. // watch input dialogs
  176. $("#create_dialog input").unbind('keyup').bind('keyup', checkInput);
  177. // do a check at load time, in case the user is using the back button (enables the continue button!)
  178. checkInput();
  179. $("#create_dialog").fadeIn(500);
  180. } // end runCreateDialog
  181. // a handle to a timeout of a running email check
  182. var emailCheckState = undefined;
  183. // the next email to check, if one is entered while a check is running
  184. var nextEmailToCheck = undefined;
  185. // a set of emails that we've checked for this session
  186. var checkedEmails = {
  187. };
  188. function runAuthenticateDialog(email, onsuccess, onerror) {
  189. $(".status").hide();
  190. $(".dialog").hide();
  191. $("#back").hide();
  192. $("#cancel").show().unbind('click').click(function() {
  193. onerror("canceled");
  194. });
  195. $("#signin_submit").show().unbind('click').click(function() {
  196. if ($(this).hasClass('disabled')) return true;
  197. var email = $("#authenticate_dialog input:eq(0)").val();
  198. var pass = $("#authenticate_dialog input:eq(1)").val();
  199. $.ajax({
  200. url: '/wsapi/authenticate_user?username=' + encodeURIComponent(email) + '&pass=' + encodeURIComponent(pass),
  201. success: function(status, textStatus, jqXHR) {
  202. var authenticated = JSON.parse(jqXHR.responseText);
  203. if (!authenticated) {
  204. $("#authenticate_dialog div.attention_lame").hide().fadeIn(400);
  205. } else {
  206. navigator.id.registerVerifiedEmail(status.username + "@primary.eyedee.me", function(publicKey) {
  207. $.ajax({
  208. url: '/wsapi/add_key?pubkey=' + encodeURIComponent(publicKey),
  209. success: function() {
  210. // key is saved - we're done?
  211. },
  212. error: function() {
  213. }});
  214. }, function(error) {
  215. runErrorDialog(
  216. "serverError",
  217. "Error Registering Address!",
  218. "There was a technical problem while trying to register your address. Sorry.");
  219. });
  220. $("#authenticate_dialog").hide(500);
  221. refreshAuthStatus();
  222. }
  223. },
  224. error: function() {
  225. runErrorDialog(
  226. "serverError",
  227. "Error Authenticating!",
  228. "There was a technical problem while trying to log you in. Yucky!",
  229. onsuccess, onerror);
  230. }
  231. });
  232. }).text("Sign In").addClass("disabled");;
  233. // preseed the email input if whoever triggered us told us to
  234. if (email) {
  235. $("#authenticate_dialog input:eq(0)").val(email);
  236. }
  237. $("#authenticate_dialog div.note > a").unbind('click').click(function() {
  238. onerror("notImplemented");
  239. });
  240. $("#authenticate_dialog div.actions div.action").unbind('click').click(function() {
  241. runCreateDialog(onsuccess, onerror);
  242. });
  243. $("#authenticate_dialog div.attention_lame").hide();
  244. $("#authenticate_dialog input").unbind('keyup').bind('keyup', function() {
  245. var email = $("#authenticate_dialog input:eq(0)").val();
  246. var pass = $("#authenticate_dialog input:eq(1)").val();
  247. if (email.length > 0 && pass.length > 0) $("#signin_submit").removeClass('disabled');
  248. else $("#signin_submit").addClass('disabled');
  249. });
  250. // $("#authenticate_dialog .bottom-bar button").hide();
  251. $("#authenticate_dialog").fadeIn(
  252. 500,
  253. function() {
  254. // where should we put the focus? On login if empty, else password
  255. var email = $("#authenticate_dialog input:eq(0)").val();
  256. if (typeof email === 'string' && email.length) {
  257. $("#authenticate_dialog input:eq(1)").focus();
  258. } else {
  259. $("#authenticate_dialog input:eq(0)").focus();
  260. }
  261. });
  262. }
  263. function runErrorDialog(code, title, message) {
  264. $(".dialog").hide();
  265. $("#error_dialog div.title").text(title);
  266. $("#error_dialog div.content").text(message);
  267. $("#error_submit").show().unbind('click').click(function() {
  268. $("#error_dialog").fadeOut(500);
  269. }).text("Close");
  270. $("#error_dialog").fadeIn(500);
  271. }
  272. // Set up initial bindings
  273. $("#sign_in").click(function() {
  274. runAuthenticateDialog(undefined);
  275. });
  276. $("#sign_out").click(function() {
  277. $("#logged_in").hide();
  278. $("#logged_out").hide();
  279. $.ajax({
  280. url: '/wsapi/signout',
  281. success: function(status, textStatus, jqXHR) {
  282. refreshAuthStatus();
  283. },
  284. error: function() {
  285. runErrorDialog(
  286. "serverError",
  287. "Error Communicating With Server!",
  288. "There was a technical problem while trying to log you out. Sorry!",
  289. onsuccess, onerror);
  290. }
  291. });
  292. });
  293. refreshAuthStatus();
  294. /* // 'Enter' in any input field triggers a click on the submit button
  295. $('input').keypress(function(e){
  296. if(e.which == 13) {
  297. $('#submit').click();
  298. e.preventDefault();
  299. }
  300. });
  301. */
  302. })();