diff --git a/app/routes/index.ts b/app/routes/index.ts index 9153c0aa..bc8f727e 100644 --- a/app/routes/index.ts +++ b/app/routes/index.ts @@ -33,9 +33,6 @@ router.get('/admin*', checkAdmin, (req, res, next) => { // Make sure all moderator routes are secure router.get('/moderator*', checkModerator, (req, res, next) => { - if (env.NODE_ENV !== 'development') { - return res.render('moderatorIndex'); // Remove when migration is finished - } next(); }); diff --git a/src/lib/assets/deactivate.mp3 b/src/lib/assets/deactivate.mp3 new file mode 100644 index 00000000..f8f81bd3 Binary files /dev/null and b/src/lib/assets/deactivate.mp3 differ diff --git a/src/lib/utils/callApi.ts b/src/lib/utils/callApi.ts index 27f0464a..7d78dfb0 100644 --- a/src/lib/utils/callApi.ts +++ b/src/lib/utils/callApi.ts @@ -8,34 +8,58 @@ const callApi = async < input: string, method: RequestInit['method'] = 'GET', body?: ReqBody, - headers?: RequestInit['headers'] -): Promise<{ status: number; body: ResBody }> => { + headers?: RequestInit['headers'], + fetchFunc = fetch +): Promise< + | { + result: 'success'; + status: number; + body: ResBody; + } + | { + result: 'failure'; + status: number; + body: { + message: string; + name: string; + }; + } +> => { let xsrfToken = get(xsrf); if (!xsrfToken && method.toUpperCase() !== 'GET') { await generateXSRFToken(); xsrfToken = get(xsrf); } - const res = await fetch('/api' + input, { + const res = await fetchFunc('/api' + input, { headers: { ...headers, - 'Content-Type': body ? 'application/json' : undefined, + 'content-type': body ? 'application/json' : undefined, 'X-XSRF-TOKEN': xsrfToken, }, method, body: body ? JSON.stringify(body) : undefined, }); - let resBody: ResBody; + let resBody: ResBody & { message: string; name: string }; if (res.headers.get('Content-Type')?.includes('application/json')) { resBody = await res.json(); } - return { status: res.status, body: resBody }; + + if (res.status < 400) { + return { result: 'success', status: res.status, body: resBody }; + } else { + return { + result: 'failure', + status: res.status, + body: resBody, + }; + } }; export const generateXSRFToken = async () => { const res = await callApi<{ csrfToken: string }>('/auth/token'); - if (res.status === 200) { + if (res.result === 'success') { xsrf.set(res.body.csrfToken); } else { console.error('Could not retrieve csrf-token'); diff --git a/src/lib/utils/cardKeyScanStore.ts b/src/lib/utils/cardKeyScanStore.ts index c248ca0f..036dd28a 100644 --- a/src/lib/utils/cardKeyScanStore.ts +++ b/src/lib/utils/cardKeyScanStore.ts @@ -114,11 +114,11 @@ export const cardKeyScanStore = writable<{ cardKey: number; time: number }>( }; } } catch (e) { + console.error(e); if (window.navigator.userAgent.includes('Android')) { alerts.push(e, 'ERROR'); } window.location.assign('/moderator/serial_error'); - console.error(e); } } diff --git a/src/lib/utils/userApi.ts b/src/lib/utils/userApi.ts index 2253d4f9..50dde710 100644 --- a/src/lib/utils/userApi.ts +++ b/src/lib/utils/userApi.ts @@ -17,7 +17,7 @@ export const changeCard = (user: Record) => { }; export const countActiveUsers = () => { - return callApi('/user/count?active=true'); + return callApi<{ users: number }>('/user/count?active=true'); }; export const deactivateNonAdminUsers = () => { diff --git a/src/routes/(election)/+page.svelte b/src/routes/(election)/+page.svelte index bf308935..33bbb490 100644 --- a/src/routes/(election)/+page.svelte +++ b/src/routes/(election)/+page.svelte @@ -21,30 +21,23 @@ let priorities: IAlternative[] = []; - type ErrorCode = { - name: string; - }; - type ErrorMessage = { - message: string; - }; - const getActiveElection = async (accessCode: string = '') => { - const res = await callApi( + const res = await callApi( '/election/active?accessCode=' + accessCode ); - if (res.status === 200) { + if (res.result === 'success') { priorities = []; electionExists = true; activeElection = res.body; errorCode = ''; } else { errorCode = res.body.name; - if (res.status == 404) { + if (res.status === 404) { electionExists = false; activeElection = null; accessCode = ''; - } else if (res.status == 403) { + } else if (res.status === 403) { electionExists = true; activeElection = null; accessCode = ''; @@ -62,7 +55,7 @@ election, priorities, }); - if (res.status === 201) { + if (res.result === 'success') { activeElection = null; priorities = []; electionExists = false; diff --git a/src/routes/(election)/retrieve/+page.svelte b/src/routes/(election)/retrieve/+page.svelte index 9783b904..79b9b4fc 100644 --- a/src/routes/(election)/retrieve/+page.svelte +++ b/src/routes/(election)/retrieve/+page.svelte @@ -24,7 +24,7 @@ const res = await callApi('/vote', 'GET', null, { 'Vote-Hash': voteHash, }); - if (res.status === 200) { + if (res.result === 'success') { vote = res.body; } }; diff --git a/src/routes/auth/login/+page.svelte b/src/routes/auth/login/+page.svelte index eaff0c99..303d2320 100644 --- a/src/routes/auth/login/+page.svelte +++ b/src/routes/auth/login/+page.svelte @@ -33,9 +33,9 @@ Object.fromEntries(new FormData(e.currentTarget)) ); - if (res.status == 200) { + if (res.result === 'success') { window.location.assign('/'); - } else if (res.status == 401) { + } else if (res.status === 401) { feedback = 'authfailed'; } else { feedback = 'unknownError'; diff --git a/src/routes/moderator/(useCardKey)/activate_user/+page.svelte b/src/routes/moderator/(useCardKey)/activate_user/+page.svelte index a19b9610..46139448 100644 --- a/src/routes/moderator/(useCardKey)/activate_user/+page.svelte +++ b/src/routes/moderator/(useCardKey)/activate_user/+page.svelte @@ -19,7 +19,7 @@ if (firstCall || !cardKey) return (firstCall = false); const res = await userApi.toggleUser(cardKey); - if (res.status === 200) { + if (res.result === 'success') { const lastAlert = alerts.getLastAlert(); if (dingAudio) dingAudio.play(); diff --git a/src/routes/moderator/(useCardKey)/change_card/+page.svelte b/src/routes/moderator/(useCardKey)/change_card/+page.svelte new file mode 100644 index 00000000..ec19f6a6 --- /dev/null +++ b/src/routes/moderator/(useCardKey)/change_card/+page.svelte @@ -0,0 +1,81 @@ + + +
+
+
+ +
+
+ +
+
+ +
+ + {#if !$cardKeyScanStore.cardKey} +

Kortnummer er påkrevd

+ {/if} +
+
diff --git a/src/routes/moderator/(useCardKey)/create_user/+page.svelte b/src/routes/moderator/(useCardKey)/create_user/+page.svelte new file mode 100644 index 00000000..2e5e2a80 --- /dev/null +++ b/src/routes/moderator/(useCardKey)/create_user/+page.svelte @@ -0,0 +1,124 @@ + + +
+
+
+ +
+ {#if !$cardKeyScanStore.cardKey} +

Kortnummer er påkrevd

+ {/if} +
+ + {#if !usernameMinLength} +

Brukernavn må være minst 5 tegn

+ {/if} + {#if !usernamePattern} +

+ Brukernavn kan bare inneholde tall eller bokstaver fra A-Z +

+ {/if} +
+
+ + {#if !passwordMinLength} +

Passord må være minst 6 tegn

+ {/if} +
+
+ + {#if !passwordMatch} +

Må være lik passordet

+ {/if} +
+ +
+
diff --git a/src/routes/moderator/(useCardKey)/deactivate_users/+page.svelte b/src/routes/moderator/(useCardKey)/deactivate_users/+page.svelte new file mode 100644 index 00000000..88848c63 --- /dev/null +++ b/src/routes/moderator/(useCardKey)/deactivate_users/+page.svelte @@ -0,0 +1,34 @@ + + +
+

Deaktivere alle brukere slik at all alle må reaktivere sin bruker.

+
    +
  1. Fysisk: Scanne seg inn i lokale med adgangskort
  2. +
  3. Digitalt: Skrive inn kode ved neste valg
  4. +
+ +
diff --git a/src/routes/moderator/(useCardKey)/generate_user/+page.svelte b/src/routes/moderator/(useCardKey)/generate_user/+page.svelte new file mode 100644 index 00000000..9827d138 --- /dev/null +++ b/src/routes/moderator/(useCardKey)/generate_user/+page.svelte @@ -0,0 +1,73 @@ + + +
+
+
+ + +
+
+ + +
+ +
+
diff --git a/src/routes/moderator/(useCardKey)/manage_register/+page.svelte b/src/routes/moderator/(useCardKey)/manage_register/+page.svelte new file mode 100644 index 00000000..f7aeca59 --- /dev/null +++ b/src/routes/moderator/(useCardKey)/manage_register/+page.svelte @@ -0,0 +1,86 @@ + + +
+
+

Genererte brukere

+

Tabellen under viser en oversikt over alle genererte brukere.

+ Brukere havner kun i denne oversikten hvis de er opprettet med "Generer bruker" + fanen, eller direkte fra API'et. Brukere laget med "Registrer bruker" eller "QR" + vil ikke vises under. +
+
+
+
+
+
+ Totalt {registers.length} genererte brukere +
+ +
+ + + + + + + + + + {#each registers.filter((r) => !searchText || Object.values(r).some((v) => typeof v === 'string' && v.includes(searchText))) as register (register._id)} + + + + + + + {/each} + +
IdentifikatorEmailFullført registrering
{register.identifier}{register.email} + {register.user ? 'Nei' : 'Ja'} + + +
+
diff --git a/src/routes/moderator/(useCardKey)/qr/+page.svelte b/src/routes/moderator/(useCardKey)/qr/+page.svelte index 37a74ba6..9cae2395 100644 --- a/src/routes/moderator/(useCardKey)/qr/+page.svelte +++ b/src/routes/moderator/(useCardKey)/qr/+page.svelte @@ -36,7 +36,7 @@ cardKey: cardKeyString, }); - if (res.status === 201) { + if (res.result === 'success') { goto( `/moderator/showqr/?token=${username}:${password}:${code}&cardKey=${cardKeyString}` ); diff --git a/src/routes/moderator/change_card/+page.svelte b/src/routes/moderator/change_card/+page.svelte deleted file mode 100644 index e69de29b..00000000 diff --git a/src/routes/moderator/create_user/+page.svelte b/src/routes/moderator/create_user/+page.svelte deleted file mode 100644 index e69de29b..00000000 diff --git a/src/routes/moderator/deactivate_users/+page.svelte b/src/routes/moderator/deactivate_users/+page.svelte deleted file mode 100644 index e69de29b..00000000 diff --git a/src/routes/moderator/generate_user/+page.svelte b/src/routes/moderator/generate_user/+page.svelte deleted file mode 100644 index e69de29b..00000000 diff --git a/src/routes/moderator/manage_register/+page.svelte b/src/routes/moderator/manage_register/+page.svelte deleted file mode 100644 index e69de29b..00000000