diff --git a/.gitignore b/.gitignore index 41ca351..f2b1bd8 100644 --- a/.gitignore +++ b/.gitignore @@ -85,6 +85,9 @@ gradle-app.setting # Cache of project .gradletasknamecache +# Node +node_modules/ + # # Work around https://youtrack.jetbrains.com/issue/IDEA-116898 # gradle/wrapper/gradle-wrapper.properties diff --git a/build.gradle b/build.gradle index 9ac2ca4..58e161e 100644 --- a/build.gradle +++ b/build.gradle @@ -43,7 +43,7 @@ dependencies { //ompile group: 'org.springframework.boot', name: 'spring-boot-starter-mail', version: '1.2.0.RELEASE' compile group: 'org.springframework.security', name: 'spring-security-core', version: '5.1.4.RELEASE' - compile group: 'at.favre.lib', name: 'bcrypt', version: '{latest-version}' + //compile group: 'at.favre.lib', name: 'bcrypt', version: '{latest-version}' //JWT compile 'io.jsonwebtoken:jjwt-api:0.10.5' diff --git a/frontend/src/layouts/MyLayout.vue b/frontend/src/layouts/MyLayout.vue index ed0e123..49ffc82 100644 --- a/frontend/src/layouts/MyLayout.vue +++ b/frontend/src/layouts/MyLayout.vue @@ -22,6 +22,7 @@ @@ -73,11 +73,10 @@ diff --git a/frontend/src/pages/Cache.vue b/frontend/src/pages/Cache.vue index 513310e..27bcf24 100644 --- a/frontend/src/pages/Cache.vue +++ b/frontend/src/pages/Cache.vue @@ -1,74 +1,185 @@ diff --git a/frontend/src/pages/Error404.vue b/frontend/src/pages/Error404.vue index a091bac..75cff24 100644 --- a/frontend/src/pages/Error404.vue +++ b/frontend/src/pages/Error404.vue @@ -5,7 +5,7 @@

Sorry, nothing here...(404)

Go backZur Startseite diff --git a/frontend/src/pages/Login.vue b/frontend/src/pages/Login.vue index cb0e8cc..e6fc7fd 100644 --- a/frontend/src/pages/Login.vue +++ b/frontend/src/pages/Login.vue @@ -1,48 +1,50 @@ diff --git a/frontend/src/pages/StationEdit.vue b/frontend/src/pages/StationEdit.vue index 547869f..f51add4 100644 --- a/frontend/src/pages/StationEdit.vue +++ b/frontend/src/pages/StationEdit.vue @@ -26,9 +26,9 @@

Lösung

