[Fix] FCM 토큰 로그 마스킹#240
Conversation
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Summary of ChangesHello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! 본 PR은 FCM 알림 발송 과정에서 발생하는 로그에 디바이스 토큰 원문이 노출되는 문제를 개선합니다. 토큰의 앞 8자리만 노출하도록 마스킹 로직을 적용함으로써, 로그를 통한 개인정보 유출 가능성을 차단하고 보안성을 강화하는 것을 목적으로 합니다. Highlights
New Features🧠 You can now enable Memory (public preview) to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console. Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize the Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counterproductive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here. Footnotes
|
There was a problem hiding this comment.
Code Review
This pull request introduces FCM token masking in log messages within AsyncNotificationDispatcher to prevent sensitive token exposure. The reviewer provided two valuable recommendations: wrapping the token deletion call in a try-catch block to ensure robust exception handling during dispatch, and adding a unit test to verify that the original unmasked token is correctly passed to the deletion service.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| private void handleSendError(String token, FirebaseMessagingException e) { | ||
| MessagingErrorCode code = e.getMessagingErrorCode(); | ||
| if (code == MessagingErrorCode.UNREGISTERED || code == MessagingErrorCode.INVALID_ARGUMENT) { | ||
| log.warn("만료/잘못된 토큰 삭제 (token={}, code={})", token, code); | ||
| log.warn("만료/잘못된 토큰 삭제 (token={}, code={})", maskToken(token), code); | ||
| fcmTokenService.deleteExpired(token); | ||
| } else { | ||
| log.error("FCM 발송 실패 (token={}, code={}): {}", token, code, e.getMessage()); | ||
| log.error("FCM 발송 실패 (token={}, code={}): {}", maskToken(token), code, e.getMessage()); | ||
| } | ||
| } |
There was a problem hiding this comment.
**[P1] **
** :**
handleSendError fcmTokenService.deleteExpired(token) , ( : , ) dispatch . handleSendError try-catch catch , . FCM .
private void handleSendError(String token, FirebaseMessagingException e) {
MessagingErrorCode code = e.getMessagingErrorCode();
if (code == MessagingErrorCode.UNREGISTERED || code == MessagingErrorCode.INVALID_ARGUMENT) {
log.warn("만료/잘못된 토큰 삭제 (token={}, code={})", maskToken(token), code);
try {
fcmTokenService.deleteExpired(token);
} catch (Exception ex) {
log.error("만료된 토큰 삭제 중 에러 발생 (token={}): {}", maskToken(token), ex.getMessage(), ex);
}
} else {
log.error("FCM 발송 실패 (token={}, code={}): {}", maskToken(token), code, e.getMessage());
}
}References
- , , FCM , ( ) . (link)
| private String maskToken(String token) { | ||
| if (token == null || token.isBlank()) { | ||
| return "<empty>"; | ||
| } | ||
| int visibleLength = Math.min(8, token.length()); | ||
| return token.substring(0, visibleLength) + "***"; | ||
| } |
There was a problem hiding this comment.
**[P3] maskToken **
** :**
maskToken handleSendError . , (maskToken(token)) , (fcmTokenService.deleteExpired(token)) , .
** :**
AsyncNotificationDispatcherTest .
@Test
void dispatchDeletesExpiredTokenWithOriginalTokenOnUnregisteredError() throws Exception {
AsyncNotificationDispatcher dispatcher = dispatcher();
NotificationDispatchCommand command = new NotificationDispatchCommand(
1L, 10L, NotificationType.COMMUNITY_COMMENT,
"title", "body", Map.of(), List.of("long-fcm-token-value")
);
doThrow(new FirebaseMessagingException("test", "unregistered", MessagingErrorCode.UNREGISTERED))
.when(fcmService).sendMessage(any(), any(), any(), any(), anyBoolean());
dispatcher.dispatch(command);
verify(fcmTokenService).deleteExpired("long-fcm-token-value");
}References
- . (link)
🧾 요약
🔗 이슈
✨ 변경 내용
AsyncNotificationDispatcher에maskToken()헬퍼 추가✅ 확인