Merge pull request #68 from ricardo-campos-org/feat/65-fix-env-file-with-server-address

fix env file with server address and error handling in the backend
This commit is contained in:
2024-09-26 21:44:45 -03:00
committed by GitHub
7 changed files with 79 additions and 14 deletions
+2 -2
View File
@@ -25,7 +25,7 @@
Strict-Transport-Security "max-age=31536000"
Content-Security-Policy "
base-uri 'self';
connect-src 'self';
connect-src 'self' {$VITE_BACKEND_SERVER};
default-src 'self';
font-src https://cdn.jsdelivr.net/npm/ 'self';
frame-src 'self';
@@ -42,7 +42,7 @@
handle /env.js {
header Content-Type "text/javascript"
respond `window.config = {"BUILD":"{$BUILD}"};`
respond `window.config = {"VITE_BUILD":"{$VITE_BUILD}","VITE_BACKEND_SERVER":"{$VITE_BACKEND_SERVER}"};`
}
file_server
+2 -2
View File
@@ -4,9 +4,9 @@ const server = env.VITE_BACKEND_SERVER;
const ApiConfig = {
signInUrl: `${server}/auth/signin`,
signInUrl: `${server}/auth/sign-in`,
registerUrl: `${server}/auth/signup`,
registerUrl: `${server}/auth/sign-up`,
refreshTokenUrl: `${server}/rest/user-sessions/refresh`,
+4
View File
@@ -35,6 +35,8 @@ async function registerUser(email: string, password: string): Promise<SigninResp
} catch (error) {
if (typeof error === 'string') {
throw new Error(error as string);
} else if (error instanceof Error) {
throw error;
}
}
throw new Error('Unknown error');
@@ -76,6 +78,8 @@ async function authenticateUser(email: string, password: string): Promise<Signin
} catch (error) {
if (typeof error === 'string') {
throw new Error(error as string);
} else if (error instanceof Error) {
throw error;
}
}
throw new Error('Unknown error');
+5 -2
View File
@@ -29,7 +29,7 @@ const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children }: Pro
return bearerToken;
} catch (e) {
if (e instanceof Error) {
if (e.message !== 'No saved token!') {
if (e.message !== 'No saved token!' && e.message !== 'Forbidden! Access denied') {
console.warn(e.message);
}
} else if (e) {
@@ -82,7 +82,10 @@ const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children }: Pro
updateUserSession(currentUser, registerResponse.token);
return Promise.resolve('OK');
} catch (e) {
return Promise.reject(e);
if (e instanceof Error) {
return Promise.reject(new Error(e.message));
}
return Promise.reject(new Error('Unknown error!'));
}
};
@@ -40,7 +40,7 @@ public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.cors(Customizer.withDefaults())
.csrf(Customizer.withDefaults())
.csrf(custom -> custom.ignoringRequestMatchers("/auth/**"))
.authorizeHttpRequests(
request ->
request
@@ -3,10 +3,13 @@ package br.com.tasknoteapp.java_api.service.impl;
import br.com.tasknoteapp.java_api.service.JwtService;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.MalformedJwtException;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Function;
import javax.crypto.SecretKey;
import org.springframework.security.core.userdetails.UserDetails;
@@ -29,7 +32,10 @@ class JwtServiceImpl implements JwtService {
@Override
public LocalDateTime extractExpiration(String token) {
Date date = extractClaim(token, Claims::getExpiration);
return date.toInstant().atZone(java.time.ZoneId.systemDefault()).toLocalDateTime();
if (!Objects.isNull(date)) {
return date.toInstant().atZone(java.time.ZoneId.systemDefault()).toLocalDateTime();
}
return null;
}
@Override
@@ -51,21 +57,33 @@ class JwtServiceImpl implements JwtService {
@Override
public boolean isTokenExpired(String token) {
return extractExpiration(token).isBefore(LocalDateTime.now());
LocalDateTime expiration = extractExpiration(token);
if (expiration != null) {
return expiration.isBefore(LocalDateTime.now());
}
return true;
}
@Override
public boolean validateTokenAndUser(String token, UserDetails user) {
final String email = user.getUsername();
return !isTokenExpired(token) && getEmailFromToken(token).equals(email);
return !isTokenExpired(token) && email.equals(getEmailFromToken(token));
}
private <T> T extractClaim(String token, Function<Claims, T> claimsResolver) {
final Claims claims = extractAllClaims(token);
return claimsResolver.apply(claims);
final Optional<Claims> claims = extractAllClaims(token);
if (claims.isPresent()) {
return claimsResolver.apply(claims.get());
}
return null;
}
private Claims extractAllClaims(String token) {
return Jwts.parser().verifyWith(KEY).build().parseSignedClaims(token).getPayload();
private Optional<Claims> extractAllClaims(String token) {
try {
return Optional.of(
Jwts.parser().verifyWith(KEY).build().parseSignedClaims(token).getPayload());
} catch (MalformedJwtException me) {
return Optional.empty();
}
}
}
+40
View File
@@ -40,6 +40,7 @@ docker pull ghcr.io/ricardo-campos-org/react-typescript-todolist/client:50
Run it:
- Client
```sh
docker run -d --rm \
-p 80:5000 \
@@ -48,3 +49,42 @@ docker run -d --rm \
--name tasknote \
ghcr.io/ricardo-campos-org/react-typescript-todolist/client:50
```
- Java API
```sh
docker run -d --rm \
-p 8585:8585 \
-e CORS_ALLOWED_ORIGINS="http://localhost:5000" \
-e POSTGRES_DB=tasknote \
-e POSTGRES_HOST=localhost \
-e POSTGRES_USER=tasknoteuser \
-e POSTGRES_PASSWORD=default \
-e POSTGRES_PORT=5435 \
--name java-api \
ghcr.io/ricardo-campos-org/react-typescript-todolist/java-api:50
```
or
```sh
docker compose --file docker-compose.prod.yml up -d server
```
- DB
```sh
docker run -d --rm \
-p 5435:5432 \
-e POSTGRES_DB="tasknote" \
-e POSTGRES_USER="tasknoteuser" \
-e POSTGRES_PASSWORD="default" \
-e POSTGRES_PORT=5435 \
-e PGDATA=/tmp \
-v "./data:/tmp" \
--name db \
postgres:15.8-bookworm
```
or
```sh
docker compose --file docker-compose.prod.yml up -d db
```
- Get container IP
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' db