Compare commits

...

2 Commits

Author SHA1 Message Date
Lorenz Hohermuth 0b9cfbcd2d added captcha 2025-06-06 10:26:34 +02:00
Lorenz Hohermuth 0ea0b8b3c6 password policy 2025-06-06 09:06:58 +02:00
4 changed files with 101 additions and 48 deletions

View File

@ -0,0 +1,4 @@
package ch.bbw.pr.tresorbackend.controller;
public class RecaptchaController {
}

View File

@ -103,3 +103,27 @@ export const loginUser = async (loginValue) => {
throw new Error('Failed to log in. ' || error.message);
}
}
export const captchaCheck = async (captchaToken) => {
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 res = await fetch(`${API_URL}/verify-recaptcha`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ captchaToken }),
});
return await res.json();
} catch (error) {
console.error('Failed to log in:', error.message);
throw new Error('Failed to log in. ' || error.message);
}
}

View File

@ -1,5 +1,7 @@
import React, { useState } from 'react';
import { useNavigate } from 'react-router-dom';
import { loginUser } from '../../comunication/FetchUser';
import { loginUser, captchaCheck } from '../../comunication/FetchUser';
import ReCAPTCHA from 'react-google-recaptcha';
/**
* LoginUser
@ -7,15 +9,26 @@ import { loginUser } from '../../comunication/FetchUser';
*/
function LoginUser({ loginValues, setLoginValues }) {
const navigate = useNavigate();
const [recaptchaToken, setRecaptchaToken] = useState(null);
const handleCaptcha = (token) => {
setRecaptchaToken(token);
};
const handleSubmit = async (e) => {
e.preventDefault();
if (!recaptchaToken) {
alert("Please verify reCAPTCHA");
return;
}
try {
const captchaData = await captchaCheck(recaptchaToken);
let isLoginValid = false
isLoginValid = await loginUser(loginValues);
console.log(loginValues);
if (isLoginValid) {
if (isLoginValid || captchaData.success) {
setLoginValues({ userName: loginValues.email, password: loginValues.password });
navigate('/');
}
@ -33,7 +46,7 @@ function LoginUser({ loginValues, setLoginValues }) {
<div>
<label>Email:</label>
<input
type="text"
type="email"
value={loginValues.email}
onChange={(e) =>
setLoginValues(prevValues => ({ ...prevValues, email: e.target.value }))}
@ -44,7 +57,7 @@ function LoginUser({ loginValues, setLoginValues }) {
<div>
<label>Password:</label>
<input
type="text"
type="password"
value={loginValues.password}
onChange={(e) =>
setLoginValues(prevValues => ({ ...prevValues, password: e.target.value }))}
@ -54,6 +67,10 @@ function LoginUser({ loginValues, setLoginValues }) {
</div>
</aside>
</section>
<ReCAPTCHA
sitekey="6LdJj1crAAAAABcEz65x0DUAsuJUBCKwdSi1Mewj"
onChange={handleCaptcha}
/>
<button type="submit">Login</button>
</form>
</div>

View File

@ -31,6 +31,14 @@ function RegisterUser({loginValues, setLoginValues}) {
return;
}
const passwordRegex = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]).{8,}$/;;
if (!passwordRegex.test(credentials.password)) {
setErrorMessage('Password must contain at least one uppercase letter, one lowercase letter, one number, and one special character.');
return;
}
try {
await postUser(credentials);
setLoginValues({ userName: credentials.email, password: credentials.password });
@ -73,7 +81,7 @@ function RegisterUser({loginValues, setLoginValues}) {
<div>
<label>Email:</label>
<input
type="text"
type="email"
value={credentials.email}
onChange={(e) =>
setCredentials(prevValues => ({ ...prevValues, email: e.target.value }))}
@ -86,7 +94,7 @@ function RegisterUser({loginValues, setLoginValues}) {
<div>
<label>Password:</label>
<input
type="text"
type="password"
value={credentials.password}
onChange={(e) =>
setCredentials(prevValues => ({ ...prevValues, password: e.target.value }))}
@ -97,7 +105,7 @@ function RegisterUser({loginValues, setLoginValues}) {
<div>
<label>Password confirmation:</label>
<input
type="text"
type="password"
value={credentials.passwordConfirmation}
onChange={(e) =>
setCredentials(prevValues => ({ ...prevValues, passwordConfirmation: e.target.value }))}