From f0ce85b7ef39516b6212a55c44c8a331778ec74d Mon Sep 17 00:00:00 2001
From: Michael Toomim <toomim@gmail.com>
Date: Thu, 1 May 2014 04:05:59 +0000
Subject: [PATCH] Simplified the voting process (for Bitcoin Foundation).

This solves the problem where users would erroneously think their
ballot was cast before completing all steps in the process, and makes
the user experience simpler and smoother for all users.

Specifically, this change eliminates one or two steps (depending on
whether the user is logged in), while retaining full functionality:

  - Merges steps 2 and 3 on the client (show_confirm and seal_ballot)
    into a single step 2.

  - Improves the formatting of the confirmed ballot in step 2 to make
    it easier to understand.

  - In the user interface, "step 3" now means the SERVER-SIDE step of
    submitting your ballot to the helios server.  Previously, this
    step was not expressed within the [1,2,3] progress bar in
    helios-booth, which contributed to users thinking they had
    finished voting even though they had not finished this "hidden
    step 4" of submitting to the server.

  - If the user is already logged in when they reach this server-side
    step 3, we now submit the ballot automatically, rather than
    requiring the user to yet-again click "submit the ballot."  We
    only require further action for users who are not logged in.
---
 helios/templates/_castconfirm_docast.html   |  2 +
 helios/templates/election_cast_confirm.html | 43 ++++++++++-----------
 heliosbooth/templates/audit.html            |  2 +-
 heliosbooth/templates/confirm.html          | 20 ----------
 heliosbooth/templates/seal.html             | 30 +++++++++-----
 heliosbooth/vote.html                       | 19 +++------
 6 files changed, 50 insertions(+), 66 deletions(-)
 delete mode 100644 heliosbooth/templates/confirm.html

diff --git a/helios/templates/_castconfirm_docast.html b/helios/templates/_castconfirm_docast.html
index 85896da..ff0424a 100644
--- a/helios/templates/_castconfirm_docast.html
+++ b/helios/templates/_castconfirm_docast.html
@@ -26,6 +26,8 @@
     You can start the voting process over again, of course.</span>
 </p>
 
+<script>$('#cast_confirm_form').submit()</script>
+
 </div>
   {% else %}
 <p style="font-size:1.4em;">
diff --git a/helios/templates/election_cast_confirm.html b/helios/templates/election_cast_confirm.html
index 273a31c..a064941 100644
--- a/helios/templates/election_cast_confirm.html
+++ b/helios/templates/election_cast_confirm.html
@@ -34,13 +34,7 @@ window.onbeforeunload = function(evt) {
 };
 
 </script>
-<h1>{{election.name}} &mdash; Submit your Vote</h1>
-
-<p>
-  We have received, <b><u>but not yet recorded</u></b>, your encrypted ballot.<br />
-Your smart ballot tracker is:<br /><br />
-    <tt style="font-size:1.8em; font-weight: bold; padding-left: 20px;">  {{vote_fingerprint}}</tt>
-</p>
+<p style="margin-top: 10px">Submitting your vote for <b>{{election.name}}</b>...</p>
 
 <div id="waiting_div">
     Verifying and Casting your ballot<br />
@@ -57,6 +51,7 @@ Your smart ballot tracker is:<br /><br />
 
 {% if show_password %}
 {% if user %}
+<h1>Wait!</h1>
 <p>
 You are logged in as <u>{{user.display_html_small|safe}}</u>, but this election<br />
 requires election-specific credentials.
@@ -69,29 +64,30 @@ requires election-specific credentials.
 {% else %}
 
 {% if user %}
-<p>
-{% if election.openreg %}
-<b>Sorry, you are <em><u>not eligible</u></em> for this election.</b><br />
-{% else %}
-<b>Sorry, you are <em>not registered</em> for this election, and registration is closed.</b><br />
-{% endif %}
-</p>
+<h1>Sorry!<h1>
+<b>Sorry, you are <em>
+  {% if election.openreg %}
+    <u>not eligible</u></em> for this election.
+  {% else %}
+    not registered</em> for this election, and registration is closed.
+  {% endif %}
+  </b><br /></p>
 <p>
     [<a href="{% url helios.views.one_election_view election.uuid %}">return to the main election page</a>]
 </p>
 {% else %}
 <p>
-  Now, we need you to log in, so we can verify your eligibility.<br /><br />
+<h1>Wait!  You need to log in.</h1>
 {% if election.openreg %}
 
