diff --git a/.babelrc b/.babelrc new file mode 100644 index 0000000..526ddfd --- /dev/null +++ b/.babelrc @@ -0,0 +1,3 @@ +{ + "presets": ["@babel/preset-env"] +} diff --git a/.gitignore b/.gitignore index 5640075..051e362 100644 --- a/.gitignore +++ b/.gitignore @@ -2,9 +2,10 @@ /.python-version /htmlcov /venv -__javascript__ +__target__ __pycache__ refs +node_modules \#* .#* diff --git a/build_js.sh b/build_js.sh index 1ae8da9..ff0e2a9 100755 --- a/build_js.sh +++ b/build_js.sh @@ -1,6 +1,6 @@ #!/bin/bash # Eos - Verifiable elections -# Copyright © 2017 RunasSudo (Yingtong Li) +# Copyright © 2017-2019 RunasSudo (Yingtong Li) # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as published by @@ -20,21 +20,14 @@ FLAGS="-k -mc -o" #for f in eos.js eos.js_tests; do for f in eos.js_tests; do transcrypt -b -n $FLAGS $f.py || exit 1 - - # Javascript identifiers cannot contain dots - perl -0777 -pi -e 's/eos.js/eosjs/g' eos/__javascript__/$f.js - - # __pragma__ sometimes stops working??? - perl -0777 -pi -e "s/__pragma__ \('.*?'\)//gs" eos/__javascript__/$f.js - - # Transcrypt by default suppresses stack traces for some reason?? - perl -0777 -pi -e 's/__except0__.__cause__ = null;//g' eos/__javascript__/$f.js - - # Fix handling of properties, Transcrypt bug #407 - perl -0777 -pi -e 's/var __get__ = function \(self, func, quotedFuncName\) \{/var __get__ = function (self, func, quotedFuncName) { if(typeof(func) != "function"){return func;}/g' eos/__javascript__/$f.js - perl -0777 -pi -e 's/property.call \((.*?), \g1.\g1.__impl__(.*?)\)/property.call ($1, $1.__impl__$2)/g' eos/__javascript__/$f.js - perl -0777 -pi -e 's/property.call \((.*?), \g1.\g1.__implpy_(.*?)\)/property.call ($1, $1.__impl__$2)/g' eos/__javascript__/$f.js done -cp eos/__javascript__/eos.js_tests.js eosweb/core/static/js/eosjs.js -perl -0777 -pi -e 's/eosjs_tests/eosjs/g' eosweb/core/static/js/eosjs.js +# Transcrypt syntax errors +perl -0777 -pi -e 's/import \{, /import \{/g' __target__/eos*.js + +# Add export +echo >> __target__/eos.js_tests.js +echo 'export {eos, __kwargtrans__};' >> __target__/eos.js_tests.js + +# Convert to ES5 +./node_modules/.bin/browserify -t babelify -r ./__target__/eos.js_tests.js:eosjs > eosweb/core/static/js/eosjs.js diff --git a/eos/core/objects/__init__.py b/eos/core/objects/__init__.py index e91c506..b819a43 100644 --- a/eos/core/objects/__init__.py +++ b/eos/core/objects/__init__.py @@ -1,5 +1,5 @@ # Eos - Verifiable elections -# Copyright © 2017 RunasSudo (Yingtong Li) +# Copyright © 2017-2019 RunasSudo (Yingtong Li) # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as published by @@ -184,18 +184,21 @@ class RelatedObjectListField(Field): return None return EosList([EosObject.deserialise_and_unwrap(x, self.object_type) for x in value]) -if is_python: - class UUIDField(Field): - def __init__(self, *args, **kwargs): +class UUIDField(Field): + def __init__(self, *args, **kwargs): + if is_python: super().__init__(default=uuid.uuid4, *args, **kwargs) - - def serialise(self, value, options=SerialiseOptions.DEFAULT): - return str(value) - - def deserialise(self, value): + else: + super().__init__(*args, **kwargs) + + def serialise(self, value, options=SerialiseOptions.DEFAULT): + return str(value) + + def deserialise(self, value): + if is_python: return uuid.UUID(value) -else: - UUIDField = PrimitiveField + else: + return value class DateTimeField(Field): def pad(self, number): @@ -359,7 +362,16 @@ class DocumentObjectType(EosObjectType): fields = {} if hasattr(cls, '_fields'): fields = cls._fields.copy() if is_python else Object.create(cls._fields) - for attr in list(dir(cls)): + + if is_python: + attrs = list(dir(cls)) + else: + # We want the raw Javascript name for getOwnPropertyDescriptor + __pragma__('jsiter') + attrs = [x for x in cls] + __pragma__('nojsiter') + + for attr in attrs: if not is_python: # We must skip things with getters or else they will be called here (too soon) if Object.getOwnPropertyDescriptor(cls, attr).js_get: diff --git a/eos/js_tests.py b/eos/js_tests.py index 8ebd141..f331784 100644 --- a/eos/js_tests.py +++ b/eos/js_tests.py @@ -1,5 +1,5 @@ # Eos - Verifiable elections -# Copyright © 2017 RunasSudo (Yingtong Li) +# Copyright © 2017-2019 RunasSudo (Yingtong Li) # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as published by @@ -14,8 +14,23 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . -import eos.js - +import eos.core.objects +import eos.core.bigint +import eos.core.hashing import eos.core.tests +import eos.core.tasks +import eos.core.tasks.direct + +import eos.base.election +import eos.base.workflow + +import eos.psr.bitstream +import eos.psr.crypto +import eos.psr.election +import eos.psr.mixnet +import eos.psr.workflow + +import eos.redditauth.election + import eos.base.tests import eos.psr.tests diff --git a/eosweb/core/static/js/booth_worker.js b/eosweb/core/static/js/booth_worker.js index fd166e5..1d505b9 100644 --- a/eosweb/core/static/js/booth_worker.js +++ b/eosweb/core/static/js/booth_worker.js @@ -1,6 +1,6 @@ /* Eos - Verifiable elections - Copyright © 2017 RunasSudo (Yingtong Li) + Copyright © 2017-2019 RunasSudo (Yingtong Li) This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by @@ -19,13 +19,15 @@ window = self; // Workaround for libraries isLibrariesLoaded = false; +eosjs = null; + function generateEncryptedVote(election, answers, should_do_fingerprint) { encrypted_answers = []; for (var q_num = 0; q_num < answers.length; q_num++) { answer_json = answers[q_num]; - answer = eosjs.eos.core.objects.__all__.EosObject.deserialise_and_unwrap(answer_json, null); - encrypted_answer = eosjs.eos.psr.election.__all__.BlockEncryptedAnswer.encrypt(election.public_key, answer, election.questions.__getitem__(q_num).max_bits() + 32); // +32 bits for the length - encrypted_answers.push(eosjs.eos.core.objects.__all__.EosObject.serialise_and_wrap(encrypted_answer, null)); + answer = eosjs.eos.core.objects.EosObject.deserialise_and_unwrap(answer_json, null); + encrypted_answer = eosjs.eos.psr.election.BlockEncryptedAnswer.encrypt(election.public_key, answer, election.questions.__getitem__(q_num).max_bits() + 32); // +32 bits for the length + encrypted_answers.push(eosjs.eos.core.objects.EosObject.serialise_and_wrap(encrypted_answer, null)); } postMessage({ @@ -40,10 +42,11 @@ onmessage = function(msg) { msg.data.static_base_url + "js/eosjs.js" ); isLibrariesLoaded = true; + eosjs = require("eosjs"); } if (msg.data.action === "generateEncryptedVote") { - msg.data.election = eosjs.eos.core.objects.__all__.EosObject.deserialise_and_unwrap(msg.data.election, null); + msg.data.election = eosjs.eos.core.objects.EosObject.deserialise_and_unwrap(msg.data.election, null); generateEncryptedVote(msg.data.election, msg.data.answers); } else { diff --git a/eosweb/core/static/nunjucks/booth/audit.html b/eosweb/core/static/nunjucks/booth/audit.html index 4b0e68e..117cb5a 100644 --- a/eosweb/core/static/nunjucks/booth/audit.html +++ b/eosweb/core/static/nunjucks/booth/audit.html @@ -2,7 +2,7 @@ {# Eos - Verifiable elections - Copyright © 2017-18 RunasSudo (Yingtong Li) + Copyright © 2017-2019 RunasSudo (Yingtong Li) This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by @@ -25,7 +25,7 @@

