diff --git a/software/backend/data/exercises.json b/software/backend/data/exercises.json
index 530c915..8ed2eed 100644
--- a/software/backend/data/exercises.json
+++ b/software/backend/data/exercises.json
@@ -27,7 +27,32 @@
"nameDe": "SQL Injections",
"nameEn": "SQL Injections",
"groupNr": 1,
- "exercises": []
+ "exercises": [
+ {
+ "nameDe": "Accountnamen auslesen",
+ "nameEn": "Readout account names",
+ "exerciseNr": 1,
+ "descriptionDe": "Lasse dir alle Accountnamen über das Suchfeld ausgeben",
+ "descriptionEn": "Readout all account names via the search field",
+ "solved": false
+ },
+ {
+ "nameDe": "Passwort auslesen",
+ "nameEn": "Readout password",
+ "exerciseNr": 2,
+ "descriptionDe": "Versuche ein Passwort aus der Datenbank eines Accounts auszulesen",
+ "descriptionEn": "Get the password of an account from the database",
+ "solved": false
+ },
+ {
+ "nameDe": "Verändere deine Account Berechtigungen",
+ "nameEn": "Change your account role",
+ "exerciseNr": 3,
+ "descriptionDe": "Ändere die Berechtigungen deines Accounts",
+ "descriptionEn": "Change the privileges of your account",
+ "solved": false
+ }
+ ]
},
{
"nameDe": "Broken Access Control",
@@ -41,6 +66,14 @@
"descriptionDe": "Manipuliere die URL so, dass du das Admin-Panel erreichen kannst",
"descriptionEn": "Manipulate the URL and access the admin panel",
"solved": false
+ },
+ {
+ "nameDe": "Das versteckte Konzert buchen",
+ "nameEn": "Book the hidden concert",
+ "exerciseNr": 2,
+ "descriptionDe": "Manipuliere die URL so, dass du das ausgebuchte Konzert aufrufen kannst und buche ein Ticket dafür",
+ "descriptionEn": "Manipulate the URL and access the sold out concert and buy a ticket",
+ "solved": false
}
]
},
@@ -56,6 +89,22 @@
"descriptionDe": "Nimm dir eine URL des Shops und erweitere sie mit JavaScript Code so, dass beim Öffnen des Links eine 'Hallo Welt' Nachricht erscheint",
"descriptionEn": "Take an URL of the shop and extend it with JavaScript code so that a 'Hello World' message appears whent the link is opened",
"solved": false
+ },
+ {
+ "nameDe": "Ein externes Script aufrufen",
+ "nameEn": "Run an external script",
+ "exerciseNr": 2,
+ "descriptionDe": "Bearbeite die URL des Shops so, dass du das Script ausführen kannst",
+ "descriptionEn": "Create an URL of the shop, which calls the script",
+ "solved": false
+ },
+ {
+ "nameDe": "Hacken mit eigenem Script",
+ "nameEn": "Hack with your script",
+ "exerciseNr": 3,
+ "descriptionDe": "Schreibe eine JavaScript Datei, lade sie über das Admin Panel hoch und kreiere eine URL, welche es ausführt",
+ "descriptionEn": "Write our own JavaScript file, upload it via Admin Panel and create an URL to execute it",
+ "solved": false
}
]
}
diff --git a/software/src/components/basics/cardView.vue b/software/src/components/basics/cardView.vue
index 2181c4e..2fc5899 100644
--- a/software/src/components/basics/cardView.vue
+++ b/software/src/components/basics/cardView.vue
@@ -29,8 +29,8 @@ defineProps({
style="background-color: transparent"
>
-
-
{{ title }}
+
+ {{ title }}
{{ subtitle }}
@@ -40,9 +40,9 @@ defineProps({
-
+
-
+
diff --git a/software/src/components/basics/confirmDialog.vue b/software/src/components/basics/confirmDialog.vue
index cd02a3e..370cbb7 100644
--- a/software/src/components/basics/confirmDialog.vue
+++ b/software/src/components/basics/confirmDialog.vue
@@ -8,12 +8,12 @@ const showDialog: ModelRef = defineModel()
const props = defineProps({
title: String,
description: String,
- onConfirm: Function
+ onConfirm: Function,
+ loading: Boolean
})
function confirmPressed() {
props.onConfirm()
- showDialog.value = false
}
@@ -22,6 +22,7 @@ function confirmPressed() {
:title="title"
max-width="400"
v-model="showDialog"
+ persistent
>
{{ description }}
@@ -30,6 +31,7 @@ function confirmPressed() {
@click="showDialog = false"
prepend-icon="mdi-close"
color="orange"
+ :loading="loading"
>
{{ $t("misc.actions.cancel") }}
@@ -38,6 +40,7 @@ function confirmPressed() {
@click="confirmPressed"
prepend-icon="mdi-check"
color="red"
+ :loading="loading"
>
{{ $t("misc.actions.confirm") }}
diff --git a/software/src/locales/de.json b/software/src/locales/de.json
index 25d7779..3a282dd 100644
--- a/software/src/locales/de.json
+++ b/software/src/locales/de.json
@@ -143,7 +143,8 @@
"title": "Übungsfortschritt zurücksetzen?",
"description": "Soll der Bearbeitungsfortschritt der Übungen wirklich zurückgesetzt werden? Dies kann nicht rückgänig gemacht werden!"
}
- }
+ },
+ "aboutProject": "Über das Projekt"
},
"help": {
"scoreBoard": {
diff --git a/software/src/locales/en.json b/software/src/locales/en.json
index 0a56d20..4df9836 100644
--- a/software/src/locales/en.json
+++ b/software/src/locales/en.json
@@ -143,7 +143,8 @@
"title": "Reset exercise progress?",
"description": "Do you really want to reset the exercise progress? This is permanent!"
}
- }
+ },
+ "aboutProject": "About the project"
},
"help": {
"scoreBoard": {
diff --git a/software/src/pages/misc/preferencesPage/aboutSection.vue b/software/src/pages/misc/preferencesPage/aboutSection.vue
new file mode 100644
index 0000000..8e238c2
--- /dev/null
+++ b/software/src/pages/misc/preferencesPage/aboutSection.vue
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/software/src/pages/misc/preferencesPage/index.vue b/software/src/pages/misc/preferencesPage/index.vue
index 062522a..7685011 100644
--- a/software/src/pages/misc/preferencesPage/index.vue
+++ b/software/src/pages/misc/preferencesPage/index.vue
@@ -1,6 +1,7 @@
@@ -16,5 +17,11 @@ import systemSetup from './systemSetup.vue';
+
+
+
+
+
+
\ No newline at end of file
diff --git a/software/src/pages/misc/preferencesPage/pageSetup.vue b/software/src/pages/misc/preferencesPage/pageSetup.vue
index ed4683d..123c8b8 100644
--- a/software/src/pages/misc/preferencesPage/pageSetup.vue
+++ b/software/src/pages/misc/preferencesPage/pageSetup.vue
@@ -30,6 +30,7 @@ function changeLanguage() {
:items="themeEnums"
:label="$t('preferences.selectedTheme')"
@update:model-value="changeTheme"
+ variant="outlined"
hide-details
/>
@@ -42,6 +43,7 @@ function changeLanguage() {
:items="$i18n.availableLocales"
:label="$t('preferences.language')"
@update:model-value="changeLanguage"
+ variant="outlined"
hide-details
/>
diff --git a/software/src/pages/misc/preferencesPage/systemSetup.vue b/software/src/pages/misc/preferencesPage/systemSetup.vue
index f35d683..c518678 100644
--- a/software/src/pages/misc/preferencesPage/systemSetup.vue
+++ b/software/src/pages/misc/preferencesPage/systemSetup.vue
@@ -1,59 +1,13 @@
@@ -64,36 +18,32 @@ async function resetExerciseProg() {
{{ $t('preferences.serverState') }}:
-
+
Online
-
+
Offline
-
+
Pending...
-
-
- Software Version: {{ packageJson.version }}
-
-
+
{{ $t('preferences.resetDatabase.resetDatabase') }}
@@ -103,10 +53,10 @@ async function resetExerciseProg() {
{{ $t('preferences.resetExerciseProgress.resetExerciseProgress') }}
@@ -118,15 +68,17 @@ async function resetExerciseProg() {
\ No newline at end of file
diff --git a/software/src/stores/preferences.store.ts b/software/src/stores/preferences.store.ts
index 5eace61..61911f5 100644
--- a/software/src/stores/preferences.store.ts
+++ b/software/src/stores/preferences.store.ts
@@ -3,6 +3,10 @@ import { useLocalStorage } from "@vueuse/core";
import { ThemeEnum } from "../data/enums/themeEnums";
import { LanguageEnum } from "../data/enums/languageEnum";
import { ref } from "vue";
+import { fetchServerState, resetDatabase, resetExerciseProgress } from "@/data/api/mainApi";
+import { ServerStateEnum } from "@/data/enums/serverStateEnum";
+import { BannerStateEnum } from "@/data/enums/bannerStateEnum";
+import { useFeedbackStore } from "./feedback.store";
export const usePreferencesStore = defineStore('preferencesStore', {
state: () => ({
@@ -13,6 +17,79 @@ export const usePreferencesStore = defineStore('preferencesStore', {
language: useLocalStorage("hackmycart/preferencesStore/language", LanguageEnum.GERMAN),
/** Request to server sent, waiting for data response */
- fetchInProgress: ref(false)
+ fetchInProgress: ref(false),
+
+ /** State of the server */
+ serverState: ref(ServerStateEnum.PENDING),
+
+ /** Show the "Delete DB?" confirm dialog */
+ showDeleteDbDialog: ref(false),
+
+ /** Show the "Delete Exercise progress?" confirm dialog */
+ showDeleteExerciseDialog: ref(false)
}),
+
+ actions: {
+ /**
+ * Request the state of the backend server
+ */
+ async getServerState() {
+ this.fetchInProgress = true
+
+ fetchServerState()
+ .then(result => {
+ if (result.status == 200) {
+ this.serverState = ServerStateEnum.ONLINE
+ } else {
+ this.serverState = ServerStateEnum.OFFLINE
+ }
+
+ this.fetchInProgress = false
+ })
+ .catch(error => {
+ this.serverState = ServerStateEnum.OFFLINE
+ this.fetchInProgress = false
+ })
+ },
+
+ /**
+ * Resets the database (without exercise tables)
+ */
+ async resetDb() {
+ const feedbackStore = useFeedbackStore()
+ this.serverState = ServerStateEnum.PENDING
+ this.fetchInProgress = true
+
+ await resetDatabase()
+ .then(result => {
+ if (result.status == 200) {
+ feedbackStore.changeBanner(BannerStateEnum.DATABASERESETSUCCESSFUL)
+ this.serverState = ServerStateEnum.ONLINE
+ }
+
+ this.fetchInProgress = false
+ this.showDeleteDbDialog = false
+ })
+ },
+
+ /**
+ * Resets the exercise progress
+ */
+ async resetExerciseProg() {
+ const feedbackStore = useFeedbackStore()
+ this.serverState = ServerStateEnum.PENDING
+ this.fetchInProgress = true
+
+ await resetExerciseProgress()
+ .then(result => {
+ if (result.status == 200) {
+ feedbackStore.changeBanner(BannerStateEnum.EXERCISEPROGRESSRESETSUCCESSFUL)
+ this.serverState = ServerStateEnum.ONLINE
+ }
+
+ this.fetchInProgress = false
+ this.showDeleteExerciseDialog = false
+ })
+ }
+ }
})
\ No newline at end of file