diff --git a/src/modules/populates/rooms.ts b/src/modules/populates/rooms.ts index 25b0bfff..c6afed60 100644 --- a/src/modules/populates/rooms.ts +++ b/src/modules/populates/rooms.ts @@ -17,7 +17,7 @@ export const roomPopulateOption = [ select: "-_id user settlementStatus readAt", populate: { path: "user", - select: "_id id name nickname profileImageUrl withdraw", + select: "_id id name nickname profileImageUrl withdraw badge", }, }, ]; @@ -26,7 +26,13 @@ interface PopulatedParticipant extends Pick { user: Pick< User, - "_id" | "id" | "name" | "nickname" | "profileImageUrl" | "withdraw" + | "_id" + | "id" + | "name" + | "nickname" + | "profileImageUrl" + | "withdraw" + | "badge" > | null; } @@ -92,7 +98,7 @@ export const formatSettlement = ( koName: roomObject.to!.koName, }, part: roomObject.part.map((participantSubDocument) => { - const { _id, name, nickname, profileImageUrl, withdraw } = + const { _id, name, nickname, profileImageUrl, withdraw, badge } = participantSubDocument.user!; const { settlementStatus, readAt } = participantSubDocument; return { @@ -101,6 +107,7 @@ export const formatSettlement = ( nickname, profileImageUrl, withdraw, + badge, isSettlement: includeSettlement ? settlementStatus : undefined, readAt: readAt ?? roomObject.madeat, }; diff --git a/src/modules/stores/mongo.ts b/src/modules/stores/mongo.ts index 41ccfa3e..eb1855c1 100755 --- a/src/modules/stores/mongo.ts +++ b/src/modules/stores/mongo.ts @@ -26,6 +26,7 @@ const userSchema = new Schema({ withdraw: { type: Boolean, default: false }, //탈퇴 여부 withdrewAt: { type: Date }, //탈퇴 시각 phoneNumber: { type: String }, // 전화번호 (2023FALL 이벤트부터 추가) + badge: { type: Boolean }, // 인증 뱃지 사용 여부 ban: { type: Boolean, default: false }, //계정 정지 여부 joinat: { type: Date, required: true }, //가입 시각 agreeOnTermsOfService: { type: Boolean, default: false }, //이용약관 동의 여부 diff --git a/src/routes/docs/users.js b/src/routes/docs/users.js index f9a5c270..c04327a7 100644 --- a/src/routes/docs/users.js +++ b/src/routes/docs/users.js @@ -194,6 +194,105 @@ usersDocs[`${apiPrefix}/editAccount`] = { }, }; +usersDocs[`${apiPrefix}/registerPhoneNumber`] = { + post: { + tags: [tag], + summary: "유저의 전화 번호 등록", + description: "유저의 전화 번호를 요청한 전화 번호로 등록합니다.", + requestBody: { + content: { + "application/json": { + schema: { + type: "object", + properties: { + phoneNumber: { + type: "string", + description: "유저의 전화 번호", + }, + }, + }, + }, + }, + }, + responses: { + 200: { + content: { + "text/html": { + example: "Users/registerPhoneNumber : create user phoneNumber successful", + }, + }, + }, + 400: { + content: { + "text/html": { + example: "Users/registerPhoneNumber : such user id does not exist", + }, + }, + }, + 500: { + content: { + "text/html": { + example: "Users/registerPhoneNumber : internal server error", + }, + }, + }, + }, + }, +}; + +usersDocs[`${apiPrefix}/editBadge`] = { + post: { + tags: [tag], + summary: "유저의 뱃지 적용 상태 변경", + description: "유저의 뱃지를 탈부착합니다.", + requestBody: { + content: { + "application/json": { + schema: { + type: "object", + properties: { + badge: { + type: "string", + description: "뱃지 상태", + }, + }, + }, + }, + }, + }, + responses: { + 200: { + content: { + "text/html": { + example: "Users/editBadge : badge successfully applied", + }, + }, + }, + 400: { + content: { + "text/html": { + example: "Users/editBadge : invalid request for badge", + }, + }, + }, + 400: { + content: { + "text/html": { + example: "Users/editBadge : Unauthorized user", + }, + }, + }, + 500: { + content: { + "text/html": { + example: "Users/editBadge : internal server error", + }, + }, + }, + }, + }, +}; + usersDocs[`${apiPrefix}/editProfileImg/getPUrl`] = { post: { tags: [tag], diff --git a/src/routes/users.ts b/src/routes/users.ts index 58d8addc..0f13c008 100755 --- a/src/routes/users.ts +++ b/src/routes/users.ts @@ -42,6 +42,17 @@ router.post( userHandlers.editAccountHandler ); +// 새 전화번호를 받아 로그인된 유저의 전화번호를 저장합니다. +router.post( + "/registerPhoneNumber", + body("phoneNumber").matches(patterns.user.phoneNumber), + validatorMiddleware, + userHandlers.registerPhoneNumberHandler +); + +// 뱃지를 부여하거나 회수합니다. +router.post("/editBadge", userHandlers.editBadgeHandler); + // 프로필 이미지를 업로드할 수 있는 Presigned-url을 발급합니다. router.post( "/editProfileImg/getPUrl", diff --git a/src/services/logininfo.js b/src/services/logininfo.js index 749f2e15..70564e12 100644 --- a/src/services/logininfo.js +++ b/src/services/logininfo.js @@ -9,7 +9,7 @@ const logininfoHandler = async (req, res) => { const userDetail = await userModel.findOne( { _id: user.oid, withdraw: false }, - "_id name nickname id withdraw phoneNumber ban joinat agreeOnTermsOfService subinfo email profileImageUrl account" + "_id name nickname id withdraw phoneNumber badge ban joinat agreeOnTermsOfService subinfo email profileImageUrl account" ); res.json({ @@ -19,6 +19,7 @@ const logininfoHandler = async (req, res) => { nickname: userDetail.nickname, withdraw: userDetail.withdraw, phoneNumber: userDetail.phoneNumber, + badge: userDetail.badge, ban: userDetail.ban, joinat: userDetail.joinat, agreeOnTermsOfService: userDetail.agreeOnTermsOfService, diff --git a/src/services/users.ts b/src/services/users.ts index e8e821c6..db869da2 100644 --- a/src/services/users.ts +++ b/src/services/users.ts @@ -123,6 +123,56 @@ export const editAccountHandler: RequestHandler = async (req, res) => { } }; +export const registerPhoneNumberHandler: RequestHandler = async (req, res) => { + try { + const newPhoneNumber = req.body.phoneNumber; + const result = await userModel.findOneAndUpdate( + { _id: req.userOid, withdraw: false }, + { phoneNumber: newPhoneNumber, badge: true } + ); + + if (result) { + return res + .status(200) + .send("Users/registerPhoneNumber : create user phoneNumber successful"); + } else { + return res + .status(400) + .send("Users/registerPhoneNumber : such user id does not exist"); + } + } catch (err) { + logger.error(err); + return res + .status(500) + .send("Users/registerPhoneNumber : internal server error"); + } +}; + +export const editBadgeHandler: RequestHandler = async (req, res) => { + try { + if (req.body.badge === "true" || req.body.badge === "false") { + await userModel.findOneAndUpdate( + { + _id: req.userOid, + withdraw: false, + phoneNumber: { $exists: true, $ne: null }, + }, + { badge: req.body.badge === "true" ? true : false } + ); + return res + .status(200) + .send("Users/editBadge : badge successfully applied"); + } else { + return res + .status(400) + .send("Users/editBadge : invalid request for badge"); + } + } catch (err) { + logger.error(err); + return res.status(500).send("Users/editBadge : internal server error"); + } +}; + export const editProfileImgGetPUrlHandler: RequestHandler = async ( req, res diff --git a/src/types/mongo.d.ts b/src/types/mongo.d.ts index 9848f4e0..b07badf0 100644 --- a/src/types/mongo.d.ts +++ b/src/types/mongo.d.ts @@ -19,6 +19,8 @@ export interface User extends Document { withdrewAt?: Date; /** 사용자의 전화번호. 2023 가을 이벤트부터 추가됨. */ phoneNumber?: string; + /** 인증 뱃지 사용 여부 */ + badge?: boolean; /** 계정 정지 여부. */ ban: boolean; /** 계정 가입 시각. */