Skip to content
Snippets Groups Projects
Commit f0ce85b7 authored by Michael Toomim's avatar Michael Toomim
Browse files

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.
parent 67d04d22
Branches
Tags
No related merge requests found
...@@ -26,6 +26,8 @@ ...@@ -26,6 +26,8 @@
You can start the voting process over again, of course.</span> You can start the voting process over again, of course.</span>
</p> </p>
<script>$('#cast_confirm_form').submit()</script>
</div> </div>
{% else %} {% else %}
<p style="font-size:1.4em;"> <p style="font-size:1.4em;">
......
...@@ -34,13 +34,7 @@ window.onbeforeunload = function(evt) { ...@@ -34,13 +34,7 @@ window.onbeforeunload = function(evt) {
}; };
</script> </script>
<h1>{{election.name}} &mdash; Submit your Vote</h1> <p style="margin-top: 10px">Submitting your vote for <b>{{election.name}}</b>...</p>
<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>
<div id="waiting_div"> <div id="waiting_div">
Verifying and Casting your ballot<br /> Verifying and Casting your ballot<br />
...@@ -57,6 +51,7 @@ Your smart ballot tracker is:<br /><br /> ...@@ -57,6 +51,7 @@ Your smart ballot tracker is:<br /><br />
{% if show_password %} {% if show_password %}
{% if user %} {% if user %}
<h1>Wait!</h1>
<p> <p>
You are logged in as <u>{{user.display_html_small|safe}}</u>, but this election<br /> You are logged in as <u>{{user.display_html_small|safe}}</u>, but this election<br />
requires election-specific credentials. requires election-specific credentials.
...@@ -69,19 +64,20 @@ requires election-specific credentials. ...@@ -69,19 +64,20 @@ requires election-specific credentials.
{% else %} {% else %}
{% if user %} {% if user %}
<p> <h1>Sorry!<h1>
<b>Sorry, you are <em>
{% if election.openreg %} {% if election.openreg %}
<b>Sorry, you are <em><u>not eligible</u></em> for this election.</b><br /> <u>not eligible</u></em> for this election.
{% else %} {% else %}
<b>Sorry, you are <em>not registered</em> for this election, and registration is closed.</b><br /> not registered</em> for this election, and registration is closed.
{% endif %} {% endif %}
</p> </b><br /></p>
<p> <p>
[<a href="{% url helios.views.one_election_view election.uuid %}">return to the main election page</a>] [<a href="{% url helios.views.one_election_view election.uuid %}">return to the main election page</a>]
</p> </p>
{% else %} {% else %}
<p> <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.openreg %}
{% if election.eligibility %} {% if election.eligibility %}
...@@ -102,7 +98,10 @@ Don't worry, we'll remember your ballot while you log in. ...@@ -102,7 +98,10 @@ Don't worry, we'll remember your ballot while you log in.
{% endif %} {% endif %}
{% 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 #} {# this closes the IF ELSE of this being password_only #}
{% endif %} {% endif %}
......
...@@ -25,7 +25,7 @@ you can post this audited ballot to the Helios tracking center so that others mi ...@@ -25,7 +25,7 @@ you can post this audited ballot to the Helios tracking center so that others mi
<br /><br /> <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> <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 /> <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; &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;"/> <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;"/>
......
<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>
...@@ -15,22 +15,34 @@ You will then be guided to re-encrypt your choices for final casting. ...@@ -15,22 +15,34 @@ You will then be guided to re-encrypt your choices for final casting.
</div> </div>
{#/if} {#/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> <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> <div id="loading_div"><img src="loading.gif" id="proceed_loading_img" /></div>
......
...@@ -48,7 +48,6 @@ BOOTH.setup_templates = function() { ...@@ -48,7 +48,6 @@ BOOTH.setup_templates = function() {
$('#header').setTemplateURL("templates/header.html" + cache_bust); $('#header').setTemplateURL("templates/header.html" + cache_bust);
$('#election_div').setTemplateURL("templates/election.html" + cache_bust); $('#election_div').setTemplateURL("templates/election.html" + cache_bust);
$('#question_div').setTemplateURL("templates/question.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); $('#seal_div').setTemplateURL("templates/seal.html" + cache_bust);
$('#audit_div').setTemplateURL("templates/audit.html" + cache_bust); $('#audit_div').setTemplateURL("templates/audit.html" + cache_bust);
$('#footer').setTemplateURL("templates/footer.html" + cache_bust); $('#footer').setTemplateURL("templates/footer.html" + cache_bust);
...@@ -245,7 +244,7 @@ BOOTH.validate_question = function(question_num) { ...@@ -245,7 +244,7 @@ BOOTH.validate_question = function(question_num) {
BOOTH.validate_and_confirm = function(question_num) { BOOTH.validate_and_confirm = function(question_num) {
if (BOOTH.validate_question(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) { ...@@ -360,7 +359,7 @@ BOOTH.show_processing_before = function(str_to_execute) {
}; };
BOOTH.show_encryption_message_before = function(func_to_execute) { BOOTH.show_encryption_message_before = function(func_to_execute) {
BOOTH.show_progress('3'); BOOTH.show_progress('2');
BOOTH.show($('#encrypting_div')); BOOTH.show($('#encrypting_div'));
func_to_execute(); func_to_execute();
...@@ -442,13 +441,6 @@ $(document).ready(function() { ...@@ -442,13 +441,6 @@ $(document).ready(function() {
BigInt.setup(BOOTH.so_lets_go, BOOTH.nojava); 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() { BOOTH.check_encryption_status = function() {
var progress = BOOTH.progress.progress(); var progress = BOOTH.progress.progress();
...@@ -474,7 +466,9 @@ BOOTH._after_ballot_encryption = function() { ...@@ -474,7 +466,9 @@ BOOTH._after_ballot_encryption = function() {
'election_uuid' : BOOTH.election.uuid, 'election_uuid' : BOOTH.election.uuid,
'election_hash' : BOOTH.election_hash, 'election_hash' : BOOTH.election_hash,
'election': BOOTH.election, '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.show($('#seal_div'));
BOOTH.encrypted_vote_json = null; BOOTH.encrypted_vote_json = null;
}; };
...@@ -623,9 +617,6 @@ BOOTH.do_done = function() { ...@@ -623,9 +617,6 @@ BOOTH.do_done = function() {
<div id="question_div" class="panel"> <div id="question_div" class="panel">
</div> </div>
<div id="confirm_div" class="panel">
</div>
<div id="processing_div" class="panel" style="display:none;"> <div id="processing_div" class="panel" style="display:none;">
<h3 align="center">Processing....</h3> <h3 align="center">Processing....</h3>
</div> </div>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment