Skip to content

Commit fc016fc

Browse files
committed
fix: signInResource
1 parent dd8d0ac commit fc016fc

File tree

1 file changed

+46
-3
lines changed

1 file changed

+46
-3
lines changed

timeless-api/src/main/java/dev/matheuscruz/presentation/SignInResource.java

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,14 @@
22

33
import dev.matheuscruz.domain.User;
44
import dev.matheuscruz.domain.UserRepository;
5+
import dev.matheuscruz.infra.security.AESAdapter;
56
import dev.matheuscruz.infra.security.BCryptAdapter;
67
import dev.matheuscruz.infra.security.Groups;
78
import io.quarkus.panache.common.Parameters;
89
import io.smallrye.jwt.build.Jwt;
10+
import jakarta.persistence.EntityManager;
11+
import jakarta.persistence.NoResultException;
12+
import jakarta.transaction.Transactional;
913
import jakarta.validation.Valid;
1014
import jakarta.validation.constraints.Email;
1115
import jakarta.validation.constraints.NotBlank;
@@ -15,22 +19,61 @@
1519
import jakarta.ws.rs.Path;
1620
import jakarta.ws.rs.core.Response;
1721
import java.time.Duration;
22+
import java.util.Optional;
1823
import java.util.Set;
1924

2025
@Path("/api/sign-in")
2126
public class SignInResource {
2227

2328
UserRepository userRepository;
29+
AESAdapter aesAdapter;
30+
EntityManager entityManager;
2431

25-
public SignInResource(UserRepository userRepository) {
32+
public SignInResource(UserRepository userRepository, AESAdapter aesAdapter, EntityManager entityManager) {
2633
this.userRepository = userRepository;
34+
this.aesAdapter = aesAdapter;
35+
this.entityManager = entityManager;
2736
}
2837

2938
@POST
39+
@Transactional
3040
public Response signIn(@Valid SignInRequest req) {
3141

32-
User user = userRepository.find("email = :email", Parameters.with("email", req.email())).firstResultOptional()
33-
.orElseThrow(ForbiddenException::new);
42+
Optional<User> userOptional = userRepository.find("email = :email", Parameters.with("email", req.email()))
43+
.firstResultOptional();
44+
45+
User user = null;
46+
47+
if (userOptional.isPresent()) {
48+
user = userOptional.get();
49+
} else {
50+
// try to find by plain text
51+
try {
52+
user = (User) entityManager.createNativeQuery("SELECT * FROM users WHERE email = :email", User.class)
53+
.setParameter("email", req.email()).getSingleResult();
54+
55+
// if found, we need to migrate the user to the new encryption format
56+
// but first we need to check the password
57+
Boolean checked = BCryptAdapter.checkPassword(req.password(), user.getPassword());
58+
59+
if (!checked) {
60+
return Response.status(Response.Status.UNAUTHORIZED).build();
61+
}
62+
63+
String encryptedEmail = aesAdapter.encrypt(req.email());
64+
String encryptedPhone = user.getPhoneNumber() != null ? aesAdapter.encrypt(user.getPhoneNumber())
65+
: null;
66+
67+
entityManager.createNativeQuery("UPDATE users SET email = :email, phone_number = :phone WHERE id = :id")
68+
.setParameter("email", encryptedEmail).setParameter("phone", encryptedPhone)
69+
.setParameter("id", user.getId()).executeUpdate();
70+
71+
} catch (NoResultException e) {
72+
throw new ForbiddenException();
73+
} catch (Exception e) {
74+
throw new RuntimeException(e);
75+
}
76+
}
3477

3578
Boolean checked = BCryptAdapter.checkPassword(req.password(), user.getPassword());
3679

0 commit comments

Comments
 (0)