Browse files

merged dev and resolved conflict

  • Loading branch information...
2 parents f437d0f + ea1b239 commit 55e16d90f2b878ba024d68841df8ead3a88b7830 @benadida benadida committed Nov 2, 2011
Showing with 3,627 additions and 1,846 deletions.
  1. +3 −0 .gitignore
  2. +13 −0 ChangeLog
  3. +6 −4 README.md
  4. +371 −0 bin/browserid
  5. +53 −10 verifier/run.js → bin/keysigner
  6. +7 −8 performance/run.js → bin/load_gen
  7. +46 −48 verifier/app.js → bin/verifier
  8. +0 −324 browserid/app.js
  9. +0 −39 browserid/static/dialog/qunit.html
  10. +0 −117 browserid/static/dialog/resources/error-messages.js
  11. +0 −21 browserid/static/dialog/test/qunit/qunit.js
  12. +0 −54 browserid/static/dialog/views/authenticate.ejs
  13. 0 browserid/static/ping.txt
  14. +0 −134 browserid/tests/lib/start-stop.js
  15. +0 −40 browserid/views/index.ejs
  16. +7 −7 { → docs}/DEPLOYMENT.md
  17. 0 performance/README.md → docs/LOAD_GENERATION.md
  18. 0 { → docs}/ORGANIZATION.md
  19. 0 {rp → example}/index.html
  20. 0 {rp → example}/jquery-min.js
  21. +5 −6 {browserid/lib → lib/browserid}/ca.js
  22. +3 −3 {browserid/lib → lib/browserid}/email.js
  23. 0 {browserid/lib → lib/browserid}/fake_verification.js
  24. +49 −0 lib/browserid/http_forward.js
  25. 0 {browserid/lib → lib/browserid}/prove_template.txt
  26. +87 −77 {browserid/lib → lib/browserid}/wsapi.js
  27. +89 −52 {libs → lib}/configuration.js
  28. +4 −3 {browserid → }/lib/db.js
  29. +85 −51 browserid/lib/db_json.js → lib/db/json.js
  30. +66 −34 browserid/lib/db_mysql.js → lib/db/mysql.js
  31. +38 −0 lib/heartbeat.js
  32. +10 −0 {browserid → }/lib/httputils.js
  33. +38 −33 browserid/run.js → lib/keysigner/ca.js
  34. 0 {performance/lib → lib/load_gen}/add_email.js
  35. 0 {performance/lib → lib/load_gen}/include_only.js
  36. 0 {performance/lib → lib/load_gen}/reauth.js
  37. 0 {performance/lib → lib/load_gen}/reset_pass.js
  38. 0 {performance/lib → lib/load_gen}/signin.js
  39. 0 {performance/lib → lib/load_gen}/signup.js
  40. 0 {performance/lib → lib/load_gen}/test.js
  41. 0 {performance/lib → lib/load_gen}/user_db.js
  42. +3 −1 {libs → lib}/logging.js
  43. 0 {libs → lib}/metrics.js
  44. +4 −5 {libs → lib}/secrets.js
  45. +32 −29 browserid/static/js/pages/forgot.js → lib/validate.js
  46. +12 −11 {verifier/lib → lib/verifier}/certassertion.js
  47. +2 −2 {libs → lib}/wsapi_client.js
  48. +0 −106 libs/substitute.js
  49. +3 −1 package.json
  50. +6 −4 {browserid → resources}/.gitignore
  51. 0 {browserid → resources}/assets/account-buttons.png
  52. 0 {browserid → resources}/assets/browserID-135x35.png
  53. 0 {browserid → resources}/assets/browserID-366x72.png
  54. 0 {browserid → resources}/assets/browserID-80x20.png
  55. 0 {browserid → resources}/assets/browserID-buttons.psd
  56. 0 {browserid → resources}/assets/browserID-logo.eps
  57. 0 {browserid → resources}/static/.well-known/host-meta
  58. 0 {browserid → resources}/static/css/m.css
  59. 0 {browserid → resources}/static/css/sil.ttf
  60. +14 −2 {browserid → resources}/static/css/style.css
  61. 0 {browserid → resources}/static/css/ts.ttf
  62. +16 −24 {browserid → resources}/static/dialog/controllers/authenticate_controller.js
  63. 0 {browserid → resources}/static/dialog/controllers/checkregistration_controller.js
  64. +37 −15 {browserid → resources}/static/dialog/controllers/dialog_controller.js
  65. +27 −7 {browserid → resources}/static/dialog/controllers/page_controller.js
  66. +12 −1 {browserid → resources}/static/dialog/controllers/pickemail_controller.js
  67. +18 −4 {browserid → resources}/static/dialog/css/m.css
  68. +47 −4 {browserid → resources}/static/dialog/css/popup.css
  69. +3 −1 {browserid → resources}/static/dialog/dialog.js
  70. 0 {browserid → resources}/static/dialog/funcunit.html
  71. 0 {browserid → resources}/static/dialog/mozilla.png
  72. +63 −0 resources/static/dialog/qunit.html
  73. 0 {browserid → resources}/static/dialog/register_iframe.html
  74. 0 {browserid → resources}/static/dialog/register_iframe.js
  75. 0 {browserid → resources}/static/dialog/resources/base64.js
  76. +118 −0 resources/static/dialog/resources/browser-support.js
  77. 0 {browserid → resources}/static/dialog/resources/browserid-extensions.js
  78. 0 {browserid → resources}/static/dialog/resources/browserid.js
  79. +65 −63 {browserid → resources}/static/dialog/resources/channel.js
  80. +59 −38 browserid/static/relay/relay.js → resources/static/dialog/resources/error-messages.js
  81. 0 {browserid → resources}/static/dialog/resources/jschannel.js
  82. +47 −15 {browserid → resources}/static/dialog/resources/network.js
  83. 0 {browserid → resources}/static/dialog/resources/storage.js
  84. +20 −8 {browserid → resources}/static/dialog/resources/tooltip.js
  85. 0 {browserid → resources}/static/dialog/resources/underscore-min.js
  86. +66 −22 {browserid → resources}/static/dialog/resources/user.js
  87. +9 −1 {browserid → resources}/static/dialog/resources/validation.js
  88. 0 {browserid → resources}/static/dialog/resources/wait-messages.js
  89. 0 {browserid → resources}/static/dialog/scripts/build.html
  90. 0 {browserid → resources}/static/dialog/scripts/build.js
  91. 0 {browserid → resources}/static/dialog/scripts/clean.js
  92. 0 {browserid → resources}/static/dialog/scripts/docs.js
  93. 0 {browserid → resources}/static/dialog/test/funcunit/dialog_test.js
  94. 0 {browserid → resources}/static/dialog/test/funcunit/funcunit.js
  95. +94 −0 resources/static/dialog/test/qunit/controllers/authenticate_controller_unit_test.js
  96. +122 −0 resources/static/dialog/test/qunit/controllers/dialog_controller_unit_test.js
  97. +63 −9 {browserid → resources}/static/dialog/test/qunit/controllers/page_controller_unit_test.js
  98. +96 −0 resources/static/dialog/test/qunit/controllers/pickemail_controller_unit_test.js
  99. 0 {browserid → resources}/static/dialog/test/qunit/dialog_test.js
  100. +52 −0 resources/static/dialog/test/qunit/include_unit_test.js
  101. +2 −2 {browserid/static/dialog/test/qunit → resources/static/dialog/test/qunit/js}/browserid_unit_test.js
  102. +81 −0 resources/static/dialog/test/qunit/js/page_helpers_unit_test.js
  103. +39 −0 resources/static/dialog/test/qunit/mocks/mocks.js
  104. +162 −0 resources/static/dialog/test/qunit/mocks/xhr.js
  105. +37 −31 {browserid → resources}/static/dialog/test/qunit/pages/add_email_address_test.js
  106. +129 −0 resources/static/dialog/test/qunit/pages/forgot_unit_test.js
  107. +39 −0 resources/static/dialog/test/qunit/qunit.js
  108. +183 −0 resources/static/dialog/test/qunit/relay/relay_unit_test.js
  109. +102 −0 resources/static/dialog/test/qunit/resources/browser-support_unit_test.js
  110. +162 −0 resources/static/dialog/test/qunit/resources/channel_unit_test.js
  111. +57 −120 {browserid → resources}/static/dialog/test/qunit/resources/network_unit_test.js
  112. 0 {browserid → resources}/static/dialog/test/qunit/resources/storage_unit_test.js
  113. +80 −0 resources/static/dialog/test/qunit/resources/tooltip_unit_test.js
  114. +193 −203 {browserid → resources}/static/dialog/test/qunit/resources/user_unit_test.js
  115. +69 −2 {browserid → resources}/static/dialog/test/qunit/resources/validation_unit_test.js
  116. +60 −0 resources/static/dialog/views/authenticate.ejs
  117. 0 {browserid → resources}/static/dialog/views/confirmemail.ejs
  118. +42 −0 resources/static/dialog/views/error.ejs
  119. +8 −0 resources/static/dialog/views/offline.ejs
  120. +7 −4 {browserid → resources}/static/dialog/views/pickemail.ejs
  121. 0 {browserid → resources}/static/dialog/views/testBodyTemplate.ejs
  122. 0 {browserid → resources}/static/dialog/views/wait.ejs
  123. 0 {browserid → resources}/static/favicon.ico
  124. 0 {browserid/static/steal/get/test → resources/static/funcunit}/.gitignore
  125. 0 {browserid/static/steal/get/test → resources/static/funcunit}/.gitmodules
  126. 0 {browserid/static/steal/get/test → resources/static/funcunit}/README
  127. 0 {browserid → resources}/static/funcunit/autosuggest/auto_suggest.js
  128. 0 {browserid → resources}/static/funcunit/autosuggest/autosuggest.css
  129. 0 {browserid → resources}/static/funcunit/autosuggest/autosuggest.html
  130. 0 {browserid → resources}/static/funcunit/autosuggest/autosuggest.js
  131. 0 {browserid → resources}/static/funcunit/autosuggest/autosuggest_test.js
  132. 0 {browserid → resources}/static/funcunit/autosuggest/funcunit.html
  133. 0 {browserid → resources}/static/funcunit/build.js
  134. 0 {browserid → resources}/static/funcunit/dependencies.json
  135. 0 {browserid → resources}/static/funcunit/docs.html
  136. 0 {browserid → resources}/static/funcunit/drivers/selenium.js
  137. 0 {browserid → resources}/static/funcunit/drivers/standard.js
  138. 0 {browserid → resources}/static/funcunit/envjs
  139. 0 {browserid → resources}/static/funcunit/envjs.bat
  140. 0 {browserid → resources}/static/funcunit/funcunit.html
  141. 0 {browserid → resources}/static/funcunit/funcunit.js
  142. 0 {browserid → resources}/static/funcunit/generate_docs.html
  143. 0 {browserid → resources}/static/funcunit/index.html
  144. 0 {browserid → resources}/static/funcunit/java/extensions/fakesteal.js
  145. 0 {browserid → resources}/static/funcunit/java/extensions/wrapped.js
  146. 0 {browserid → resources}/static/funcunit/java/selenium-java-client-driver.jar
  147. 0 {browserid → resources}/static/funcunit/java/selenium-server-standalone-2.0b3.jar
  148. 0 {browserid → resources}/static/funcunit/java/user-extensions.js
  149. 0 {browserid → resources}/static/funcunit/loader.js
  150. 0 {browserid → resources}/static/funcunit/pages/example.js
  151. 0 {browserid → resources}/static/funcunit/pages/follow.js
  152. 0 {browserid → resources}/static/funcunit/pages/init.js
  153. 0 {browserid → resources}/static/funcunit/pages/mastering.js
  154. 0 {browserid → resources}/static/funcunit/pages/selenium.js
  155. 0 {browserid → resources}/static/funcunit/pages/setup.js
  156. 0 {browserid → resources}/static/funcunit/pages/standalone.js
  157. 0 {browserid → resources}/static/funcunit/pages/writing.js
  158. 0 {browserid → resources}/static/funcunit/qunit.html
  159. 0 {browserid/static/funcunit/syn/resources → resources/static/funcunit}/qunit/qunit.css
  160. 0 {browserid → resources}/static/funcunit/qunit/qunit.js
  161. 0 {browserid → resources}/static/funcunit/qunit/rhino/rhino.js
  162. 0 {browserid → resources}/static/funcunit/qunit/test/qunit.html
  163. 0 {browserid → resources}/static/funcunit/qunit/test/test.js
  164. 0 {browserid/static/funcunit/syn → resources/static/funcunit}/resources/jquery.js
  165. 0 {browserid → resources}/static/funcunit/resources/json.js
  166. 0 {browserid → resources}/static/funcunit/resources/selector.js
  167. 0 {browserid → resources}/static/funcunit/resources/selenium_start.js
  168. 0 {browserid → resources}/static/funcunit/scripts/run.js
  169. 0 {browserid → resources}/static/funcunit/settings.js
  170. 0 {browserid → resources}/static/funcunit/summary.ejs
  171. 0 {browserid → resources}/static/funcunit/syn/.gitignore
  172. 0 {browserid → resources}/static/funcunit/syn/README
  173. 0 {browserid → resources}/static/funcunit/syn/browsers.js
  174. 0 {browserid → resources}/static/funcunit/syn/build.js
  175. 0 {browserid → resources}/static/funcunit/syn/demo.html
  176. 0 {browserid → resources}/static/funcunit/syn/demo/record.js
  177. 0 {browserid → resources}/static/funcunit/syn/drag/drag.html
  178. 0 {browserid → resources}/static/funcunit/syn/drag/drag.js
  179. 0 {browserid → resources}/static/funcunit/syn/drag/qunit.html
  180. 0 {browserid → resources}/static/funcunit/syn/drag/test/qunit/drag_test.js
  181. 0 {browserid → resources}/static/funcunit/syn/drag/test/qunit/qunit.js
  182. 0 {browserid → resources}/static/funcunit/syn/key.js
  183. 0 {browserid → resources}/static/funcunit/syn/mouse.js
  184. 0 {browserid → resources}/static/funcunit/syn/qunit.html
  185. 0 {browserid → resources}/static/funcunit/syn/recorder.html
  186. 0 {browserid → resources}/static/funcunit/syn/resources/jquery.event.drag.js
  187. 0 {browserid → resources}/static/funcunit/syn/resources/jquery.event.drop.js
  188. 0 {browserid/static/funcunit → resources/static/funcunit/syn}/resources/jquery.js
  189. 0 {browserid/static/funcunit → resources/static/funcunit/syn/resources}/qunit/qunit.css
  190. 0 {browserid → resources}/static/funcunit/syn/resources/qunit/qunit.js
  191. 0 {browserid → resources}/static/funcunit/syn/syn.js
  192. 0 {browserid → resources}/static/funcunit/syn/synthetic.html
  193. 0 {browserid → resources}/static/funcunit/syn/synthetic.js
  194. 0 {browserid → resources}/static/funcunit/syn/test/clickbasic.html
  195. 0 {browserid → resources}/static/funcunit/syn/test/qunit/h3.html
  196. 0 {browserid → resources}/static/funcunit/syn/test/qunit/key_test.js
  197. 0 {browserid → resources}/static/funcunit/syn/test/qunit/mouse_test.js
  198. 0 {browserid → resources}/static/funcunit/syn/test/qunit/page1.html
  199. 0 {browserid → resources}/static/funcunit/syn/test/qunit/page2.html
  200. 0 {browserid → resources}/static/funcunit/syn/test/qunit/qunit.js
  201. 0 {browserid → resources}/static/funcunit/syn/test/qunit/syn_test.js
  202. 0 {browserid → resources}/static/funcunit/syn/test/submit.html
  203. 0 {browserid → resources}/static/funcunit/syn/test/submitted.html
  204. 0 {browserid → resources}/static/funcunit/template.html
  205. 0 {browserid → resources}/static/funcunit/test/drag.html
  206. 0 {browserid → resources}/static/funcunit/test/findclosest.html
  207. 0 {browserid → resources}/static/funcunit/test/funcunit/find_closest_test.js
  208. 0 {browserid → resources}/static/funcunit/test/funcunit/funcunit.js
  209. 0 {browserid → resources}/static/funcunit/test/funcunit/funcunit_test.js
  210. 0 {browserid → resources}/static/funcunit/test/funcunit/open_test.js
  211. 0 {browserid → resources}/static/funcunit/test/funcunit/protodrag_test.js
  212. 0 {browserid → resources}/static/funcunit/test/funcunit/syn_test.js
  213. 0 {browserid → resources}/static/funcunit/test/jquery.event.drag.js
  214. 0 {browserid → resources}/static/funcunit/test/jquery.event.drop.js
  215. 0 {browserid → resources}/static/funcunit/test/jquery.js
  216. 0 {browserid → resources}/static/funcunit/test/myapp.html
  217. 0 {browserid → resources}/static/funcunit/test/myotherapp.html
  218. 0 {browserid → resources}/static/funcunit/test/protodrag/dragdrop.js
  219. 0 {browserid → resources}/static/funcunit/test/protodrag/effects.js
  220. 0 {browserid → resources}/static/funcunit/test/protodrag/funcunit_test.js
  221. 0 {browserid → resources}/static/funcunit/test/protodrag/myapp.html
  222. 0 {browserid → resources}/static/funcunit/test/protodrag/prototype.js
  223. 0 {browserid → resources}/static/funcunit/test/protodrag/scriptaculous.js
  224. 0 {browserid → resources}/static/funcunit/test/qunit/qunit.js
  225. 0 {browserid → resources}/static/funcunit/test/run.js
  226. 0 {browserid → resources}/static/funcunit/update
  227. 0 {browserid → resources}/static/i/a_better_way.png
  228. 0 {browserid → resources}/static/i/arrow.png
  229. 0 {browserid → resources}/static/i/bg.png
  230. 0 {browserid → resources}/static/i/blink.gif
  231. 0 {browserid → resources}/static/i/browserid_logo_lil.png
  232. 0 {browserid → resources}/static/i/browserid_logo_sm.png
  233. 0 {browserid → resources}/static/i/card.png
  234. 0 {browserid → resources}/static/i/check.png
  235. 0 {browserid → resources}/static/i/count.png
  236. BIN resources/static/i/firefox_logo.png
  237. 0 {browserid → resources}/static/i/hint.png
  238. 0 {browserid → resources}/static/i/icon.png
  239. 0 {browserid → resources}/static/i/labs-logo-small.png
  240. 0 {browserid → resources}/static/i/lock.png
  241. 0 {browserid → resources}/static/i/sign_in_blue.png
  242. 0 {browserid → resources}/static/i/sign_in_green.png
  243. 0 {browserid → resources}/static/i/sign_in_grey.png
  244. 0 {browserid → resources}/static/i/sign_in_orange.png
  245. 0 {browserid → resources}/static/i/sign_in_red.png
  246. 0 {browserid → resources}/static/i/slit.png
  247. 0 {browserid → resources}/static/i/sprite.png
  248. 0 {browserid → resources}/static/i/sunny.png
  249. 0 {browserid → resources}/static/i/times.gif
  250. 0 {browserid → resources}/static/i/tutorial_1.png
  251. 0 {browserid → resources}/static/i/tutorial_2.png
  252. 0 {browserid → resources}/static/i/tutorial_3.png
  253. +85 −46 {browserid → resources}/static/include.js
  254. 0 {browserid → resources}/static/jquery/.gitignore
  255. 0 {browserid → resources}/static/jquery/README
  256. 0 {browserid → resources}/static/jquery/build.js
  257. 0 {browserid → resources}/static/jquery/buildAll.js
  258. 0 {browserid → resources}/static/jquery/class/class.html
  259. 0 {browserid → resources}/static/jquery/class/class.js
  260. 0 {browserid → resources}/static/jquery/class/class_test.js
  261. 0 {browserid → resources}/static/jquery/class/qunit.html
  262. 0 {browserid → resources}/static/jquery/controller/controller.html
  263. 0 {browserid → resources}/static/jquery/controller/controller.js
  264. 0 {browserid → resources}/static/jquery/controller/controller_test.js
  265. 0 {browserid → resources}/static/jquery/controller/history/history.html
  266. 0 {browserid → resources}/static/jquery/controller/history/history.js
  267. 0 {browserid → resources}/static/jquery/controller/history/html5/html5.js
  268. 0 {browserid → resources}/static/jquery/controller/history/html5/qunit.html
  269. 0 {browserid → resources}/static/jquery/controller/history/html5/qunit/qunit.js
  270. 0 {browserid → resources}/static/jquery/controller/history/qunit.html
  271. 0 {browserid → resources}/static/jquery/controller/history/qunit/qunit.js
  272. 0 {browserid → resources}/static/jquery/controller/pages/document.js
  273. 0 {browserid → resources}/static/jquery/controller/pages/listening.js
  274. 0 {browserid → resources}/static/jquery/controller/pages/plugin.js
  275. 0 {browserid → resources}/static/jquery/controller/qunit.html
  276. 0 {browserid → resources}/static/jquery/controller/subscribe/funcunit.html
  277. 0 {browserid → resources}/static/jquery/controller/subscribe/subscribe.html
  278. 0 {browserid → resources}/static/jquery/controller/subscribe/subscribe.js
  279. 0 {browserid → resources}/static/jquery/controller/view/qunit.html
  280. 0 {browserid → resources}/static/jquery/controller/view/test/qunit/controller_view_test.js
  281. 0 {browserid → resources}/static/jquery/controller/view/test/qunit/qunit.js
  282. 0 {browserid → resources}/static/jquery/controller/view/test/qunit/views/init.micro
  283. 0 {browserid → resources}/static/jquery/controller/view/view.js
  284. 0 {browserid → resources}/static/jquery/dom/closest/closest.js
  285. 0 {browserid → resources}/static/jquery/dom/compare/compare.html
  286. 0 {browserid → resources}/static/jquery/dom/compare/compare.js
  287. 0 {browserid → resources}/static/jquery/dom/compare/compare_test.js
  288. 0 {browserid → resources}/static/jquery/dom/compare/qunit.html
  289. 0 {browserid → resources}/static/jquery/dom/cookie/cookie.js
  290. 0 {browserid → resources}/static/jquery/dom/cur_styles/cur_styles.html
  291. 0 {browserid → resources}/static/jquery/dom/cur_styles/cur_styles.js
  292. 0 {browserid → resources}/static/jquery/dom/cur_styles/cur_styles_test.js
  293. 0 {browserid → resources}/static/jquery/dom/cur_styles/qunit.html
  294. 0 ...c/jquery/dom/dimensions/test/qunit → resources/static/jquery/dom/cur_styles/test}/curStyles.micro
  295. 0 {browserid → resources}/static/jquery/dom/dimensions/dimensions.html
  296. 0 {browserid → resources}/static/jquery/dom/dimensions/dimensions.js
  297. 0 {browserid → resources}/static/jquery/dom/dimensions/qunit.html
  298. 0 ...c/jquery/dom/cur_styles/test → resources/static/jquery/dom/dimensions/test/qunit}/curStyles.micro
  299. 0 {browserid → resources}/static/jquery/dom/dimensions/test/qunit/dimensions_test.js
  300. 0 {browserid → resources}/static/jquery/dom/dimensions/test/qunit/outer.micro
