diff --git a/backend-service/pom.xml b/backend-service/pom.xml index 675356a..4ed377b 100644 --- a/backend-service/pom.xml +++ b/backend-service/pom.xml @@ -42,11 +42,6 @@ org.springframework.boot spring-boot-starter-web - - org.springframework.boot - spring-boot-starter-websocket - 3.2.0 - com.mysql mysql-connector-j @@ -84,21 +79,6 @@ 0.11.1 runtime - - com.twilio.sdk - twilio - 10.0.0 - - - me.paulschwarz - spring-dotenv - 4.0.0 - - - org.springframework.amqp - spring-amqp - 3.0.2 - io.netty netty-resolver-dns-native-macos diff --git a/backend-service/src/main/java/co/teamsphere/api/config/WebSocketConfig.java b/backend-service/src/main/java/co/teamsphere/api/config/WebSocketConfig.java deleted file mode 100644 index 1b3f8dc..0000000 --- a/backend-service/src/main/java/co/teamsphere/api/config/WebSocketConfig.java +++ /dev/null @@ -1,40 +0,0 @@ -package co.teamsphere.api.config; - -import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.annotation.Configuration; -import org.springframework.messaging.simp.config.MessageBrokerRegistry; -import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker; -import org.springframework.web.socket.config.annotation.StompEndpointRegistry; -import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer; - -@Configuration -@EnableWebSocketMessageBroker -public class WebSocketConfig implements WebSocketMessageBrokerConfigurer{ - - @Value("${spring.rabbitmq.username}") - private String userName; - @Value("${spring.rabbitmq.password}") - private String password; - @Value("${spring.rabbitmq.host}") - private String host; - @Value("${spring.rabbitmq.port}") - private int port; - - @SuppressWarnings("null") - @Override - public void registerStompEndpoints(StompEndpointRegistry registry) { - registry.addEndpoint("/ws").setAllowedOriginPatterns("*").withSockJS(); - } - - @SuppressWarnings("null") - @Override - public void configureMessageBroker(MessageBrokerRegistry registry) { - registry.enableStompBrokerRelay("/group", "/user") - .setRelayHost(host) - .setRelayPort(port) - .setSystemLogin(userName) - .setSystemPasscode(password); - registry.setApplicationDestinationPrefixes("/app"); - registry.setUserDestinationPrefix("/user"); - } -} diff --git a/backend-service/src/main/java/co/teamsphere/api/controller/AuthController.java b/backend-service/src/main/java/co/teamsphere/api/controller/AuthController.java index 253e4f0..ca6436e 100644 --- a/backend-service/src/main/java/co/teamsphere/api/controller/AuthController.java +++ b/backend-service/src/main/java/co/teamsphere/api/controller/AuthController.java @@ -1,50 +1,34 @@ package co.teamsphere.api.controller; -import java.time.Instant; -import java.time.LocalDateTime; -import java.time.ZoneOffset; -import java.util.Optional; -import java.util.UUID; - -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; -import org.springframework.http.ResponseEntity; -import org.springframework.security.authentication.BadCredentialsException; -import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.security.crypto.password.PasswordEncoder; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.ModelAttribute; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestPart; -import org.springframework.web.bind.annotation.RestController; - import co.teamsphere.api.config.JWTTokenProvider; import co.teamsphere.api.exception.ProfileImageException; import co.teamsphere.api.exception.RefreshTokenException; import co.teamsphere.api.exception.UserException; -import co.teamsphere.api.models.RefreshToken; -import co.teamsphere.api.models.User; -import co.teamsphere.api.repository.UserRepository; import co.teamsphere.api.request.LoginRequest; import co.teamsphere.api.request.RefreshTokenRequest; import co.teamsphere.api.request.SignupRequest; import co.teamsphere.api.response.AuthResponse; import co.teamsphere.api.services.AuthenticationService; import co.teamsphere.api.services.RefreshTokenService; -import co.teamsphere.api.utils.GoogleAuthRequest; -import co.teamsphere.api.utils.GoogleUserInfo; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; -import jakarta.transaction.Transactional; import jakarta.validation.Valid; import lombok.extern.slf4j.Slf4j; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.security.authentication.BadCredentialsException; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/auth") @@ -56,21 +40,13 @@ public class AuthController { private final RefreshTokenService refreshTokenService; - private final UserRepository userRepository; - - private final PasswordEncoder passwordEncoder; - public AuthController(JWTTokenProvider jwtTokenProvider, AuthenticationService authenticationService, - RefreshTokenService refreshTokenService, - UserRepository userRepository, - PasswordEncoder passwordEncoder + RefreshTokenService refreshTokenService ) { this.jwtTokenProvider = jwtTokenProvider; this.authenticationService = authenticationService; this.refreshTokenService = refreshTokenService; - this.userRepository = userRepository; - this.passwordEncoder = passwordEncoder; } @GetMapping("/verify") @@ -118,7 +94,7 @@ public ResponseEntity verifyJwtToken() { }) public ResponseEntity refreshTest(@RequestBody RefreshTokenRequest request) throws RefreshTokenException { try { - // there is a way to do this with just optionals and maps, but you are a funny guy if you think im writing that out (its not readable) + // there is a way to do this with just optionals and maps, but you are a funny guy if you think im writing that out (it's not readable) log.info("Processing refresh token request"); var refreshToken = refreshTokenService.findRefreshToken(request.getRefreshToken()); @@ -224,86 +200,4 @@ public ResponseEntity userLoginMethod( throw new UserException("Unexpected error during login process."); } } - - @PostMapping("/google") - @Transactional // move business logic to service layer - @Operation(summary = "Authenticate via Google", description = "login/signup via Google OAuth.") - @ApiResponses(value = { - @ApiResponse(responseCode = "200", - description = "Authentication successful", - content = @Content( - mediaType = MediaType.APPLICATION_JSON_VALUE, - schema = @Schema(implementation = AuthResponse.class) - ) - ), - @ApiResponse(responseCode = "500", description = "Google authentication failed") - }) - public ResponseEntity authenticateWithGoogleMethod( - @Schema( - description = "Google OAuth request body", - implementation = GoogleAuthRequest.class - ) - @RequestPart("googleUser") - @RequestBody GoogleAuthRequest request) { - try { - log.info("Processing Google authentication request"); - - GoogleUserInfo googleUserInfo = request.getGoogleUserInfo(); - - String email = googleUserInfo.getEmail(); - String username = googleUserInfo.getName(); - String pictureUrl = googleUserInfo.getPicture(); - - // Check if user exists - User googleUser = null; - Optional optionalUser = userRepository.findByEmail(email); - if (optionalUser.isPresent()) { - log.info("Existing user found with userId: {}", optionalUser.get().getId()); - googleUser = optionalUser.get(); - } else { - // Register a new user if not exists - var currentDateTime = LocalDateTime.now().atOffset(ZoneOffset.UTC); - var user = User.builder() - .email(email) - .username(username) - .password(passwordEncoder.encode(UUID.randomUUID().toString())) // consider adding this cause a userpass field should NEVER be null - .profilePicture(pictureUrl) - .createdDate(currentDateTime) - .lastUpdatedDate(currentDateTime) - .build(); - - googleUser = userRepository.save(user); - log.info("New user created with email: {}", email); - } - - // Just incase - if (googleUser == null) { - log.error("Error during Google authentication, user still came out as null!"); - throw new Exception("Error during Google authentication!"); - } - - // Load UserDetails and set authentication context - Authentication authentication = new UsernamePasswordAuthenticationToken(email, null); - SecurityContextHolder.getContext().setAuthentication(authentication); - - // Generate JWT token - String token = jwtTokenProvider.generateJwtToken(authentication, googleUser.getId()); - RefreshToken refreshToken = createRefreshToken(googleUser.getId().toString(), email); - - AuthResponse authResponse = new AuthResponse(token, refreshToken.getRefreshToken(), true); - return new ResponseEntity<>(authResponse, HttpStatus.OK); - } catch (Exception e) { - log.error("Error during Google authentication: ", e); - return new ResponseEntity<>(new AuthResponse("Error during Google authentication!" + e.getMessage(), "", false), HttpStatus.INTERNAL_SERVER_ERROR); - } - } - - private RefreshToken createRefreshToken(String userID, String email) throws UserException { - RefreshToken refreshToken = refreshTokenService.findByUserId(userID); - if (refreshToken == null || refreshToken.getExpiredAt().compareTo(Instant.now()) < 0) { - refreshToken = refreshTokenService.createRefreshToken(email); - } - - return refreshToken; - } } diff --git a/backend-service/src/main/java/co/teamsphere/api/controller/MainController.java b/backend-service/src/main/java/co/teamsphere/api/controller/MainController.java new file mode 100644 index 0000000..f729e3c --- /dev/null +++ b/backend-service/src/main/java/co/teamsphere/api/controller/MainController.java @@ -0,0 +1,52 @@ +package co.teamsphere.api.controller; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.ApplicationContext; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.time.LocalDateTime; +import java.util.LinkedHashMap; +import java.util.Map; + +@RestController +@RequestMapping("/") +public class MainController { + + @Value("${spring.profiles.active:default}") + private String activeProfiles; + + private final ApplicationContext applicationContext; + + public MainController(ApplicationContext applicationContext) { + this.applicationContext = applicationContext; + } + + @GetMapping("/") + public ResponseEntity> home() { + Map status = new LinkedHashMap<>(); + + // Basic info + status.put("application", "TeamSphere API"); + status.put("status", "UP"); + status.put("timestamp", LocalDateTime.now().toString()); + status.put("activeProfile", activeProfiles); + + // Environment info + status.put("environment", applicationContext.getEnvironment().getProperty("spring.application.name")); + + return ResponseEntity.ok(status); + } + + @GetMapping("/health") + public ResponseEntity> health() { + Map health = new LinkedHashMap<>(); + health.put("status", "UP"); + health.put("timestamp", LocalDateTime.now().toString()); + health.put("profile", activeProfiles); + + return ResponseEntity.ok(health); + } +} diff --git a/backend-service/src/main/java/co/teamsphere/api/controller/RealTimeMsgController.java b/backend-service/src/main/java/co/teamsphere/api/controller/RealTimeMsgController.java deleted file mode 100644 index 1ba2970..0000000 --- a/backend-service/src/main/java/co/teamsphere/api/controller/RealTimeMsgController.java +++ /dev/null @@ -1,92 +0,0 @@ -package co.teamsphere.api.controller; - -import co.teamsphere.api.exception.ChatException; -import co.teamsphere.api.exception.UserException; -import co.teamsphere.api.models.Chat; -import co.teamsphere.api.models.Messages; -import co.teamsphere.api.models.User; -import co.teamsphere.api.request.SendMessageRequest; -import co.teamsphere.api.services.ChatService; -import co.teamsphere.api.services.MessageService; -import co.teamsphere.api.services.UserService; -import lombok.extern.slf4j.Slf4j; -import org.springframework.messaging.handler.annotation.Header; -import org.springframework.messaging.handler.annotation.MessageMapping; -import org.springframework.messaging.handler.annotation.Payload; -import org.springframework.messaging.handler.annotation.SendTo; -import org.springframework.messaging.handler.annotation.DestinationVariable; - -import org.springframework.messaging.simp.SimpMessagingTemplate; - -import java.util.Iterator; - -@Slf4j -public class RealTimeMsgController { - - private final SimpMessagingTemplate simpMessagingTemplate; - - private final UserService userService; - - private final MessageService messageService; - - private final ChatService chatService; - - public RealTimeMsgController(SimpMessagingTemplate simpMessagingTemplate, - UserService userService, - MessageService messageService, - ChatService chatService) { - this.simpMessagingTemplate = simpMessagingTemplate; - this.userService = userService; - this.messageService = messageService; - this.chatService = chatService; - } - - @MessageMapping("/message") - @SendTo("/group/public") - public Messages receiveMessage(@Payload Messages messages){ - - simpMessagingTemplate.convertAndSend("/group/"+ messages.getChat().getId().toString(), messages); - - return messages; - } - - @MessageMapping("/chat/{groupId}") - public Messages sendToUser(@Payload SendMessageRequest req, @Header("Authorization") String jwt, @DestinationVariable String groupId) throws ChatException, UserException { - try { - log.info("Processing send message request for userId= {} to group: {}", req.getUserId(), groupId); - - User user = userService.findUserProfile(jwt); - req.setUserId(user.getId()); - - Chat chat = chatService.findChatById(req.getChatId()); - - Messages createdMessages = messageService.sendMessage(req); - - User receiverUser = receiver(chat, user); - - simpMessagingTemplate.convertAndSendToUser(groupId, "/private", createdMessages); - - log.info("Message sent successfully to group: {} by userId: {}", groupId, req.getUserId()); - - return createdMessages; - } catch (ChatException e) { - log.error("Error during send message process", e); - throw new ChatException("Error during send message process" + e); - } catch (UserException e) { - log.error("Error during send message process", e); - throw new UserException("Error during send message process" + e); - } - } - - public User receiver(Chat chat, User reqUser) { - Iterator iterator = chat.getUsers().iterator(); - - User user1 = iterator.next(); // get first user - User user2 = iterator.next(); // get second user - - if(user1.getId().equals(reqUser.getId())){ - return user2; - } - return user1; - } -} diff --git a/backend-service/src/main/java/co/teamsphere/api/controller/mainController.java b/backend-service/src/main/java/co/teamsphere/api/controller/mainController.java deleted file mode 100644 index 013e03a..0000000 --- a/backend-service/src/main/java/co/teamsphere/api/controller/mainController.java +++ /dev/null @@ -1,15 +0,0 @@ -package co.teamsphere.api.controller; - -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -@RestController -@RequestMapping("/") -public class mainController { - - @GetMapping("/") - public String home() { - return "Welcome to TeamSphere API!"; - } -} diff --git a/backend-service/src/main/java/co/teamsphere/api/services/AuthenticationService.java b/backend-service/src/main/java/co/teamsphere/api/services/AuthenticationService.java index db4c337..de4af72 100644 --- a/backend-service/src/main/java/co/teamsphere/api/services/AuthenticationService.java +++ b/backend-service/src/main/java/co/teamsphere/api/services/AuthenticationService.java @@ -6,7 +6,6 @@ import co.teamsphere.api.exception.UserException; import co.teamsphere.api.request.SignupRequest; import co.teamsphere.api.response.AuthResponse; -import co.teamsphere.api.utils.GoogleAuthRequest; import jakarta.validation.Valid; @Service @@ -14,6 +13,4 @@ public interface AuthenticationService { AuthResponse signupUser(@Valid SignupRequest request) throws UserException, ProfileImageException; AuthResponse loginUser(String username, String password) throws UserException; - - AuthResponse loginWithGoogle(GoogleAuthRequest request) throws UserException; } diff --git a/backend-service/src/main/java/co/teamsphere/api/services/impl/AuthenticationServiceImpl.java b/backend-service/src/main/java/co/teamsphere/api/services/impl/AuthenticationServiceImpl.java index d459219..64d9419 100644 --- a/backend-service/src/main/java/co/teamsphere/api/services/impl/AuthenticationServiceImpl.java +++ b/backend-service/src/main/java/co/teamsphere/api/services/impl/AuthenticationServiceImpl.java @@ -1,24 +1,5 @@ package co.teamsphere.api.services.impl; -import java.time.Instant; -import java.time.LocalDateTime; -import java.time.ZoneOffset; -import java.util.Objects; -import java.util.Optional; -import java.util.UUID; -import java.util.regex.Pattern; - -import org.springframework.security.authentication.BadCredentialsException; -import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.context.SecurityContext; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.security.core.userdetails.UserDetails; -import org.springframework.security.crypto.password.PasswordEncoder; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; -import org.springframework.validation.annotation.Validated; - import co.teamsphere.api.config.JWTTokenProvider; import co.teamsphere.api.exception.ProfileImageException; import co.teamsphere.api.exception.UserException; @@ -31,10 +12,24 @@ import co.teamsphere.api.services.AuthenticationService; import co.teamsphere.api.services.CloudflareApiService; import co.teamsphere.api.services.RefreshTokenService; -import co.teamsphere.api.utils.GoogleAuthRequest; -import co.teamsphere.api.utils.GoogleUserInfo; import jakarta.validation.Valid; import lombok.extern.slf4j.Slf4j; +import org.springframework.security.authentication.BadCredentialsException; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.validation.annotation.Validated; + +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.ZoneOffset; +import java.util.Objects; +import java.util.Optional; +import java.util.regex.Pattern; @Service @Validated @@ -175,56 +170,6 @@ public AuthResponse loginUser(String email, String password) throws UserExceptio } } - @Override - @Transactional - public AuthResponse loginWithGoogle(GoogleAuthRequest request) throws UserException { - try { - GoogleUserInfo googleUserInfo = request.getGoogleUserInfo(); - - String email = googleUserInfo.getEmail(); - String username = googleUserInfo.getName(); - String pictureUrl = googleUserInfo.getPicture(); - - // Check if user exists - User googleUser; - Optional optionalUser = userRepository.findByEmail(email); - if (optionalUser.isPresent()) { - log.info("Existing user found with userId: {}", optionalUser.get().getId()); - googleUser = optionalUser.get(); - } else { - // Register a new user if not exists - var currentDateTime = LocalDateTime.now().atOffset(ZoneOffset.UTC); - var user = User.builder() - .email(email) - .username(username) - .password(passwordEncoder.encode(UUID.randomUUID().toString())) // consider adding this cause the password field should NEVER be null - .profilePicture(pictureUrl) - .createdDate(currentDateTime) - .lastUpdatedDate(currentDateTime) - .build(); - - googleUser = userRepository.saveAndFlush(user); - log.info("New user created with email: {}", email); - } - - // Load UserDetails and set authentication context - SecurityContext context = SecurityContextHolder.getContext(); - Authentication authentication = new UsernamePasswordAuthenticationToken(email, null); - context.setAuthentication(authentication); - SecurityContextHolder.setContext(context); - - String token = jwtTokenProvider.generateJwtTokenFromEmail(email, googleUser.getId()); - RefreshToken refreshToken = createRefreshToken(googleUser.getId().toString(), email); - return new AuthResponse(token, refreshToken.getRefreshToken(), true); - } catch (BadCredentialsException e) { - log.error("Error during Google authentication: ", e); - throw new BadCredentialsException("Error during Google authentication"); - } catch (Exception e) { - log.error("Error during Google authentication: ", e); - throw new UserException("Error during Google authentication"); - } - } - public static boolean isEmailInvalid(String email) { if (email.isEmpty()) return true; diff --git a/backend-service/src/main/java/co/teamsphere/api/utils/GoogleAuthRequest.java b/backend-service/src/main/java/co/teamsphere/api/utils/GoogleAuthRequest.java deleted file mode 100644 index 4080f59..0000000 --- a/backend-service/src/main/java/co/teamsphere/api/utils/GoogleAuthRequest.java +++ /dev/null @@ -1,8 +0,0 @@ -package co.teamsphere.api.utils; - -import lombok.Data; - -@Data -public class GoogleAuthRequest { - private GoogleUserInfo googleUserInfo; -} diff --git a/backend-service/src/main/java/co/teamsphere/api/utils/GoogleUserInfo.java b/backend-service/src/main/java/co/teamsphere/api/utils/GoogleUserInfo.java deleted file mode 100644 index 147cd92..0000000 --- a/backend-service/src/main/java/co/teamsphere/api/utils/GoogleUserInfo.java +++ /dev/null @@ -1,14 +0,0 @@ -package co.teamsphere.api.utils; - -import lombok.Data; - -@Data -public class GoogleUserInfo { - private String id; - private String email; - private boolean verified_email; - private String name; - private String given_name; - private String family_name; - private String picture; -} diff --git a/backend-service/src/main/java/co/teamsphere/api/utils/SmsUtils.java b/backend-service/src/main/java/co/teamsphere/api/utils/SmsUtils.java deleted file mode 100644 index dfd4118..0000000 --- a/backend-service/src/main/java/co/teamsphere/api/utils/SmsUtils.java +++ /dev/null @@ -1,22 +0,0 @@ -package co.teamsphere.api.utils; - -import com.twilio.Twilio; -import com.twilio.rest.api.v2010.account.Message; -import com.twilio.type.PhoneNumber; -import lombok.extern.slf4j.Slf4j; - -import static com.twilio.rest.api.v2010.account.Message.creator; - - -@Slf4j -public class SmsUtils { - public static final String FROM_NUMBER = "+"; - public static final String SID_KEY = ""; - public static final String TOKEN_KEY = ""; - - public static void sendSMS(String to, String messageBody) { - Twilio.init(SID_KEY, TOKEN_KEY); - Message message = creator(new PhoneNumber("+" + to), new PhoneNumber(FROM_NUMBER), messageBody).create(); - log.info(message.toString()); - } -} \ No newline at end of file diff --git a/backend-service/src/main/resources/application-dev.yml b/backend-service/src/main/resources/application-dev.yml index 43b6ce2..2320f94 100644 --- a/backend-service/src/main/resources/application-dev.yml +++ b/backend-service/src/main/resources/application-dev.yml @@ -24,18 +24,11 @@ spring: database: mysql hibernate: ddl-auto: update - rabbitmq: - host: ${RABBITMQ_DEV_HOST} - username: ${RABBITMQ_USERNAME} - password: ${RABBITMQ_PASSWORD} - port: ${RABBITMQ_PORT} - requested-heartbeat: 580 servlet: multipart: max-file-size: 20MB max-request-size: 20MB - app: environment: ALLOWED_ORIGINS: diff --git a/backend-service/src/main/resources/application-local.yml b/backend-service/src/main/resources/application-local.yml index 57df646..14cc836 100644 --- a/backend-service/src/main/resources/application-local.yml +++ b/backend-service/src/main/resources/application-local.yml @@ -18,12 +18,6 @@ spring: database: mysql hibernate: ddl-auto: update - rabbitmq: - host: ${RABBITMQ_HOST} - username: ${RABBITMQ_USERNAME} - password: ${RABBITMQ_PASSWORD} - port: 30716 - requested-heartbeat: 580 servlet: multipart: max-file-size: 20MB diff --git a/backend-service/src/main/resources/application-prod.yml b/backend-service/src/main/resources/application-prod.yml index 192be81..f1b9d7d 100644 --- a/backend-service/src/main/resources/application-prod.yml +++ b/backend-service/src/main/resources/application-prod.yml @@ -24,18 +24,11 @@ spring: database: mysql hibernate: ddl-auto: update - rabbitmq: - host: ${RABBITMQ_PROD_HOST} - username: ${RABBITMQ_USERNAME} - password: ${RABBITMQ_PASSWORD} - port: ${RABBITMQ_PORT} - requested-heartbeat: 580 servlet: multipart: max-file-size: 20MB max-request-size: 20MB - app: environment: ALLOWED_ORIGINS: diff --git a/backend-service/src/main/resources/application.yml b/backend-service/src/main/resources/application.yml index f4f203c..4994c3a 100644 --- a/backend-service/src/main/resources/application.yml +++ b/backend-service/src/main/resources/application.yml @@ -21,17 +21,3 @@ spring: show-sql: true profiles: active: local - rabbitmq: - cache: - channel: - size: 10 - host: '' - password: '' - port: 15672 - requested-heartbeat: 580 - username: '' - virtual-host: '' -twilio: - accountSid: '' - authToken: '' - phoneNumber: '' \ No newline at end of file diff --git a/backend-service/src/test/java/co/teamsphere/api/controller/AuthControllerTest.java b/backend-service/src/test/java/co/teamsphere/api/controller/AuthControllerTest.java index 6c3f39c..c6cc246 100644 --- a/backend-service/src/test/java/co/teamsphere/api/controller/AuthControllerTest.java +++ b/backend-service/src/test/java/co/teamsphere/api/controller/AuthControllerTest.java @@ -1,21 +1,17 @@ package co.teamsphere.api.controller; -import java.time.Instant; -import java.util.Optional; -import java.util.UUID; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; +import co.teamsphere.api.exception.ProfileImageException; +import co.teamsphere.api.exception.UserException; +import co.teamsphere.api.models.RefreshToken; +import co.teamsphere.api.request.LoginRequest; +import co.teamsphere.api.request.SignupRequest; +import co.teamsphere.api.response.AuthResponse; +import co.teamsphere.api.services.AuthenticationService; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyString; import org.mockito.InjectMocks; import org.mockito.Mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -24,40 +20,18 @@ import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContext; import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.security.crypto.password.PasswordEncoder; -import co.teamsphere.api.config.JWTTokenProvider; -import co.teamsphere.api.exception.ProfileImageException; -import co.teamsphere.api.exception.UserException; -import co.teamsphere.api.models.RefreshToken; -import co.teamsphere.api.models.User; -import co.teamsphere.api.repository.UserRepository; -import co.teamsphere.api.request.LoginRequest; -import co.teamsphere.api.request.SignupRequest; -import co.teamsphere.api.response.AuthResponse; -import co.teamsphere.api.services.AuthenticationService; -import co.teamsphere.api.services.RefreshTokenService; -import co.teamsphere.api.utils.GoogleAuthRequest; -import co.teamsphere.api.utils.GoogleUserInfo; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; @ExtendWith(MockitoExtension.class) public class AuthControllerTest { - - @Mock - private UserRepository userRepository; - - @Mock - private PasswordEncoder passwordEncoder; - - @Mock - private JWTTokenProvider jwtTokenProvider; - @Mock private AuthenticationService authenticationService; - @Mock - private RefreshTokenService refreshTokenService; - @Mock private SecurityContext securityContext; @@ -70,7 +44,6 @@ public class AuthControllerTest { private SignupRequest signupRequest; private LoginRequest loginRequest; private AuthResponse successAuthResponse; - private GoogleAuthRequest googleAuthRequest; @BeforeEach void setUp() { @@ -97,15 +70,6 @@ void setUp() { // Setup success AuthResponse successAuthResponse = new AuthResponse("jwt.token.here", "refresh.token.here", true); - // Setup GoogleAuthRequest - GoogleUserInfo googleUserInfo = new GoogleUserInfo(); - googleUserInfo.setEmail("test@example.com"); - googleUserInfo.setName("Test User"); - googleUserInfo.setPicture("https://example.com/profile.jpg"); - - googleAuthRequest = new GoogleAuthRequest(); - googleAuthRequest.setGoogleUserInfo(googleUserInfo); - RefreshToken mockRefreshToken = new RefreshToken(); mockRefreshToken.setRefreshToken("refresh.token.here"); } @@ -207,103 +171,4 @@ void userLoginMethod_InvalidCredentials_ThrowsUserException() throws Exception { verify(authenticationService).loginUser(loginRequest.getEmail(), loginRequest.getPassword()); } - - @Test - void authenticateWithGoogleMethod_NewUser_CreatesUserAndReturnsOk() throws UserException { - // Arrange - when(userRepository.findByEmail("test@example.com")).thenReturn(Optional.empty()); - when(passwordEncoder.encode(anyString())).thenReturn("encodedPassword"); - - var savedUser = User.builder() - .id(UUID.randomUUID()) - .email("test@example.com") - .username("Test User") - .password("encodedPassword") - .profilePicture("https://example.com/profile.jpg") - .build(); - - when(userRepository.save(any(User.class))).thenReturn(savedUser); - - when(jwtTokenProvider.generateJwtToken(any(Authentication.class), any(UUID.class))).thenReturn("jwt.token.here"); - - var mockRefreshToken = RefreshToken.builder() - .id(UUID.randomUUID()) - .user(savedUser) - .refreshToken("refresh.token.here") - .build(); - when(refreshTokenService.findByUserId(savedUser.getId().toString())).thenReturn(null); - when(refreshTokenService.createRefreshToken("test@example.com")).thenReturn(mockRefreshToken); - - // Act - ResponseEntity response = authController.authenticateWithGoogleMethod(googleAuthRequest); - - // Assert - assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(response.getBody().getJwt()).isEqualTo("jwt.token.here"); - assertThat(response.getBody().getRefreshToken()).isEqualTo("refresh.token.here"); - assertThat(response.getBody().isStatus()).isTrue(); - - verify(userRepository).findByEmail("test@example.com"); - verify(userRepository).save(any(User.class)); - verify(jwtTokenProvider).generateJwtToken(any(Authentication.class), any(UUID.class)); - verify(refreshTokenService).createRefreshToken("test@example.com"); - } - - @Test - void authenticateWithGoogleMethod_ExistingUser_ReturnsOk() throws UserException { - // Arrange - var existingUser = User.builder() - .id(UUID.randomUUID()) - .email("test@example.com") - .username("Test User") - .profilePicture("https://example.com/profile.jpg") - .build(); - - when(userRepository.findByEmail("test@example.com")).thenReturn(Optional.of(existingUser)); - when(jwtTokenProvider.generateJwtToken(any(Authentication.class), any(UUID.class))).thenReturn("jwt.token.here"); - - var existingRefreshToken = RefreshToken.builder() - .id(UUID.randomUUID()) - .user(existingUser) - .refreshToken("existing.refresh.token") - .expiredAt(Instant.now().plusSeconds(3600)) - .build(); - - when(refreshTokenService.findByUserId(existingUser.getId().toString())).thenReturn(existingRefreshToken); - - // Act - ResponseEntity response = authController.authenticateWithGoogleMethod(googleAuthRequest); - - // Assert - assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(response.getBody().getJwt()).isEqualTo("jwt.token.here"); - assertThat(response.getBody().getRefreshToken()).isEqualTo("existing.refresh.token"); - assertThat(response.getBody().isStatus()).isTrue(); - - verify(userRepository).findByEmail("test@example.com"); - verify(userRepository, never()).save(any(User.class)); - verify(jwtTokenProvider).generateJwtToken(any(Authentication.class), any(UUID.class)); - verify(refreshTokenService).findByUserId(existingUser.getId().toString()); - verify(refreshTokenService, never()).createRefreshToken(anyString()); - } - - @Test - void authenticateWithGoogleMethod_Exception_ReturnsInternalServerError() throws UserException { - // Arrange - when(userRepository.findByEmail(anyString())).thenThrow(new RuntimeException("Database error")); - - // Act - ResponseEntity response = authController.authenticateWithGoogleMethod(googleAuthRequest); - - // Assert - assertThat(response.getStatusCode()).isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR); - assertThat(response.getBody().isStatus()).isFalse(); - assertThat(response.getBody().getJwt()).contains("Error during Google authentication"); - assertThat(response.getBody().getRefreshToken()).isEqualTo(""); - - // Verify repository was called but not the token services - verify(userRepository).findByEmail("test@example.com"); - verify(jwtTokenProvider, never()).generateJwtToken(any(Authentication.class), any(UUID.class)); - verify(refreshTokenService, never()).createRefreshToken(anyString()); - } } diff --git a/pom.xml b/pom.xml index e210ecc..a663520 100644 --- a/pom.xml +++ b/pom.xml @@ -30,11 +30,6 @@ - - org.springframework.boot - spring-boot-starter-websocket - 3.2.0 - io.jsonwebtoken jjwt-api @@ -52,21 +47,6 @@ 0.11.1 runtime - - com.twilio.sdk - twilio - 10.0.0 - - - me.paulschwarz - spring-dotenv - 4.0.0 - - - org.springframework.amqp - spring-amqp - 3.0.2 - io.netty netty-resolver-dns-native-macos