diff --git a/pages/api/submit-vote.ts b/pages/api/submit-vote.ts
index 92d4ca6f..467d8d1e 100644
--- a/pages/api/submit-vote.ts
+++ b/pages/api/submit-vote.ts
@@ -9,7 +9,10 @@ import { validateAuthToken } from './check-auth-token'
import { pusher } from './pusher'
export default async (req: NextApiRequest, res: NextApiResponse) => {
- const { auth, election_id, encrypted_vote } = req.body
+ const payload = req.method === 'POST' ? req.body : req.query
+ const { auth, election_id, encrypted_vote } = payload
+
+ // return res.status(200).json({ auth, election_id, encrypted_vote })
const electionDoc = firebase.firestore().collection('elections').doc(election_id)
diff --git a/src/vote/AirGappedSubmission.tsx b/src/vote/AirGappedSubmission.tsx
index bd74b02d..d5da0a35 100644
--- a/src/vote/AirGappedSubmission.tsx
+++ b/src/vote/AirGappedSubmission.tsx
@@ -1,3 +1,4 @@
+import { useRouter } from 'next/router'
import { useEffect, useState } from 'react'
import { DetailedEncryptionReceipt } from './submitted/DetailedEncryptionReceipt'
@@ -13,7 +14,9 @@ export const AirGappedSubmission = ({
state: State
}) => {
const [isOffline, setIsOffline] = useState(false)
+ const path = useRouter().asPath
+ // Show when going offline
useEffect(() => {
const setOnline = () => setIsOffline(false)
const setOffline = () => setIsOffline(true)
@@ -27,7 +30,12 @@ export const AirGappedSubmission = ({
}
}, [])
- if (!isOffline) return null
+ // Or include "offline" in path (e.g /vote?auth=foo&offline) to show even if online
+ if (!(isOffline || path.includes('offline'))) return null
+
+ const submission_url = `/api/submit-vote?auth=${auth}&election_id=${election_id}&encrypted_vote=${JSON.stringify(
+ sortedKeys(state.encrypted),
+ )}`
return (
@@ -37,18 +45,18 @@ export const AirGappedSubmission = ({
You can submit your vote via an air-gapped submission. If you do this from a Private Incognito window, it
ensures even this webapp cannot possibly extract your private vote selections.
- When you{"'"}re done making your vote selections...
+ 1. When you{"'"}re done making your vote selections...
- 1. Copy and Paste the following
Detailed Encryption Receipt somewhere safe for your own private records:
+ Copy and Paste the following
Detailed Encryption Receipt somewhere safe for your own private records:
-
Verifying your Vote
- 2. The easiest way to quickly verify your vote was counted correctly is your
Verification #.
+
2. Verifying your Vote
+ The easiest way to quickly verify your vote was counted correctly is your
Verification #.
This unique secret number is generated randomly on your own device. No one else can know it.
@@ -64,6 +72,47 @@ export const AirGappedSubmission = ({
for quicker access.
+
+
+
3. Submitting your Vote
+ Lastly, now that your private verification information is backed up, you are ready to submit your encrypted
+ vote.
+
Your full encrypted vote is:
+
+ {JSON.stringify(sortedKeys(state.encrypted), null, 2)}
+
+
+ You can submit this encrypted payload by visiting this Submission URL, once
+ you turn your internet back on:
+
+
+
+
+ Once you{"'"}ve copied down your private data and Submission URL, you can close this window, turn your
+ internet back on, and visit your submission URL.
+
+
)
}
+
+function sortedKeys(obj: unknown): string {
+ const sortedObj = JSON.parse(
+ JSON.stringify(obj, (key, value) =>
+ value instanceof Object && !(value instanceof Array)
+ ? Object.keys(value)
+ .sort()
+ .reduce((sorted, key) => {
+ sorted[key] = value[key]
+ return sorted
+ }, {} as Record)
+ : value,
+ ),
+ )
+ return sortedObj
+}