Your vote has not yet been cast. Please follow the instructions to continue.

-

The following is your ballot with fingerprint {{ eosjs.eos.core.hashing.__all__.SHA256().update_obj(ballot).hash_as_b64() }}, decrypted and ready for auditing.

+

The following is your ballot with fingerprint {{ eosjs.eos.core.hashing.SHA256().update_obj(ballot).hash_as_b64() }}, decrypted and ready for auditing.

{# For some reason nunjucks doesn't like calling this the normal way #} diff --git a/eosweb/core/static/nunjucks/booth/base.html b/eosweb/core/static/nunjucks/booth/base.html index fadd25a..d9b3897 100644 --- a/eosweb/core/static/nunjucks/booth/base.html +++ b/eosweb/core/static/nunjucks/booth/base.html @@ -1,6 +1,6 @@ {# Eos - Verifiable elections - Copyright © 2017-18 RunasSudo (Yingtong Li) + Copyright © 2017-2019 RunasSudo (Yingtong Li) This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by @@ -18,7 +18,7 @@

{{ election.name }}

-

{{ election.kind|title }} fingerprint: {{ eosjs.eos.core.hashing.__all__.SHA256().update_obj(election).hash_as_b64() }}

+

{{ election.kind|title }} fingerprint: {{ eosjs.eos.core.hashing.SHA256().update_obj(election).hash_as_b64() }}

{# Convert the template name to a numerical index for comparison #} {% if template == 'booth/welcome.html' %} diff --git a/eosweb/core/static/nunjucks/booth/cast.html b/eosweb/core/static/nunjucks/booth/cast.html index 1a00120..9a78604 100644 --- a/eosweb/core/static/nunjucks/booth/cast.html +++ b/eosweb/core/static/nunjucks/booth/cast.html @@ -2,7 +2,7 @@ {# Eos - Verifiable elections - Copyright © 2017-18 RunasSudo (Yingtong Li) + Copyright © 2017-2019 RunasSudo (Yingtong Li) This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by @@ -20,7 +20,7 @@ {% block content %}
-

Your vote has not yet been cast. Please make a note of your ballot fingerprint, {{ eosjs.eos.core.hashing.__all__.SHA256().update_obj(ballot).hash_as_b64(true) }}.

+

Your vote has not yet been cast. Please make a note of your ballot fingerprint, {{ eosjs.eos.core.hashing.SHA256().update_obj(ballot).hash_as_b64(true) }}.

Your vote has not yet been cast. Please follow the instructions to continue.

@@ -71,7 +71,7 @@ {% block after %}
Information for advanced users
-

Your full ballot fingerprint is {{ eosjs.eos.core.hashing.__all__.SHA256().update_obj(ballot).hash_as_b64() }}.

+

Your full ballot fingerprint is {{ eosjs.eos.core.hashing.SHA256().update_obj(ballot).hash_as_b64() }}.