- +
- +
@@ -36,35 +36,46 @@ diff --git a/frontend/src/pages/ranking.vue b/frontend/src/pages/ranking.vue new file mode 100644 index 0000000..9ed887f --- /dev/null +++ b/frontend/src/pages/ranking.vue @@ -0,0 +1,90 @@ + + + + diff --git a/frontend/src/router/routes.js b/frontend/src/router/routes.js index ce6b632..0024f01 100644 --- a/frontend/src/router/routes.js +++ b/frontend/src/router/routes.js @@ -5,6 +5,7 @@ const routes = [ children: [{ path: "", component: () => import("pages/Index.vue") }] }, { + path: "/overview/", component: () => import("layouts/MyLayout.vue"), children: [{ path: "", component: () => import("pages/Overview.vue") }] @@ -14,20 +15,41 @@ const routes = [ component: () => import("layouts/MyLayout.vue"), children: [{ path: "", component: () => import("pages/Cache.vue") }] }, + { + path: "/cache/:id", + component: () => import("layouts/MyLayout.vue"), + children: [{ path: "", component: () => import("pages/Cache.vue") }] + }, { path: "/station/", component: () => import("layouts/MyLayout.vue"), children: [{ path: "", component: () => import("pages/StationEdit.vue") }] }, { - path: "/station/:id", + path: "/station/:cache/:id", component: () => import("layouts/MyLayout.vue"), children: [{ path: "", component: () => import("pages/StationView.vue") }] }, + { + path: "/station-l/:pos", + path: "/ranking/", + component: () => import("layouts/MyLayout.vue"), + children: [{path: "", component: () => import("pages/ranking.vue")}] + }, +{ + path: "/station/", + component: () => import("layouts/MyLayout.vue"), + children: [{ path: "", component: () => import("pages/StationEdit.vue") }] + }, { path: "/login/", component: () => import("layouts/MyLayout.vue"), children: [{ path: "", component: () => import("pages/Login.vue") }] + }, + { + path: "/profile/", + component: () => import("layouts/MyLayout.vue"), + children: [{ path: "", component: () => import("pages/Profile.vue") }] } ]; diff --git a/frontend/src/store/auth/getters.js b/frontend/src/store/auth/getters.js index cc054a3..da66d9b 100644 --- a/frontend/src/store/auth/getters.js +++ b/frontend/src/store/auth/getters.js @@ -1,4 +1,24 @@ -/* -export function someGetter (state) { +/** + * @return {boolean} + */ +export function GET_ADMINSTATE(state) { + console.log("GET_ADMINSTATE()"); + if (state.userAuthenticated !== null) { + console.log(state.userAuthenticated.roles.find(x => x.name === "admin") != null); + return state.userAuthenticated.roles.find(x => x.name === "admin") != null; + } else { + console.log(state.userAuthenticated); + return false; + } } -*/ + +// /** +// * @return {boolean} +// */ +// export function IS_AUTHENTICATED(state) { +// console.log("IS_AUTHENTICATED()"); +// console.log(JSON.parse(localStorage.getItem('userToken'))); +// console.log(!(JSON.parse(localStorage.getItem('userToken')) === null)); +// console.log(!(localStorage.getItem('userToken') === null)); +// return !(localStorage.getItem('userToken') === null); +// } diff --git a/frontend/src/store/auth/mutations.js b/frontend/src/store/auth/mutations.js index 46266c0..fed76c1 100644 --- a/frontend/src/store/auth/mutations.js +++ b/frontend/src/store/auth/mutations.js @@ -3,16 +3,41 @@ export const SET_AUTHENTICATED = (state) => { console.log("SET_AUTHENTICATED()"); console.log(JSON.parse(localStorage.getItem('userToken'))); if (localStorage.getItem('userToken')) { - state.userAuthenticated.isAuthenticated = true; + state.isAuthenticated = true; } else { - state.userAuthenticated.isAuthenticated = false; + state.isAuthenticated = false; } }; -export const SET_USER_PROPERTIES = (state, user) => { - console.log("SET_USER_PROPERTIES()"); - console.log("still todo!"); -}; export const SET_LOGOUT = (state) => { console.log("SET_LOGOUT()"); + localStorage.removeItem('userToken'); state.userAuthenticated = null; + state.isAuthenticated = false; + console.log(localStorage.getItem('userToken')); }; +export const SET_USER = (state) => { + console.log("SET_USER()"); + if (localStorage.getItem('userToken')) { + axios.get('http://localhost:8080/api/getUser', { + params: { + token: JSON.parse(localStorage.getItem('userToken')) + } + }) + .then((response) => { + console.log("GET/POST http://localhost:8080/api/getUser - response: "); + console.log(response.data); + state.userAuthenticated = response.data; + state.isAuthenticated = true; + if (state.userAuthenticated.hasOwnProperty('password')) delete state.userAuthenticated.password; + console.log(state.userAuthenticated); + }) + .catch((error) => { + console.log("Catch Block: ") + console.log(error) + }); + } else { + state.isAuthenticated = false; + state.userAuthenticated = null; + } +}; + diff --git a/frontend/src/store/auth/state.js b/frontend/src/store/auth/state.js index 0e9581a..902a77e 100644 --- a/frontend/src/store/auth/state.js +++ b/frontend/src/store/auth/state.js @@ -1,12 +1,19 @@ export default { - userAuthenticated: { - id: 1, - firstname: "t", - lastname: "v", - username: "mo", - email: "test@user.com", - rankingPointsSum: 345, - isAuthenticated: false, - isAdmin: false, - }, + isAuthenticated: false, + userAuthenticated: null, + // userAuthenticated: { + // id: 1, + // firstname: "Timo", + // lastname: "Volkmann", + // username: "moximoti", + // rankingPointsSum: 0, + // email: "test@user.com", + // password: "$2a$10$c3Fo5nuUG.nlwXP94qc7qO01/UC1OL2DebEm.5zYlisKJGRhXMnqq", + // roles: [ + // { + // id: 0, + // name: "admin" + // } + // ] + // }, } diff --git a/frontend/src/store/cacheCollector/getters.js b/frontend/src/store/cacheCollector/getters.js index cc054a3..b2b2dbe 100644 --- a/frontend/src/store/cacheCollector/getters.js +++ b/frontend/src/store/cacheCollector/getters.js @@ -1,4 +1,8 @@ -/* -export function someGetter (state) { -} -*/ +export const GET_CACHE = (state) => { + console.log("GET_CACHE: retrieve cache from store. "); + return state.newCache; +}; +export const GET_TEMPSTATION = (state) => { + console.log("GET_TEMPSTATION: retrieve cache from store. "); + return state.tempStation; +}; diff --git a/frontend/src/store/cacheCollector/mutations.js b/frontend/src/store/cacheCollector/mutations.js index 63131e2..646ab0f 100644 --- a/frontend/src/store/cacheCollector/mutations.js +++ b/frontend/src/store/cacheCollector/mutations.js @@ -1,4 +1,56 @@ -/* -export function someMutation (state) { -} -*/ +export const SET_CACHE = (state, cache) => { + console.log("SET_CACHE: save cache to store. ") + state.newCache = cache; +}; +export const SET_TEMPSTATION = (state, station) => { + console.log("SET_TEMPSTATION: add new station to cache: "+station); + state.tempStation = station; +}; +export const ADD_STATION = (state, station) => { + console.log("ADD_STATION: add new station to cache: "+station); + state.newCache.stationen.push(station); +}; +export const EDIT_STATION = (state, indexStation) => { + let index, station; + index = indexStation.index; + station = indexStation.station; + console.log("EDIT_STATION: "+index+" "+station); + + state.newCache.stationen[index] = station; +}; +export const REMOVE_STATION = (state, index) => { + console.log("REMOVE_STATION: "+index); + state.newCache.stationen.splice(index,1); +}; +export const RESET_NEW_CACHE = (state) => { + state.newCache = { + name: "", + description: "", + rankingPoints: 0, + stationen: [] + }; + console.log("resetted new Cache"); +}; +export const LOAD_REMOTE_CACHE = (state, id) => { + console.log("LOAD_REMOTE_CACHE: get caches from remote"); + this.$axios.get('http://localhost:8080/api/allCaches') + .then((response) => { + const allCaches = JSON.parse(response.data); + console.log("Caches: " + allCaches.length); + if (response.data === undefined || allCaches.length === 0) { + console.log("aborted processing data."); + return; + } + let cacheToSet = null; + for (let cache in allCaches) { + console.log("Cachedata: "); + console.log(cache.id); + console.log(cache.name); + if (cache.id === id) { + cacheToSet = cache; + console.log("found matching ID: setted cache to store."); + break; + } + } + }); +}; diff --git a/frontend/src/store/cacheCollector/state.js b/frontend/src/store/cacheCollector/state.js index 40b8bc3..7087a3a 100644 --- a/frontend/src/store/cacheCollector/state.js +++ b/frontend/src/store/cacheCollector/state.js @@ -1,3 +1,44 @@ export default { - // + newCache: { + name: "", + description: "", + rankingPoints: 0, + stationen: [] + }, + // newCache: { + // name: "Blumencache", + // description: "Dieser Cache umfasst 4 Stationen mit Rätseln rund um das Thema Blumen", + // rankingPoints: 100, + // stationen: [ + // { + // description: "Ein kleines winterliches Schlaginstrument. Welche Blume ist damit gemeint?", + // longitude: 9.206628, + // lattitude: 49.147734, + // code: 213812, + // solution: "Schneeglöckchen" + // }, + // { + // description: "Ein blühendes Federvieh. Welche Blume ist damit gemeint?", + // longitude: 9.206806, + // lattitude: 49.147318, + // code: 237823, + // solution: "Gänseblümchen" + // }, + // { + // description: "Eine wertvolle Farbe. Welche Blume ist damit gemeint?", + // longitude: 9.207844, + // lattitude: 49.148032, + // code: 899423, + // solution: "Edelweiß" + // }, + // { + // description: "Ein Zerkleinerungsgerät in der Brüllöffnung eines Raubtieres. Welche Blume ist damit gemeint?", + // longitude: 9.207649, + // lattitude: 49.150142, + // code: 347923, + // solution: "Löwenzahn" + // } + // ] + // }, + tempStation: {}, } diff --git a/frontend/src/store/index.js b/frontend/src/store/index.js index 8eb6c71..0ce2a96 100644 --- a/frontend/src/store/index.js +++ b/frontend/src/store/index.js @@ -22,7 +22,8 @@ export default function (/* { ssrContext } */) { // enable strict mode (adds overhead!) // for dev mode only - strict: process.env.DEV + //strict: process.env.DEV + strict: false }) /* diff --git a/src/main/java/hhn/labsw/bugageocaching/Application.java b/src/main/java/hhn/labsw/bugageocaching/Application.java index 3a6de76..1eb29fa 100644 --- a/src/main/java/hhn/labsw/bugageocaching/Application.java +++ b/src/main/java/hhn/labsw/bugageocaching/Application.java @@ -12,7 +12,7 @@ public class Application{ /**@Override protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { - return application.sources(Application.class); + return application.sources(Application.class); }**/ public static void main(String[] args) throws Exception { diff --git a/src/main/java/hhn/labsw/bugageocaching/controller/Controller.java b/src/main/java/hhn/labsw/bugageocaching/controller/Controller.java index 91e0c3f..95b376a 100644 --- a/src/main/java/hhn/labsw/bugageocaching/controller/Controller.java +++ b/src/main/java/hhn/labsw/bugageocaching/controller/Controller.java @@ -1,7 +1,7 @@ package hhn.labsw.bugageocaching.controller; import com.google.gson.Gson; - +import com.google.gson.GsonBuilder; import hhn.labsw.bugageocaching.entities.*; import hhn.labsw.bugageocaching.exceptions.IllegalParameterException; import hhn.labsw.bugageocaching.repositories.*; @@ -9,12 +9,17 @@ import io.jsonwebtoken.Claims; import io.jsonwebtoken.ExpiredJwtException; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureAlgorithm; +import io.jsonwebtoken.security.Keys; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.crypto.bcrypt.BCrypt; import org.springframework.web.bind.annotation.*; import javax.annotation.PostConstruct; +import javax.xml.bind.DatatypeConverter; +import java.lang.reflect.Array; +import java.security.Key; import java.security.SecureRandom; import java.util.*; import java.util.concurrent.atomic.AtomicLong; @@ -45,9 +50,6 @@ public class Controller { @Autowired UserRepository userRepository; - @Autowired - StationReihenfolgeRepository stationReihenfolgeRepository; - private AtomicLong counter = new AtomicLong(); byte[] key = new byte[64]; @@ -118,7 +120,6 @@ public class Controller { .setSigningKey(key) .parseClaimsJws(token).getBody(); - User user = userRepository.findByUsername(claims.getSubject()); if (user == null) { return ResponseEntity.status(404).body("User was not found"); @@ -128,29 +129,35 @@ public class Controller { Optional cacheOptional = cacheRepository.findById(Integer.valueOf(cacheID)); if (cacheOptional.isPresent()) { Cache cache = cacheOptional.get(); + + if (bearbeitetRepository.findByUserAndCache(user, cache) != null) { + Bearbeitet bearbeitet1 = bearbeitetRepository.findByUserAndCache(user, cache); + return ResponseEntity.status(200).body(bearbeitet1); + } + bearbeitet.setCache(cache); - Station startStation = cache.getStationen().get(0); - bearbeitet.setAktuelleStation(startStation); - } else { - return ResponseEntity.status(404).body("Couldnt find Cache " + cacheID); - } + Station startStation = cache.getStationen().get(0); + bearbeitet.setAktuelleStation(startStation); + } else { + return ResponseEntity.status(404).body("Couldnt find Cache " + cacheID); + } - Optional cacheAccesDefinitionOptional = - cacheAccesDefinitionRepository.findById(0); // angefangen - if (cacheAccesDefinitionOptional.isPresent()) { - CacheAccesDefinition cacheAccesDefinition = cacheAccesDefinitionOptional.get(); - bearbeitet.setCacheAccesDefinition(cacheAccesDefinition); - } else { - return ResponseEntity.status(404).body("There is no cacheAccesDefinition with the ID " + 0); - } + Optional cacheAccesDefinitionOptional = + cacheAccesDefinitionRepository.findById(0); // angefangen + if (cacheAccesDefinitionOptional.isPresent()) { + CacheAccesDefinition cacheAccesDefinition = cacheAccesDefinitionOptional.get(); + bearbeitet.setCacheAccesDefinition(cacheAccesDefinition); + } else { + return ResponseEntity.status(404).body("There is no cacheAccesDefinition with the ID " + 0); + } bearbeitetRepository.save(bearbeitet); - return ResponseEntity.status(200).body(new Gson().toJson(bearbeitet)); + return ResponseEntity.status(201).body(new Gson().toJson(bearbeitet)); } catch (ExpiredJwtException e) { return ResponseEntity.status(400).body("JWT Token expired"); - } catch (Exception e){ + } catch (Exception e) { return ResponseEntity.status(400).body("JWT Token invalid"); } @@ -187,9 +194,9 @@ public class Controller { .parseClaimsJws(token).getBody(); return ResponseEntity.status(200).body(claims.get("admin")); - }catch (ExpiredJwtException e) { + } catch (ExpiredJwtException e) { return ResponseEntity.status(400).body("JWT Token expired"); - } catch (Exception e){ + } catch (Exception e) { return ResponseEntity.status(400).body("JWT Token invalid"); } @@ -224,20 +231,24 @@ public class Controller { Cache cache = optionalCache.get(); - for (StationReihenfolge stationReihenfolge : stationReihenfolgeRepository.findAll()) { - if (stationReihenfolge.getCache().getId() == cache.getId()) { - stationReihenfolgeRepository.delete(stationReihenfolge); - } - } - for (Bearbeitet bearbeitet : bearbeitetRepository.findAll()) { if (bearbeitet.getCache().getId() == cache.getId()) { bearbeitetRepository.delete(bearbeitet); } } + ArrayList stationen = new ArrayList<>(); + for (Station station : cache.getStationen()) { + stationen.add(stationRepository.findById(station.getId()).get()); + } + cacheRepository.delete(cache); + for (Station station : stationen) { + stationRepository.delete(station); + } + + return ResponseEntity.status(200).body(new Gson().toJson(true)); } @@ -268,7 +279,7 @@ public class Controller { } } catch (ExpiredJwtException e) { return ResponseEntity.status(400).body("JWT Token expired"); - } catch (Exception e){ + } catch (Exception e) { return ResponseEntity.status(400).body("JWT Token invalid"); } } @@ -277,7 +288,18 @@ public class Controller { @RequestMapping("/api/getRankingList") @ResponseBody public ResponseEntity getRankingList() { - return ResponseEntity.status(200).body(new Gson().toJson(userRepository.getRankingList())); + + List sendBackUsers = new LinkedList<>(); + List rankingUsers = userRepository.getRankingList(); + for (Object[] obj : rankingUsers) { + User u = new User(); + u.setId((int) obj[0]); + u.setUsername((String) obj[1]); + u.setRankingPointsSum((int) obj[2]); + sendBackUsers.add(u); + } + + return ResponseEntity.status(200).body(new Gson().toJson(sendBackUsers)); } @CrossOrigin(origins = "http://localhost:8081") // only for dev purpose @@ -298,7 +320,7 @@ public class Controller { } } catch (ExpiredJwtException e) { return ResponseEntity.status(400).body("JWT Token expired"); - } catch (Exception e){ + } catch (Exception e) { return ResponseEntity.status(400).body("JWT Token invalid"); } } diff --git a/src/main/java/hhn/labsw/bugageocaching/entities/StationReihenfolge.java b/src/main/java/hhn/labsw/bugageocaching/entities/StationReihenfolge.java deleted file mode 100644 index b51ef51..0000000 --- a/src/main/java/hhn/labsw/bugageocaching/entities/StationReihenfolge.java +++ /dev/null @@ -1,53 +0,0 @@ -package hhn.labsw.bugageocaching.entities; - -import javax.persistence.*; - -@Entity -@Table -public class StationReihenfolge { - - @Id - @GeneratedValue - private int id; - - @OneToOne - private Cache cache; - - @OneToOne - private Station station; - - @OneToOne - private Station nachfolgeStation; - - public int getId() { - return id; - } - - public void setId(int id) { - this.id = id; - } - - public Cache getCache() { - return cache; - } - - public void setCache(Cache cache) { - this.cache = cache; - } - - public Station getStation() { - return station; - } - - public void setStation(Station station) { - this.station = station; - } - - public Station getNachfolgeStation() { - return nachfolgeStation; - } - - public void setNachfolgeStation(Station nachfolgeStation) { - this.nachfolgeStation = nachfolgeStation; - } -} diff --git a/src/main/java/hhn/labsw/bugageocaching/repositories/BearbeitetRepository.java b/src/main/java/hhn/labsw/bugageocaching/repositories/BearbeitetRepository.java index ac5484c..4b5c1a0 100644 --- a/src/main/java/hhn/labsw/bugageocaching/repositories/BearbeitetRepository.java +++ b/src/main/java/hhn/labsw/bugageocaching/repositories/BearbeitetRepository.java @@ -1,8 +1,11 @@ package hhn.labsw.bugageocaching.repositories; import hhn.labsw.bugageocaching.entities.Bearbeitet; +import hhn.labsw.bugageocaching.entities.Cache; +import hhn.labsw.bugageocaching.entities.User; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.repository.CrudRepository; public interface BearbeitetRepository extends JpaRepository { + Bearbeitet findByUserAndCache(User user, Cache cache); } diff --git a/src/main/java/hhn/labsw/bugageocaching/repositories/StationReihenfolgeRepository.java b/src/main/java/hhn/labsw/bugageocaching/repositories/StationReihenfolgeRepository.java deleted file mode 100644 index 8897965..0000000 --- a/src/main/java/hhn/labsw/bugageocaching/repositories/StationReihenfolgeRepository.java +++ /dev/null @@ -1,7 +0,0 @@ -package hhn.labsw.bugageocaching.repositories; - -import hhn.labsw.bugageocaching.entities.StationReihenfolge; -import org.springframework.data.repository.CrudRepository; - -public interface StationReihenfolgeRepository extends CrudRepository { -} diff --git a/src/main/java/hhn/labsw/bugageocaching/repositories/UserRepository.java b/src/main/java/hhn/labsw/bugageocaching/repositories/UserRepository.java index df051fc..8ab2115 100644 --- a/src/main/java/hhn/labsw/bugageocaching/repositories/UserRepository.java +++ b/src/main/java/hhn/labsw/bugageocaching/repositories/UserRepository.java @@ -14,7 +14,7 @@ import java.util.List; public interface UserRepository extends CrudRepository { User findByUsername(String username); - @Query(value = "SELECT u.username, u.ranking_points_sum from user u order by ranking_points_sum DESC", nativeQuery = true) + @Query(value = "SELECT u.id, u.username, u.ranking_points_sum from user u order by ranking_points_sum DESC", nativeQuery = true) List getRankingList(); }