Implement exercise 1.1 (open help page)
This commit is contained in:
@@ -10,16 +10,14 @@
|
|||||||
"nameEn": "Register",
|
"nameEn": "Register",
|
||||||
"exerciseNr": 1,
|
"exerciseNr": 1,
|
||||||
"descriptionDe": "Erstelle einen neuen Account im Online Shop",
|
"descriptionDe": "Erstelle einen neuen Account im Online Shop",
|
||||||
"descriptionEn": "Create a new account in the online shop",
|
"descriptionEn": "Create a new account in the online shop"
|
||||||
"solved": false
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"nameDe": "Ein Ticket kaufen",
|
"nameDe": "Ein Ticket kaufen",
|
||||||
"nameEn": "Buy a ticket",
|
"nameEn": "Buy a ticket",
|
||||||
"exerciseNr": 2,
|
"exerciseNr": 2,
|
||||||
"descriptionDe": "Suche dir ein Event deiner Wahl und kaufe dafür ein Ticket",
|
"descriptionDe": "Suche dir ein Event deiner Wahl und kaufe dafür ein Ticket",
|
||||||
"descriptionEn": "Search for an event of choice and buy a ticket for",
|
"descriptionEn": "Search for an event of choice and buy a ticket for"
|
||||||
"solved": false
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -33,16 +31,14 @@
|
|||||||
"nameEn": "Access Help Page",
|
"nameEn": "Access Help Page",
|
||||||
"exerciseNr": 1,
|
"exerciseNr": 1,
|
||||||
"descriptionDe": "Manipuliere die URL so, dass du die Hilfe-Seite erreichen kannst",
|
"descriptionDe": "Manipuliere die URL so, dass du die Hilfe-Seite erreichen kannst",
|
||||||
"descriptionEn": "Manipulate the URL and access the help page",
|
"descriptionEn": "Manipulate the URL and access the help page"
|
||||||
"solved": false
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"nameDe": "Das ausgebuchte Konzert buchen",
|
"nameDe": "Das ausgebuchte Konzert buchen",
|
||||||
"nameEn": "Book the unavailable concert",
|
"nameEn": "Book the unavailable concert",
|
||||||
"exerciseNr": 2,
|
"exerciseNr": 2,
|
||||||
"descriptionDe": "Manipuliere die URL so, dass du das ausgebuchte Konzert aufrufen kannst und buche ein Ticket dafür",
|
"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",
|
"descriptionEn": "Manipulate the URL and access the sold out concert and buy a ticket"
|
||||||
"solved": false
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -56,24 +52,21 @@
|
|||||||
"nameEn": "Readout account names",
|
"nameEn": "Readout account names",
|
||||||
"exerciseNr": 1,
|
"exerciseNr": 1,
|
||||||
"descriptionDe": "Lasse dir alle Accountnamen über das Suchfeld ausgeben",
|
"descriptionDe": "Lasse dir alle Accountnamen über das Suchfeld ausgeben",
|
||||||
"descriptionEn": "Readout all account names via the search field",
|
"descriptionEn": "Readout all account names via the search field"
|
||||||
"solved": false
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"nameDe": "Passwort auslesen",
|
"nameDe": "Passwort auslesen",
|
||||||
"nameEn": "Readout password",
|
"nameEn": "Readout password",
|
||||||
"exerciseNr": 2,
|
"exerciseNr": 2,
|
||||||
"descriptionDe": "Versuche ein Passwort aus der Datenbank eines Accounts auszulesen",
|
"descriptionDe": "Versuche ein Passwort aus der Datenbank eines Accounts auszulesen",
|
||||||
"descriptionEn": "Get the password of an account from the database",
|
"descriptionEn": "Get the password of an account from the database"
|
||||||
"solved": false
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"nameDe": "Verändere deine Account Berechtigungen",
|
"nameDe": "Verändere deine Account Berechtigungen",
|
||||||
"nameEn": "Change your account role",
|
"nameEn": "Change your account role",
|
||||||
"exerciseNr": 3,
|
"exerciseNr": 3,
|
||||||
"descriptionDe": "Ändere die Berechtigungen deines Accounts",
|
"descriptionDe": "Ändere die Berechtigungen deines Accounts",
|
||||||
"descriptionEn": "Change the privileges of your account",
|
"descriptionEn": "Change the privileges of your account"
|
||||||
"solved": false
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -87,24 +80,21 @@
|
|||||||
"nameEn": "Hello World!",
|
"nameEn": "Hello World!",
|
||||||
"exerciseNr": 1,
|
"exerciseNr": 1,
|
||||||
"descriptionDe": "Nimm dir eine URL des Shops und erweitere sie mit JavaScript Code so, dass beim Öffnen des Links eine 'Hallo Welt' Nachricht erscheint",
|
"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",
|
"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",
|
"nameDe": "Ein externes Script aufrufen",
|
||||||
"nameEn": "Run an external script",
|
"nameEn": "Run an external script",
|
||||||
"exerciseNr": 2,
|
"exerciseNr": 2,
|
||||||
"descriptionDe": "Bearbeite die URL des Shops so, dass du das Script ausführen kannst",
|
"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",
|
"descriptionEn": "Create an URL of the shop, which calls the script"
|
||||||
"solved": false
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"nameDe": "Hacken mit eigenem Script",
|
"nameDe": "Hacken mit eigenem Script",
|
||||||
"nameEn": "Hack with your script",
|
"nameEn": "Hack with your script",
|
||||||
"exerciseNr": 3,
|
"exerciseNr": 3,
|
||||||
"descriptionDe": "Schreibe eine JavaScript Datei, lade sie über das Admin Panel hoch und kreiere eine URL, welche es ausführt",
|
"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",
|
"descriptionEn": "Write our own JavaScript file, upload it via Admin Panel and create an URL to execute it"
|
||||||
"solved": false
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,11 +21,9 @@ account.get("/", (req: Request, res: Response) => {
|
|||||||
// Login user
|
// Login user
|
||||||
account.post("/login", async (req: Request, res: Response) => {
|
account.post("/login", async (req: Request, res: Response) => {
|
||||||
// Using raw SQL code for SQL injections!
|
// Using raw SQL code for SQL injections!
|
||||||
// todo: Inner join
|
|
||||||
const [results, metadata] =
|
const [results, metadata] =
|
||||||
await sequelize.query(
|
await sequelize.query(
|
||||||
"SELECT * FROM Accounts " +
|
"SELECT * FROM Accounts " +
|
||||||
"INNER JOIN Addresses ON Accounts.id=Addresses.accountId " +
|
|
||||||
"WHERE (username='" + req.body.username +
|
"WHERE (username='" + req.body.username +
|
||||||
"' AND password='" + req.body.password + "')")
|
"' AND password='" + req.body.password + "')")
|
||||||
|
|
||||||
@@ -42,6 +40,7 @@ account.post("/login", async (req: Request, res: Response) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (results.length != 0) {
|
if (results.length != 0) {
|
||||||
|
|
||||||
// Status: 200 OK
|
// Status: 200 OK
|
||||||
res.status(200).json(results[0])
|
res.status(200).json(results[0])
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { Op } from "sequelize";
|
||||||
import { Exercise } from "../models/exercises/exercise.model";
|
import { Exercise } from "../models/exercises/exercise.model";
|
||||||
import { ExerciseGroup } from "../models/exercises/exerciseGroup.model";
|
import { ExerciseGroup } from "../models/exercises/exerciseGroup.model";
|
||||||
import { Request, Response, Router } from "express";
|
import { Request, Response, Router } from "express";
|
||||||
@@ -27,19 +28,47 @@ exercises.get("/", (req: Request, res: Response) => {
|
|||||||
* @param state New state boolean
|
* @param state New state boolean
|
||||||
*/
|
*/
|
||||||
exercises.post("/:groupNr/:exerciseNr/:state", (req: Request, res: Response) => {
|
exercises.post("/:groupNr/:exerciseNr/:state", (req: Request, res: Response) => {
|
||||||
ExerciseGroup.findOne({
|
Exercise.findOne({
|
||||||
where: { groupNr: req.params.groupNr }
|
where: {
|
||||||
})
|
[Op.and] : [
|
||||||
.then(group => {
|
{
|
||||||
Exercise.findOne({
|
exerciseNr: req.params.exerciseNr
|
||||||
where: {
|
},
|
||||||
exerciseNr: req.params.exerciseNr,
|
{
|
||||||
exerciseGroupId: group.id
|
"$exerciseGroup.groupNr$": req.params.groupNr
|
||||||
}
|
}
|
||||||
})
|
]
|
||||||
.then(exercise => {
|
},
|
||||||
exercise.update({ solved: req.params.state == "1"})
|
include: [ ExerciseGroup ]
|
||||||
res.status(200).send()
|
})
|
||||||
|
.then(async exercise => {
|
||||||
|
let changed = false
|
||||||
|
|
||||||
|
if (exercise.dataValues.solved != (req.params.state == "1")) {
|
||||||
|
await exercise.update({ solved: req.params.state == "1" })
|
||||||
|
changed = true
|
||||||
|
}
|
||||||
|
|
||||||
|
res.status(200).json({
|
||||||
|
exercise: exercise,
|
||||||
|
changed: changed
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
// ExerciseGroup.findOne({
|
||||||
|
// where: { groupNr: req.params.groupNr }
|
||||||
|
// })
|
||||||
|
// .then(group => {
|
||||||
|
// Exercise.findOne({
|
||||||
|
// where: {
|
||||||
|
// exerciseNr: req.params.exerciseNr,
|
||||||
|
// exerciseGroupId: group.id
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
// .then(exercise => {
|
||||||
|
// exercise.update({ solved: req.params.state == "1"})
|
||||||
|
// res.status(200).send()
|
||||||
|
// })
|
||||||
|
// })
|
||||||
})
|
})
|
||||||
@@ -131,7 +131,6 @@ location.get("/search", (req: Request, res: Response) => {
|
|||||||
include: [ City, Concert ]
|
include: [ City, Concert ]
|
||||||
})
|
})
|
||||||
.then(locations => {
|
.then(locations => {
|
||||||
console.log(locations)
|
|
||||||
res.status(200).json(locations)
|
res.status(200).json(locations)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -64,6 +64,7 @@ export async function prepopulateExerciseDatabase() {
|
|||||||
.then(async dataset => {
|
.then(async dataset => {
|
||||||
for (let exercise of exerciseGroup.exercises) {
|
for (let exercise of exerciseGroup.exercises) {
|
||||||
exercise["exerciseGroupId"] = dataset.id
|
exercise["exerciseGroupId"] = dataset.id
|
||||||
|
exercise["solved"] = false
|
||||||
|
|
||||||
await Exercise.create(exercise)
|
await Exercise.create(exercise)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,13 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { useAccountStore } from '@/stores/account.store';
|
import { useAccountStore } from '@/stores/account.store';
|
||||||
import { useBasketStore } from '@/stores/basket.store';
|
import { useBasketStore } from '@/stores/basket.store';
|
||||||
|
import { useExerciseStore } from '@/stores/exercise.store';
|
||||||
|
|
||||||
const accountStore = useAccountStore()
|
const accountStore = useAccountStore()
|
||||||
const basketStore = useBasketStore()
|
const basketStore = useBasketStore()
|
||||||
|
const exerciseStore = useExerciseStore()
|
||||||
|
|
||||||
|
exerciseStore.getAllExercises()
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -30,6 +34,12 @@ const basketStore = useBasketStore()
|
|||||||
to="/admin"
|
to="/admin"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<v-btn variant="plain" icon="mdi-help" to="/help" />
|
<v-btn
|
||||||
|
v-if="exerciseStore.helpPageVisible"
|
||||||
|
variant="plain"
|
||||||
|
icon="mdi-help"
|
||||||
|
to="/help"
|
||||||
|
/>
|
||||||
|
|
||||||
<v-btn variant="plain" icon="mdi-cog" to="/preferences"/>
|
<v-btn variant="plain" icon="mdi-cog" to="/preferences"/>
|
||||||
</template>
|
</template>
|
||||||
@@ -9,7 +9,7 @@ import { LanguageEnum } from '@/data/enums/languageEnum';
|
|||||||
const exerciseStore = useExerciseStore()
|
const exerciseStore = useExerciseStore()
|
||||||
const preferencesStore = usePreferencesStore()
|
const preferencesStore = usePreferencesStore()
|
||||||
|
|
||||||
exerciseStore.getAllExercises()
|
exerciseStore.solveExercise(1, 1)
|
||||||
|
|
||||||
function getDotColor(exerciseGroupNr: number) {
|
function getDotColor(exerciseGroupNr: number) {
|
||||||
switch(exerciseGroupNr) {
|
switch(exerciseGroupNr) {
|
||||||
|
|||||||
@@ -11,7 +11,9 @@ export const useExerciseStore = defineStore("exerciseStore", {
|
|||||||
exercises: ref<Array<ExerciseModel>>([]),
|
exercises: ref<Array<ExerciseModel>>([]),
|
||||||
|
|
||||||
/** Request to server sent, waiting for data response */
|
/** Request to server sent, waiting for data response */
|
||||||
fetchInProgress: ref(false)
|
fetchInProgress: ref(false),
|
||||||
|
|
||||||
|
helpPageVisible: ref(false)
|
||||||
}),
|
}),
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
@@ -24,10 +26,26 @@ export const useExerciseStore = defineStore("exerciseStore", {
|
|||||||
await fetchAllExerciseGroups()
|
await fetchAllExerciseGroups()
|
||||||
.then(result => {
|
.then(result => {
|
||||||
this.exercises = result.data
|
this.exercises = result.data
|
||||||
|
|
||||||
|
this.helpPageVisible = this.getExercise(1, 1).solved
|
||||||
this.fetchInProgress = false
|
this.fetchInProgress = false
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a exercise by group and exercise number
|
||||||
|
*
|
||||||
|
* @param exerciseGroupNr Number of group of exercise
|
||||||
|
* @param exerciseNr Number of exercise in group
|
||||||
|
*
|
||||||
|
* @returns ExerciseModel
|
||||||
|
*/
|
||||||
|
getExercise(exerciseGroupNr: number, exerciseNr: number): ExerciseModel {
|
||||||
|
return this.exercises.find((exercise: ExerciseModel) => {
|
||||||
|
return exercise.exerciseNr == exerciseNr && exercise.exerciseGroup.groupNr == exerciseGroupNr
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mark an exercise as solved
|
* Mark an exercise as solved
|
||||||
*
|
*
|
||||||
@@ -42,56 +60,57 @@ export const useExerciseStore = defineStore("exerciseStore", {
|
|||||||
this.fetchInProgress = true
|
this.fetchInProgress = true
|
||||||
|
|
||||||
// Change only if the exercise is not solved
|
// Change only if the exercise is not solved
|
||||||
if(!this.exerciseGroups[exerciseGroupNr].exercises[exerciseNr - 1].solved) {
|
updateExercise(exerciseGroupNr, exerciseNr, true)
|
||||||
updateExercise(exerciseGroupNr, exerciseNr, true)
|
.then(result => {
|
||||||
.then(result => {
|
if (result.data.changed) {
|
||||||
|
|
||||||
let bannerState = BannerStateEnum.ERROR
|
let bannerState = BannerStateEnum.ERROR
|
||||||
|
|
||||||
switch(exerciseGroupNr) {
|
switch(exerciseGroupNr) {
|
||||||
case 0: {
|
case 0: {
|
||||||
switch(exerciseNr) {
|
switch(exerciseNr) {
|
||||||
case 1: bannerState = BannerStateEnum.EXERCISESOLVED01; break;
|
case 1: bannerState = BannerStateEnum.EXERCISESOLVED01; break;
|
||||||
case 2: bannerState = BannerStateEnum.EXERCISESOLVED02; break;
|
case 2: bannerState = BannerStateEnum.EXERCISESOLVED02; break;
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case 1: {
|
break;
|
||||||
switch(exerciseNr) {
|
|
||||||
case 1: bannerState = BannerStateEnum.EXERCISESOLVED11; break;
|
|
||||||
case 2: bannerState = BannerStateEnum.EXERCISESOLVED12; break;
|
|
||||||
case 3: bannerState = BannerStateEnum.EXERCISESOLVED13; break;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 2: {
|
|
||||||
switch(exerciseNr) {
|
|
||||||
case 1: bannerState = BannerStateEnum.EXERCISESOLVED21; break;
|
|
||||||
case 2: bannerState = BannerStateEnum.EXERCISESOLVED22; break;
|
|
||||||
case 3: bannerState = BannerStateEnum.EXERCISESOLVED23; break;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 3: {
|
|
||||||
switch(exerciseNr) {
|
|
||||||
case 1: bannerState = BannerStateEnum.EXERCISESOLVED31; break;
|
|
||||||
case 2: bannerState = BannerStateEnum.EXERCISESOLVED32; break;
|
|
||||||
case 3: bannerState = BannerStateEnum.EXERCISESOLVED33; break;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case 1: {
|
||||||
|
switch(exerciseNr) {
|
||||||
|
case 1: bannerState = BannerStateEnum.EXERCISESOLVED11; break;
|
||||||
|
case 2: bannerState = BannerStateEnum.EXERCISESOLVED12; break;
|
||||||
|
case 3: bannerState = BannerStateEnum.EXERCISESOLVED13; break;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 2: {
|
||||||
|
switch(exerciseNr) {
|
||||||
|
case 1: bannerState = BannerStateEnum.EXERCISESOLVED21; break;
|
||||||
|
case 2: bannerState = BannerStateEnum.EXERCISESOLVED22; break;
|
||||||
|
case 3: bannerState = BannerStateEnum.EXERCISESOLVED23; break;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 3: {
|
||||||
|
switch(exerciseNr) {
|
||||||
|
case 1: bannerState = BannerStateEnum.EXERCISESOLVED31; break;
|
||||||
|
case 2: bannerState = BannerStateEnum.EXERCISESOLVED32; break;
|
||||||
|
case 3: bannerState = BannerStateEnum.EXERCISESOLVED33; break;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
feedbackStore.changeBanner(bannerState)
|
feedbackStore.changeBanner(bannerState)
|
||||||
this.getAllExercises()
|
this.getAllExercises()
|
||||||
})
|
}
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
Reference in New Issue
Block a user