Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
00d71bd
refactor/#38 - chatting PD
BAEK0111 Aug 20, 2025
eaa1788
refactor/#38 - chatting PD
BAEK0111 Aug 20, 2025
82895c4
refactor/#38
BAEK0111 Aug 20, 2025
8d4d838
refactor/#38
BAEK0111 Aug 25, 2025
4d172a4
refactor/#38
BAEK0111 Sep 4, 2025
f6b41d4
refactor/#38 - chatting PD
BAEK0111 Sep 4, 2025
1428268
refactor/#38
BAEK0111 Aug 25, 2025
70464da
refactor/#38 - chatting Controller 수정
BAEK0111 Sep 4, 2025
974190a
Merge remote-tracking branch 'origin/refactor/#38-chatting-change-sec…
BAEK0111 Sep 4, 2025
68cf793
refactor/#38 - chatting Controller 수정
BAEK0111 Sep 7, 2025
a73c502
[FIX/#82] 웹소켓 설정 변경
eeeeeaaan Sep 10, 2025
8a58d3a
refactor/#38 - chatting Controller 수정
BAEK0111 Sep 12, 2025
368dfe8
Merge branch 'develop' of https://github.com/S0ftwareC0ntest/ASSU_BE …
BAEK0111 Sep 12, 2025
4a7172c
[FIX/#82] 자잘한 수정
eeeeeaaan Sep 14, 2025
a47653e
Merge branch 'develop' into refactor/#85-certification-edit
eeeeeaaan Sep 14, 2025
f845eeb
Merge pull request #95 from ASSU-org/refactor/#85-certification-edit
eeeeeaaan Sep 14, 2025
6a7931b
Merge branch 'develop' of https://github.com/S0ftwareC0ntest/ASSU_BE …
BAEK0111 Sep 14, 2025
6efa144
[MOD/#98] 엔드포인트 수정
kimyw1018 Sep 14, 2025
f775ff1
Merge pull request #99 from ASSU-org/refactor/#98-dashboard
kimyw1018 Sep 14, 2025
59ee719
refactor/#38 - ci 해결
BAEK0111 Sep 14, 2025
d0b47b7
refactor/#38 - 최신 application-test.yml
BAEK0111 Sep 14, 2025
6d7d0aa
Merge pull request #72 from ASSU-org/refactor/#38-chatting-change-sec…
BAEK0111 Sep 14, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package com.assu.server.domain.certification.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.ChannelRegistration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;
Expand All @@ -18,17 +20,18 @@ public class CertifyWebSocketConfig implements WebSocketMessageBrokerConfigurer
@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.enableSimpleBroker("/certification"); // 인증현황을 받아보기 위한 구독 주소
config.setApplicationDestinationPrefixes("/certification"); // 클라이언트가 인증 요청을 보내는 주소
config.setApplicationDestinationPrefixes("/app"); // 클라이언트가 인증 요청을 보내는 주소
}

@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/ws") // 클라이언트 WebSocket 연결 주소
.setAllowedOriginPatterns("*").withSockJS(); // CORS 허용
registry.addEndpoint("/ws").setAllowedOriginPatterns("*"); // 클라이언트 WebSocket 연결 주소
// .setAllowedOriginPatterns("http://10.0.2.2:8080", "ws://10.0.2.2:8080");// CORS 허용
}

@Override
public void configureClientInboundChannel(ChannelRegistration registration) {
registration.interceptors(stompAuthChannelInterceptor);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
import org.springframework.messaging.support.ChannelInterceptor;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;
import lombok.extern.slf4j.Slf4j; // SLF4j 로그 추가

@Slf4j // SLF4j 어노테이션 추가
@Component
@RequiredArgsConstructor
public class StompAuthChannelInterceptor implements ChannelInterceptor {
Expand All @@ -17,19 +19,32 @@ public class StompAuthChannelInterceptor implements ChannelInterceptor {
@Override
public Message<?> preSend(Message<?> message, MessageChannel channel) {
StompHeaderAccessor accessor = StompHeaderAccessor.wrap(message);
log.info("StompCommand: {}", accessor.getCommand()); // StompCommand 로그 추가

if (StompCommand.CONNECT.equals(accessor.getCommand())) {
log.info("CONNECT command received.");
// 프론트에서 connect 시 Authorization 헤더 넣어야 함
String authHeader = accessor.getFirstNativeHeader("Authorization");
log.info("Authorization Header: {}", authHeader); // Authorization 헤더 로그 추가

if (authHeader != null && authHeader.startsWith("Bearer ")) {
String token = jwtUtil.getTokenFromHeader(authHeader);
log.info("Extracted Token: {}", token); // 추출된 토큰 로그 추가

// JwtUtil 이용해서 Authentication 복원
Authentication authentication = jwtUtil.getAuthentication(token);
log.info("Authentication restored: {}", authentication); // 복원된 인증 정보 로그 추가

// WebSocket 세션에 Authentication(UserPrincipal) 저장
accessor.setUser(authentication);
log.info("User principal set on accessor.");
} else {
log.warn("Authorization header is missing or not in Bearer format.");
}
} else if (StompCommand.SEND.equals(accessor.getCommand())) {
// SEND 명령어에 대한 로그 추가 (메시지 전송 시)
Object payload = message.getPayload();
log.info("SEND command received. Destination: {}, Payload: {}", accessor.getDestination(), payload);
}

return message;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,27 +60,27 @@ public ResponseEntity<BaseResponse<CertificationResponseDTO.getSessionIdResponse
return ResponseEntity.ok(BaseResponse.onSuccess(SuccessStatus.GROUP_SESSION_CREATE, result));
}

@MessageMapping("/certify")
@Operation(summary = "그룹 세션 인증 api", description = "그룹에 대한 세션 인증 요청을 보냅니다.")
public ResponseEntity<BaseResponse<Void>> certifyGroup(
CertificationRequestDTO.groupSessionRequest dto , PrincipalDetails pd

) {
certificationService.handleCertification(dto, pd.getMember());

return ResponseEntity.ok(BaseResponse.onSuccess(SuccessStatus.GROUP_CERTIFICATION_SUCCESS, null));
}
// @MessageMapping("/certify")
// @Operation(summary = "그룹 세션 인증 api", description = "그룹에 대한 세션 인증 요청을 보냅니다.")
// public ResponseEntity<BaseResponse<Void>> certifyGroup(
// CertificationRequestDTO.groupSessionRequest dto , PrincipalDetails pd
//
// ) {
// certificationService.handleCertification(dto, pd.getMember());
//
// return ResponseEntity.ok(BaseResponse.onSuccess(SuccessStatus.GROUP_CERTIFICATION_SUCCESS, null));
// }

@PostMapping("/certification/personal")
@Operation(summary = "개인 인증 api", description = "사실 크게 필요없는데, 제휴 내역 통계를 위해 데이터를 post하는 api 입니다. "
+ "가게 별 제휴를 조회하고 people값이 null 인 제휴를 선택한 경우 그룹 인증 대신 요청하는 api 입니다.")
public ResponseEntity<BaseResponse<Void>> personalCertification(
public ResponseEntity<BaseResponse<String>> personalCertification(
@AuthenticationPrincipal PrincipalDetails pd,
@RequestBody CertificationRequestDTO.personalRequest dto
) {
certificationService.certificatePersonal(dto, pd.getMember());

return ResponseEntity.ok(BaseResponse.onSuccessWithoutData(SuccessStatus.PERSONAL_CERTIFICATION_SUCCESS));
return ResponseEntity.ok(BaseResponse.onSuccess(SuccessStatus.PERSONAL_CERTIFICATION_SUCCESS, "null"));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package com.assu.server.domain.certification.controller;

import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.Payload;
import org.springframework.messaging.simp.SimpMessageHeaderAccessor;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Controller;

import com.assu.server.domain.certification.dto.GroupSessionRequest;
import com.assu.server.domain.certification.service.CertificationService;
import com.assu.server.domain.member.entity.Member;
import com.assu.server.global.util.PrincipalDetails;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@Controller // STOMP 메시지 처리를 위한 컨트롤러
@RequiredArgsConstructor
public class GroupCertificationController {

private final CertificationService certificationService;

@MessageMapping("/certify")
public void certifyGroup(@Payload GroupSessionRequest dto, SimpMessageHeaderAccessor headerAccessor) {
try {
log.info("### SUCCESS ### 인증 요청 메시지 수신 - adminId: {}, sessionId: {}", dto.getAdminId(), dto.getSessionId());

// Authentication에서 Member 정보 추출
Authentication auth = (Authentication) headerAccessor.getUser();
if (auth != null && auth.getPrincipal() instanceof PrincipalDetails) {
PrincipalDetails principalDetails = (PrincipalDetails) auth.getPrincipal();
// 실제 비즈니스 로직 호출
certificationService.handleCertification(dto, principalDetails.getMember());
log.info("### SUCCESS ### 그룹 인증 처리 완료");
}
} catch (Exception e) {
log.error("### ERROR ### 인증 처리 실패", e);
}
}

// @MessageMapping("/certify")
// public void certifyGroup(SimpMessageHeaderAccessor headerAccessor) {
// log.info("### DEBUG ### 메서드 진입!");
// log.info("### DEBUG ### User: {}", headerAccessor.getUser());
// log.info("### DEBUG ### SessionId: {}", headerAccessor.getSessionId());
// }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.assu.server.domain.certification.controller;

import lombok.extern.slf4j.Slf4j;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.Payload;
import org.springframework.stereotype.Controller;

@Slf4j
@Controller
public class WebSocketTestController {

@MessageMapping("/test")
public void test(@Payload String payload) {
log.info("### 테스트용 메시지 수신 성공! 페이로드: {}", payload);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.assu.server.domain.certification.dto.CertificationRequestDTO;
import com.assu.server.domain.certification.dto.CertificationResponseDTO;
import com.assu.server.domain.certification.entity.AssociateCertification;
import com.assu.server.domain.certification.entity.enums.SessionStatus;
import com.assu.server.domain.member.entity.Member;
import com.assu.server.domain.store.entity.Store;

Expand All @@ -12,6 +13,7 @@ public static AssociateCertification toAssociateCertification(CertificationReque
return AssociateCertification.builder()
.store(store)
.partner(store.getPartner())
.status(SessionStatus.OPENED)
.isCertified(false)
.peopleNumber(dto.getPeople())
.tableNumber(dto.getTableNumber())
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package com.assu.server.domain.certification.dto;

import java.util.List;

import lombok.AllArgsConstructor;
import lombok.Getter;

// public class CurrentProgress {
// private int count;
//
//
// @Getter
// public static class CertificationNumber{
// public CertificationNumber(int count){
// this.count= count;
// }
//
// int count;
// }
//
// @Getter
// public static class CompletedNotification{
// public CompletedNotification(String message, List<Long> userIds){
//
// this.message= message;
// this.userIds= userIds;
// }
// String message;
// List<Long> userIds;
// }

// }
@Getter
@AllArgsConstructor
public class CertificationProgressResponseDTO {
private String type;
private Integer count;
private String message;
private List<Long> userIds;

// 생성자들
public static CertificationProgressResponseDTO progress(int count) {
return new CertificationProgressResponseDTO("progress", count, null, null);
}

public static CertificationProgressResponseDTO completed(String message, List<Long> userIds) {
return new CertificationProgressResponseDTO("completed", userIds.size(), message, userIds);
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package com.assu.server.domain.certification.dto;

import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;

import lombok.NoArgsConstructor;

public class CertificationRequestDTO {

Expand All @@ -20,9 +22,11 @@ public static class personalRequest{
Integer tableNumber;
}

@Getter
public static class groupSessionRequest{
Long adminId;
Long sessionId;
}
// @Getter
// @NoArgsConstructor(access = AccessLevel.PROTECTED)
// @AllArgsConstructor
// public static class groupSessionRequest {
// private Long adminId;
// private Long sessionId;
// }
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.assu.server.domain.certification.dto;

import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

@Getter
@NoArgsConstructor
@Setter
public class GroupSessionRequest {
Long adminId;
Long sessionId;

@Override
public String toString() {
return "GroupSessionRequest{" +
"adminId=" + adminId +
", sessionId=" + sessionId +
'}';
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// package com.assu.server.domain.certification.handler;
//
// import org.springframework.stereotype.Component;
// import org.springframework.web.socket.CloseStatus;
// import org.springframework.web.socket.TextMessage;
// import org.springframework.web.socket.WebSocketSession;
// import org.springframework.web.socket.handler.TextWebSocketHandler;
//
// @Component
// public class CertificationWebsocketHandler extends TextWebSocketHandler {
//
// @Override
// public void afterConnectionEstablished(WebSocketSession session) throws Exception {
// // 클라이언트 연결이 성공적으로 수립되었을 때 호출됩니다.
// System.out.println("Client connected: " + session.getId());
// }
//
// @Override
// protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
// // 클라이언트로부터 텍스트 메시지를 받았을 때 호출됩니다.
// String payload = message.getPayload();
// System.out.println("Message received from " + session.getId() + ": " + payload);
//
// // 받은 메시지를 다시 클라이언트에게 보내거나 다른 로직을 처리합니다.
// session.sendMessage(new TextMessage("Echo: " + payload));
// }
//
// @Override
// public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
// // 클라이언트 연결이 종료되었을 때 호출됩니다.
// System.out.println("Client disconnected: " + session.getId() + " with status " + status.getCode());
// }
//
// @Override
// public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
// // 전송 오류가 발생했을 때 호출됩니다.
// System.err.println("Transport error for session " + session.getId() + ": " + exception.getMessage());
// // 필요한 경우 연결을 종료하거나 오류를 처리합니다.
// session.close(CloseStatus.SERVER_ERROR);
// }
// }
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@

import com.assu.server.domain.certification.dto.CertificationRequestDTO;
import com.assu.server.domain.certification.dto.CertificationResponseDTO;
import com.assu.server.domain.certification.dto.GroupSessionRequest;
import com.assu.server.domain.member.entity.Member;

public interface CertificationService {

CertificationResponseDTO.getSessionIdResponse getSessionId(CertificationRequestDTO.groupRequest dto, Member member);

void handleCertification(CertificationRequestDTO.groupSessionRequest dto, Member member);
void handleCertification(GroupSessionRequest dto, Member member);

void certificatePersonal(CertificationRequestDTO.personalRequest dto, Member member);
}
Loading