-{% if election.eligibility %}
-{% else %}
- This election is open to <em>anyone</em>, so log in with your preferred account.
-{% endif %}
+  {% if election.eligibility %}
+  {% else %}
+   This election is open to <em>anyone</em>, so log in with your preferred account.
+  {% endif %}
 
 {% else %}
-This election is only open to <em>registered voters</em>, so log in with
-the same account you registered with.
+  This election is only open to <em>registered voters</em>, so log in with
+  the same account you registered with.
 {% endif %}
 </p>
 
@@ -102,7 +98,10 @@ Don't worry, we'll remember your ballot while you log in.
 {% endif %}
 
 {% endif %}
-
+<br />
+Your smart ballot tracker is:<br /><br />
+    <tt style="font-size:1.3em; font-weight: bold; padding-left: 20px;">  {{vote_fingerprint}}</tt>
+</p>
 {# this closes the IF ELSE of this being password_only #}
 {% endif %}
 
diff --git a/heliosbooth/templates/audit.html b/heliosbooth/templates/audit.html
index 20cd3d4..9165d52 100644
--- a/heliosbooth/templates/audit.html
+++ b/heliosbooth/templates/audit.html
@@ -25,7 +25,7 @@ you can post this audited ballot to the Helios tracking center so that others mi
 <br /><br />
 <b>Even if you post your audited ballot, you must go back to voting and choose "cast" if you want your vote to count.</b>
 <br /><br />
-<input type="button" value="back to voting" onclick="BOOTH.reset_ciphertexts();BOOTH.show_confirm();" class="pretty" />
+<input type="button" value="back to voting" onclick="BOOTH.reset_ciphertexts();BOOTH.seal_ballot();" class="pretty" />
 &nbsp; &nbsp;&nbsp;
 <input type="button" value="post audited ballot to tracking center" onclick="$(this).attr('disabled', 'disabled');BOOTH.post_audited_ballot();" id="post_audited_ballot_button" class="pretty" style="font-size:0.8em;"/>
 
diff --git a/heliosbooth/templates/confirm.html b/heliosbooth/templates/confirm.html
deleted file mode 100644
index e8a1f90..0000000
--- a/heliosbooth/templates/confirm.html
+++ /dev/null
@@ -1,20 +0,0 @@
-
-<h3>Review your Ballot</h3>
-
-{#foreach $T.questions as question}
-<p>
-{$T.question.short_name}<br />
-
-<b style="font-size:1.4em;">{#foreach $T.choices[$T.question$index] as choice}
-{$T.choice}{#if !$T.choice$last}, {#/if}
-{#/for}</b>
-{#if $T.choices[$T.question$index].length < $T.question.max}
-&nbsp;&nbsp;&nbsp;
-[you under-voted: you may select up to {$T.question.max}]
-{#/if}
-&nbsp;&nbsp;&nbsp;
-[<a onclick="BOOTH.show_question({$T.question$index}); return false;" href="#">edit</a>]
-</p>
-{#/for}
-
-<button onclick="BOOTH.seal_ballot();">Confirm Choices and Encrypt Ballot</button>
diff --git a/heliosbooth/templates/seal.html b/heliosbooth/templates/seal.html
index a9d3ecc..a17de4b 100644
--- a/heliosbooth/templates/seal.html
+++ b/heliosbooth/templates/seal.html
@@ -15,22 +15,34 @@ You will then be guided to re-encrypt your choices for final casting.
 </div>
 {#/if}
 
-<h3>Your ballot is ready to be submitted</h3>
+<h3>Review your Ballot</h3>
 
-<p>
-<em>Don't forget to click "Proceed to Submission" below!</em>
-</p>
 
-<p>Before submitting, you can take note of your smart ballot tracker [<a onclick="BOOTH.show_receipt(); return false;" href="#">print</a>]:<br /><br />
+<div style="padding: 10px; margin-bottom: 10px; background-color: #eee; border: 1px #ddd solid; max-width: 340px;">
+{#foreach $T.questions as question}
 
-<b><tt style="font-size: 16pt;">&nbsp;&nbsp;&nbsp;{$T.encrypted_vote_hash}</tt></b><br /><br />
+<b>Question #{$T.question$index + 1}: {$T.question.short_name}</b><br>
+{#if $T.choices[$T.question$index].length == 0}
+<div style="margin-left: 15px;">&#x2610; <i>No choice selected</i></div>
+{#/if}
+{#foreach $T.choices[$T.question$index] as choice}
+<div style="margin-left: 15px;">&#x2713; {$T.choice}</div>
+{#/for}
+{#if $T.choices[$T.question$index].length < $T.question.max}
+[you under-voted: you may select up to {$T.question.max}]
+{#/if}
+[<a onclick="BOOTH.show_question({$T.question$index}); return false;" href="#">edit responses</a>]
+{#if !$T.question$last}<br><br>{#/if}
+{#/for}
+</div>
 
-</p>
+
+<p><p>Your ballot tracker is <b><tt style="font-size: 11pt;">{$T.encrypted_vote_hash}</tt></b>, and you can <a onclick="BOOTH.show_receipt(); return false;" href="#">print</a> it.<br /><br /></p>
 
 <p>
-Once you click "Proceed", Helios will remember only your encrypted vote. Thus, only you know your vote.</p>
+Once you click "Submit", the unencrypted version of your ballot will be destroyed, and only the encrypted version will remain.  The encrypted version will be submitted to the Helios server.</p>
 
-<button id="proceed_button" onclick="BOOTH.cast_ballot();">Proceed to Submission</button><br />
+<button id="proceed_button" onclick="BOOTH.cast_ballot();">Submit this Vote!</button><br />
 <div id="loading_div"><img src="loading.gif" id="proceed_loading_img" /></div>
 
 
diff --git a/heliosbooth/vote.html b/heliosbooth/vote.html
index 3154795..e69a2d9 100644
--- a/heliosbooth/vote.html
+++ b/heliosbooth/vote.html
@@ -48,7 +48,6 @@ BOOTH.setup_templates = function() {
     $('#header').setTemplateURL("templates/header.html" + cache_bust);
     $('#election_div').setTemplateURL("templates/election.html" + cache_bust);
     $('#question_div').setTemplateURL("templates/question.html" + cache_bust);
-    $('#confirm_div').setTemplateURL("templates/confirm.html" + cache_bust);
     $('#seal_div').setTemplateURL("templates/seal.html" + cache_bust);
     $('#audit_div').setTemplateURL("templates/audit.html" + cache_bust);
     $('#footer').setTemplateURL("templates/footer.html" + cache_bust);
@@ -245,7 +244,7 @@ BOOTH.validate_question = function(question_num) {
 
 BOOTH.validate_and_confirm = function(question_num) {
   if (BOOTH.validate_question(question_num)) {
-      BOOTH.show_confirm();
+      BOOTH.seal_ballot();
   }
 };
 
@@ -360,7 +359,7 @@ BOOTH.show_processing_before = function(str_to_execute) {
 };
 
 BOOTH.show_encryption_message_before = function(func_to_execute) {
-    BOOTH.show_progress('3');
+    BOOTH.show_progress('2');
     BOOTH.show($('#encrypting_div'));
 
     func_to_execute();
@@ -442,13 +441,6 @@ $(document).ready(function() {
     BigInt.setup(BOOTH.so_lets_go, BOOTH.nojava);
 });
 
-BOOTH.show_confirm = function() {
-    // process the answers
-    var choices = BALLOT.pretty_choices(BOOTH.election, BOOTH.ballot);
-
-    BOOTH.show($('#confirm_div')).processTemplate({'questions' : BOOTH.election.questions, 'choices' : choices});
-    BOOTH.show_progress('2');
-};
 
 BOOTH.check_encryption_status = function() {
   var progress = BOOTH.progress.progress();
@@ -474,7 +466,9 @@ BOOTH._after_ballot_encryption = function() {
         'election_uuid' : BOOTH.election.uuid,
         'election_hash' : BOOTH.election_hash,
         'election': BOOTH.election,
-        'election_metadata': BOOTH.election_metadata});
+        'election_metadata': BOOTH.election_metadata,
+        'questions' : BOOTH.election.questions,
+        'choices' : BALLOT.pretty_choices(BOOTH.election, BOOTH.ballot)});
       BOOTH.show($('#seal_div'));
       BOOTH.encrypted_vote_json = null;
     };
@@ -623,9 +617,6 @@ BOOTH.do_done = function() {
   <div id="question_div" class="panel">
   </div>
 
-  <div id="confirm_div" class="panel">
-  </div>
-
   <div id="processing_div" class="panel" style="display:none;">
       <h3 align="center">Processing....</h3>
   </div>
-- 
GitLab