package com.kpaudel.controller;
import com.kpaudel.model.User;
import com.kpaudel.repository.UserRepository;
import com.kpaudel.security.JwtUtil;
import com.kpaudel.service.EmailService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.*;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;
@RestController
@RequestMapping("/api/auth")
@CrossOrigin(origins = {"http://localhost:3000"})
public class AuthController {
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private UserRepository userRepository;
@Autowired
private JwtUtil jwtUtil;
@Autowired
private PasswordEncoder passwordEncoder;
@Autowired
private EmailService emailService;
@PostMapping("/register")
public ResponseEntity<?> register(@RequestBody Map<String, String> request) {
String username = request.get("username");
String email = request.get("email");
String firstName=request.get("firstName");
String lastName=request.get("lastName");
String password = request.get("password");
if (userRepository.findByUsername(username).isPresent()) {
return ResponseEntity.status(HttpStatus.BAD_REQUEST)
.body(Map.of("error", "Username already exists"));
}
if (userRepository.findByEmail(email).isPresent()) {
return ResponseEntity.status(HttpStatus.BAD_REQUEST)
.body(Map.of("error", "Email already exists"));
}
User user = new User();
user.setUsername(username);
user.setEmail(email);
user.setFirstName(firstName);
user.setLastName(lastName);
user.setPassword(passwordEncoder.encode(password));
String confirmationToken = UUID.randomUUID().toString();
user.setConfirmationToken(confirmationToken);
userRepository.save(user);
emailService.sendConfirmationEmail(email, confirmationToken);
return ResponseEntity.ok(Map.of("message", "User registered successfully. Please check your email for confirmation."));
}
@PostMapping("/login")
public ResponseEntity<?> login(@RequestBody Map<String, String> request) {
String username = request.get("username");
String password = request.get("password");
try {
Authentication authentication = authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(username, password)
);
UserDetails userDetails = (UserDetails) authentication.getPrincipal();
String token = jwtUtil.generateToken(userDetails);
return ResponseEntity.ok(Map.of("token", token, "username", username));
} catch (Exception e) {
return ResponseEntity.status(HttpStatus.UNAUTHORIZED)
.body(Map.of("error", "Invalid credentials"));
}
}
@GetMapping("/confirm")
public ResponseEntity<?> confirm(@RequestParam String token) {
Optional<User> optionalUser = userRepository.findByConfirmationToken(token);
if (optionalUser.isPresent()) {
User user = optionalUser.get();
if (user.getStatus() == User.UserStatus.PENDING) {
user.setStatus(User.UserStatus.CONFIRMED);
user.setConfirmationToken(null);
userRepository.save(user);
emailService.sendWelcomeEmail(user.getEmail());
return ResponseEntity.ok(Map.of("message", "Email confirmed successfully. You can now log in."));
} else {
return ResponseEntity.status(HttpStatus.BAD_REQUEST)
.body(Map.of("error", "Invalid or already confirmed token"));
}
}
return ResponseEntity.status(HttpStatus.BAD_REQUEST)
.body(Map.of("error", "Invalid token"));
}
}