Skip to content

Commit bb48b42

Browse files
authored
Merge pull request #590 from sparcs-kaist/589-phoneNumber-badge
#589 전화번호 인증 뱃지 기능
2 parents 47b5c6e + f1227cf commit bb48b42

File tree

7 files changed

+175
-4
lines changed

7 files changed

+175
-4
lines changed

src/modules/populates/rooms.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ export const roomPopulateOption = [
1717
select: "-_id user settlementStatus readAt",
1818
populate: {
1919
path: "user",
20-
select: "_id id name nickname profileImageUrl withdraw",
20+
select: "_id id name nickname profileImageUrl withdraw badge",
2121
},
2222
},
2323
];
@@ -26,7 +26,13 @@ interface PopulatedParticipant
2626
extends Pick<Participant, "settlementStatus" | "readAt"> {
2727
user: Pick<
2828
User,
29-
"_id" | "id" | "name" | "nickname" | "profileImageUrl" | "withdraw"
29+
| "_id"
30+
| "id"
31+
| "name"
32+
| "nickname"
33+
| "profileImageUrl"
34+
| "withdraw"
35+
| "badge"
3036
> | null;
3137
}
3238

@@ -92,7 +98,7 @@ export const formatSettlement = (
9298
koName: roomObject.to!.koName,
9399
},
94100
part: roomObject.part.map((participantSubDocument) => {
95-
const { _id, name, nickname, profileImageUrl, withdraw } =
101+
const { _id, name, nickname, profileImageUrl, withdraw, badge } =
96102
participantSubDocument.user!;
97103
const { settlementStatus, readAt } = participantSubDocument;
98104
return {
@@ -101,6 +107,7 @@ export const formatSettlement = (
101107
nickname,
102108
profileImageUrl,
103109
withdraw,
110+
badge,
104111
isSettlement: includeSettlement ? settlementStatus : undefined,
105112
readAt: readAt ?? roomObject.madeat,
106113
};

src/modules/stores/mongo.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ const userSchema = new Schema<User>({
2626
withdraw: { type: Boolean, default: false }, //탈퇴 여부
2727
withdrewAt: { type: Date }, //탈퇴 시각
2828
phoneNumber: { type: String }, // 전화번호 (2023FALL 이벤트부터 추가)
29+
badge: { type: Boolean }, // 인증 뱃지 사용 여부
2930
ban: { type: Boolean, default: false }, //계정 정지 여부
3031
joinat: { type: Date, required: true }, //가입 시각
3132
agreeOnTermsOfService: { type: Boolean, default: false }, //이용약관 동의 여부

src/routes/docs/users.js

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,105 @@ usersDocs[`${apiPrefix}/editAccount`] = {
194194
},
195195
};
196196

197+
usersDocs[`${apiPrefix}/registerPhoneNumber`] = {
198+
post: {
199+
tags: [tag],
200+
summary: "유저의 전화 번호 등록",
201+
description: "유저의 전화 번호를 요청한 전화 번호로 등록합니다.",
202+
requestBody: {
203+
content: {
204+
"application/json": {
205+
schema: {
206+
type: "object",
207+
properties: {
208+
phoneNumber: {
209+
type: "string",
210+
description: "유저의 전화 번호",
211+
},
212+
},
213+
},
214+
},
215+
},
216+
},
217+
responses: {
218+
200: {
219+
content: {
220+
"text/html": {
221+
example: "Users/registerPhoneNumber : create user phoneNumber successful",
222+
},
223+
},
224+
},
225+
400: {
226+
content: {
227+
"text/html": {
228+
example: "Users/registerPhoneNumber : such user id does not exist",
229+
},
230+
},
231+
},
232+
500: {
233+
content: {
234+
"text/html": {
235+
example: "Users/registerPhoneNumber : internal server error",
236+
},
237+
},
238+
},
239+
},
240+
},
241+
};
242+
243+
usersDocs[`${apiPrefix}/editBadge`] = {
244+
post: {
245+
tags: [tag],
246+
summary: "유저의 뱃지 적용 상태 변경",
247+
description: "유저의 뱃지를 탈부착합니다.",
248+
requestBody: {
249+
content: {
250+
"application/json": {
251+
schema: {
252+
type: "object",
253+
properties: {
254+
badge: {
255+
type: "string",
256+
description: "뱃지 상태",
257+
},
258+
},
259+
},
260+
},
261+
},
262+
},
263+
responses: {
264+
200: {
265+
content: {
266+
"text/html": {
267+
example: "Users/editBadge : badge successfully applied",
268+
},
269+
},
270+
},
271+
400: {
272+
content: {
273+
"text/html": {
274+
example: "Users/editBadge : invalid request for badge",
275+
},
276+
},
277+
},
278+
400: {
279+
content: {
280+
"text/html": {
281+
example: "Users/editBadge : Unauthorized user",
282+
},
283+
},
284+
},
285+
500: {
286+
content: {
287+
"text/html": {
288+
example: "Users/editBadge : internal server error",
289+
},
290+
},
291+
},
292+
},
293+
},
294+
};
295+
197296
usersDocs[`${apiPrefix}/editProfileImg/getPUrl`] = {
198297
post: {
199298
tags: [tag],

src/routes/users.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,17 @@ router.post(
4242
userHandlers.editAccountHandler
4343
);
4444

45+
// 새 전화번호를 받아 로그인된 유저의 전화번호를 저장합니다.
46+
router.post(
47+
"/registerPhoneNumber",
48+
body("phoneNumber").matches(patterns.user.phoneNumber),
49+
validatorMiddleware,
50+
userHandlers.registerPhoneNumberHandler
51+
);
52+
53+
// 뱃지를 부여하거나 회수합니다.
54+
router.post("/editBadge", userHandlers.editBadgeHandler);
55+
4556
// 프로필 이미지를 업로드할 수 있는 Presigned-url을 발급합니다.
4657
router.post(
4758
"/editProfileImg/getPUrl",

src/services/logininfo.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ const logininfoHandler = async (req, res) => {
99

1010
const userDetail = await userModel.findOne(
1111
{ _id: user.oid, withdraw: false },
12-
"_id name nickname id withdraw phoneNumber ban joinat agreeOnTermsOfService subinfo email profileImageUrl account"
12+
"_id name nickname id withdraw phoneNumber badge ban joinat agreeOnTermsOfService subinfo email profileImageUrl account"
1313
);
1414

1515
res.json({
@@ -19,6 +19,7 @@ const logininfoHandler = async (req, res) => {
1919
nickname: userDetail.nickname,
2020
withdraw: userDetail.withdraw,
2121
phoneNumber: userDetail.phoneNumber,
22+
badge: userDetail.badge,
2223
ban: userDetail.ban,
2324
joinat: userDetail.joinat,
2425
agreeOnTermsOfService: userDetail.agreeOnTermsOfService,

src/services/users.ts

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,56 @@ export const editAccountHandler: RequestHandler = async (req, res) => {
123123
}
124124
};
125125

126+
export const registerPhoneNumberHandler: RequestHandler = async (req, res) => {
127+
try {
128+
const newPhoneNumber = req.body.phoneNumber;
129+
const result = await userModel.findOneAndUpdate(
130+
{ _id: req.userOid, withdraw: false },
131+
{ phoneNumber: newPhoneNumber, badge: true }
132+
);
133+
134+
if (result) {
135+
return res
136+
.status(200)
137+
.send("Users/registerPhoneNumber : create user phoneNumber successful");
138+
} else {
139+
return res
140+
.status(400)
141+
.send("Users/registerPhoneNumber : such user id does not exist");
142+
}
143+
} catch (err) {
144+
logger.error(err);
145+
return res
146+
.status(500)
147+
.send("Users/registerPhoneNumber : internal server error");
148+
}
149+
};
150+
151+
export const editBadgeHandler: RequestHandler = async (req, res) => {
152+
try {
153+
if (req.body.badge === "true" || req.body.badge === "false") {
154+
await userModel.findOneAndUpdate(
155+
{
156+
_id: req.userOid,
157+
withdraw: false,
158+
phoneNumber: { $exists: true, $ne: null },
159+
},
160+
{ badge: req.body.badge === "true" ? true : false }
161+
);
162+
return res
163+
.status(200)
164+
.send("Users/editBadge : badge successfully applied");
165+
} else {
166+
return res
167+
.status(400)
168+
.send("Users/editBadge : invalid request for badge");
169+
}
170+
} catch (err) {
171+
logger.error(err);
172+
return res.status(500).send("Users/editBadge : internal server error");
173+
}
174+
};
175+
126176
export const editProfileImgGetPUrlHandler: RequestHandler = async (
127177
req,
128178
res

src/types/mongo.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ export interface User extends Document<Types.ObjectId> {
1919
withdrewAt?: Date;
2020
/** 사용자의 전화번호. 2023 가을 이벤트부터 추가됨. */
2121
phoneNumber?: string;
22+
/** 인증 뱃지 사용 여부 */
23+
badge?: boolean;
2224
/** 계정 정지 여부. */
2325
ban: boolean;
2426
/** 계정 가입 시각. */

0 commit comments

Comments
 (0)