-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathwrite.html
More file actions
145 lines (135 loc) · 5.51 KB
/
write.html
File metadata and controls
145 lines (135 loc) · 5.51 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
<head>
<link rel="stylesheet" type="text/css" href="stylesheets/shared_style.css">
</head>
<body>
<div class="container">
<form id="make-ballot" action="javascript:createBallot()">
<input id="candidateAdd" class="btn" type="button" value="Add Candidate (+)"><br>
<div id="TextBoxContainer">
<!-- At least two candidates are required on a ballot -->
<input required id="candidate" name = "candidateTextBox" type="text"/><br>
<input required id="candidate" name = "candidateTextBox" type="text"/>
<!--Textboxes will be added here -->
</div>
<div class="radioButton-wrap">
<input required type="radio" name="ballotType" id="fptp" value="First Past the Post">
<label for="fptp" class="radio-label">First Past the Post</label><br>
<input required type="radio" name="ballotType" id="ranked-choice" value="Ranked Choice">
<label for="ranked-choice" class="radio-label">Ranked Choice</label><br>
<input required type="radio" name="ballotType" id="approval" value="Approval Voting">
<label for="approval" class="radio-label">Approval Voting</label><br>
</div>
<button class="btn" type="submit">Make ballot!</button>
</form>
</div> <!-- container -->
<!-- The core Firebase JS SDK is always required and must be listed first -->
<script src="https://www.gstatic.com/firebasejs/7.9.3/firebase-app.js"></script>
<!-- TODO: Add SDKs for Firebase products that you want to use
https://firebase.google.com/docs/web/setup#available-libraries -->
<script src="https://www.gstatic.com/firebasejs/7.9.3/firebase-database.js"></script>
<!-- JQuery -->
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script>
// Your web app's Firebase configuration
var firebaseConfig = {
apiKey: "AIzaSyByAyDFaMNDwKpfRhAQPk0B70ILYst-oS4",
authDomain: "ballot-d933a.firebaseapp.com",
databaseURL: "https://ballot-d933a.firebaseio.com",
projectId: "ballot-d933a",
storageBucket: "ballot-d933a.appspot.com",
messagingSenderId: "227086842486",
appId: "1:227086842486:web:849611a5373b9fc0ce7d57",
measurementId: "G-Y8X924EG6M"
};
// Initialize Firebase
firebase.initializeApp(firebaseConfig);
function createBallot(){
var form = document.getElementById('make-ballot');
var ballotType = form.elements.ballotType.value;
var fields = document.querySelectorAll('[id^=candidate]');
var candidates = [];
for(var i=1; i < fields.length; i++){
var sanitizedInput = sanitize(fields[i].value); // prevent injection attack
if(!sanitizedInput || !sanitizedInput.trim()){ // check if sanitized string is empty
alert("All the characters in the candidate name " + fields[i].value +
" are removed to prevent injection attack please add alphanumeric characters");
return
}
candidates.push(sanitizedInput);
}
var token = generate_token(5);
firebaseStore(token, ballotType, candidates);
}
function firebaseStore(token, ballotType, candidates){
var candidateDict = {};
for(var i=0; i < candidates.length; i++){
candidateDict[candidates[i]] = 0
}
firebase.database().ref('ballots/' + token).set({
ballotType: ballotType,
numVotes: 0,
candidateDict: candidateDict,
timeLastUpdated: firebase.database.ServerValue.TIMESTAMP
});
clearBallot('make-ballot');
$(".Container").append(linkToBallot(token));
}
function generate_token(length){
//edit the token allowed characters
var a = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".split("");
var b = [];
for (var i=0; i<length; i++) {
var j = (Math.random() * (a.length-1)).toFixed(0);
b[i] = a[j];
}
return b.join("");
}
$(function () {
$("#candidateAdd").bind("click", function () {
var div = $("<div />");
div.html(GetDynamicTextBox());
$("#TextBoxContainer").append(div);
});
$("body").on("click", ".remove", function () {
$(this).closest("div").remove();
});
});
function GetDynamicTextBox() {
return '<input required id="candidate" name = "DynamicTextBox" type="text" /> ' +
'<input type="button" value="-" class="remove" />'
}
function clearBallot(elementID) {
document.getElementById(elementID).innerHTML = "";
}
function linkToBallot(token){
return '<p>The token is ' + token + '</p>' +
'<p>To vote visit</p>' +
'<a href="/read?token=' + token + '">' +
window.location.hostname + ':' + window.location.port + '/read?token=' + token + '</a>' +
'<form>' +
'<input type="hidden" name="token" value="' + token + '"</input>' +
'<button id="linkToBallot" class="btn" type="submit"' +
'formaction="/results.html?token=">View Results</button>' +
'</form>'
}
function sanitize(inputStr){
// remove . # $ / [ and ] because they cause key errors
// remove \ & < > " ' : ; because they can cause xss vulnerabilities
inputStr = inputStr.replace(/"/g, """);
inputStr = inputStr.replace(/#/g, "&35");
inputStr = inputStr.replace(/\$/g, "&36");
inputStr = inputStr.replace(/&/g, "&");
inputStr = inputStr.replace(/'/g, "&39");
inputStr = inputStr.replace(/\./g, "&46");
inputStr = inputStr.replace(/\//g, "&47");
inputStr = inputStr.replace(/:/g, "&58");
inputStr = inputStr.replace(/;/g, "&59");
inputStr = inputStr.replace(/</g, "<");
inputStr = inputStr.replace(/>/g, ">");
inputStr = inputStr.replace(/\[/g, "&91");
inputStr = inputStr.replace(/\\/g, "&92");
inputStr = inputStr.replace(/\]/g, "&93");
return inputStr
}
</script>
</body>