Changeset ae83647 for petify-backend/src/main
- Timestamp:
- 06/26/26 16:32:12 (2 days ago)
- Branches:
- master
- Parents:
- fa32d0f
- Location:
- petify-backend/src/main
- Files:
-
- 4 added
- 5 edited
-
java/com/petify/petify/api/AdminClinicApplicationsController.java (modified) (3 diffs)
-
java/com/petify/petify/api/AuthController.java (modified) (2 diffs)
-
java/com/petify/petify/dto/ChangePasswordRequest.java (added)
-
java/com/petify/petify/dto/ForgotPasswordRequest.java (added)
-
java/com/petify/petify/repo/VetClinicRepository.java (modified) (1 diff)
-
java/com/petify/petify/service/AuthService.java (modified) (5 diffs)
-
java/com/petify/petify/service/ClinicApprovalService.java (added)
-
java/com/petify/petify/service/ClinicCredentialsEmailService.java (added)
-
resources/application.properties (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
petify-backend/src/main/java/com/petify/petify/api/AdminClinicApplicationsController.java
rfa32d0f rae83647 1 1 package com.petify.petify.api; 2 2 3 import com.petify.petify.domain.VetClinic;4 3 import com.petify.petify.domain.VetClinicApplication; 5 4 import com.petify.petify.dto.VetClinicApplicationDTO; 6 5 import com.petify.petify.repo.AdminRepository; 7 6 import com.petify.petify.repo.VetClinicApplicationRepository; 8 import com.petify.petify. repo.VetClinicRepository;7 import com.petify.petify.service.ClinicApprovalService; 9 8 import org.springframework.http.HttpStatus; 10 9 import org.springframework.http.ResponseEntity; … … 20 19 21 20 private final VetClinicApplicationRepository applicationRepository; 22 private final VetClinicRepository clinicRepository;23 21 private final AdminRepository adminRepository; 22 private final ClinicApprovalService clinicApprovalService; 24 23 25 24 public AdminClinicApplicationsController(VetClinicApplicationRepository applicationRepository, 26 VetClinicRepository clinicRepository,27 AdminRepository adminRepository) {25 AdminRepository adminRepository, 26 ClinicApprovalService clinicApprovalService) { 28 27 this.applicationRepository = applicationRepository; 29 this.clinicRepository = clinicRepository;30 28 this.adminRepository = adminRepository; 29 this.clinicApprovalService = clinicApprovalService; 31 30 } 32 31 … … 56 55 .body(Map.of("error", "Admin access required")); 57 56 } 58 VetClinicApplication application = applicationRepository.findById(applicationId) 59 .orElseThrow(() -> new RuntimeException("Application not found")); 60 61 application.setStatus("APPROVED"); 62 application.setReviewedAt(LocalDateTime.now()); 63 application.setReviewedBy(adminUserId); 64 application.setDenialReason(null); 65 VetClinicApplication saved = applicationRepository.save(application); 66 67 boolean clinicExists = clinicRepository.findAll().stream() 68 .anyMatch(clinic -> applicationId.equals(clinic.getApplicationId())); 69 if (!clinicExists) { 70 VetClinic clinic = new VetClinic(); 71 clinic.setApplicationId(application.getApplicationId()); 72 clinic.setName(application.getName()); 73 clinic.setEmail(application.getEmail()); 74 clinic.setPhone(application.getPhone()); 75 clinic.setCity(application.getCity()); 76 clinic.setAddress(application.getAddress()); 77 clinicRepository.save(clinic); 78 } 57 VetClinicApplication saved = clinicApprovalService.approveApplication(applicationId, adminUserId); 79 58 80 59 return ResponseEntity.ok(new VetClinicApplicationDTO(saved)); -
petify-backend/src/main/java/com/petify/petify/api/AuthController.java
rfa32d0f rae83647 2 2 3 3 import com.petify.petify.dto.AuthResponse; 4 import com.petify.petify.dto.ChangePasswordRequest; 5 import com.petify.petify.dto.ForgotPasswordRequest; 4 6 import com.petify.petify.dto.LoginRequest; 5 7 import com.petify.petify.dto.SignUpRequest; … … 47 49 } 48 50 51 @PostMapping("/change-password") 52 public ResponseEntity<?> changePassword(@RequestBody ChangePasswordRequest request) { 53 try { 54 authService.changePassword(request.getUserId(), request.getCurrentPassword(), request.getNewPassword()); 55 return ResponseEntity.ok(Map.of("message", "Password changed successfully")); 56 } catch (RuntimeException e) { 57 return ResponseEntity.badRequest() 58 .body(Map.of("message", e.getMessage())); 59 } 60 } 61 62 @PostMapping("/forgot-password") 63 public ResponseEntity<?> forgotPassword(@RequestBody ForgotPasswordRequest request) { 64 try { 65 authService.sendForgotPasswordEmail(request.getIdentifier()); 66 return ResponseEntity.ok(Map.of("message", "If an account matches that username or email, a temporary password has been sent.")); 67 } catch (RuntimeException e) { 68 return ResponseEntity.badRequest() 69 .body(Map.of("message", e.getMessage())); 70 } 71 } 72 49 73 50 74 @GetMapping("/users") -
petify-backend/src/main/java/com/petify/petify/repo/VetClinicRepository.java
rfa32d0f rae83647 10 10 public interface VetClinicRepository extends JpaRepository<VetClinic, Long> { 11 11 java.util.List<VetClinic> findAllByOrderByNameAsc(); 12 Optional<VetClinic> findByApplicationId(Long applicationId); 12 13 Optional<VetClinic> findByUserId(Long userId); 13 14 boolean existsByUserId(Long userId); -
petify-backend/src/main/java/com/petify/petify/service/AuthService.java
rfa32d0f rae83647 22 22 import org.springframework.transaction.annotation.Transactional; 23 23 24 import java.security.SecureRandom; 24 25 import java.time.LocalDateTime; 25 26 import java.util.List; … … 31 32 32 33 private static final Logger logger = LoggerFactory.getLogger(AuthService.class); 34 private static final String PASSWORD_CHARS = "ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz23456789!@#$%"; 35 private static final SecureRandom SECURE_RANDOM = new SecureRandom(); 33 36 34 37 private final UserRepository userRepository; … … 39 42 private final AnalyticsRepository analyticsRepository; 40 43 private final VetClinicRepository vetClinicRepository; 44 private final ClinicCredentialsEmailService credentialsEmailService; 41 45 42 46 public AuthService(UserRepository userRepository, ClientRepository clientRepository, 43 47 OwnerRepository ownerRepository, AdminRepository adminRepository, 44 48 PasswordEncoder passwordEncoder, AnalyticsRepository analyticsRepository, 45 VetClinicRepository vetClinicRepository) { 49 VetClinicRepository vetClinicRepository, 50 ClinicCredentialsEmailService credentialsEmailService) { 46 51 this.userRepository = userRepository; 47 52 this.clientRepository = clientRepository; … … 51 56 this.analyticsRepository = analyticsRepository; 52 57 this.vetClinicRepository = vetClinicRepository; 58 this.credentialsEmailService = credentialsEmailService; 53 59 } 54 60 … … 177 183 isVerified 178 184 ); 185 } 186 187 @Transactional 188 public void changePassword(Long userId, String currentPassword, String newPassword) { 189 if (userId == null) { 190 throw new RuntimeException("User is required"); 191 } 192 if (currentPassword == null || currentPassword.isBlank()) { 193 throw new RuntimeException("Current password is required"); 194 } 195 if (newPassword == null || newPassword.isBlank()) { 196 throw new RuntimeException("New password is required"); 197 } 198 if (newPassword.length() < 8) { 199 throw new RuntimeException("New password must be at least 8 characters long"); 200 } 201 if (newPassword.equals(currentPassword)) { 202 throw new RuntimeException("New password must be different from the current password"); 203 } 204 205 User user = userRepository.findById(userId) 206 .orElseThrow(() -> new RuntimeException("User not found")); 207 208 boolean passwordMatches = passwordEncoder.matches(currentPassword, user.getPassword()); 209 if (!passwordMatches && !currentPassword.equals(user.getPassword())) { 210 throw new RuntimeException("Current password is incorrect"); 211 } 212 213 user.setPassword(passwordEncoder.encode(newPassword)); 214 userRepository.save(user); 215 logger.info("Password changed successfully for user: {}", user.getUsername()); 216 } 217 218 @Transactional 219 public void sendForgotPasswordEmail(String identifier) { 220 if (identifier == null || identifier.isBlank()) { 221 throw new RuntimeException("Username or email is required"); 222 } 223 224 Optional<User> user = userRepository.findByUsernameOrEmail(identifier.trim(), identifier.trim()); 225 if (user.isEmpty()) { 226 logger.info("Password reset requested for unknown identifier: {}", identifier); 227 return; 228 } 229 230 User foundUser = user.get(); 231 String temporaryPassword = generateTemporaryPassword(); 232 foundUser.setPassword(passwordEncoder.encode(temporaryPassword)); 233 userRepository.save(foundUser); 234 235 credentialsEmailService.sendTemporaryPassword( 236 foundUser.getEmail(), 237 foundUser.getFirstName(), 238 foundUser.getUsername(), 239 temporaryPassword 240 ); 241 logger.info("Temporary password sent for user: {}", foundUser.getUsername()); 242 } 243 244 private String generateTemporaryPassword() { 245 StringBuilder password = new StringBuilder(); 246 for (int i = 0; i < 14; i++) { 247 password.append(PASSWORD_CHARS.charAt(SECURE_RANDOM.nextInt(PASSWORD_CHARS.length()))); 248 } 249 return password.toString(); 179 250 } 180 251 -
petify-backend/src/main/resources/application.properties
rfa32d0f rae83647 33 33 spring.flyway.baseline-version=0 34 34 35 # Mail 36 spring.mail.host=${MAIL_HOST:smtp.gmail.com} 37 spring.mail.port=${MAIL_PORT:587} 38 spring.mail.username=${MAIL_USERNAME:} 39 spring.mail.password=${MAIL_PASSWORD:} 40 spring.mail.properties.mail.smtp.auth=true 41 spring.mail.properties.mail.smtp.starttls.enable=true 42 spring.mail.properties.mail.smtp.starttls.required=true 43 management.health.mail.enabled=false 44 35 45 spring.profiles.active=local 36 spring.config.import=optional:file:.env.properties 46 spring.config.import=optional:file:.env.properties,optional:file:petify-backend/.env.properties 37 47 38 48
Note:
See TracChangeset
for help on using the changeset viewer.
