Skip to content

MOSU-165 feat: OAuth Auth 회원가입 로직 병합#167

Merged
wlgns12370 merged 4 commits intodevelopfrom
feature/mosu-165
Jul 29, 2025
Merged

MOSU-165 feat: OAuth Auth 회원가입 로직 병합#167
wlgns12370 merged 4 commits intodevelopfrom
feature/mosu-165

Conversation

@wlgns12370
Copy link
Contributor

@wlgns12370 wlgns12370 commented Jul 29, 2025

✨ 구현한 기능

📢 논의하고 싶은 내용

  • x

🎸 기타

  • x

Summary by CodeRabbit

  • New Features

    • Added a new endpoint to retrieve user information, returning name, birth date, phone number, and gender.
    • Introduced a new endpoint for generating a certification token for master users.
    • Enhanced sign-up requests to require user name, birth date, gender, and phone number.
  • Bug Fixes

    • Improved handling of token headers during sign-up and authentication processes.
  • Refactor

    • Updated package structure for request and response DTOs for better organization.
    • Standardized extraction and handling of user information.
  • Documentation

    • Enhanced API documentation with new validation and schema annotations for user-related endpoints.

@wlgns12370 wlgns12370 self-assigned this Jul 29, 2025
@coderabbitai
Copy link

coderabbitai bot commented Jul 29, 2025

Caution

Review failed

The pull request is closed.

Walkthrough

This change introduces new user profile retrieval features, adds and modifies endpoints for user information and certification, and reorganizes DTO package structures. It also updates OAuth user info extraction to use hardcoded values and enhances the sign-up request with additional required fields and validation. Several classes are updated to reflect the new DTO structure.

Changes

Cohort / File(s) Change Summary
OAuth User Info Hardcoding
src/main/java/life/mosu/mosuserver/application/oauth/OAuthUserInfo.java
Replaces dynamic extraction of user info from Kakao with hardcoded name, email, phone number, and birthday values in ofKakao.
User Profile Info Feature
src/main/java/life/mosu/mosuserver/application/user/UserService.java, src/main/java/life/mosu/mosuserver/presentation/user/UserController.java, src/main/java/life/mosu/mosuserver/presentation/user/dto/response/UserInfoResponse.java
Adds a new service method and controller endpoint to retrieve user profile info, and introduces a response DTO for user info.
Sign-up Request Enhancement
src/main/java/life/mosu/mosuserver/presentation/auth/dto/SignUpAccountRequest.java
Adds new required fields (userName, birth, gender, phoneNumber) with validation and Swagger annotations; hardcodes agreement flags in entity mapping.
KMC Certification Endpoint
src/main/java/life/mosu/mosuserver/presentation/auth/MasterController.java
Adds a GET endpoint for generating KMC certification tokens, with event publishing and error handling.
Token Cookie Utility Update
src/main/java/life/mosu/mosuserver/presentation/auth/SignUpController.java
Replaces usage of temporaryCookieString with createCookie for setting token cookies.
DTO Package Refactor
src/main/java/life/mosu/mosuserver/application/user/MyUserService.java, src/main/java/life/mosu/mosuserver/presentation/user/MyUserController.java, src/main/java/life/mosu/mosuserver/presentation/user/MyUserControllerDocs.java, src/main/java/life/mosu/mosuserver/presentation/user/UserControllerDocs.java, src/main/java/life/mosu/mosuserver/presentation/user/dto/request/ChangePasswordRequest.java, .../FindLoginIdRequest.java, .../FindPasswordRequest.java, .../IsLoginIdAvailableResponse.java, src/main/java/life/mosu/mosuserver/presentation/user/dto/response/ChangePasswordResponse.java, .../CustomerKeyResponse.java, .../FindLoginIdResponse.java
Updates import statements and package declarations for DTOs, moving them into request and response subpackages for improved organization. No logic changes.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant UserController
    participant UserService
    participant UserRepository
    participant UserInfoResponse

    Client->>UserController: GET /user/info (with userId)
    UserController->>UserService: getUserInfo(userId)
    UserService->>UserRepository: findById(userId)
    UserRepository-->>UserService: UserJpaEntity or not found
    UserService->>UserInfoResponse: from(UserJpaEntity)
    UserInfoResponse-->>UserService: UserInfoResponse
    UserService-->>UserController: UserInfoResponse
    UserController-->>Client: 200 OK + ApiResponseWrapper<UserInfoResponse>
Loading
sequenceDiagram
    participant Client
    participant MasterController
    participant OneTimeTokenProvider
    participant KmcEventTxService

    Client->>MasterController: GET /master/kmc
    MasterController->>OneTimeTokenProvider: create(certNumber)
    OneTimeTokenProvider-->>MasterController: token
    MasterController->>KmcEventTxService: publishIssueEvent(certNumber, token, expire)
    alt Success
        MasterController-->>Client: 200 OK + token
    else Failure
        MasterController->>KmcEventTxService: publishFailEvent(certNumber)
        MasterController-->>Client: Exception thrown
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Assessment against linked issues

