diff --git a/.github/workflows/go_dvoting_test.yml b/.github/workflows/go_dvoting_test.yml index f98569577..19acabb77 100644 --- a/.github/workflows/go_dvoting_test.yml +++ b/.github/workflows/go_dvoting_test.yml @@ -12,10 +12,10 @@ jobs: name: Scenario runs-on: ubuntu-latest steps: - - name: Set up Go ^1.17 - uses: actions/setup-go@v2 + - name: Use Go 1.20 + uses: actions/setup-go@v4 with: - go-version: ^1.17 + go-version: '1.20' - name: Install crypto util from Dela run: | diff --git a/.github/workflows/go_integration_tests.yml b/.github/workflows/go_integration_tests.yml index 5b0cfc9dd..07813af07 100644 --- a/.github/workflows/go_integration_tests.yml +++ b/.github/workflows/go_integration_tests.yml @@ -11,10 +11,10 @@ jobs: name: Integration test runs-on: ubuntu-latest steps: - - name: Set up Go ^1.17 - uses: actions/setup-go@v2 + - name: Use Go 1.20 + uses: actions/setup-go@v4 with: - go-version: ^1.17 + go-version: '1.20' - name: Check out code into the Go module directory uses: actions/checkout@v2 @@ -25,10 +25,10 @@ jobs: name: Test bad vote runs-on: ubuntu-latest steps: - - name: Set up Go ^1.17 - uses: actions/setup-go@v2 + - name: Use Go 1.20 + uses: actions/setup-go@v4 with: - go-version: ^1.17 + go-version: '1.20' - name: Check out code into the Go module directory uses: actions/checkout@v2 @@ -39,24 +39,29 @@ jobs: name: Test crash runs-on: ubuntu-latest steps: - - name: Set up Go ^1.17 - uses: actions/setup-go@v2 + - name: Use Go 1.20 + uses: actions/setup-go@v4 with: - go-version: ^1.17 + go-version: '1.20' - name: Check out code into the Go module directory uses: actions/checkout@v2 - name: Run the crash test - run: go test -timeout 10m -run TestCrash ./integration/... + run: | + for a in $( seq 3 ); do + echo "Testing sequence $a" + go test -timeout 10m -run TestCrash ./integration/... && exit 0 + done + exit 1 revote: name: Test revote runs-on: ubuntu-latest steps: - - name: Set up Go ^1.17 - uses: actions/setup-go@v2 + - name: Use Go 1.20 + uses: actions/setup-go@v4 with: - go-version: ^1.17 + go-version: '1.20' - name: Check out code into the Go module directory uses: actions/checkout@v2 diff --git a/.github/workflows/go_scenario_test.yml b/.github/workflows/go_scenario_test.yml index c2e609697..c6f274417 100644 --- a/.github/workflows/go_scenario_test.yml +++ b/.github/workflows/go_scenario_test.yml @@ -11,10 +11,10 @@ jobs: name: Tests runs-on: ubuntu-latest steps: - - name: Set up Go ^1.17 - uses: actions/setup-go@v2 + - name: Use Go 1.20 + uses: actions/setup-go@v4 with: - go-version: ^1.17 + go-version: '1.20' - name: Install crypto util from Dela run: | diff --git a/.github/workflows/go_test.yml b/.github/workflows/go_test.yml index dba5a8188..302364b03 100644 --- a/.github/workflows/go_test.yml +++ b/.github/workflows/go_test.yml @@ -10,10 +10,10 @@ jobs: name: Tests runs-on: ubuntu-latest steps: - - name: Use Go >= 1.19 - uses: actions/setup-go@v3 + - name: Use Go 1.20 + uses: actions/setup-go@v4 with: - go-version: '>=1.19' + go-version: '1.20' id: go - name: Check out code into the Go module directory diff --git a/.github/workflows/releases.yml b/.github/workflows/releases.yml index a4b775e5f..84d119f27 100644 --- a/.github/workflows/releases.yml +++ b/.github/workflows/releases.yml @@ -13,10 +13,10 @@ jobs: - name: checkout uses: actions/checkout@v3 - - name: Use go - uses: actions/setup-go@v3 + - name: Use Go 1.20 + uses: actions/setup-go@v4 with: - go-version: '>=1.18' + go-version: '1.20' - name: Install fpm run: | diff --git a/go.mod b/go.mod index 01a0b65dc..ad9c4034c 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/c4dt/d-voting -go 1.19 +go 1.20 require ( github.com/gorilla/mux v1.8.0 diff --git a/integration/integration_test.go b/integration/integration_test.go index b6bd9fcf1..4833a3663 100644 --- a/integration/integration_test.go +++ b/integration/integration_test.go @@ -37,8 +37,6 @@ func getIntegrationTest(numNodes, numVotes int) func(*testing.T) { adminID := "first admin" // ##### SETUP ENV ##### - // make tests reproducible - rand.Seed(1) delaPkg.Logger = delaPkg.Logger.Level(zerolog.WarnLevel) @@ -178,8 +176,6 @@ func getIntegrationTestCrash(numNodes, numVotes, failingNodes int) func(*testing adminID := "first admin" // ##### SETUP ENV ##### - // make tests reproducible - rand.Seed(1) delaPkg.Logger = delaPkg.Logger.Level(zerolog.WarnLevel) @@ -328,8 +324,6 @@ func getIntegrationBenchmark(numNodes, numVotes int) func(*testing.B) { adminID := "first admin" // ##### SETUP ENV ##### - // make tests reproducible - rand.Seed(1) delaPkg.Logger = delaPkg.Logger.Level(zerolog.WarnLevel) diff --git a/integration/performance_test.go b/integration/performance_test.go index aaeb38a51..7a4233e55 100644 --- a/integration/performance_test.go +++ b/integration/performance_test.go @@ -4,7 +4,6 @@ import ( "crypto/sha256" "encoding/base64" "fmt" - "math/rand" "os" "strconv" "strings" @@ -31,8 +30,6 @@ func BenchmarkIntegration_CustomVotesScenario(b *testing.B) { adminID := "I am an admin" // ##### SETUP ENV ##### - // make tests reproducible - rand.Seed(1) dirPath, err := os.MkdirTemp(os.TempDir(), "d-voting-three-votes") require.NoError(b, err) diff --git a/integration/scenario_test.go b/integration/scenario_test.go index d2c636689..cd1473b32 100644 --- a/integration/scenario_test.go +++ b/integration/scenario_test.go @@ -72,7 +72,6 @@ func getScenarioTest(numNodes int, numVotes int, numForm int) func(*testing.T) { func startFormProcess(wg *sync.WaitGroup, numNodes, numVotes, numSec int, proxyArray []string, t *testing.T, numForm int, testType testType) { defer wg.Done() - rand.Seed(0) const contentType = "application/json" secretkeyBuf, err := hex.DecodeString("28912721dfd507e198b31602fb67824856eb5a674c021d49fdccbe52f0234409") diff --git a/integration/votes_test.go b/integration/votes_test.go index 53eb765af..207798f18 100644 --- a/integration/votes_test.go +++ b/integration/votes_test.go @@ -2,7 +2,6 @@ package integration import ( "fmt" - "math/rand" "os" "strconv" @@ -34,8 +33,6 @@ func getIntegrationTestBadVote(numNodes, numVotes, numBadVotes int) func(*testin adminID := "first admin" // ##### SETUP ENV ##### - // make tests reproducible - rand.Seed(1) delaPkg.Logger = delaPkg.Logger.Level(zerolog.WarnLevel) @@ -174,8 +171,6 @@ func getIntegrationTestRevote(numNodes, numVotes, numRevotes int) func(*testing. adminID := "first admin" // ##### SETUP ENV ##### - // make tests reproducible - rand.Seed(1) delaPkg.Logger = delaPkg.Logger.Level(zerolog.WarnLevel) diff --git a/scripts/.gitignore b/scripts/.gitignore new file mode 100644 index 000000000..f1c040d8e --- /dev/null +++ b/scripts/.gitignore @@ -0,0 +1 @@ +formid.env diff --git a/scripts/local_forms.sh b/scripts/local_forms.sh index 1cb5bcdde..24aa138c5 100755 --- a/scripts/local_forms.sh +++ b/scripts/local_forms.sh @@ -6,6 +6,7 @@ SCRIPT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &>/dev/null && pwd) echo "add form" RESP=$(curl -sk "$FRONTEND_URL/api/evoting/forms" -X POST -H 'Content-Type: application/json' -b cookies.txt --data-raw $'{"Configuration":{"Title":{"En":"Colours","Fr":"","De":""},"Scaffold":[{"ID":"A7GsJxVJ","Title":{"En":"Colours","Fr":"","De":""},"Order":["GhidLIfw"],"Ranks":[],"Selects":[{"ID":"GhidLIfw","Title":{"En":"RGB","Fr":"","De":"RGB"},"MaxN":3,"MinN":1,"Choices":["{\\"en\\":\\"Red\\",\\"de\\":\\"Rot\\"}","{\\"en\\":\\"Green\\",\\"de\\":\\"Gr\xfcn\\"}","{\\"en\\":\\"Blue\\",\\"de\\":\\"Blau\\"}"],"Hint":{"En":"","Fr":"","De":"RGB"}}],"Texts":[],"Subjects":[]}]}}') FORMID=$(echo "$RESP" | jq -r .FormID) +echo "FORMID=$FORMID" > "$SCRIPT_DIR/formid.env" echo "add permissions - it's normal to have a timeout error after this command" curl -k "$FRONTEND_URL/api/evoting/authorizations" -X PUT -H 'Content-Type: application/json' -b cookies.txt --data "$(jq -cn --arg FormID $FORMID '$ARGS.named')" -m 1 diff --git a/scripts/test_admin_nonowner_addvote.sh b/scripts/test_admin_nonowner_addvote.sh new file mode 100755 index 000000000..f0cdbdfd4 --- /dev/null +++ b/scripts/test_admin_nonowner_addvote.sh @@ -0,0 +1,48 @@ +#!/bin/bash + +# This script tests that an admin who is not the owner of a form +# cannot add voters to the form. +# It also tests that the admin who created the form can actually add +# voters to the form. + +SCRIPT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &>/dev/null && pwd) +"$SCRIPT_DIR/run_local.sh" + +. "$SCRIPT_DIR/local_vars.sh" +SECOND_ADMIN=123321 +echo "Adding $SECOND_ADMIN to admin" +(cd web/backend && npx ts-node src/cli.ts addAdmin --sciper $SECOND_ADMIN | grep -v Executing) + +"$SCRIPT_DIR/local_proxies.sh" +"$SCRIPT_DIR/local_forms.sh" + +. "$SCRIPT_DIR/formid.env" + +tmp_dir=$(mktemp -d) +trap 'rm -rf -- "tmpdir"' EXIT + +tmp_cookie_owner="$tmp_dir/cookie_owner" +curl -k "$FRONTEND_URL/api/get_dev_login/$REACT_APP_SCIPER_ADMIN" -X GET -c "$tmp_cookie_owner" -o /dev/null -s +tmp_cookie_nonowner="$tmp_dir/cookie_nonowner" +curl -k "$FRONTEND_URL/api/get_dev_login/$SECOND_ADMIN" -X GET -c "$tmp_cookie_nonowner" -o /dev/null -s + +echo "This should fail with an error that we're not allowed" +tmp_output="$tmp_dir/output" +curl -s 'http://localhost:3000/api/add_role' \ + -H 'Content-Type: application/json' \ + --data-raw "{\"userId\":444555,\"subject\":\"$FORMID\",\"permission\":\"vote\"}" \ + -b "$tmp_cookie_nonowner" 2>&1 | tee "$tmp_output" +echo + +if ! grep -q "not owner of form" "$tmp_output"; then + echo + echo "ERROR: Reply should be 'not owner of form'" + exit 1 +fi + +echo "This should pass for the owner of the form" +curl 'http://localhost:3000/api/add_role' \ + -H 'Content-Type: application/json' \ + --data-raw "{\"userId\":444555,\"subject\":\"$FORMID\",\"permission\":\"vote\"}" \ + -b "$tmp_cookie_owner" +echo diff --git a/web/backend/src/controllers/users.ts b/web/backend/src/controllers/users.ts index f5239df05..2b0a6f71b 100644 --- a/web/backend/src/controllers/users.ts +++ b/web/backend/src/controllers/users.ts @@ -28,6 +28,12 @@ usersRouter.post('/add_role', (req, res, next) => { return; } + if (req.body.permission === 'vote') { + if (!isAuthorized(req.session.userId, req.body.subject, PERMISSIONS.ACTIONS.OWN)) { + res.status(400).send('Unauthorized - not owner of form'); + } + } + addPolicy(req.body.userId, req.body.subject, req.body.permission) .then(() => { res.set(200).send(); diff --git a/web/frontend/src/language/de.json b/web/frontend/src/language/de.json index ab1b8ed31..f938a4333 100644 --- a/web/frontend/src/language/de.json +++ b/web/frontend/src/language/de.json @@ -218,7 +218,7 @@ "operationFailure": "Der Vorgang ist fehlgeschlagen. Versuchen Sie, die Seite zu aktualisieren.", "shuffleFail": "Die Zufallsmischung ist fehlgeschlagen.", "voteImpossible": "Unmöglich abstimmen", - "notFoundVoteImpossible": "Zurück zur Formulartabelle", + "returnToFormTable": "Zurück zur Formulartabelle", "voteImpossibleDescription": "Das Formular ist nicht mehr zur Abstimmung geöffnet.", "yes": "Ja", "no": "Nein", @@ -289,6 +289,8 @@ "footerUnknown": "?", "footerVersion": "version:", "footerBuild": "build:", - "footerBuildTime": "in:" + "footerBuildTime": "in:", + "voteNotVoter": "Wählen nicht erlaubt.", + "voteNotVoterDescription": "Sie sind nicht wahlberechtigt in dieser Wahl. Falls Sie denken, dass ein Fehler vorliegt, wenden Sie sich bitte an die verantwortliche Stelle." } } diff --git a/web/frontend/src/language/en.json b/web/frontend/src/language/en.json index 1c5597d1c..7f0a25b6e 100644 --- a/web/frontend/src/language/en.json +++ b/web/frontend/src/language/en.json @@ -218,7 +218,7 @@ "operationFailure": "The operation failed. Try refreshing the page.", "shuffleFail": "The shuffle operation failed.", "voteImpossible": "Vote Impossible", - "notFoundVoteImpossible": "Go back to form table", + "returnToFormTable": "Go back to form table", "voteImpossibleDescription": "The form is not open for voting anymore.", "yes": "Yes", "no": "No", @@ -290,6 +290,8 @@ "footerUnknown": "?", "footerVersion": "version:", "footerBuild": "build:", - "footerBuildTime": "in:" + "footerBuildTime": "in:", + "voteNotVoter": "Voting not allowed.", + "voteNotVoterDescription": "You are not allowed to vote in this form. If you believe this is an error, please contact the responsible of the service." } } diff --git a/web/frontend/src/language/fr.json b/web/frontend/src/language/fr.json index ea517af5c..d783e8c1d 100644 --- a/web/frontend/src/language/fr.json +++ b/web/frontend/src/language/fr.json @@ -218,7 +218,7 @@ "operationFailure": "L'opération a échoué. Essayez de rafraichir la page.", "shuffleFail": "L'opération de mélange a échoué", "voteImpossible": "Vote Impossible", - "notFoundVoteImpossible": "Retournez à l'onglet des sondages", + "returnToFormTable": "Retournez à l'onglet des sondages", "voteImpossibleDescription": "Le sondage n'est plus ouvert au vote.", "yes": "Oui", "no": "Non", @@ -289,6 +289,8 @@ "footerUnknown": "?", "footerVersion": "version:", "footerBuild": "build:", - "footerBuildTime": "en:" + "footerBuildTime": "en:", + "voteNotVoter": "Interdit de voter.", + "voteNotVoterDescription": "Vous n'avez pas le droit de voter dans cette élection. Si vous pensez qu'il s'agit d'une erreur, veuillez contacter le/la reponsable de service." } } diff --git a/web/frontend/src/pages/ballot/Show.tsx b/web/frontend/src/pages/ballot/Show.tsx index 5aa8b1140..c04ebf2ac 100644 --- a/web/frontend/src/pages/ballot/Show.tsx +++ b/web/frontend/src/pages/ballot/Show.tsx @@ -1,4 +1,6 @@ -import { FC, useState } from 'react'; +import { FC, useContext, useState } from 'react'; +import { AuthContext } from 'index'; +import { isVoter } from './../../utils/auth'; import { useTranslation } from 'react-i18next'; import { useParams } from 'react-router-dom'; import kyber from '@dedis/kyber'; @@ -17,7 +19,7 @@ import { useConfiguration } from 'components/utils/useConfiguration'; import { Status } from 'types/form'; import { ballotIsValid } from './components/ValidateAnswers'; import BallotDisplay from './components/BallotDisplay'; -import FormClosed from './components/FormClosed'; +import FormNotAvailable from './components/FormNotAvailable'; import Loading from 'pages/Loading'; import RedirectToModal from 'components/modal/RedirectToModal'; import { default as i18n } from 'i18next'; @@ -39,6 +41,7 @@ const Ballot: FC = () => { const [castVoteLoading, setCastVoteLoading] = useState(false); const navigate = useNavigate(); + const { authorization, isLogged } = useContext(AuthContext); const hexToBytes = (hex: string) => { const bytes: number[] = []; @@ -113,6 +116,8 @@ const Ballot: FC = () => { event.currentTarget.disabled = true; }; + const userIsVoter = isVoter(formID, authorization, isLogged); + return ( <> { ) : ( <> - {status === Status.Open && ( + {status === Status.Open && userIsVoter && (

@@ -165,7 +170,8 @@ const Ballot: FC = () => {

)} - {status !== Status.Open && } + {!userIsVoter && } + {status !== Status.Open && } )} diff --git a/web/frontend/src/pages/ballot/components/FormClosed.tsx b/web/frontend/src/pages/ballot/components/FormNotAvailable.tsx similarity index 77% rename from web/frontend/src/pages/ballot/components/FormClosed.tsx rename to web/frontend/src/pages/ballot/components/FormNotAvailable.tsx index 79e6e967d..a149694a1 100644 --- a/web/frontend/src/pages/ballot/components/FormClosed.tsx +++ b/web/frontend/src/pages/ballot/components/FormNotAvailable.tsx @@ -2,7 +2,7 @@ import { useTranslation } from 'react-i18next'; import { Link } from 'react-router-dom'; import { ROUTE_FORM_INDEX } from 'Routes'; -export default function FormClosed() { +export default function FormNotAvailable(props) { const { t } = useTranslation(); return ( @@ -13,15 +13,17 @@ export default function FormClosed() {

- {t('voteImpossible')} + {props.isVoter ? t('voteImpossible') : t('voteNotVoter')}

-

{t('voteImpossibleDescription')}

+

+ {props.isVoter ? t('voteImpossibleDescription') : t('voteNotVoterDescription')} +

- {t('notFoundVoteImpossible')} + {t('returnToFormTable')}
diff --git a/web/frontend/src/pages/form/GroupedResult.tsx b/web/frontend/src/pages/form/GroupedResult.tsx index bb077bfd4..5608a54c2 100644 --- a/web/frontend/src/pages/form/GroupedResult.tsx +++ b/web/frontend/src/pages/form/GroupedResult.tsx @@ -124,9 +124,15 @@ const GroupedResult: FC = ({ rankResult, selectResult, textR const select = element as SelectQuestion; if (selectResult.has(id)) { - res = countSelectResult(selectResult.get(id)).resultsInPercent.map((percent, index) => { - return { Candidate: select.Choices[index], Percentage: `${percent}%` }; - }); + res = countSelectResult(selectResult.get(id)) + .map(([, totalCount], index) => { + return { + Candidate: select.Choices[index], + TotalCount: totalCount, + NumberOfBallots: selectResult.get(id).length, // number of combined ballots for this election + }; + }) + .sort((x, y) => y.TotalCount - x.TotalCount); dataToDownload.push({ Title: element.Title.En, Results: res }); } break; diff --git a/web/frontend/src/pages/form/components/ActionButtons/AddVotersButton.tsx b/web/frontend/src/pages/form/components/ActionButtons/AddVotersButton.tsx index e4a1e78b0..72e22f4a1 100644 --- a/web/frontend/src/pages/form/components/ActionButtons/AddVotersButton.tsx +++ b/web/frontend/src/pages/form/components/ActionButtons/AddVotersButton.tsx @@ -1,6 +1,6 @@ import { DocumentAddIcon } from '@heroicons/react/outline'; import { useTranslation } from 'react-i18next'; -import { isManager } from './utils'; +import { isManager } from './../../../../utils/auth'; import { AuthContext } from 'index'; import { useContext } from 'react'; diff --git a/web/frontend/src/pages/form/components/ActionButtons/CancelButton.tsx b/web/frontend/src/pages/form/components/ActionButtons/CancelButton.tsx index 820028bc3..41f2bbece 100644 --- a/web/frontend/src/pages/form/components/ActionButtons/CancelButton.tsx +++ b/web/frontend/src/pages/form/components/ActionButtons/CancelButton.tsx @@ -4,7 +4,7 @@ import { useContext } from 'react'; import { useTranslation } from 'react-i18next'; import { OngoingAction, Status } from 'types/form'; import ActionButton from './ActionButton'; -import { isManager } from './utils'; +import { isManager } from './../../../../utils/auth'; const CancelButton = ({ status, handleCancel, ongoingAction, formID }) => { const { authorization, isLogged } = useContext(AuthContext); diff --git a/web/frontend/src/pages/form/components/ActionButtons/CloseButton.tsx b/web/frontend/src/pages/form/components/ActionButtons/CloseButton.tsx index 916f5af71..4259a016a 100644 --- a/web/frontend/src/pages/form/components/ActionButtons/CloseButton.tsx +++ b/web/frontend/src/pages/form/components/ActionButtons/CloseButton.tsx @@ -4,7 +4,7 @@ import { useContext } from 'react'; import { useTranslation } from 'react-i18next'; import { OngoingAction, Status } from 'types/form'; import ActionButton from './ActionButton'; -import { isManager } from './utils'; +import { isManager } from './../../../../utils/auth'; const CloseButton = ({ status, handleClose, ongoingAction, formID }) => { const { authorization, isLogged } = useContext(AuthContext); diff --git a/web/frontend/src/pages/form/components/ActionButtons/CombineButton.tsx b/web/frontend/src/pages/form/components/ActionButtons/CombineButton.tsx index e4a2f7258..7dc5e651d 100644 --- a/web/frontend/src/pages/form/components/ActionButtons/CombineButton.tsx +++ b/web/frontend/src/pages/form/components/ActionButtons/CombineButton.tsx @@ -4,7 +4,7 @@ import { useContext } from 'react'; import { useTranslation } from 'react-i18next'; import { OngoingAction, Status } from 'types/form'; import ActionButton from './ActionButton'; -import { isManager } from './utils'; +import { isManager } from './../../../../utils/auth'; const CombineButton = ({ status, handleCombine, ongoingAction, formID }) => { const { t } = useTranslation(); diff --git a/web/frontend/src/pages/form/components/ActionButtons/DecryptButton.tsx b/web/frontend/src/pages/form/components/ActionButtons/DecryptButton.tsx index 65242a181..328a6978e 100644 --- a/web/frontend/src/pages/form/components/ActionButtons/DecryptButton.tsx +++ b/web/frontend/src/pages/form/components/ActionButtons/DecryptButton.tsx @@ -4,7 +4,7 @@ import { useContext } from 'react'; import { useTranslation } from 'react-i18next'; import { OngoingAction, Status } from 'types/form'; import ActionButton from './ActionButton'; -import { isManager } from './utils'; +import { isManager } from './../../../../utils/auth'; const DecryptButton = ({ status, handleDecrypt, ongoingAction, formID }) => { const { authorization, isLogged } = useContext(AuthContext); diff --git a/web/frontend/src/pages/form/components/ActionButtons/DeleteButton.tsx b/web/frontend/src/pages/form/components/ActionButtons/DeleteButton.tsx index 937d868d8..fd7712310 100644 --- a/web/frontend/src/pages/form/components/ActionButtons/DeleteButton.tsx +++ b/web/frontend/src/pages/form/components/ActionButtons/DeleteButton.tsx @@ -2,7 +2,7 @@ import { TrashIcon } from '@heroicons/react/outline'; import { AuthContext } from 'index'; import { useContext } from 'react'; import { useTranslation } from 'react-i18next'; -import { isManager } from './utils'; +import { isManager } from './../../../../utils/auth'; const DeleteButton = ({ handleDelete, formID }) => { const { t } = useTranslation(); diff --git a/web/frontend/src/pages/form/components/ActionButtons/InitializeButton.tsx b/web/frontend/src/pages/form/components/ActionButtons/InitializeButton.tsx index 7def2696a..9cb4c5281 100644 --- a/web/frontend/src/pages/form/components/ActionButtons/InitializeButton.tsx +++ b/web/frontend/src/pages/form/components/ActionButtons/InitializeButton.tsx @@ -4,7 +4,7 @@ import { useContext } from 'react'; import { useTranslation } from 'react-i18next'; import { OngoingAction, Status } from 'types/form'; import ActionButton from './ActionButton'; -import { isManager } from './utils'; +import { isManager } from './../../../../utils/auth'; const InitializeButton = ({ status, handleInitialize, ongoingAction, formID }) => { const { authorization, isLogged } = useContext(AuthContext); diff --git a/web/frontend/src/pages/form/components/ActionButtons/OpenButton.tsx b/web/frontend/src/pages/form/components/ActionButtons/OpenButton.tsx index 77a1b282b..80a48a70d 100644 --- a/web/frontend/src/pages/form/components/ActionButtons/OpenButton.tsx +++ b/web/frontend/src/pages/form/components/ActionButtons/OpenButton.tsx @@ -4,7 +4,7 @@ import { useContext } from 'react'; import { useTranslation } from 'react-i18next'; import { OngoingAction, Status } from 'types/form'; import ActionButton from './ActionButton'; -import { isManager } from './utils'; +import { isManager } from './../../../../utils/auth'; const OpenButton = ({ status, handleOpen, ongoingAction, formID }) => { const { t } = useTranslation(); diff --git a/web/frontend/src/pages/form/components/ActionButtons/SetupButton.tsx b/web/frontend/src/pages/form/components/ActionButtons/SetupButton.tsx index 09d6c8e48..f1848c94c 100644 --- a/web/frontend/src/pages/form/components/ActionButtons/SetupButton.tsx +++ b/web/frontend/src/pages/form/components/ActionButtons/SetupButton.tsx @@ -4,7 +4,7 @@ import { useContext } from 'react'; import { useTranslation } from 'react-i18next'; import { OngoingAction, Status } from 'types/form'; import ActionButton from './ActionButton'; -import { isManager } from './utils'; +import { isManager } from './../../../../utils/auth'; const SetupButton = ({ status, handleSetup, ongoingAction, formID }) => { const { t } = useTranslation(); diff --git a/web/frontend/src/pages/form/components/ActionButtons/ShuffleButton.tsx b/web/frontend/src/pages/form/components/ActionButtons/ShuffleButton.tsx index 4c537a78f..178b67896 100644 --- a/web/frontend/src/pages/form/components/ActionButtons/ShuffleButton.tsx +++ b/web/frontend/src/pages/form/components/ActionButtons/ShuffleButton.tsx @@ -4,7 +4,7 @@ import { useContext } from 'react'; import { useTranslation } from 'react-i18next'; import { OngoingAction, Status } from 'types/form'; import ActionButton from './ActionButton'; -import { isManager } from './utils'; +import { isManager } from './../../../../utils/auth'; const ShuffleButton = ({ status, handleShuffle, ongoingAction, formID }) => { const { t } = useTranslation(); diff --git a/web/frontend/src/pages/form/components/AddVotersModal.tsx b/web/frontend/src/pages/form/components/AddVotersModal.tsx index d54113f3f..4a619940f 100644 --- a/web/frontend/src/pages/form/components/AddVotersModal.tsx +++ b/web/frontend/src/pages/form/components/AddVotersModal.tsx @@ -169,6 +169,7 @@ export const AddVotersModal: FC = ({