diff --git a/183_12_1_tresorbackend_rupe-master/pom.xml b/183_12_1_tresorbackend_rupe-master/pom.xml
index 5804d6d..119064b 100644
--- a/183_12_1_tresorbackend_rupe-master/pom.xml
+++ b/183_12_1_tresorbackend_rupe-master/pom.xml
@@ -94,6 +94,17 @@
1.5.0
+
+ io.jsonwebtoken
+ jjwt
+ 0.9.1
+
+
+
+ org.glassfish.jaxb
+ jaxb-runtime
+ 2.3.1
+
diff --git a/183_12_1_tresorbackend_rupe-master/src/main/java/ch/bbw/pr/tresorbackend/controller/AuthController.java b/183_12_1_tresorbackend_rupe-master/src/main/java/ch/bbw/pr/tresorbackend/controller/AuthController.java
new file mode 100644
index 0000000..82409fb
--- /dev/null
+++ b/183_12_1_tresorbackend_rupe-master/src/main/java/ch/bbw/pr/tresorbackend/controller/AuthController.java
@@ -0,0 +1,35 @@
+package ch.bbw.pr.tresorbackend.controller;
+
+import ch.bbw.pr.tresorbackend.model.AuthRequest;
+import ch.bbw.pr.tresorbackend.model.AuthResponse;
+import ch.bbw.pr.tresorbackend.model.User;
+import ch.bbw.pr.tresorbackend.repository.UserRepository;
+import ch.bbw.pr.tresorbackend.service.PasswordEncryptionService;
+import ch.bbw.pr.tresorbackend.util.JwtUtil;
+import jakarta.validation.Valid;
+import lombok.AllArgsConstructor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
+import org.springframework.web.bind.annotation.*;
+
+@RestController
+@AllArgsConstructor
+@RequestMapping("/api/auth")
+public class AuthController {
+ private JwtUtil jwtUtil;
+ private UserRepository userRepository;
+ private PasswordEncryptionService passwordService;
+
+ @CrossOrigin(origins = "${CROSS_ORIGIN}")
+ @PostMapping("/")
+ public ResponseEntity> authentication(@Valid @RequestBody AuthRequest request) {
+ User user = userRepository.findByEmail(request.getEmail()).orElse(null);
+ if (user == null || !passwordService.verifyPassword(user, request.getPassword()) ) {
+ return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
+ }
+ String token = jwtUtil.generateToken(user);
+ return ResponseEntity.ok(new AuthResponse(token));
+ }
+}
\ No newline at end of file
diff --git a/183_12_1_tresorbackend_rupe-master/src/main/java/ch/bbw/pr/tresorbackend/controller/UserController.java b/183_12_1_tresorbackend_rupe-master/src/main/java/ch/bbw/pr/tresorbackend/controller/UserController.java
index 160c754..6aa7e57 100644
--- a/183_12_1_tresorbackend_rupe-master/src/main/java/ch/bbw/pr/tresorbackend/controller/UserController.java
+++ b/183_12_1_tresorbackend_rupe-master/src/main/java/ch/bbw/pr/tresorbackend/controller/UserController.java
@@ -4,6 +4,7 @@ import ch.bbw.pr.tresorbackend.model.*;
import ch.bbw.pr.tresorbackend.service.PasswordEncryptionService;
import ch.bbw.pr.tresorbackend.service.UserService;
+import ch.bbw.pr.tresorbackend.util.Role;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
@@ -22,6 +23,7 @@ import java.util.stream.Collectors;
/**
* UserController
+ *
* @author Peter Rutschmann
*/
@RestController
@@ -85,7 +87,8 @@ public class UserController {
registerUser.getLastName(),
registerUser.getEmail(),
passwordService.hashPassword(registerUser.getPassword()),
- null
+ null,
+ Role.USER
);
User savedUser = userService.createUser(user);
diff --git a/183_12_1_tresorbackend_rupe-master/src/main/java/ch/bbw/pr/tresorbackend/model/AuthRequest.java b/183_12_1_tresorbackend_rupe-master/src/main/java/ch/bbw/pr/tresorbackend/model/AuthRequest.java
new file mode 100644
index 0000000..66afedc
--- /dev/null
+++ b/183_12_1_tresorbackend_rupe-master/src/main/java/ch/bbw/pr/tresorbackend/model/AuthRequest.java
@@ -0,0 +1,9 @@
+package ch.bbw.pr.tresorbackend.model;
+
+import lombok.Value;
+
+@Value
+public class AuthRequest {
+ String email;
+ String password;
+}
diff --git a/183_12_1_tresorbackend_rupe-master/src/main/java/ch/bbw/pr/tresorbackend/model/AuthResponse.java b/183_12_1_tresorbackend_rupe-master/src/main/java/ch/bbw/pr/tresorbackend/model/AuthResponse.java
new file mode 100644
index 0000000..eb444bd
--- /dev/null
+++ b/183_12_1_tresorbackend_rupe-master/src/main/java/ch/bbw/pr/tresorbackend/model/AuthResponse.java
@@ -0,0 +1,10 @@
+package ch.bbw.pr.tresorbackend.model;
+
+import lombok.Value;
+
+@Value
+public class AuthResponse {
+ String token;
+ public AuthResponse(String token) { this.token = token; }
+ public String getToken() { return token; }
+}
diff --git a/183_12_1_tresorbackend_rupe-master/src/main/java/ch/bbw/pr/tresorbackend/model/User.java b/183_12_1_tresorbackend_rupe-master/src/main/java/ch/bbw/pr/tresorbackend/model/User.java
index a0a6958..aa8b310 100644
--- a/183_12_1_tresorbackend_rupe-master/src/main/java/ch/bbw/pr/tresorbackend/model/User.java
+++ b/183_12_1_tresorbackend_rupe-master/src/main/java/ch/bbw/pr/tresorbackend/model/User.java
@@ -1,5 +1,6 @@
package ch.bbw.pr.tresorbackend.model;
+import ch.bbw.pr.tresorbackend.util.Role;
import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Getter;
@@ -35,4 +36,8 @@ public class User {
@Column(nullable = true)
private String two_fa_secret;
+
+ @Column(nullable = true)
+ @Enumerated(EnumType.STRING)
+ private Role role;
}
\ No newline at end of file
diff --git a/183_12_1_tresorbackend_rupe-master/src/main/java/ch/bbw/pr/tresorbackend/util/JwtUtil.java b/183_12_1_tresorbackend_rupe-master/src/main/java/ch/bbw/pr/tresorbackend/util/JwtUtil.java
new file mode 100644
index 0000000..adfa510
--- /dev/null
+++ b/183_12_1_tresorbackend_rupe-master/src/main/java/ch/bbw/pr/tresorbackend/util/JwtUtil.java
@@ -0,0 +1,29 @@
+package ch.bbw.pr.tresorbackend.util;
+
+import ch.bbw.pr.tresorbackend.model.User;
+import io.jsonwebtoken.Claims;
+import io.jsonwebtoken.ExpiredJwtException;
+import io.jsonwebtoken.Jwts;
+import io.jsonwebtoken.SignatureAlgorithm;
+import org.springframework.stereotype.Component;
+
+import java.util.Date;
+
+@Component
+public class JwtUtil {
+ private final String SECRET = "secret-key";
+
+ public String generateToken(User user) {
+ return Jwts.builder()
+ .setSubject(user.getEmail())
+ .claim("role", user.getRole().name())
+ .setIssuedAt(new Date())
+ .setExpiration(new Date(System.currentTimeMillis() + 1000 * 60 * 60))
+ .signWith(SignatureAlgorithm.HS256, SECRET.getBytes())
+ .compact();
+ }
+
+ public Claims validateToken(String token) throws ExpiredJwtException {
+ return Jwts.parser().setSigningKey(SECRET.getBytes()).parseClaimsJws(token).getBody();
+ }
+}
\ No newline at end of file
diff --git a/183_12_1_tresorbackend_rupe-master/src/main/java/ch/bbw/pr/tresorbackend/util/Role.java b/183_12_1_tresorbackend_rupe-master/src/main/java/ch/bbw/pr/tresorbackend/util/Role.java
new file mode 100644
index 0000000..60c65c5
--- /dev/null
+++ b/183_12_1_tresorbackend_rupe-master/src/main/java/ch/bbw/pr/tresorbackend/util/Role.java
@@ -0,0 +1,5 @@
+package ch.bbw.pr.tresorbackend.util;
+
+public enum Role {
+ USER, ADMIN
+}
\ No newline at end of file
diff --git a/183_12_2_tresorfrontend_rupe-master/src/comunication/JwtToken.js b/183_12_2_tresorfrontend_rupe-master/src/comunication/JwtToken.js
new file mode 100644
index 0000000..e824a95
--- /dev/null
+++ b/183_12_2_tresorfrontend_rupe-master/src/comunication/JwtToken.js
@@ -0,0 +1,32 @@
+export const fetchJwtToken = async (loginValues) => {
+ const protocol = process.env.REACT_APP_API_PROTOCOL; // "http"
+ const host = process.env.REACT_APP_API_HOST; // "localhost"
+ const port = process.env.REACT_APP_API_PORT; // "8080"
+ const path = process.env.REACT_APP_API_PATH; // "/api"
+ const portPart = port ? `:${port}` : ''; // port is optional
+ const API_URL = `${protocol}://${host}${portPart}${path}`;
+
+ try {
+ const response = await fetch(`${API_URL}/auth/`, {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json'
+ },
+ body: JSON.stringify({
+ email: loginValues.email,
+ password: loginValues.password,
+ })
+ });
+
+ if (response.ok) {
+ const resJson = await response.json();
+ console.log(resJson)
+ console.log(resJson.token)
+ return resJson.token
+ }
+ throw new Error('jwttoken is not okey');
+ } catch (error) {
+ console.error('Failed to get jwt', error.message);
+ throw new Error('Failed to get jwt' || error.message);
+ }
+};
diff --git a/183_12_2_tresorfrontend_rupe-master/src/pages/user/LoginUser.jsx b/183_12_2_tresorfrontend_rupe-master/src/pages/user/LoginUser.jsx
index 5135ede..f2426a9 100644
--- a/183_12_2_tresorfrontend_rupe-master/src/pages/user/LoginUser.jsx
+++ b/183_12_2_tresorfrontend_rupe-master/src/pages/user/LoginUser.jsx
@@ -3,6 +3,7 @@ import { useNavigate } from 'react-router-dom';
import { loginUser, captchaCheck } from '../../comunication/FetchUser';
import ReCAPTCHA from 'react-google-recaptcha';
import { generate2FACode, verify2FACode } from '../../comunication/TwoFactorAuth';
+import { fetchJwtToken } from '../../comunication/JwtToken';
/**
* LoginUser
@@ -45,6 +46,8 @@ function LoginUser({ loginValues, setLoginValues }) {
const verify2FA = async () => {
const res = await verify2FACode({ loginValues, code });
if (res) {
+ const jwtToken = await fetchJwtToken(loginValues)
+ document.cookie = "jwtToken=" + jwtToken;
navigate('/')
return
}