Sorry, we could not display the entire diff because too many files (1,194) changed.
View
3 .gitignore
@@ -3,3 +3,6 @@
.\#*
/node_modules
/var
+/rpmbuild
+/npm-debug.log
+
View
13 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
View
10 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.
View
371 bin/browserid
@@ -0,0 +1,371 @@
+#!/usr/bin/env node
+
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla BrowserID.
+ *
+ * The Initial Developer of the Original Code is Mozilla.
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+const
+fs = require('fs'),
+path = require('path'),
+url = require('url'),
+http = require('http');
+sessions = require('connect-cookie-session');
+
+// add lib/ to the require path
+require.paths.unshift(path.join(__dirname, '..', 'lib'));
+
+const
+wsapi = require('browserid/wsapi.js'),
+ca = require('browserid/ca.js'),
+httputils = require('httputils.js'),
+express = require('express'),
+secrets = require('secrets.js'),
+db = require('db.js'),
+config = require('configuration.js'),
+heartbeat = require('heartbeat.js'),
+metrics = require("metrics.js"),
+logger = require("logging.js").logger,
+forward = require('browserid/http_forward'),
+urlparse = require('urlparse');
+
+var app = undefined;
+
+app = express.createServer();
+
+logger.info("browserid server starting up");
+
+const COOKIE_SECRET = secrets.hydrateSecret('browserid_cookie', config.get('var_path'));
+const COOKIE_KEY = 'browserid_state';
+
+// verify that we have a keysigner configured
+if (!config.get('keysigner_url')) {
+ logger.error('missing required configuration - url for the keysigner (KEYSIGNER_URL in env)');
+ process.exit(1);
+}
+
+function internal_redirector(new_url, suppress_noframes) {
+ return function(req, resp, next) {
+ if (suppress_noframes)
+ resp.removeHeader('x-frame-options');
+ req.url = new_url;
+ return next();
+ };
+}
+
+function router(app) {
+ app.set("views", path.join(__dirname, "..", "resources", "views"));
+
+ app.set('view options', {
+ production: config.get('use_minified_resources')
+ });
+
+ // this should probably be an internal redirect
+ // as soon as relative paths are figured out.
+ app.get('/sign_in', function(req, res, next ) {
+ metrics.userEntry(req);
+ res.render('dialog.ejs', {
+ title: 'A Better Way to Sign In',
+ layout: 'dialog_layout.ejs',
+ useJavascript: true,
+ production: config.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));
+
+ // Used for a relay page for communication.
+ app.get("/relay", function(req,res, next) {
+ // Allow the relay to be run within a frame
+ res.removeHeader('x-frame-options');
+ res.render('relay.ejs', {
+ layout: false,
+ production: config.get('use_minified_resources')
+ });
+ });
+
+
+ app.get('/', function(req,res) {
+ res.render('index.ejs', {title: 'A Better Way to Sign In', fullpage: true});
+ });
+
+ app.get("/signup", function(req, res) {
+ res.render('signup.ejs', {title: 'Sign Up', fullpage: false});
+ });
+
+ app.get("/forgot", function(req, res) {
+ res.render('forgot.ejs', {title: 'Forgot Password', fullpage: false, email: req.query.email});
+ });
+
+ app.get("/signin", function(req, res) {
+ res.render('signin.ejs', {title: 'Sign In', fullpage: false});
+ });
+
+ app.get("/about", function(req, res) {
+ res.render('about.ejs', {title: 'About', fullpage: false});
+ });
+
+ app.get("/tos", function(req, res) {
+ res.render('tos.ejs', {title: 'Terms of Service', fullpage: false});
+ });
+
+ app.get("/privacy", function(req, res) {
+ res.render('privacy.ejs', {title: 'Privacy Policy', fullpage: false});
+ });
+
+ app.get("/verify_email_address", function(req, res) {
+ res.render('verifyuser.ejs', {title: 'Complete Registration', fullpage: true, token: req.query.token});
+ });
+
+ app.get("/add_email_address", function(req,res) {
+ res.render('verifyemail.ejs', {title: 'Verify Email Address', fullpage: false});
+ });
+
+ // REDIRECTS
+ REDIRECTS = {
+ "/manage": "/",
+ "/users": "/",
+ "/users/": "/",
+ "/primaries" : "/developers",
+ "/primaries/" : "/developers",
+ "/developers" : "https://github.com/mozilla/browserid/wiki/How-to-Use-BrowserID-on-Your-Site"
+ };
+
+ // set up all the redirects
+ // oh my watch out for scope issues on var url - closure time
+ for (var url in REDIRECTS) {
+ (function(from,to) {
+ app.get(from, function(req, res) {
+ res.redirect(to);
+ });
+ })(url, REDIRECTS[url]);
+ }
+
+ // register all the WSAPI handlers
+ wsapi.setup(app);
+
+ // setup health check / heartbeat
+ heartbeat.setup(app, function(cb) {
+ // let's check stuff! first the heartbeat of our keysigner
+ heartbeat.check(config.get('keysigner_url'), cb);
+ });
+
+ // the public key
+ app.get("/pk", function(req, res) {
+ res.json(ca.PUBLIC_KEY.toSimpleObject());
+ });
+
+ // vep bundle of JavaScript
+ app.get("/vepbundle", function(req, res) {
+ fs.readFile(__dirname + "/../node_modules/jwcrypto/vepbundle.js", function(error, content) {
+ if (error) {
+ res.writeHead(500);
+ res.end("oops");
+ console.log(error);
+ } else {
+ res.writeHead(200, {'Content-Type': 'text/javascript'});
+ res.write(content);
+ res.end();
+ }
+ });
+ });
+
+ app.get('/code_update', function(req, resp, next) {
+ logger.warn("code updated. shutting down.");
+ process.exit();
+ });
+};
+
+// request to logger, dev formatted which omits personal data in the requests
+app.use(express.logger({
+ format: 'dev',
+ stream: {
+ write: function(x) {
+ logger.info(typeof x === 'string' ? x.trim() : x);
+ }
+ }
+}));
+
+// if these are verify requests, we'll redirect them off
+// to the verifier
+if (config.get('verifier_url')) {
+ app.use(function(req, res, next) {
+ if (/^\/verify$/.test(req.url)) {
+ forward(
+ config.get('verifier_url'), req, res,
+ function(err) {
+ if (err) {
+ logger.error("error forwarding request:", err);
+ }
+ });
+ } else {
+ return next();
+ }
+ });
+}
+
+// over SSL?
+var overSSL = (config.get('scheme') == 'https');
+
+app.use(express.cookieParser());
+
+var cookieSessionMiddleware = sessions({
+ secret: COOKIE_SECRET,
+ key: COOKIE_KEY,
+ cookie: {
+ path: '/wsapi',
+ httpOnly: true,
+ // IMPORTANT: we allow users to go 1 weeks on the same device
+ // without entering their password again
+ maxAge: config.get('authentication_duration_ms'),
+ secure: overSSL
+ }
+});
+
+// cookie sessions && cache control
+app.use(function(req, resp, next) {
+ // cookie sessions are only applied to calls to /wsapi
+ // as all other resources can be aggressively cached
+ // by layers higher up based on cache control headers.
+ // the fallout is that all code that interacts with sessions
+ // should be under /wsapi
+ if (/^\/wsapi/.test(req.url)) {
+ // explicitly disallow caching on all /wsapi calls (issue #294)
+ resp.setHeader('Cache-Control', 'no-cache, max-age=0');
+
+ // we set this parameter so the connect-cookie-session
+ // sends the cookie even though the local connection is HTTP
+ // (the load balancer does SSL)
+ if (overSSL)
+ req.connection.proxySecure = true;
+
+ return cookieSessionMiddleware(req, resp, next);
+
+ } else {
+ return next();
+ }
+});
+
+config.performSubstitution(app);
+
+// verify all JSON responses are objects - prevents regression on issue #217
+app.use(function(req, resp, next) {
+ var realRespJSON = resp.json;
+ resp.json = function(obj) {
+ if (!obj || typeof obj !== 'object') {
+ logger.error("INTERNAL ERROR! *all* json responses must be objects");
+ throw "internal error";
+ }
+ realRespJSON.call(resp, obj);
+ };
+ return next();
+});
+
+app.use(express.bodyParser());
+
+// Check CSRF token early. POST requests are only allowed to
+// /wsapi and they always must have a valid csrf token
+app.use(function(req, resp, next) {
+ // only on POSTs
+ if (req.method == "POST") {
+ var denied = false;
+ if (!/^\/wsapi/.test(req.url)) { // post requests only allowed to /wsapi
+ denied = true;
+ logger.warn("CSRF validation failure: POST only allowed to /wsapi urls. not '" + req.url + "'");
+ }
+
+ else if (req.session === undefined) { // there must be a session
+ denied = true;
+ logger.warn("CSRF validation failure: POST calls to /wsapi require an active session");
+ }
+
+ // the session must have a csrf token
+ else if (typeof req.session.csrf !== 'string') {
+ denied = true;
+ logger.warn("CSRF validation failure: POST calls to /wsapi require an csrf token to be set");
+ }
+
+ // and the token must match what is sent in the post body
+ else if (req.body.csrf != req.session.csrf) {
+ denied = true;
+ // if any of these things are false, then we'll block the request
+ logger.warn("CSRF validation failure, token mismatch. got:" + req.body.csrf + " want:" + req.session.csrf);
+ }
+
+ if (denied) return httputils.badRequest(resp, "CSRF violation");
+
+ }
+ return next();
+});
+
+// a tweak to get the content type of host-meta correct
+app.use(function(req, resp, next) {
+ if (req.url === '/.well-known/host-meta') {
+ resp.setHeader('content-type', 'text/xml');
+ }
+ next();
+});
+
+// Strict Transport Security
+app.use(function(req, resp, next) {
+ if (overSSL) {
+ // expires in 30 days, include subdomains like www
+ resp.setHeader("Strict-Transport-Security", "max-age=2592000; includeSubdomains");
+ }
+ next();
+});
+
+// prevent framing
+app.use(function(req, resp, next) {
+ resp.setHeader('x-frame-options', 'DENY');
+ next();
+});
+
+// add the actual URL handlers other than static
+router(app);
+
+// use the express 'static' middleware for serving of static files (cache headers, HTTP range, etc)
+app.use(express.static(path.join(__dirname, "..", "resources", "static")));
+
+// open the databse
+db.open(config.get('database'), function () {
+ var bindTo = config.get('bind_to');
+ app.listen(bindTo.port, bindTo.host, function() {
+ logger.info("running on http://" + app.address().address + ":" + app.address().port);
+ });
+});
View
63 verifier/run.js → bin/keysigner
@@ -35,19 +35,62 @@
*
* ***** END LICENSE BLOCK ***** */
-var sys = require("sys"),
- path = require("path"),
- fs = require("fs"),
- express = require("express");
+// I sign keys. That's what I do.
-var PRIMARY_HOST = "127.0.0.1";
-var PRIMARY_PORT = 62800;
+const
+path = require('path'),
+express = require('express');
-var handler = require("./app.js");
+// add lib/ to the require path for our own libs
+require.paths.unshift(path.join(__dirname, '..', 'lib'));
+const
+config = require('configuration.js'),
+validate = require('validate.js'),
+metrics = require("metrics.js"),
+logger = require("logging.js").logger,
+ca = require('keysigner/ca.js'),
+heartbeat = require('heartbeat');
+
+// create an express server
var app = express.createServer();
-// let the specific server interact directly with the express server to register their middleware
-if (handler.setup) handler.setup(app);
+// our server will log
+app.use(express.logger({
+ format: 'dev',
+ stream: {
+ write: function(x) {
+ logger.info(typeof x === 'string' ? x.trim() : x);
+ }
+ }
+}));
+
+app.use(function(req, resp, next) {
+ next();
+});
+
+// parse POST bodies
+app.use(express.bodyParser());
+
+heartbeat.setup(app);
+
+// and our single function
+app.post('/wsapi/cert_key', validate(["email", "pubkey"]), function(req, resp) {
+ // parse the pubkey
+ var pk = ca.parsePublicKey(req.body.pubkey);
+
+ // same account, we certify the key
+ // we certify it for a day for now
+ var expiration = new Date();
+ expiration.setTime(new Date().valueOf() + config.get('certificate_validity_ms'));
+ var cert = ca.certify(req.body.email, pk, expiration);
+
+ resp.writeHead(200, {'Content-Type': 'text/plain'});
+ resp.write(cert);
+ resp.end();
+});
-app.listen(PRIMARY_PORT, PRIMARY_HOST);
+var bindTo = config.get('bind_to');
+app.listen(bindTo.port, bindTo.host, function() {
+ logger.info("running on http://" + app.address().address + ":" + app.address().port);
+});
View
15 performance/run.js → bin/load_gen
@@ -20,7 +20,7 @@
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
- * Lloyd Hilaiel <lloyd@hilaiel.com>
+ * Lloyd Hilaiel <lloyd@hilaiel.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@@ -40,8 +40,7 @@
* tool, which is capable of analysing the maximum active users that
* a browserid deployment can support */
-
-// option processing with optimist
+// option processing with optimist
var argv = require('optimist')
.usage('Apply load to a BrowserID server.\nUsage: $0', [ "foo" ])
.alias('h', 'help')
@@ -92,14 +91,14 @@ var completed = {
const activitiesPerUserPerSecond = (40.0 / ( 24 * 60 * 60 ));
// activities
-var activity = {
+var activity = {
"signup": {
// a %20 montly growth rate means there's a 20% probability of
// the monthly activity generated by an active user being a
// new user signup
probability: (1.0 / (40 * 28 * .2))
},
- "reset_pass": {
+ "reset_pass": {
// users forget their password once every 4 weeks
probability: (1.0 / (40 * 28.0))
},
@@ -129,7 +128,7 @@ var activity = {
// now attach "start functions" to the activity map by including
// the implementation of each activity
Object.keys(activity).forEach(function(k) {
- activity[k].startFunc = require("./lib/" + k).startFunc;
+ activity[k].startFunc = require("../lib/performance/" + k).startFunc;
});
// probs is a 2d array mapping normalized probabilities from 0-1 to
@@ -237,12 +236,12 @@ function poll() {
// how many active users would we like to simulate
var targetActive = args.m;
-
+
// if we're not throttled, then we'll trying 150% as many as
// we're simulating right now. If we're not simulating at least
// 10000 active users, that shall be our lower bound
if (!targetActive) {
- if (averages[0] > 10000) targetActive = averages[0] * 1.5;
+ if (averages[0] > 10000) targetActive = averages[0] * 1.5;
else targetActive = 10000;
}
View
94 verifier/app.js → bin/verifier 100644 → 100755
@@ -1,3 +1,5 @@
+#!/usr/bin/env node
+
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
@@ -34,25 +36,49 @@
*
* ***** END LICENSE BLOCK ***** */
-const path = require('path'),
- url = require('url'),
- fs = require('fs'),
-certassertion = require('./lib/certassertion.js'),
- express = require('express'),
- metrics = require('../libs/metrics.js'),
- logger = require('../libs/logging.js').logger;
+const
+sys = require("sys"),
+path = require('path'),
+url = require('url'),
+fs = require('fs'),
+express = require('express'),
+certassertion = require('../lib/verifier/certassertion.js'),
+metrics = require('../lib/metrics'),
+heartbeat = require('../lib/heartbeat'),
+logger = require('../lib/logging').logger,
+config = require('../lib/configuration');
logger.info("verifier server starting up");
-// updating this call for certs now (Ben - 2011-09-06)
-// assertion is the single assertion of email
-// audience is the intended audience
-// certificates is the list of chained certificates, CSV-style
-function doVerify(req, resp, next) {
+var app = express.createServer();
+
+// request to logger, dev formatted which omits personal data in the requests
+app.use(express.logger({
+ stream: {
+ write: function(x) {
+ logger.info(typeof x === 'string' ? x.trim() : x);
+ }
+ }
+}));
+
+app.use(express.bodyParser());
+
+// code_update is an internal api that causes the node server to
+// shut down. This should never be externally accessible and
+// is used during the dead simple deployment procedure.
+app.get("/code_update", function (req, resp) {
+ logger.warn("code updated. shutting down.");
+ process.exit();
+});
+
+// setup health check / heartbeat
+heartbeat.setup(app);
+
+app.post('/verify', function(req, resp, next) {
req.body = req.body || {}
- var assertion = (req.query && req.query.assertion) ? req.query.assertion : req.body.assertion;
- var audience = (req.query && req.query.audience) ? req.query.audience : req.body.audience;
+ var assertion = req.body.assertion;
+ var audience = req.body.audience;
if (!(assertion && audience))
return resp.json({ status: "failure", reason: "need assertion and audience" });
@@ -86,41 +112,13 @@ function doVerify(req, resp, next) {
resp.json({"status":"failure", reason: (error ? error.toString() : "unknown")});
metrics.report('verify', {
result: 'failure',
- rp: audienceFromAssertion
+ rp: audience
});
});
-}
-
-exports.setup = function(app) {
- // request to logger, dev formatted which omits personal data in the requests
-
- app.use(express.logger({
- format: 'dev',
- stream: {
- write: function(x) {
- logger.info(typeof x === 'string' ? x.trim() : x);
- }
- }
- }));
-
- app.use(express.bodyParser());
-
- // code_update is an internal api that causes the node server to
- // shut down. This should never be externally accessible and
- // is used during the dead simple deployment procedure.
- app.get("/code_update", function (req, resp) {
- logger.warn("code updated. shutting down.");
- process.exit();
- });
-
- // A simple ping hook for monitoring.
- app.get("/ping.txt", function(req ,resp) {
- resp.writeHead(200, {"Content-Type": "text/plain"})
- resp.write("k.");
- resp.end();
- });
+});
- app.post('/', doVerify);
- app.post('/verify', doVerify);
-};
+var bindTo = config.get('bind_to');
+app.listen(bindTo.port, bindTo.host, function(conn) {
+ logger.info("running on http://" + app.address().address + ":" + app.address().port);
+});
View
324 browserid/app.js
@@ -1,324 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla BrowserID.
- *
- * The Initial Developer of the Original Code is Mozilla.
- * Portions created by the Initial Developer are Copyright (C) 2011
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-const
-fs = require('fs'),
-path = require('path'),
-url = require('url'),
-wsapi = require('./lib/wsapi.js'),
-ca = require('./lib/ca.js'),
-httputils = require('./lib/httputils.js'),
-sessions = require('connect-cookie-session'),
-express = require('express'),
-secrets = require('../libs/secrets.js'),
-db = require('./lib/db.js'),
-configuration = require('../libs/configuration.js'),
-substitution = require('../libs/substitute.js');
-metrics = require("../libs/metrics.js"),
-logger = require("../libs/logging.js").logger;
-
-logger.info("browserid server starting up");
-
-// open the databse
-db.open(configuration.get('database'));
-
-const COOKIE_SECRET = secrets.hydrateSecret('browserid_cookie', configuration.get('var_path'));
-const COOKIE_KEY = 'browserid_state';
-
-function internal_redirector(new_url, suppress_noframes) {
- return function(req, resp, next) {
- if (suppress_noframes)
- resp.removeHeader('x-frame-options');
- req.url = new_url;
- return next();
- };
-}
-
-function router(app) {
- app.set("views", __dirname + '/views');
-
- app.set('view options', {
- production: configuration.get('use_minified_resources')
- });
-
- // this should probably be an internal redirect
- // as soon as relative paths are figured out.
- app.get('/sign_in', function(req, res, next ) {
- metrics.userEntry(req);
- res.render('dialog.ejs', {
- title: 'A Better Way to Sign In',
- layout: false,
- production: configuration.get('use_minified_resources')
- });
- });
-
- // simple redirects (internal for now)
- app.get('/register_iframe', internal_redirector('/dialog/register_iframe.html',true));
-
- // Used for a relay page for communication.
- app.get("/relay", function(req,res, next) {
- // Allow the relay to be run within a frame
- res.removeHeader('x-frame-options');
- res.render('relay.ejs', {
- layout: false,
- production: configuration.get('use_minified_resources')
- });
- });
-
-
- app.get('/', function(req,res) {
- 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});
- });
-
- app.get("/forgot", function(req, res) {
- res.render('forgot.ejs', {title: 'Forgot Password', fullpage: false, email: req.query.email});
- });
-
- app.get("/signin", function(req, res) {
- res.render('signin.ejs', {title: 'Sign In', fullpage: false});
- });
-
- app.get("/about", function(req, res) {
- res.render('about.ejs', {title: 'About', fullpage: false});
- });
-
- app.get("/tos", function(req, res) {
- res.render('tos.ejs', {title: 'Terms of Service', fullpage: false});
- });
-
- app.get("/privacy", function(req, res) {
- res.render('privacy.ejs', {title: 'Privacy Policy', fullpage: false});
- });
-
- app.get("/verify_email_address", function(req, res) {
- res.render('verifyuser.ejs', {title: 'Complete Registration', fullpage: true, token: req.query.token});
- });
-
- app.get("/add_email_address", function(req,res) {
- res.render('verifyemail.ejs', {title: 'Verify Email Address', fullpage: false});
- });
-
- // REDIRECTS
- REDIRECTS = {
- "/manage": "/",
- "/users": "/",
- "/users/": "/",
- "/primaries" : "/developers",
- "/primaries/" : "/developers",
- "/developers" : "https://github.com/mozilla/browserid/wiki/How-to-Use-BrowserID-on-Your-Site"
- };
-
- // set up all the redirects
- // oh my watch out for scope issues on var url - closure time
- for (var url in REDIRECTS) {
- (function(from,to) {
- app.get(from, function(req, res) {
- res.redirect(to);
- });
- })(url, REDIRECTS[url]);
- }
-
- // register all the WSAPI handlers
- wsapi.setup(app);
-
- // the public key
- app.get("/pk", function(req, res) {
- res.json(ca.PUBLIC_KEY.toSimpleObject());
- });
-
- // vep bundle of JavaScript
- app.get("/vepbundle", function(req, res) {
- fs.readFile(__dirname + "/../node_modules/jwcrypto/vepbundle.js", function(error, content) {
- if (error) {
- res.writeHead(500);
- res.end("oops");
- console.log(error);
- } else {
- res.writeHead(200, {'Content-Type': 'text/javascript'});
- res.write(content);
- res.end();
- }
- });
- });
-
- app.get('/code_update', function(req, resp, next) {
- logger.warn("code updated. shutting down.");
- process.exit();
- });
-};
-
-exports.setup = function(server) {
- // request to logger, dev formatted which omits personal data in the requests
- server.use(express.logger({
- format: 'dev',
- stream: {
- write: function(x) {
- logger.info(typeof x === 'string' ? x.trim() : x);
- }
- }
- }));
-
- // over SSL?
- var overSSL = (configuration.get('scheme') == 'https');
-
- server.use(express.cookieParser());
-
- var cookieSessionMiddleware = sessions({
- secret: COOKIE_SECRET,
- key: COOKIE_KEY,
- cookie: {
- path: '/wsapi',
- httpOnly: true,
- // IMPORTANT: we allow users to go 1 weeks on the same device
- // without entering their password again
- maxAge: configuration.get('authentication_duration_ms'),
- secure: overSSL
- }
- });
-
- // cookie sessions && cache control
- server.use(function(req, resp, next) {
- // cookie sessions are only applied to calls to /wsapi
- // as all other resources can be aggressively cached
- // by layers higher up based on cache control headers.
- // the fallout is that all code that interacts with sessions
- // should be under /wsapi
- if (/^\/wsapi/.test(req.url)) {
- // explicitly disallow caching on all /wsapi calls (issue #294)
- resp.setHeader('Cache-Control', 'no-cache, max-age=0');
-
- // we set this parameter so the connect-cookie-session
- // sends the cookie even though the local connection is HTTP
- // (the load balancer does SSL)
- if (overSSL)
- req.connection.proxySecure = true;
-
- return cookieSessionMiddleware(req, resp, next);
-
- } else {
- return next();
- }
- });
-
- // verify all JSON responses are objects - prevents regression on issue #217
- server.use(function(req, resp, next) {
- var realRespJSON = resp.json;
- resp.json = function(obj) {
- if (!obj || typeof obj !== 'object') {
- logger.error("INTERNAL ERROR! *all* json responses must be objects");
- throw "internal error";
- }
- realRespJSON.call(resp, obj);
- };
- return next();
- });
-
- server.use(express.bodyParser());
-
- // Check CSRF token early. POST requests are only allowed to
- // /wsapi and they always must have a valid csrf token
- server.use(function(req, resp, next) {
- // only on POSTs
- if (req.method == "POST") {
- var denied = false;
- if (!/^\/wsapi/.test(req.url)) { // post requests only allowed to /wsapi
- denied = true;
- logger.warn("CSRF validation failure: POST only allowed to /wsapi urls. not '" + req.url + "'");
- }
-
- if (req.session === undefined) { // there must be a session
- denied = true;
- logger.warn("CSRF validation failure: POST calls to /wsapi require an active session");
- }
-
- // the session must have a csrf token
- if (typeof req.session.csrf !== 'string') {
- denied = true;
- logger.warn("CSRF validation failure: POST calls to /wsapi require an csrf token to be set");
- }
-
- // and the token must match what is sent in the post body
- if (req.body.csrf != req.session.csrf) {
- denied = true;
- // if any of these things are false, then we'll block the request
- logger.warn("CSRF validation failure, token mismatch. got:" + req.body.csrf + " want:" + req.session.csrf);
- }
-
- if (denied) return httputils.badRequest(resp, "CSRF violation");
-
- }
- return next();
- });
-
- // a tweak to get the content type of host-meta correct
- server.use(function(req, resp, next) {
- if (req.url === '/.well-known/host-meta') {
- resp.setHeader('content-type', 'text/xml');
- }
- next();
- });
-
- // Strict Transport Security
- server.use(function(req, resp, next) {
- if (overSSL) {
- // expires in 30 days, include subdomains like www
- resp.setHeader("Strict-Transport-Security", "max-age=2592000; includeSubdomains");
- }
- next();
- });
-
- // prevent framing
- server.use(function(req, resp, next) {
- resp.setHeader('x-frame-options', 'DENY');
- next();
- });
-
- // add middleware to re-write urls if needed
- configuration.performSubstitution(server);
-
- // add the actual URL handlers other than static
- router(server);
-}
-
-exports.shutdown = function() {
- db.close();
-};
View
39 browserid/static/dialog/qunit.html
@@ -1,39 +0,0 @@
-<html>
- <head>
- <link rel="stylesheet" type="text/css" href="/funcunit/qunit/qunit.css" />
- <title>dialog QUnit Test</title>
- <script type='text/javascript' src='/vepbundle'></script>
- <script type='text/javascript' src='/steal/steal.js?/dialog/test/qunit'></script>
- </head>
- <body>
-
- <h1 id="qunit-header">dialog Test Suite</h1>
- <h2 id="qunit-banner"></h2>
- <div id="qunit-testrunner-toolbar"></div>
- <h2 id="qunit-userAgent"></h2>
- <div id="test-content">
- <div id="page_controller">
-
- <div id="formWrap">
- <div class="contents"></div>
- </div>
-
- <div id="wait">
- <div class="contents"></div>
- </div>
-
- <div id="error">
- <div class="contents"></div>
- </div>
-
- </div>
- <span id="email"></span>
- <span id="cannotconfirm" class="error">Cannot confirm</span>
- <span id="cannotcommunicate" class="error">Cannot communicate</span>
- <span id="siteinfo" class="error"><span class="website"></span></span>
- <span class=".hint">Hint</span>
- </div>
- <ol id="qunit-tests"></ol>
- <div id="qunit-test-area"></div>
- </body>
-</html>
View
117 browserid/static/dialog/resources/error-messages.js
@@ -1,117 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla BrowserID.
- *
- * The Initial Developer of the Original Code is Mozilla.
- * Portions created by the Initial Developer are Copyright (C) 2011
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-BrowserID.Errors = (function(){
- "use strict";
-
- var Errors = {
- authenticate: {
- type: "serverError",
- title: "Error Authenticating",
- message: "There was a technical problem while trying to log you in. Yucky!"
- },
-
- addEmail: {
- type: "serverError",
- title: "Error Adding Address",
- message: "There was a technical problem while trying to add this email to your account. Yucky!"
- },
-
- checkAuthentication: {
- type: "serverError",
- title: "Error Checking Authentication",
- message: "There was a technical problem while trying to log you in. Yucky!"
- },
-
- createUser: {
- type: "serverError",
- title: "Error Creating Account",
- message: "There was a technical problem while trying to create your account. Yucky!"
- },
-
- getAssertion: {
- type: "serverError",
- title: "Error Getting Assertion",
- message: "There was a technical problem while trying to authenticate you. Yucky!"
- },
-
- isEmailRegistered: {
- type: "serverError",
- title: "Error Checking Email Address",
- message: "There was a technical problem while trying to check that email address. Yucky!"
- },
-
- logoutUser: {
- type: "serverError",
- title: "Logout Failed",
- message: "An error was encountered while signing you out. Yucky!"
- },
-
- offline: {
- type: "networkError",
- title: "You are offline!",
- message: "Unfortunately, BrowserID cannot communicate while offline!"
- },
-
- registration: {
- type: "serverError",
- title: "Registration Failed",
- message: "An error was encountered and the signup cannot be completed. Yucky!"
- },
-
- requestPasswordReset: {
- type: "serverError",
- title: "Error Resetting Password",
- message: "There was a technical problem while trying to reset your password."
- },
-
- signIn: {
- type: "serverError",
- title: "Signin Failed",
- message: "There was an error signing in. Yucky!"
- },
-
- syncAddress: {
- type: "serverError",
- title: "Error Syncing Address",
- message: "There was a technical problem while trying to synchronize your account. Yucky!"
- }
-
- };
-
-
- return Errors;
-}());
-
-
View
21 browserid/static/dialog/test/qunit/qunit.js
@@ -1,21 +0,0 @@
-steal("/dialog/resources/browserid.js",
- "/dialog/resources/storage.js",
- "/dialog/resources/tooltip.js",
- "/dialog/resources/validation.js",
- "/dialog/resources/underscore-min.js")
- .plugins(
- "jquery",
- "jquery/controller",
- "jquery/controller/subscribe",
- "jquery/controller/view",
- "jquery/view/ejs",
- "funcunit/qunit")
- .views('testBodyTemplate.ejs')
- .views('wait.ejs')
- .then("browserid_unit_test")
- .then("pages/add_email_address_test")
- .then("controllers/page_controller_unit_test")
- .then("resources/validation_unit_test")
- .then("resources/storage_unit_test")
- .then("resources/network_unit_test")
- .then("resources/user_unit_test")
View
54 browserid/static/dialog/views/authenticate.ejs
@@ -1,54 +0,0 @@
- <strong>Sign in using</strong>
- <ul class="inputs">
-
- <li>
- <label for="email" class="serif">Email</label>
- <input id="email" class="sans" type="email" autocapitalize="off" autocorrect="off" value="<%= email %>" />
-
- <div id="email_format" class="tooltip" for="email">
- This field must be an email address.
- </div>
-
- <div id="email_required" class="tooltip" for="email">
- The email field is required.
- </div>
- </li>
-
- <li id="hint_section" class="start">
- <p>Enter your email address to sign in to <strong><%= sitename %></strong></p>
- </li>
-
- <li id="create_text_section" class="newuser">
- <p><strong>Welcome to BrowserID!</strong></p>
- <p>This email looks new, so let's get you set up.</p>
- </li>
-
- <li id="password_section" class="returning">
-
- <label for="password" class="half serif">Password</label>
- <div class="half right">
- <a id="forgotPassword" href="#">forgot your password?</a>
- </div>
- <input id="password" class="sans" type="password" maxlength="80">
-
-
- <div id="password_required" class="tooltip" for="password">
- The password field is required.
- </div>
-
- <div id="cannot_authenticate" class="tooltip" for="password">
- The account cannot be logged in with this username and password.
- </div>
- </li>
-
- </ul>
-
- <div class="submit cf">
- <button class="start">next</button>
- <button class="newuser">Verify Email</button>
-
- <button class="returning">sign in</button>
-
- <button class="forgot">Reset Password</button>
- <button id="cancel_forgot_password" class="forgot">Cancel</button>
- </div>
View
0 browserid/static/ping.txt
No changes.
View
134 browserid/tests/lib/start-stop.js
@@ -1,134 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla BrowserID.
- *
- * The Initial Developer of the Original Code is Mozilla.
- * Portions created by the Initial Developer are Copyright (C) 2011
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-const assert = require('assert'),
- fs = require('fs'),
- path = require('path'),
- wsapi = require('./wsapi.js');
-
-const varPath = path.join(path.dirname(path.dirname(__dirname)), "var");
-
-function removeVarDir() {
- try {
- fs.readdirSync(varPath).forEach(function(f) {
- fs.unlinkSync(path.join(varPath, f));
- });
- fs.rmdirSync(varPath);
- } catch(e) {}
-}
-
-exports.addStartupBatches = function(suite) {
- suite.addBatch({
- "remove the user database": {
- topic: function() {
- removeVarDir();
- fs.mkdirSync(varPath, 0755);
- return true;
- },
- "directory should exist": function(x) {
- assert.ok(fs.statSync(varPath).isDirectory());
- }
- }
- });
-
- suite.addBatch({
- "run the server": {
- topic: function() {
- const server = require("../../run.js");
- server.runServer();
- return true;
- },
- "server should be running": {
- topic: wsapi.get('/ping.txt'),
- "server is running": function (r, err) {
- assert.equal(r.code, 200);
- }
- }
- }
- });
-
- suite.addBatch({
- "wait for readiness": {
- topic: function() {
- var cb = this.callback;
- require("../../lib/db.js").onReady(function() { cb(true) });
- },
- "readiness has arrived": function(v) {
- assert.ok(v);
- }
- }
- });
-};
-
-exports.addShutdownBatches = function(suite) {
- // stop the server
- suite.addBatch({
- "stop the server": {
- topic: function() {
- const server = require("../../run.js");
- var cb = this.callback;
- server.stopServer(function() { cb(true); });
- },
- "stopped": function(x) {
- assert.strictEqual(x, true);
- }
- }
- });
-
- // stop the database
- suite.addBatch({
- "stop the database": {
- topic: function() {
- require("../../lib/db.js").close(this.callback);
- },
- "stopped": function(x) {
- assert.isUndefined(x);
- }
- }
- });
-
- // clean up
- suite.addBatch({
- "clean up": {
- topic: function() {
- removeVarDir();
- return true;
- },
- "directory should not exist": function(x) {
- assert.throws(function(){ fs.statSync(varPath) });
- }
- }
- });
-}
View
40 browserid/views/index.ejs
@@ -1,40 +0,0 @@
- <div id="content" style="display:none;">
- <div id="manage">
- <h1 class="serif">Account Manager</h1>
- <div class="edit cf">
- <strong>Your Email Addresses</strong>
-
- <a id="manageAccounts" href="#">edit</a>
- <a id="cancelManage" href="#">done</a>
- </div>
- <ul id="emailList">
- </ul>
- <div id="disclaimer">You may, at any time, <a href="#" id="cancelAccount">cancel your account</a></div>
- </div>
- </div>
-
- <div id="vAlign" style="display:none;">
- <div id="signUp">
- <div id="card"><img src="/i/slit.png"></div>
- <div id="hint"></div>
- <div id="status"></div>
-
- <p>Connect with <em>BrowserID</em>, the safest &amp; easiest way to sign in.</p>
- <p>
- <a class="granted info" href="/about">Take the tour</a> or
- <a href="/signup" class="button granted create">sign up</a>
- </p>
- </div>
- </div>
-
-<script type="text/html" id="templateUser">
- <li class="identity cf">
- <div class="email">{{ email }}</div>
- <div class="activity cf">
- <button class="delete">remove</button>
- <!-- removed registration info. We want to replace this with Last Used At ... -->
- <!-- <abbr title="Registered: {{ created }}" class="status">Registered {{ relative }}.</abbr>-->
- </div>
- </li>
-</script>
-
View
14 DEPLOYMENT.md → docs/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/*
<pre>
#!/bin/bash
-/usr/local/bin/node $1 > $(dirname $1)/error.log 2>&1 &
+/usr/local/bin/node $1 > $(dirname $1)/error.log 2>&1 &
</pre>
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
</pre>
@@ -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
</pre>
View
0 performance/README.md → docs/LOAD_GENERATION.md
File renamed without changes.
View
0 ORGANIZATION.md → docs/ORGANIZATION.md
File renamed without changes.
View
0 rp/index.html → example/index.html
File renamed without changes.
View
0 rp/jquery-min.js → example/jquery-min.js
File renamed without changes.
View
11 browserid/lib/ca.js → lib/browserid/ca.js
@@ -39,8 +39,7 @@
var jwcert = require('jwcrypto/jwcert'),
jwk = require('jwcrypto/jwk'),
jws = require('jwcrypto/jws'),
- configuration = require('../../libs/configuration'),
- secrets = require('../../libs/secrets'),
+ configuration = require('configuration'),
path = require("path"),
fs = require("fs");
@@ -59,7 +58,7 @@ function parseCert(serializedCert) {
function certify(email, publicKey, expiration) {
if (expiration == null)
throw "expiration cannot be null";
- return new jwcert.JWCert(HOSTNAME, expiration, publicKey, {email: email}).sign(secrets.SECRET_KEY);
+ return new jwcert.JWCert(HOSTNAME, expiration, publicKey, {email: email}).sign(configuration.get('secret_key'));
}
function verifyChain(certChain, cb) {
@@ -70,8 +69,8 @@ function verifyChain(certChain, cb) {
// for now we only do browserid.org issued keys
if (issuer != HOSTNAME)
return next(null);
-
- next(secrets.PUBLIC_KEY);
+
+ next(exports.PUBLIC_KEY);
}, cb);
}
@@ -80,4 +79,4 @@ exports.certify = certify;
exports.verifyChain = verifyChain;
exports.parsePublicKey = parsePublicKey;
exports.parseCert = parseCert;
-exports.PUBLIC_KEY = secrets.PUBLIC_KEY;
+exports.PUBLIC_KEY = configuration.get('public_key');
View
6 browserid/lib/email.js → lib/browserid/email.js
@@ -34,13 +34,13 @@
* ***** END LICENSE BLOCK ***** */
const
-db = require('./db'),
+db = require('db.js'),
emailer = require('nodemailer'),
fs = require('fs'),
path = require('path'),
mustache = require('mustache'),
-config = require('../../libs/configuration.js'),
-logger = require('../../libs/logging.js').logger;
+config = require('configuration.js'),
+logger = require('logging.js').logger;
/* if smtp parameters are configured, use them */
var smtp_params = config.get('smtp');
View
0 browserid/lib/fake_verification.js → lib/browserid/fake_verification.js
File renamed without changes.
View
49 lib/browserid/http_forward.js
@@ -0,0 +1,49 @@
+const
+url = require('url'),
+http = require('http'),
+https = require('https'),
+logger = require('logging.js').logger,
+querystring = require('querystring');
+
+module.exports = function(dest, req, res, cb) {
+ var u = url.parse(dest.toString());
+
+ var m = u.protocol === 'http:' ? http : https;
+
+ var preq = m.request({
+ host: u.hostname,
+ port: u.port,
+ path: u.pathname,
+ method: req.method
+ }, function(pres) {
+ res.writeHead(
+ pres.statusCode,
+ pres.headers
+ );
+ pres.on('data', function (chunk) {
+ res.write(chunk);
+ }).on('end', function() {
+ res.end();
+ cb();
+ });
+ }).on('error', function(e) {
+ res.end();
+ cb(e);
+ });
+
+ if (req.headers['content-type']) {
+ preq.setHeader('content-type', req.headers['content-type']);
+ }
+
+ // if the body has already been parsed, we'll write it
+ if (req.body) {
+ var data = querystring.stringify(req.body);
+ preq.setHeader('content-length', data.length);
+ preq.write(data);
+ preq.end();
+ } else {
+ req.on('data', function(chunk) { preq.write(chunk) })
+ .on('end', function() { preq.end() });
+ }
+ logger.info("forwarding request: " + req.url + " -> " + dest);
+};
View
0 browserid/lib/prove_template.txt → lib/browserid/prove_template.txt
File renamed without changes.
View
164 browserid/lib/wsapi.js → lib/browserid/wsapi.js
@@ -39,38 +39,17 @@
// with HTTP methods and the like, apply middleware, etc.
const
-db = require('./db.js'),
+db = require('db.js'),
url = require('url'),
-httputils = require('./httputils.js'),
+httputils = require('httputils.js'),
email = require('./email.js'),
bcrypt