From 23340c1c0ff6cd16b9c1731e40abd9cfeb85bff1 Mon Sep 17 00:00:00 2001 From: static Date: Tue, 24 Oct 2023 22:48:28 +0900 Subject: [PATCH 01/11] Refactor: profileImageUrl now stores full url --- src/routes/docs/users.md | 4 ++-- src/services/users.js | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/routes/docs/users.md b/src/routes/docs/users.md index 6b46963b..850323ff 100755 --- a/src/routes/docs/users.md +++ b/src/routes/docs/users.md @@ -93,7 +93,7 @@ User { - 프로필 이미지를 업로드할 수 있는 Presigned-url을 발급합니다. - 프로필 사진은 아래 규칙을 만족해야 함. 1. 파일 형식은 image/png, image/jpg, image/jpeg 중 하나 - 2. 파일 크기는 최대 50 MB + 2. 파일 크기는 최대 2 MB #### URL Parameters @@ -125,7 +125,7 @@ User { ```javascript { result: Boolean, // 정상적으로 업로드 되었으면 true - profileImageUrl?: user._id, // 정상적으로 업로드 되었으면 새 프로필 이미지 파일명, 그렇지 않은 경우 undefined + profileImageUrl?: user._id, // 정상적으로 업로드 되었으면 새 프로필 이미지 URL, 그렇지 않은 경우 undefined } ``` diff --git a/src/services/users.js b/src/services/users.js index f4a00d6a..f22c7f99 100644 --- a/src/services/users.js +++ b/src/services/users.js @@ -133,7 +133,7 @@ const editProfileImgDoneHandler = async (req, res) => { } const userAfter = await userModel.findOneAndUpdate( { id: req.userId }, - { profileImageUrl: user._id }, + { profileImageUrl: aws.getS3Url(`/${key}?token=${req.timestamp}`) }, { new: true } ); if (!userAfter) { @@ -143,7 +143,7 @@ const editProfileImgDoneHandler = async (req, res) => { } res.json({ result: true, - profileImageUrl: userAfter._id, + profileImageUrl: userAfter.profileImageUrl, }); }); } catch (e) { From 90d658bec8eb1b4c9992d052b62e0fc9f1594fae Mon Sep 17 00:00:00 2001 From: static Date: Thu, 26 Oct 2023 23:12:28 +0900 Subject: [PATCH 02/11] Add: scripts/profileImageUrlUpdate.js --- scripts/profileImageUrlUpdater.js | 35 +++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 scripts/profileImageUrlUpdater.js diff --git a/scripts/profileImageUrlUpdater.js b/scripts/profileImageUrlUpdater.js new file mode 100644 index 00000000..30f8fbbd --- /dev/null +++ b/scripts/profileImageUrlUpdater.js @@ -0,0 +1,35 @@ +// For Issue #173 + +const { MongoClient } = require("mongodb"); +const { mongo: mongoUrl, aws: awsEnv } = require("../loadenv"); + +const time = Date.now(); + +const client = new MongoClient(mongoUrl); +const db = client.db("taxi"); +const users = db.collection("users"); + +async function run() { + try { + for await (const doc of users.find()) { + // 이미 변환이 완료된 경우에는 Pass합니다. + if (doc.profileImageUrl.startsWith(awsEnv.s3Url)) continue; + + await users.findOneAndUpdate( + { _id: doc._id }, + { + $set: { + profileImageUrl: `${awsEnv.s3Url}/profile-img/${doc.profileImageUrl}?token=${time}`, + }, + } + ); + } + } catch (err) { + console.log(err); + } finally { + await client.close(); + } +} +run().then(() => { + console.log("Done!"); +}); From 32cd08035a9754d90308f5b8c3d8948228e77590 Mon Sep 17 00:00:00 2001 From: static Date: Thu, 26 Oct 2023 23:18:45 +0900 Subject: [PATCH 03/11] Add: runscript script --- package.json | 2 ++ pnpm-lock.yaml | 57 ++++++++++++++++++++++++++++++++++++-------------- 2 files changed, 43 insertions(+), 16 deletions(-) diff --git a/package.json b/package.json index fecc4769..307baba9 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,7 @@ "test": "npm run sample && cross-env TZ='Asia/Seoul' npm run mocha", "mocha": "cross-env TZ='Asia/Seoul' NODE_ENV=test mocha --recursive --reporter spec --exit", "serve": "cross-env TZ='Asia/Seoul' NODE_ENV=production node app.js", + "runscript": "cross-env TZ='Asia/Seoul' NODE_ENV=production node", "lint": "npx eslint --fix .", "sample": "cd sampleGenerator && npm start && cd .." }, @@ -59,6 +60,7 @@ "eslint": "^8.22.0", "eslint-plugin-mocha": "^10.1.0", "mocha": "^10.2.0", + "mongodb": "^6.2.0", "nodemon": "^3.0.1", "supertest": "^6.2.4" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d197fbe1..545f1c18 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -34,7 +34,7 @@ dependencies: version: 2.2.0 connect-mongo: specifier: ^4.6.0 - version: 4.6.0(express-session@1.17.3)(mongodb@4.17.1) + version: 4.6.0(express-session@1.17.3)(mongodb@6.2.0) connect-redis: specifier: ^6.1.3 version: 6.1.3 @@ -121,6 +121,9 @@ devDependencies: mocha: specifier: ^10.2.0 version: 10.2.0 + mongodb: + specifier: ^6.2.0 + version: 6.2.0 nodemon: specifier: ^3.0.1 version: 3.0.1 @@ -2530,8 +2533,6 @@ packages: requiresBuild: true dependencies: sparse-bitfield: 3.0.3 - dev: false - optional: true /@nodelib/fs.scandir@2.1.5: resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} @@ -3808,7 +3809,6 @@ packages: /@types/node@20.4.7: resolution: {integrity: sha512-bUBrPjEry2QUTsnuEjzjbS7voGWCc30W0qzgMf90GPeDGFRakvrz47ju+oqDAKCXLUCe39u57/ORMl/O/04/9g==} - dev: false /@types/object.omit@3.0.0: resolution: {integrity: sha512-I27IoPpH250TUzc9FzXd0P1BV/BMJuzqD3jOz98ehf9dQqGkxlq+hO1bIqZGWqCg5bVOy0g4AUVJtnxe0klDmw==} @@ -3896,14 +3896,12 @@ packages: /@types/webidl-conversions@7.0.0: resolution: {integrity: sha512-xTE1E+YF4aWPJJeUzaZI5DRntlkY3+BCVJi0axFptnjGmAoWxkyREIh/XMrfxVLejwQxMCfDXdICo0VLxThrog==} - dev: false /@types/whatwg-url@8.2.2: resolution: {integrity: sha512-FtQu10RWgn3D9U4aazdwIE2yzphmTJREDqNdODHrbrZmmMqI0vMheC/6NE/J1Yveaj8H+ela+YwWTjq5PGmuhA==} dependencies: '@types/node': 20.4.7 '@types/webidl-conversions': 7.0.0 - dev: false /abbrev@1.1.1: resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==} @@ -4314,6 +4312,10 @@ packages: buffer: 5.7.1 dev: false + /bson@6.2.0: + resolution: {integrity: sha512-ID1cI+7bazPDyL9wYy9GaQ8gEEohWvcUl/Yf0dIdutJxnmInEEyCsb4awy/OiBfall7zBA179Pahi3vCdFze3Q==} + engines: {node: '>=16.20.1'} + /buffer-equal-constant-time@1.0.1: resolution: {integrity: sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==} dev: false @@ -4568,7 +4570,7 @@ packages: /concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} - /connect-mongo@4.6.0(express-session@1.17.3)(mongodb@4.17.1): + /connect-mongo@4.6.0(express-session@1.17.3)(mongodb@6.2.0): resolution: {integrity: sha512-8new4Z7NLP3CGP65Aw6ls3xDBeKVvHRSh39CXuDZTQsvpeeU9oNMzfFgvqmHqZ6gWpxIl663RyoVEmCAGf1yOg==} engines: {node: '>=10'} peerDependencies: @@ -4578,7 +4580,7 @@ packages: debug: 4.3.4 express-session: 1.17.3 kruptein: 3.0.6 - mongodb: 4.17.1 + mongodb: 6.2.0 transitivePeerDependencies: - supports-color dev: false @@ -6427,8 +6429,6 @@ packages: /memory-pager@1.5.0: resolution: {integrity: sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==} requiresBuild: true - dev: false - optional: true /merge-descriptors@1.0.1: resolution: {integrity: sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==} @@ -6564,7 +6564,6 @@ packages: dependencies: '@types/whatwg-url': 8.2.2 whatwg-url: 11.0.0 - dev: false /mongodb@4.17.1: resolution: {integrity: sha512-MBuyYiPUPRTqfH2dV0ya4dcr2E5N52ocBuZ8Sgg/M030nGF78v855B3Z27mZJnp8PxjnUquEnAtjOsphgMZOlQ==} @@ -6580,6 +6579,37 @@ packages: - aws-crt dev: false + /mongodb@6.2.0: + resolution: {integrity: sha512-d7OSuGjGWDZ5usZPqfvb36laQ9CPhnWkAGHT61x5P95p/8nMVeH8asloMwW6GcYFeB0Vj4CB/1wOTDG2RA9BFA==} + engines: {node: '>=16.20.1'} + peerDependencies: + '@aws-sdk/credential-providers': ^3.188.0 + '@mongodb-js/zstd': ^1.1.0 + gcp-metadata: ^5.2.0 + kerberos: ^2.0.1 + mongodb-client-encryption: '>=6.0.0 <7' + snappy: ^7.2.2 + socks: ^2.7.1 + peerDependenciesMeta: + '@aws-sdk/credential-providers': + optional: true + '@mongodb-js/zstd': + optional: true + gcp-metadata: + optional: true + kerberos: + optional: true + mongodb-client-encryption: + optional: true + snappy: + optional: true + socks: + optional: true + dependencies: + '@mongodb-js/saslprep': 1.1.0 + bson: 6.2.0 + mongodb-connection-string-url: 2.6.0 + /mongoose@6.12.0: resolution: {integrity: sha512-sd/q83C6TBRPBrrD2A/POSbA/exbCFM2WOuY7Lf2JuIJFlHFG39zYSDTTAEiYlzIfahNOLmXPxBGFxdAch41Mw==} engines: {node: '>=12.0.0'} @@ -7865,8 +7895,6 @@ packages: requiresBuild: true dependencies: memory-pager: 1.5.0 - dev: false - optional: true /stack-trace@0.0.10: resolution: {integrity: sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==} @@ -8138,7 +8166,6 @@ packages: engines: {node: '>=12'} dependencies: punycode: 2.3.0 - dev: false /triple-beam@1.4.1: resolution: {integrity: sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg==} @@ -8382,7 +8409,6 @@ packages: /webidl-conversions@7.0.0: resolution: {integrity: sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==} engines: {node: '>=12'} - dev: false /websocket-driver@0.7.4: resolution: {integrity: sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==} @@ -8404,7 +8430,6 @@ packages: dependencies: tr46: 3.0.0 webidl-conversions: 7.0.0 - dev: false /whatwg-url@5.0.0: resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} From 17ed317c036b7068e8b7b9ef38e055bafbf8b12a Mon Sep 17 00:00:00 2001 From: static Date: Mon, 30 Oct 2023 22:34:49 +0900 Subject: [PATCH 04/11] Fix: default profile image url --- src/modules/modifyProfile.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/modules/modifyProfile.js b/src/modules/modifyProfile.js index 0d15bd58..e8702f98 100755 --- a/src/modules/modifyProfile.js +++ b/src/modules/modifyProfile.js @@ -1,4 +1,5 @@ const crypto = require("crypto"); +const aws = require("./stores/aws"); const nouns = [ "재료역학", @@ -81,7 +82,7 @@ const generateNickname = (id) => { // 기존 프로필 사진의 URI 중 하나를 무작위로 선택해 반환합니다. const generateProfileImageUrl = () => { const ridx = crypto.randomInt(defaultProfile.length); - return `default/${defaultProfile[ridx]}`; + return aws.getS3Url(`/profile-img/default/${defaultProfile[ridx]}`); }; // 사용자의 이름과 성을 받아, 한글인지 영어인지에 따라 전체 이름을 반환합니다. From 48af97c4ecfe9031021eb520aec7614bac5fd582 Mon Sep 17 00:00:00 2001 From: static Date: Tue, 31 Oct 2023 21:04:13 +0900 Subject: [PATCH 05/11] Refactor: scripts/profileImageUrlUpdater.js MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jeong Sang (정상) --- scripts/profileImageUrlUpdater.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/profileImageUrlUpdater.js b/scripts/profileImageUrlUpdater.js index 30f8fbbd..78ebe778 100644 --- a/scripts/profileImageUrlUpdater.js +++ b/scripts/profileImageUrlUpdater.js @@ -1,4 +1,5 @@ -// For Issue #173 +// Issue #173을 해결하기 위한 DB 마이그레이션 스크립트입니다. +// https://github.com/sparcs-kaist/taxi-back/issues/173 const { MongoClient } = require("mongodb"); const { mongo: mongoUrl, aws: awsEnv } = require("../loadenv"); From ae4f520232c2f9b26ae4ce5231458cbad3164842 Mon Sep 17 00:00:00 2001 From: T-dubb Date: Tue, 28 Nov 2023 22:49:39 +0900 Subject: [PATCH 06/11] =?UTF-8?q?Fix:=20socket.js=20socket=20update=20?= =?UTF-8?q?=EC=98=A4=ED=83=80=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/modules/socket.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/modules/socket.js b/src/modules/socket.js index bca99161..312a6b77 100644 --- a/src/modules/socket.js +++ b/src/modules/socket.js @@ -219,9 +219,11 @@ const emitUpdateEvent = async (io, roomId) => { throw new IllegalArgumentsException(); } - part.forEach(({ user }) => io.in(`user-${user}`).emit("chat_update"), { - roomId, - }); + part.forEach(({ user }) => + io.in(`user-${user}`).emit("chat_update", { + roomId, + }) + ); return true; } catch (err) { From 17a94f87004e22ae634bd7e516b29445ec2a9e0c Mon Sep 17 00:00:00 2001 From: Dongwon Choi Date: Sat, 9 Dec 2023 12:32:41 +0000 Subject: [PATCH 07/11] Docs: basic format --- src/routes/docs/users.js | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/src/routes/docs/users.js b/src/routes/docs/users.js index e76cd2b4..e2b64891 100644 --- a/src/routes/docs/users.js +++ b/src/routes/docs/users.js @@ -2,6 +2,24 @@ const tag = "users"; const apiPrefix = "/users"; const usersDocs = {}; +usersDocs[`${apiPrefix}/agreeOnTermsOfService`] = { + post: { + tags: [tag], + }, +}; + +usersDocs[`${apiPrefix}/getAgreeOnTermsOfService`] = { + get: { + tags: [tag], + }, +}; + +usersDocs[`${apiPrefix}/editNickname`] = { + post: { + tags: [tag], + }, +}; + usersDocs[`${apiPrefix}/resetNickname`] = { get: { tags: [tag], @@ -33,6 +51,24 @@ usersDocs[`${apiPrefix}/resetNickname`] = { }, }; +usersDocs[`${apiPrefix}/editAccount`] = { + post: { + tags: [tag], + }, +}; + +usersDocs[`${apiPrefix}/editProfileImg/getPUrl`] = { + post: { + tags: [tag], + }, +}; + +usersDocs[`${apiPrefix}/editProfileImg/done`] = { + get: { + tags: [tag], + }, +}; + usersDocs[`${apiPrefix}/resetProfileImg`] = { get: { tags: [tag], From 0256863a686f230816bb636225b963e99ed317bf Mon Sep 17 00:00:00 2001 From: Dongwon Choi Date: Sat, 9 Dec 2023 13:51:36 +0000 Subject: [PATCH 08/11] Fix: unify send message prefix --- src/services/users.js | 54 +++++++++++++++++++++++++------------------ 1 file changed, 31 insertions(+), 23 deletions(-) diff --git a/src/services/users.js b/src/services/users.js index 3c26b164..0922cf8a 100644 --- a/src/services/users.js +++ b/src/services/users.js @@ -18,13 +18,13 @@ const agreeOnTermsOfServiceHandler = async (req, res) => { res .status(200) .send( - "User/agreeOnTermsOfService : agree on Terms of Service successful" + "Users/agreeOnTermsOfService : agree on Terms of Service successful" ); } else { - res.status(400).send("User/agreeOnTermsOfService : already agreed"); + res.status(400).send("Users/agreeOnTermsOfService : already agreed"); } } catch { - res.status(500).send("User/agreeOnTermsOfService : internal server error"); + res.status(500).send("Users/agreeOnTermsOfService : internal server error"); } }; @@ -36,7 +36,9 @@ const getAgreeOnTermsOfServiceHandler = async (req, res) => { const agreeOnTermsOfService = user.agreeOnTermsOfService === true; res.json({ agreeOnTermsOfService }); } catch { - res.status(500).send("/getAgreeOnTermsOfService : internal server error"); + res + .status(500) + .send("Users/getAgreeOnTermsOfService : internal server error"); } }; @@ -55,13 +57,15 @@ const editNicknameHandler = async (req, res) => { req.timestamp ); - res.status(200).send("User/editNickname : edit user nickname successful"); + res + .status(200) + .send("Users/editNickname : edit user nickname successful"); } else { - res.status(400).send("User/editNickname : such user id does not exist"); + res.status(400).send("Users/editNickname : such user id does not exist"); } } catch (err) { logger.error(err); - res.status(500).send("User/editNickname : internal server error"); + res.status(500).send("Users/editNickname : internal server error"); } }; @@ -81,13 +85,13 @@ const editAccountHandler = async (req, res) => { newAccount ); - res.status(200).send("User/editAccount : edit user account successful"); + res.status(200).send("Users/editAccount : edit user account successful"); } else { - res.status(400).send("User/editAccount : such user id does not exist"); + res.status(400).send("Users/editAccount : such user id does not exist"); } } catch (err) { logger.error(err); - res.status(500).send("User/editAccount : internal server error"); + res.status(500).send("Users/editAccount : internal server error"); } }; @@ -98,14 +102,14 @@ const editProfileImgGetPUrlHandler = async (req, res) => { if (!user) { return res .status(500) - .send("User/editProfileImg/getPUrl : internal server error"); + .send("Users/editProfileImg/getPUrl : internal server error"); } const key = `profile-img/${user._id}`; aws.getUploadPUrlPost(key, type, (err, data) => { if (err) { return res .status(500) - .send("User/editProfileImg/getPUrl : internal server error"); + .send("Users/editProfileImg/getPUrl : internal server error"); } data.fields["Content-Type"] = type; data.fields["key"] = key; @@ -115,7 +119,9 @@ const editProfileImgGetPUrlHandler = async (req, res) => { }); }); } catch (e) { - res.status(500).send("User/editProfileImg/getPUrl : internal server error"); + res + .status(500) + .send("Users/editProfileImg/getPUrl : internal server error"); } }; @@ -125,7 +131,7 @@ const editProfileImgDoneHandler = async (req, res) => { if (!user) { return res .status(500) - .send("User/editProfileImg/done : internal server error"); + .send("Users/editProfileImg/done : internal server error"); } const key = `profile-img/${user._id}`; aws.foundObject(key, async (err) => { @@ -133,7 +139,7 @@ const editProfileImgDoneHandler = async (req, res) => { logger.error(err); return res .status(500) - .send("User/editProfileImg/done : internal server error"); + .send("Users/editProfileImg/done : internal server error"); } const userAfter = await userModel.findOneAndUpdate( { id: req.userId }, @@ -143,7 +149,7 @@ const editProfileImgDoneHandler = async (req, res) => { if (!userAfter) { return res .status(500) - .send("User/editProfileImg/done : internal server error"); + .send("Users/editProfileImg/done : internal server error"); } res.json({ result: true, @@ -151,7 +157,7 @@ const editProfileImgDoneHandler = async (req, res) => { }); }); } catch (e) { - res.status(500).send("User/editProfileImg/done : internal server error"); + res.status(500).send("Users/editProfileImg/done : internal server error"); } }; @@ -165,11 +171,13 @@ const resetNicknameHandler = async (req, res) => { if (!result) return res .status(400) - .send("User/resetNickname : such user does not exist"); - res.status(200).send("User/resetNickname : reset user nickname successful"); + .send("Users/resetNickname : such user does not exist"); + res + .status(200) + .send("Users/resetNickname : reset user nickname successful"); } catch (err) { logger.error(err); - res.status(500).send("User/resetNickname : internal server error"); + res.status(500).send("Users/resetNickname : internal server error"); } }; @@ -183,12 +191,12 @@ const resetProfileImgHandler = async (req, res) => { if (!result) return res .status(400) - .send("User/resetProfileImg : such user does not exist"); + .send("Users/resetProfileImg : such user does not exist"); res .status(200) - .send("User/resetProfileImg : reset user profile image successful"); + .send("Users/resetProfileImg : reset user profile image successful"); } catch (err) { - res.status(500).send("User/resetProfileImg : internal server error"); + res.status(500).send("Users/resetProfileImg : internal server error"); } }; From 574fad4f57f174521b0734a872dafd4418d13d95 Mon Sep 17 00:00:00 2001 From: Dongwon Choi Date: Sat, 9 Dec 2023 13:55:47 +0000 Subject: [PATCH 09/11] Docs: add users swagger document --- src/routes/docs/users.js | 239 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 233 insertions(+), 6 deletions(-) diff --git a/src/routes/docs/users.js b/src/routes/docs/users.js index e2b64891..193eb702 100644 --- a/src/routes/docs/users.js +++ b/src/routes/docs/users.js @@ -5,18 +5,113 @@ const usersDocs = {}; usersDocs[`${apiPrefix}/agreeOnTermsOfService`] = { post: { tags: [tag], + summary: "이용 약관에 동의", + description: + "요청을 보낸 유저의 약관 동의 여부를 동의함으로 변경합니다. 철회는 불가능합니다.", + responses: { + 200: { + content: { + "text/html": { + example: + "Users/agreeOnTermsOfService : agree on Terms of Service successful", + }, + }, + }, + 400: { + content: { + "text/html": { + example: "Users/agreeOnTermsOfService : already agreed", + }, + }, + }, + 500: { + content: { + "text/html": { + example: "Users/agreeOnTermsOfService : internal server error", + }, + }, + }, + }, }, }; usersDocs[`${apiPrefix}/getAgreeOnTermsOfService`] = { get: { tags: [tag], + summary: "이용 약관 동의 여부 전송", + description: + "요청을 보낸 유저의 이용 약관 동의 여부를 json 형태로 전송합니다.", + responses: { + 200: { + content: { + "application/json": { + schema: { + type: "object", + properties: { + agreeOnTermsOfService: { + type: "boolean", + description: "유저의 이용 약관 동의 여부", + example: true, + }, + }, + }, + }, + }, + }, + 500: { + content: { + "text/html": { + example: "Users/getAgreeOnTermsOfService : internal server error", + }, + }, + }, + }, }, }; usersDocs[`${apiPrefix}/editNickname`] = { post: { tags: [tag], + summary: "유저의 닉네임 변경", + description: "유저의 닉네임을 요청한 닉네임으로 변경합니다.", + requestBody: { + content: { + "application/json": { + schema: { + type: "object", + properties: { + nickname: { + type: "string", + description: "유저의 새 닉네임", + }, + }, + }, + }, + }, + }, + responses: { + 200: { + content: { + "text/html": { + example: "Users/editNickname : edit user nickname successful", + }, + }, + }, + 400: { + content: { + "text/html": { + example: "Users/editNickname : such user id does not exist", + }, + }, + }, + 500: { + content: { + "text/html": { + example: "Users/editNickname : internal server error", + }, + }, + }, + }, }, }; @@ -29,21 +124,21 @@ usersDocs[`${apiPrefix}/resetNickname`] = { 200: { content: { "text/html": { - example: "User/resetNickname : reset user nickname successful", + example: "Users/resetNickname : reset user nickname successful", }, }, }, 400: { content: { "text/html": { - example: "User/resetNickname : such user does not exist", + example: "Users/resetNickname : such user does not exist", }, }, }, 500: { content: { "text/html": { - example: "User/resetNickname : internal server error", + example: "Users/resetNickname : internal server error", }, }, }, @@ -54,18 +149,150 @@ usersDocs[`${apiPrefix}/resetNickname`] = { usersDocs[`${apiPrefix}/editAccount`] = { post: { tags: [tag], + summary: "유저의 계좌 번호 변경", + description: "유저의 계좌 번호를 요청한 계좌 번호로 변경합니다.", + requestBody: { + content: { + "application/json": { + schema: { + type: "object", + properties: { + account: { + type: "string", + description: "유저의 새 계좌 번호", + }, + }, + }, + }, + }, + }, + responses: { + 200: { + content: { + "text/html": { + example: "Users/editAccount : edit user account successful", + }, + }, + }, + 400: { + content: { + "text/html": { + example: "Users/editAccount : such user id does not exist", + }, + }, + }, + 500: { + content: { + "text/html": { + example: "Users/editAccount : internal server error", + }, + }, + }, + }, }, }; usersDocs[`${apiPrefix}/editProfileImg/getPUrl`] = { post: { tags: [tag], + summary: "프로필 이미지 업로드를 위한 presigned-url 발급", + description: `유저의 프로필 이미지는 AWS S3에서 관리됩니다. 변경할 프로필을 업로드 하기 위한 주소인 presigned-url을 발급합니다.
+
+ **프로필 사진은 아래 규칙을 만족해야 합니다:**
+ 1. 파일 형식은 image/png, image/jpg, image/jpeg 중 하나
+ 2. 파일 크기는 최대 50 MB`, + requestBody: { + content: { + "application/json": { + schema: { + type: "object", + properties: { + type: { + type: "string", + description: "업로드할 이미지 type", + example: "image/png", + }, + }, + }, + }, + }, + }, + responses: { + 200: { + content: { + "application/json": { + schema: { + type: "object", + properties: { + url: { + type: "string", + description: "이미지 업로드를 위한 presigned-url", + }, + fields: { + type: "object", + properties: { + "Content-Type": { + type: "string", + description: "이미지의 type", + }, + key: { + type: "string", + description: "이미지의 S3 파일 경로", + }, + }, + description: "업로드 파일의 type 및 key 정보", + }, + }, + }, + }, + }, + }, + 500: { + contnet: { + "text/html": { + example: "Users/editProfileImg/getPUrl : internal server error", + }, + }, + }, + }, }, }; usersDocs[`${apiPrefix}/editProfileImg/done`] = { get: { tags: [tag], + summary: "프로필 이미지 정상 업로드 여부 확인", + description: `프로필 이미지가 S3에 정상적으로 업로드 되었는지 확인합니다.
+ 정상적으로 확인 되었다면, 유저의 \`profileImageUrl\` 정보를 새 프로필 이미지 파일명으로 업데이트 합니다.`, + responses: { + 200: { + content: { + "application/json": { + schema: { + type: "object", + properties: { + result: { + type: "boolean", + description: "정상적인 업로드 성공 여부", + }, + profileImageUrl: { + type: "string", + description: + "새 프로필 이미지 파일명 (업로드 실패 시 `undefined`)", + }, + }, + }, + }, + }, + }, + 500: { + contnet: { + "text/html": { + example: "Users/editProfileImg/done : internal server error", + }, + }, + }, + }, }, }; @@ -79,21 +306,21 @@ usersDocs[`${apiPrefix}/resetProfileImg`] = { content: { "text/html": { example: - "User/resetProfileImg : reset user profile image successful", + "Users/resetProfileImg : reset user profile image successful", }, }, }, 400: { content: { "text/html": { - example: "User/resetProfileImg : such user does not exist", + example: "Users/resetProfileImg : such user does not exist", }, }, }, 500: { content: { "text/html": { - example: "User/resetProfileImg : internal server error", + example: "Users/resetProfileImg : internal server error", }, }, }, From 4e036758b954a688b36ad02ad9df001cfd0a9cb8 Mon Sep 17 00:00:00 2001 From: Dongwon Choi Date: Sat, 9 Dec 2023 13:59:29 +0000 Subject: [PATCH 10/11] Remove: users.md --- src/routes/docs/users.md | 305 --------------------------------------- 1 file changed, 305 deletions(-) delete mode 100755 src/routes/docs/users.md diff --git a/src/routes/docs/users.md b/src/routes/docs/users.md deleted file mode 100755 index 6b46963b..00000000 --- a/src/routes/docs/users.md +++ /dev/null @@ -1,305 +0,0 @@ -## `/users` - -- 사용자 정보 조회 및 수정 기능을 지원하는 API. -- 로그인된 상태에서만 접근 가능 -- 사용자를 반환할 경우 그 type은 다음과 같다. - -```javascript -User { - name: String, - nickname: String, // 3글자 이상 25글자 이하로 구성되며 영어 대소문자, 한글, " ", 0~9, "-", "_" 으로만 이루어져야 함. - id: String, - withdraw: Boolean, - ban: Boolean, - joinat: Date, - agreeOnTermsOfService: { type: Boolean, default: false }, //이용약관 동의 여부 - room: [Room], - subinfo: { - kaist: String, - sparcs: String, - facebook: String, - twitter: String, - }, - email: String, - __v: Number, -} -``` - -### `/agreeOnTermsOfService` **(POST)** - -- 이용 약관에 동의함 (철회 불가) - -#### URL Parameters, Request JSON form - -- 없음 - -#### Response - -- 200 "agree on Terms of Service successful" -- 400 "already agreed" -- 500 "internal server error" - -### `/getAgreeOnTermsOfService` **(GET)** - -- 이용 약관 동의 여부를 가져옴 - -#### URL Parameters, Request JSON form - -- 없음 - -#### Response - -```javascript -{ - agreeOnTermsOfService: Boolean -}, -``` - -### `/editNickname` **(POST)** - -- 해당 사용자의 닉네임을 새로 설정함. -- 새로운 닉네임은 상술한 규칙을 만족해야 함. - -#### URL Parameters - -- user_id : 사용자의 SPARCS SSO ID - -#### request JSON form - -```javascript -{ - nickname: String, // 새 닉네임 -} -``` - -#### Response - -```javascript -{ - status: 200, - data: "edit user nickname successful", -} -``` - -#### Errors - -- 400 "wrong nickname" -- 400 "such user id does not exist" -- 403 "not logged in" -- 500 "internal server error" - -### `/editProfileImg/getPUrl` **(POST)** - -- 프로필 이미지를 업로드할 수 있는 Presigned-url을 발급합니다. -- 프로필 사진은 아래 규칙을 만족해야 함. - 1. 파일 형식은 image/png, image/jpg, image/jpeg 중 하나 - 2. 파일 크기는 최대 50 MB - -#### URL Parameters - -- type : 업로드할 이미지 type - -#### request JSON form - -```javascript -{ - url: String, // pre-signed url - fields: Object, // post fields -} -``` - -#### Errors - -- 500 "internal server error" - -### `/editProfileImg/done` **(GET)** - -- 프로필 이미지가 S3에 정상적으로 업로드가 되었는지 확인합니다. - -#### URL Parameters - -- 없음 - -#### request JSON form - -```javascript -{ - result: Boolean, // 정상적으로 업로드 되었으면 true - profileImageUrl?: user._id, // 정상적으로 업로드 되었으면 새 프로필 이미지 파일명, 그렇지 않은 경우 undefined -} -``` - -#### Errors - -- 500 "internal server error" - -### `/` **(GET)** (for dev) - -- 사용자 전체 리스트를 반환함. - -#### URL Parameters - -- 없음 - -#### Response - -```javascript -{ - status: 200, - data: User[], // 전체 사용자 리스트 -} -``` - -#### Errors - -- 없음 - -### `/rooms` **(GET)** (for dev) - -- 사용자의 방 리스트를 반환함. - -#### URL Parameters - -- id : User document의 id - -#### Response - -```javascript -{ - id: String, // 요청된 id - rooms: Room[], // 방 리스트 -} -``` - -#### Errors - -- 404 "user/rooms : such id does not exist" -- 500 "user/rooms : internal server error" - -### `/:id` **(GET)** (for dev) - -- 사용자 정보를 반환함. - -#### URL Parameters - -- id : User document의 id - -#### Response - -```javascript -{ - status: 200, - data: User, //id에 대응되는 사용자 정보 -} -``` - -#### Errors - -- 404 "user/:id : such id does not exist" -- 500 "user/:id : internal server error" - -### `/:id/edit` **(POST)** (for dev) - -- 새 사용자 정보를 받아 업데이트함. - -#### URL Parameters - -- id : User document의 id - -#### request JSON form - -```javascript -User; //수정할 사용자 정보 -``` - -#### Response - -```javascript -{ - status: 200, - data: "edit user successful", -} -``` - -#### Errors - -- 400 "such id does not exist" - -### `/:id/ban` **(GET)** (for dev) - -- 해당 사용자를 밴함. - -#### URL Parameters - -- id : User document의 id - -#### Response - -```javascript -{ - status: 200, - data: "The user banned successfully", -} -``` - -#### Errors - -- 400 "The user does not exist" -- 409 "The user is already banned" -- 500 "User/ban : Error 500" - -### `/:id/unban` **(GET)** (for dev) - -- 해당 사용자를 밴 해제함. - -#### URL Parameters - -- id : User document의 id - -#### Response - -```javascript -{ - status: 200, - data: "The user unbanned successfully", -} -``` - -#### Errors - -- 400 "The user does not exist" -- 409 "The user is already banned" -- 500 "User/unban : Error 500" - -### `/:id/participate` **(POST)** (for dev) - -- 해당 사용자를 특정 방에 참여시킴. - -#### URL Parameters - -- id : User document의 id - -#### request JSON form - -```javascript -{ - room: String, // Room document의 id -} -``` - -#### Response - -```javascript -{ - status: 200, - data: "User/participate : Successful", -} -``` - -#### Errors - -- 400 "User/participate : Bad request" -- 400 "User/participate : No corresponding room" -- 400 "The user does not exist" -- 409 "The user already entered the room" -- 500 "User/participate : Error 500" From 90185f964d215134f52ec32c79dea9c1488b2a1d Mon Sep 17 00:00:00 2001 From: Dongwon Choi Date: Sat, 9 Dec 2023 14:02:20 +0000 Subject: [PATCH 11/11] Test: change check message --- test/services/users.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/services/users.js b/test/services/users.js index 1bb2f586..4f2195da 100644 --- a/test/services/users.js +++ b/test/services/users.js @@ -15,7 +15,7 @@ describe("[users] 1.agreeOnTermsOfServiceHandler", () => { it("should return correct response from handler", async () => { const testUser1 = await userGenerator("test1", testData); const msg = - "User/agreeOnTermsOfService : agree on Terms of Service successful"; + "Users/agreeOnTermsOfService : agree on Terms of Service successful"; let req = httpMocks.createRequest({ userId: testUser1.id, }); @@ -50,7 +50,7 @@ describe("[users] 3.editNicknameHandler", () => { it("should return correct response from handler", async () => { const testUser1 = await userModel.findOne({ id: "test1" }); - const msg = "User/editNickname : edit user nickname successful"; + const msg = "Users/editNickname : edit user nickname successful"; let req = httpMocks.createRequest({ userId: testUser1.id, body: { @@ -77,7 +77,7 @@ describe("[users] 4.editAccountHandler", () => { it("should return correct response from handler", async () => { const testUser1 = await userModel.findOne({ id: "test1" }); - const msg = "User/editAccount : edit user account successful"; + const msg = "Users/editAccount : edit user account successful"; let req = httpMocks.createRequest({ userId: testUser1.id, body: {