Objective Addressed Explanation
회원가입 후 info 조회하여 프로필 등록 (#165)

Assessment against linked issues: Out-of-scope changes

No out-of-scope changes found.

Possibly related PRs

Suggested labels

우선순위 중

Poem

A bunny hops with DTOs anew,
User info fields now shining through.
Endpoints bloom for KMC and more,
With cookies set and tokens in store.
Refactored packages, neat and bright—
This codebase leaps to further height!
🐇✨

Note

⚡️ Unit Test Generation is now available in beta!

Learn more here, or try it out under "Finishing Touches" below.


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b738390 and c328f79.

📒 Files selected for processing (18)
  • src/main/java/life/mosu/mosuserver/application/oauth/OAuthUserInfo.java (1 hunks)
  • src/main/java/life/mosu/mosuserver/application/user/MyUserService.java (1 hunks)
  • src/main/java/life/mosu/mosuserver/application/user/UserService.java (2 hunks)
  • src/main/java/life/mosu/mosuserver/presentation/auth/MasterController.java (4 hunks)
  • src/main/java/life/mosu/mosuserver/presentation/auth/SignUpController.java (1 hunks)
  • src/main/java/life/mosu/mosuserver/presentation/auth/dto/SignUpAccountRequest.java (2 hunks)
  • src/main/java/life/mosu/mosuserver/presentation/user/MyUserController.java (1 hunks)
  • src/main/java/life/mosu/mosuserver/presentation/user/MyUserControllerDocs.java (1 hunks)
  • src/main/java/life/mosu/mosuserver/presentation/user/UserController.java (2 hunks)
  • src/main/java/life/mosu/mosuserver/presentation/user/UserControllerDocs.java (1 hunks)
  • src/main/java/life/mosu/mosuserver/presentation/user/dto/request/ChangePasswordRequest.java (1 hunks)
  • src/main/java/life/mosu/mosuserver/presentation/user/dto/request/FindLoginIdRequest.java (1 hunks)
  • src/main/java/life/mosu/mosuserver/presentation/user/dto/request/FindPasswordRequest.java (1 hunks)
  • src/main/java/life/mosu/mosuserver/presentation/user/dto/request/IsLoginIdAvailableResponse.java (1 hunks)
  • src/main/java/life/mosu/mosuserver/presentation/user/dto/response/ChangePasswordResponse.java (1 hunks)
  • src/main/java/life/mosu/mosuserver/presentation/user/dto/response/CustomerKeyResponse.java (1 hunks)
  • src/main/java/life/mosu/mosuserver/presentation/user/dto/response/FindLoginIdResponse.java (1 hunks)
  • src/main/java/life/mosu/mosuserver/presentation/user/dto/response/UserInfoResponse.java (1 hunks)
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/mosu-165

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.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary of Changes

Hello @wlgns12370, 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!

This pull request primarily focuses on enhancing the user registration and profile management system. It expands the user signup request to include more personal details, introduces a new flow for KMC-based identity verification, and provides an endpoint for retrieving user profile information, particularly for users in a 'PENDING' state. Additionally, it includes significant refactoring of DTOs into separate request and response packages to improve code structure.

Highlights

  • Enhanced User Registration DTO: The SignUpAccountRequest DTO has been significantly expanded to include more detailed personal information such as userName, birth, gender, and phoneNumber. This change likely supports a more comprehensive user profile or integration with identity verification processes. Note that agreedToTermsOfService and agreedToPrivacyPolicy are now hardcoded to true in the toAuthEntity method, which might be a temporary measure.
  • New KMC Signup Flow: A new API endpoint, GET /master/kmc, has been introduced in MasterController. This endpoint initiates a KMC (Korean Mobile Certification) based signup flow, involving the generation of a one-time token and publishing KMC events. This suggests a new identity verification step in the user registration process.
  • User Information Retrieval for Pending Users: A new service method getUserInfo(Long userId) has been added to UserService, along with a corresponding API endpoint GET /users/info in UserController. This endpoint is secured with @PreAuthorize("isAuthenticated() and hasRole('PENDING')"), indicating that it's designed to retrieve user profile information specifically for users who are in a 'PENDING' registration state, suggesting a multi-step or staged registration process.
  • DTO Package Refactoring: A major refactoring of the DTO package structure has been performed. DTOs are now separated into dedicated request and response subpackages within presentation.user.dto for improved organization and clarity. This involved renaming several existing DTO files and updating their import paths across various services and controllers.
Using Gemini Code Assist

The 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 in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in issue comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize 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 .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments or fill out our survey to provide feedback.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@wlgns12370 wlgns12370 merged commit ff9a9a1 into develop Jul 29, 2025
1 of 2 checks passed
Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request merges the OAuth and standard user sign-up flows, refactors DTOs into request/response packages, and adds new endpoints for KMC authentication and fetching user information.

The review identified several critical issues that need to be addressed before merging:

  • Hardcoded test data in the OAuth flow which will break Kakao login.
  • Bypassing user consent for terms of service by hardcoding agreement values.
  • A security regression in cookie handling that makes tokens less secure.
  • A bug where new fields in the sign-up request are ignored.

Additionally, there are suggestions for improving code maintainability by reducing duplication, improving error handling, and fixing an incorrectly packaged DTO.

Comment on lines +53 to 56
.name("김모수")
.phoneNumber("010-1234-5678")
.birthDay(LocalDate.EPOCH)
.email("test123@gmali.com")

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

These user details are hardcoded. This appears to be for testing purposes and must be reverted before merging to production. These values should be dynamically retrieved from the OAuth provider's response.

For example:

  • name should come from the profile object (as it was before).
  • phoneNumber, birthDay, and email should be extracted from the kakaoAccount object.

Also, the email test123@gmali.com seems to have a typo and should probably be gmail.com.

Comment on lines +47 to 55
headers.add(HttpHeaders.SET_COOKIE, CookieBuilderUtil.createCookie(
ACCESS_TOKEN_COOKIE_NAME,
token.accessToken(),
token.accessTokenExpireTime()
));
headers.add(HttpHeaders.SET_COOKIE, CookieBuilderUtil.temporaryCookieString(
headers.add(HttpHeaders.SET_COOKIE, CookieBuilderUtil.createCookie(
REFRESH_TOKEN_COOKIE_NAME,
token.refreshToken(),
token.refreshTokenExpireTime()

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

The switch from CookieBuilderUtil.temporaryCookieString to CookieBuilderUtil.createCookie significantly reduces the security of the cookies being set.

createCookie sets secure(false) and doesn't specify domain or SameSite attributes. This means the access and refresh tokens could be sent over unencrypted HTTP connections, and cross-domain behavior might be broken or less secure.

For sensitive tokens, it's crucial to use secure(true). The temporaryCookieString method seems more appropriate for production environments. If this change was not intentional, it should be reverted.

Suggested change
headers.add(HttpHeaders.SET_COOKIE, CookieBuilderUtil.createCookie(
ACCESS_TOKEN_COOKIE_NAME,
token.accessToken(),
token.accessTokenExpireTime()
));
headers.add(HttpHeaders.SET_COOKIE, CookieBuilderUtil.temporaryCookieString(
headers.add(HttpHeaders.SET_COOKIE, CookieBuilderUtil.createCookie(
REFRESH_TOKEN_COOKIE_NAME,
token.refreshToken(),
token.refreshTokenExpireTime()
headers.add(HttpHeaders.SET_COOKIE, CookieBuilderUtil.temporaryCookieString(
ACCESS_TOKEN_COOKIE_NAME,
token.accessToken(),
token.accessTokenExpireTime()
));
headers.add(HttpHeaders.SET_COOKIE, CookieBuilderUtil.temporaryCookieString(
REFRESH_TOKEN_COOKIE_NAME,
token.refreshToken(),
token.refreshTokenExpireTime()
));

Comment on lines +54 to +57
} catch (Exception ex) {
eventTxService.publishFailureEvent(certNum);
throw new RuntimeException("KMC 인증 요청 생성에 실패했습니다.", ex);
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Catching a generic Exception is discouraged as it can hide the actual problems and catch unexpected runtime exceptions like NullPointerException. It's better to catch more specific exceptions that publishIssueEvent might throw.

Additionally, instead of throwing a generic RuntimeException, consider using the project's CustomRuntimeException with a dedicated ErrorCode. This will ensure consistent error handling and response formatting across the application.

Lastly, the success message "프로필 등록 성공" seems misleading. This endpoint appears to initiate an authentication process, so a message like "KMC 인증 요청 생성 성공" would be more accurate.

Comment on lines +41 to +44
UserJpaEntity user = userJpaRepository.findById(userId)
.orElseThrow(() -> new CustomRuntimeException(ErrorCode.USER_NOT_FOUND));

return UserInfoResponse.from(user);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

There's an opportunity to reduce code duplication here. The logic to find a user by ID or throw an exception is already encapsulated in the getUserOrThrow(Long userId) method. You can reuse it here to make the code more concise and maintainable.

Suggested change
UserJpaEntity user = userJpaRepository.findById(userId)
.orElseThrow(() -> new CustomRuntimeException(ErrorCode.USER_NOT_FOUND));
return UserInfoResponse.from(user);
UserJpaEntity user = getUserOrThrow(userId);
return UserInfoResponse.from(user);

@@ -1,4 +1,4 @@
package life.mosu.mosuserver.presentation.user.dto;
package life.mosu.mosuserver.presentation.user.dto.request;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The IsLoginIdAvailableResponse class is used as a response body for an endpoint. According to the new package structure refactoring in this PR, it should be in the ...dto.response package, not ...dto.request. Please move it to the correct package for consistency.

Suggested change
package life.mosu.mosuserver.presentation.user.dto.request;
package life.mosu.mosuserver.presentation.user.dto.response;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

[🛠 리팩토링] OAuth Auth 회원가입 로직 병합

1 participant