Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
14 changes: 13 additions & 1 deletion src/controllers/auth.controller.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import axios from "axios";
import { getTTLFromToken } from "../Auths/token.js";
import { checkDuplicatedEmail, checkDuplicatedUsername, signUpUser, loginUser, updateRefreshToken, SendVerifyEmailCode, checkEmailCode, getAccountInfo, resetPassword, logoutUser, withdrawUser, verifySocialAccount, socialLoginUser, socialLoginCertification } from "../services/auth.service.js";
import { checkDuplicatedEmail, checkDuplicatedUsername, signUpUser, loginUser, updateRefreshToken, SendVerifyEmailCode, checkEmailCode, getAccountInfo, resetPassword, logoutUser, withdrawUser, verifySocialAccount, socialLoginUser, socialLoginCertification, changePassword } from "../services/auth.service.js";
import { createSocialUserDTO } from "../dtos/auth.dto.js";

export const handleSignUp = async (req, res, next) => {
Expand Down Expand Up @@ -180,6 +180,18 @@ export const handleResetPassword = async (req, res, next) => {
try{
const result = await resetPassword({userId, oldPassword, newPassword});

res.status(200).success(result);
} catch(err) {
next(err);
}
}

export const handleChangePassword = async (req, res, next) => {
const userId = req.user.id;
const {password} = req.body;
try{
const result = await changePassword({userId, password});

res.status(200).success(result);
} catch(err) {
next(err);
Expand Down
7 changes: 4 additions & 3 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { specs } from "./configs/swagger.config.js";
import { jwtStrategy } from "./Auths/strategies/jwt.strategy.js";
import { handleGetFriendsList, handlePostFriendsRequest, handleGetIncomingFriendRequests, handleGetOutgoingFriendRequests, handleAcceptFriendRequest, handleRejectFriendRequest, handleDeleteFriendRequest } from "./controllers/friend.controller.js";
import { handleSendMyLetter, handleSendOtherLetter, handleGetLetterDetail, handleRemoveLetterLike, handleAddLetterLike, handleGetPublicLetterFromOther, handleGetPublicLetterFromFriend, handleGetUserLetterStats, handleGetLetterAssets, handleGetLetterByAiKeyword } from "./controllers/letter.controller.js";
import { handleCheckDuplicatedEmail, handleLogin, handleRefreshToken, handleSignUp, handleSendVerifyEmailCode, handleCheckEmailCode, handleGetAccountInfo, handleResetPassword, handleLogout, handleWithdrawUser, handleCheckDuplicatedUsername, handleSocialLogin, handleSocialLoginCertification, handleSocialLoginCallback } from "./controllers/auth.controller.js";
import { handleCheckDuplicatedEmail, handleLogin, handleRefreshToken, handleSignUp, handleSendVerifyEmailCode, handleCheckEmailCode, handleGetAccountInfo, handleResetPassword, handleLogout, handleWithdrawUser, handleCheckDuplicatedUsername, handleSocialLogin, handleSocialLoginCertification, handleSocialLoginCallback, handleChangePassword } from "./controllers/auth.controller.js";
import { handlePostMatchingSession, handlePatchMatchingSessionStatusDiscarded, handlePatchMatchingSessionStatusFriends, handlePostSessionReview } from "./controllers/session.controller.js";
import { handleCreateUserAgreements, handlePatchOnboardingStep1, handleGetAllInterests, handleGetMyInterests, handleUpdateMyOnboardingInterests, handleGetMyNotificationSettings, handleUpdateMyNotificationSettings, handleGetMyProfile, handlePatchMyProfile, handlePostMyProfileImage, handlePutMyPushSubscription, handleGetMyConsents, handlePatchMyConsents, handleUpdateActivity, } from "./controllers/user.controller.js";
import { handleGetAnonymousThreads, handleGetAnonymousThreadLetters, handleGetSelfMailbox, handleGetLetterFromFriend, } from "./controllers/mailbox.controller.js";
Expand All @@ -20,7 +20,7 @@ import { handleGetCommunityGuidelines, handleGetTerms, handleGetPrivacy, } from
import { handleGetWeeklyReport } from "./controllers/weeklyReport.controller.js";
import { handleGetTodayQuestion } from "./controllers/question.controller.js";
import { validate } from "./middlewares/validate.middleware.js";
import { emailSchema, loginSchema, passwordSchema, SignUpSchema, usernameSchema, verificationConfirmCodeSchema, verificationSendCodeSchema } from "./schemas/auth.schema.js";
import { changePasswordSchema, emailSchema, loginSchema, resetPasswordSchema, SignUpSchema, usernameSchema, verificationConfirmCodeSchema, verificationSendCodeSchema } from "./schemas/auth.schema.js";
import { handleInsertInquiryAsUser, handleInsertInquiryAsAdmin, handleGetInquiry, handleGetInquiryDetail } from "./controllers/inquiry.controller.js";
import { isLogin } from "./middlewares/auth.middleware.js";
import { isRestricted } from "./middlewares/restriction.middleware.js";
Expand Down Expand Up @@ -160,7 +160,8 @@ app.get("/auth/refresh", handleRefreshToken);
app.post("/auth/:type/verification-codes", validate(verificationSendCodeSchema), handleSendVerifyEmailCode); // 이메일 인증번호 전송
app.post("/auth/:type/verification-codes/confirm", validate(verificationConfirmCodeSchema), handleCheckEmailCode); // 이메일 인증번호 확인
app.post("/auth/find-id", validate(emailSchema), handleGetAccountInfo); // 아이디 찾기
app.patch("/auth/reset-password", isLogin, validate(passwordSchema), handleResetPassword); // 비밀번호 찾기
app.patch("/auth/reset-password", isLogin, validate(resetPasswordSchema), handleResetPassword); // 비밀번호 초기화
app.patch("/auth/change-password", isLogin, validate(changePasswordSchema), handleChangePassword); // 비밀번호 변경
app.post("/auth/logout", isLogin, handleLogout); // 로그아웃
app.delete("/users", isLogin, handleWithdrawUser); // 탈퇴
app.post("/users/me/agreements", isLogin, validate(createUserAgreementsSchema), handleCreateUserAgreements) // 이용약관 동의
Expand Down
10 changes: 8 additions & 2 deletions src/schemas/auth.schema.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { z } from "zod";

const emailPart = z.email("이메일 형식이 올바르지 않습니다.");
const usernamePart = z.string("아이디는 필수입니다.").min(6, "아이디는 최소 6자 이상입니다.").max(16, "아이디는 최대 6자 이상입니다.");
const passwordPart = z.string("비밀번호는 필수입니다.").regex(/^(?=.*[a-zA-Z])(?=.*[0-9])[a-zA-Z0-9]{8,16}$/, "비밀번호는 최소 8자-16자 제한입니다. (영문, 숫자 포함해 최대 16자리)");
const passwordPart = z.string("비밀번호는 필수입니다.").regex(/^(?=.*[a-zA-Z])(?=.*[0-9])[a-zA-Z0-9!@#$%^&*]{8,16}$/, "비밀번호는 최소 8자-16자 제한입니다. (영문, 숫자 포함해 최대 16자리)");
const phoneNumberPart = z.string("전화번호는 필수입니다.").regex(/^01(?:0|1|[6-9])-(?:\d{3}|\d{4})-\d{4}$/, "전화번호 형식이 올바르지 않습니다.");

export const SignUpSchema = z.object({
Expand Down Expand Up @@ -39,7 +39,13 @@ export const usernameSchema = z.object({
})
})

export const passwordSchema = z.object({
export const changePasswordSchema = z.object({
body: z.object({
password: passwordPart
})
})

export const resetPasswordSchema = z.object({
body: z.object({
oldPassword: passwordPart,
newPassword: passwordPart
Expand Down
7 changes: 7 additions & 0 deletions src/services/auth.service.js
Original file line number Diff line number Diff line change
Expand Up @@ -300,5 +300,12 @@ export const resetPassword = async ({userId, oldPassword, newPassword}) => {
const newPasswordHash = await bcrypt.hash(newPassword, 10);
await updatePassword({userId, newPassword: newPasswordHash});

return { message: "비밀번호 재설정이 완료되었습니다." };
}

export const changePassword = async ({userId, password}) => {
const newPasswordHash = await bcrypt.hash(password, 10);
await updatePassword({userId, newPassword: newPasswordHash});

return { message: "비밀번호 재설정이 완료되었습니다." };
}
107 changes: 106 additions & 1 deletion src/swagger/auth.swagger.js
Original file line number Diff line number Diff line change
Expand Up @@ -691,7 +691,7 @@
* @swagger
* /auth/reset-password:
* patch:
* summary: 비밀번호 재설정
* summary: 비밀번호 초기화
* description: "/auth/reset-password/confirm 에서 발급받은 임시 AccessToken이 필요합니다."
* tags: [로그인]
* security:
Expand Down Expand Up @@ -810,6 +810,111 @@
* example: "기존 비밀번호를 찾을 수 없습니다."
*/

/**
* @swagger
* /auth/change-password:
* patch:
* summary: 비밀번호 변경
* description: "비밀번호 변경 API입니다."
* tags: [로그인]
* security:
* - bearerAuth: []
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* required:
* - password
* properties:
* password:
* type: string
* example: "Password123!"
* responses:
* 200:
* description: 비밀번호 변경 성공
* content:
* application/json:
* schema:
* allOf:
* - $ref: '#/components/schemas/SuccessResponse'
* - properties:
* success:
* type: object
* properties:
* message:
* type: string
* example: "비밀번호 재설정이 완료되었습니다."
* 401:
* description: |
* 인증 실패:
* - `AUTH_TOKEN_EXPIRED`: 토큰이 만료되었습니다.
* - `AUTH_INVALID_TOKEN`: 액세스 토큰이 아니거나 유효하지 않습니다.
* - `AUTH_NOT_ACCESS_TOKEN`: 액세스 토큰이 아닙니다.
* - `AUTH_EXPIRED_TOKEN`: 이미 로그아웃된 토큰입니다.
* - `AUTH_UNAUTHORIZED`: 액세스 토큰이 유효하지 않습니다.
* - `AUTH_NOT_FOUND`: 인증 토큰이 없습니다.
* content:
* application/json:
* schema:
* oneOf:
* - allOf:
* - $ref: '#/components/schemas/ErrorResponse'
* - properties:
* error:
* properties:
* errorCode:
* example: "AUTH_TOKEN_EXPIRED"
* reason:
* example: "토큰이 만료되었습니다."
* - allOf:
* - $ref: '#/components/schemas/ErrorResponse'
* - properties:
* error:
* properties:
* errorCode:
* example: "AUTH_INVALID_TOKEN"
* reason:
* example: "액세스 토큰이 아니거나 유효하지 않습니다."
* - allOf:
* - $ref: '#/components/schemas/ErrorResponse'
* - properties:
* error:
* properties:
* errorCode:
* example: "AUTH_NOT_ACCESS_TOKEN"
* reason:
* example: "액세스 토큰이 아닙니다."
* - allOf:
* - $ref: '#/components/schemas/ErrorResponse'
* - properties:
* error:
* properties:
* errorCode:
* example: "AUTH_EXPIRED_TOKEN"
* reason:
* example: "이미 로그아웃된 토큰입니다."
* - allOf:
* - $ref: '#/components/schemas/ErrorResponse'
* - properties:
* error:
* properties:
* errorCode:
* example: "AUTH_UNAUTHORIZED"
* reason:
* example: "액세스 토큰이 유효하지 않습니다."
* - allOf:
* - $ref: '#/components/schemas/ErrorResponse'
* - properties:
* error:
* properties:
* errorCode:
* example: "AUTH_NOT_FOUND"
* reason:
* example: "인증 토큰이 없습니다."
*/

/**
* @swagger
* /auth/logout:
Expand Down