From 9a204f2ff9a39e695cbe1713362a14d709da7037 Mon Sep 17 00:00:00 2001 From: lshyun955 Date: Tue, 15 Mar 2022 20:31:01 +0900 Subject: [PATCH 1/3] =?UTF-8?q?[feat]=20=EC=9C=A0=EC=A0=80=20=ED=94=84?= =?UTF-8?q?=EB=A1=9C=ED=95=84=20=EC=84=A4=EC=A0=95=EA=B8=B0=EB=8A=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-lock.json | 273 +++++++++++++++++- package.json | 4 + src/socialLogin/dto/completeFirstLogin.dto.ts | 1 - src/user/dto/create-user.dto.ts | 1 - src/user/dto/createUserProfile.dto.ts | 17 ++ src/user/dto/update-user.dto.ts | 4 - src/user/user.controller.ts | 54 ++-- src/user/user.module.ts | 8 +- src/user/user.service.ts | 69 ++++- 9 files changed, 394 insertions(+), 37 deletions(-) delete mode 100644 src/user/dto/create-user.dto.ts create mode 100644 src/user/dto/createUserProfile.dto.ts delete mode 100644 src/user/dto/update-user.dto.ts diff --git a/package-lock.json b/package-lock.json index 4aa8e40..25c7b07 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,10 +18,13 @@ "@nestjs/platform-express": "^8.0.0", "@nestjs/typeorm": "^8.0.3", "@types/jsonwebtoken": "^8.5.8", + "aws-sdk": "^2.1093.0", "axios": "^0.26.1", "class-validator": "^0.13.2", "jsonwebtoken": "^8.5.1", "md5": "^2.3.0", + "multer": "^1.4.4", + "multer-s3": "^2.10.0", "mysql2": "^2.3.3", "passport": "^0.5.2", "passport-local": "^1.0.0", @@ -39,6 +42,7 @@ "@types/express": "^4.17.13", "@types/jest": "27.4.1", "@types/md5": "^2.3.2", + "@types/multer": "^1.4.7", "@types/node": "^16.0.0", "@types/passport-local": "^1.0.34", "@types/supertest": "^2.0.11", @@ -2021,6 +2025,15 @@ "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==", "dev": true }, + "node_modules/@types/multer": { + "version": "1.4.7", + "resolved": "https://registry.npmjs.org/@types/multer/-/multer-1.4.7.tgz", + "integrity": "sha512-/SNsDidUFCvqqcWDwxv2feww/yqhNeTRL5CVoL3jU4Goc4kKEL10T7Eye65ZqPNi4HRx8sAEX59pV1aEH7drNA==", + "dev": true, + "dependencies": { + "@types/express": "*" + } + }, "node_modules/@types/node": { "version": "16.11.26", "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.26.tgz", @@ -2745,6 +2758,84 @@ "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", "dev": true }, + "node_modules/aws-sdk": { + "version": "2.1093.0", + "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1093.0.tgz", + "integrity": "sha512-YD6VNemoKkzDMHsUiGP/MwpM0T20ukp3KTSxPY34Xw3Ww0zP19C54CfjaXhn//R27f2c57BtVez+he2RZ5GwyQ==", + "dependencies": { + "buffer": "4.9.2", + "events": "1.1.1", + "ieee754": "1.1.13", + "jmespath": "0.16.0", + "querystring": "0.2.0", + "sax": "1.2.1", + "url": "0.10.3", + "uuid": "3.3.2", + "xml2js": "0.4.19" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/aws-sdk/node_modules/buffer": { + "version": "4.9.2", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", + "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", + "dependencies": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" + } + }, + "node_modules/aws-sdk/node_modules/events": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", + "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=", + "engines": { + "node": ">=0.4.x" + } + }, + "node_modules/aws-sdk/node_modules/ieee754": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", + "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==" + }, + "node_modules/aws-sdk/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "node_modules/aws-sdk/node_modules/sax": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz", + "integrity": "sha1-e45lYZCyKOgaZq6nSEgNgozS03o=" + }, + "node_modules/aws-sdk/node_modules/uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/aws-sdk/node_modules/xml2js": { + "version": "0.4.19", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.19.tgz", + "integrity": "sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q==", + "dependencies": { + "sax": ">=0.6.0", + "xmlbuilder": "~9.0.1" + } + }, + "node_modules/aws-sdk/node_modules/xmlbuilder": { + "version": "9.0.7", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz", + "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=", + "engines": { + "node": ">=4.0" + } + }, "node_modules/axios": { "version": "0.26.1", "resolved": "https://registry.npmjs.org/axios/-/axios-0.26.1.tgz", @@ -4543,6 +4634,14 @@ "node": "^10.12.0 || >=12.0.0" } }, + "node_modules/file-type": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz", + "integrity": "sha1-JXoHg4TR24CHvESdEH1SpSZyuek=", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -4976,6 +5075,11 @@ "node": "*" } }, + "node_modules/html-comment-regex": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/html-comment-regex/-/html-comment-regex-1.1.2.tgz", + "integrity": "sha512-P+M65QY2JQ5Y0G9KKdlDpo0zK+/OHptU5AaBwUfAIDJZk1MYf32Frm84EcOytfJE0t5JvkAnKlmjsXDnWzCJmQ==" + }, "node_modules/html-encoding-sniffer": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", @@ -6305,6 +6409,14 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, + "node_modules/jmespath": { + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.16.0.tgz", + "integrity": "sha512-9FzQjJ7MATs1tSpnco1K6ayiYE3figslrXA72G2HQ/n76RzvYlofyi5QM+iX4YRs/pu3yzxlVQSST23+dMDknw==", + "engines": { + "node": ">= 0.6.0" + } + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -6868,6 +6980,16 @@ "node": ">= 0.10.0" } }, + "node_modules/multer-s3": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/multer-s3/-/multer-s3-2.10.0.tgz", + "integrity": "sha512-RZsiqG19C9gE82lB7v8duJ+TMIf70fWYHlIwuNcsanOH1ePBoPXZvboEQxEow9jUkk7WQsuyVA2TgriOuDrVrw==", + "dependencies": { + "file-type": "^3.3.0", + "html-comment-regex": "^1.1.2", + "run-parallel": "^1.1.6" + } + }, "node_modules/mute-stream": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", @@ -7543,11 +7665,19 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", + "deprecated": "The querystring API is considered Legacy. new code should use the URLSearchParams API instead.", + "engines": { + "node": ">=0.4.x" + } + }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, "funding": [ { "type": "github", @@ -7775,7 +7905,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, "funding": [ { "type": "github", @@ -9101,6 +9230,20 @@ "punycode": "^2.1.0" } }, + "node_modules/url": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/url/-/url-0.10.3.tgz", + "integrity": "sha1-Ah5NnHcF8hu/N9A861h2dAJ3TGQ=", + "dependencies": { + "punycode": "1.3.2", + "querystring": "0.2.0" + } + }, + "node_modules/url/node_modules/punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=" + }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -11139,6 +11282,15 @@ "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==", "dev": true }, + "@types/multer": { + "version": "1.4.7", + "resolved": "https://registry.npmjs.org/@types/multer/-/multer-1.4.7.tgz", + "integrity": "sha512-/SNsDidUFCvqqcWDwxv2feww/yqhNeTRL5CVoL3jU4Goc4kKEL10T7Eye65ZqPNi4HRx8sAEX59pV1aEH7drNA==", + "dev": true, + "requires": { + "@types/express": "*" + } + }, "@types/node": { "version": "16.11.26", "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.26.tgz", @@ -11705,6 +11857,73 @@ "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", "dev": true }, + "aws-sdk": { + "version": "2.1093.0", + "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1093.0.tgz", + "integrity": "sha512-YD6VNemoKkzDMHsUiGP/MwpM0T20ukp3KTSxPY34Xw3Ww0zP19C54CfjaXhn//R27f2c57BtVez+he2RZ5GwyQ==", + "requires": { + "buffer": "4.9.2", + "events": "1.1.1", + "ieee754": "1.1.13", + "jmespath": "0.16.0", + "querystring": "0.2.0", + "sax": "1.2.1", + "url": "0.10.3", + "uuid": "3.3.2", + "xml2js": "0.4.19" + }, + "dependencies": { + "buffer": { + "version": "4.9.2", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", + "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", + "requires": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" + } + }, + "events": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", + "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=" + }, + "ieee754": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", + "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==" + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "sax": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz", + "integrity": "sha1-e45lYZCyKOgaZq6nSEgNgozS03o=" + }, + "uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" + }, + "xml2js": { + "version": "0.4.19", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.19.tgz", + "integrity": "sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q==", + "requires": { + "sax": ">=0.6.0", + "xmlbuilder": "~9.0.1" + } + }, + "xmlbuilder": { + "version": "9.0.7", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz", + "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=" + } + } + }, "axios": { "version": "0.26.1", "resolved": "https://registry.npmjs.org/axios/-/axios-0.26.1.tgz", @@ -13092,6 +13311,11 @@ "flat-cache": "^3.0.4" } }, + "file-type": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz", + "integrity": "sha1-JXoHg4TR24CHvESdEH1SpSZyuek=" + }, "fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -13400,6 +13624,11 @@ "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz", "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==" }, + "html-comment-regex": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/html-comment-regex/-/html-comment-regex-1.1.2.tgz", + "integrity": "sha512-P+M65QY2JQ5Y0G9KKdlDpo0zK+/OHptU5AaBwUfAIDJZk1MYf32Frm84EcOytfJE0t5JvkAnKlmjsXDnWzCJmQ==" + }, "html-encoding-sniffer": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", @@ -14408,6 +14637,11 @@ } } }, + "jmespath": { + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.16.0.tgz", + "integrity": "sha512-9FzQjJ7MATs1tSpnco1K6ayiYE3figslrXA72G2HQ/n76RzvYlofyi5QM+iX4YRs/pu3yzxlVQSST23+dMDknw==" + }, "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -14858,6 +15092,16 @@ "xtend": "^4.0.0" } }, + "multer-s3": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/multer-s3/-/multer-s3-2.10.0.tgz", + "integrity": "sha512-RZsiqG19C9gE82lB7v8duJ+TMIf70fWYHlIwuNcsanOH1ePBoPXZvboEQxEow9jUkk7WQsuyVA2TgriOuDrVrw==", + "requires": { + "file-type": "^3.3.0", + "html-comment-regex": "^1.1.2", + "run-parallel": "^1.1.6" + } + }, "mute-stream": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", @@ -15372,11 +15616,15 @@ "side-channel": "^1.0.4" } }, + "querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=" + }, "queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==" }, "randombytes": { "version": "2.1.0", @@ -15534,7 +15782,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, "requires": { "queue-microtask": "^1.2.2" } @@ -16443,6 +16690,22 @@ "punycode": "^2.1.0" } }, + "url": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/url/-/url-0.10.3.tgz", + "integrity": "sha1-Ah5NnHcF8hu/N9A861h2dAJ3TGQ=", + "requires": { + "punycode": "1.3.2", + "querystring": "0.2.0" + }, + "dependencies": { + "punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=" + } + } + }, "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", diff --git a/package.json b/package.json index 3dc72e1..f0b1f46 100644 --- a/package.json +++ b/package.json @@ -30,10 +30,13 @@ "@nestjs/platform-express": "^8.0.0", "@nestjs/typeorm": "^8.0.3", "@types/jsonwebtoken": "^8.5.8", + "aws-sdk": "^2.1093.0", "axios": "^0.26.1", "class-validator": "^0.13.2", "jsonwebtoken": "^8.5.1", "md5": "^2.3.0", + "multer": "^1.4.4", + "multer-s3": "^2.10.0", "mysql2": "^2.3.3", "passport": "^0.5.2", "passport-local": "^1.0.0", @@ -51,6 +54,7 @@ "@types/express": "^4.17.13", "@types/jest": "27.4.1", "@types/md5": "^2.3.2", + "@types/multer": "^1.4.7", "@types/node": "^16.0.0", "@types/passport-local": "^1.0.34", "@types/supertest": "^2.0.11", diff --git a/src/socialLogin/dto/completeFirstLogin.dto.ts b/src/socialLogin/dto/completeFirstLogin.dto.ts index b9dbf5c..4e5aa5b 100644 --- a/src/socialLogin/dto/completeFirstLogin.dto.ts +++ b/src/socialLogin/dto/completeFirstLogin.dto.ts @@ -2,7 +2,6 @@ import { IsEmail, IsString, IsNumber, - IsBoolean, MaxLength, MinLength, } from 'class-validator'; diff --git a/src/user/dto/create-user.dto.ts b/src/user/dto/create-user.dto.ts deleted file mode 100644 index 0311be1..0000000 --- a/src/user/dto/create-user.dto.ts +++ /dev/null @@ -1 +0,0 @@ -export class CreateUserDto {} diff --git a/src/user/dto/createUserProfile.dto.ts b/src/user/dto/createUserProfile.dto.ts new file mode 100644 index 0000000..87c6ed2 --- /dev/null +++ b/src/user/dto/createUserProfile.dto.ts @@ -0,0 +1,17 @@ +import { IsString, MaxLength, MinLength } from 'class-validator'; + +export class CreateUserProfileDTO { + @MaxLength(13) + @MinLength(4) + @IsString() + nickname: string; + + @IsString() + technologyStack: string; + + @IsString() + selfIntroduction: string; + + @IsString() + portfolioUrl: string; +} diff --git a/src/user/dto/update-user.dto.ts b/src/user/dto/update-user.dto.ts deleted file mode 100644 index dfd37fb..0000000 --- a/src/user/dto/update-user.dto.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { PartialType } from '@nestjs/mapped-types'; -import { CreateUserDto } from './create-user.dto'; - -export class UpdateUserDto extends PartialType(CreateUserDto) {} diff --git a/src/user/user.controller.ts b/src/user/user.controller.ts index 995519c..85b3589 100644 --- a/src/user/user.controller.ts +++ b/src/user/user.controller.ts @@ -1,34 +1,50 @@ -import { Controller, Get, Post, Body, Patch, Param, Delete } from '@nestjs/common'; +import { + Controller, + Get, + Post, + Body, + Patch, + Param, + Delete, + UseInterceptors, + UploadedFile, + Req, +} from '@nestjs/common'; +import { FileInterceptor } from '@nestjs/platform-express'; +import { CreateUserProfileDTO } from './dto/createUserProfile.dto'; import { UserService } from './user.service'; -import { CreateUserDto } from './dto/create-user.dto'; -import { UpdateUserDto } from './dto/update-user.dto'; @Controller('user') export class UserController { constructor(private readonly userService: UserService) {} @Post() - create(@Body() createUserDto: CreateUserDto) { - return this.userService.create(createUserDto); + @UseInterceptors(FileInterceptor('profileImg')) + create( + @Req() user, + @UploadedFile() file: Express.Multer.File, + @Body() createUserProfileDto: CreateUserProfileDTO, + ) { + return this.userService.createUserProfile( + 'profileImg', + user.userId, + file, + createUserProfileDto, + ); } - @Get() - findAll() { - return this.userService.findAll(); + @Get('/profile') + async getProfile(@Req() user) { + return this.userService.getMyProfile(user.userId); } - @Get(':id') - findOne(@Param('id') id: string) { - return this.userService.findOne(+id); + @Get('/love') + getLovePosts(@Req() user) { + return this.userService.getLovePosts(user.userId); } - @Patch(':id') - update(@Param('id') id: string, @Body() updateUserDto: UpdateUserDto) { - return this.userService.update(+id, updateUserDto); - } - - @Delete(':id') - remove(@Param('id') id: string) { - return this.userService.remove(+id); + @Get('/keep') + getKeepPosts(@Req() user) { + return this.userService.getKeepPosts(user.userId); } } diff --git a/src/user/user.module.ts b/src/user/user.module.ts index be770ab..8a6f056 100644 --- a/src/user/user.module.ts +++ b/src/user/user.module.ts @@ -4,9 +4,15 @@ import { UserService } from './user.service'; import { UserController } from './user.controller'; import { Notification } from './entities/Notification'; import { UserReputation } from './entities/UserReputation'; +import { ConfigModule } from '@nestjs/config'; @Module({ - imports: [TypeOrmModule.forFeature([Notification, UserReputation])], + imports: [ + ConfigModule.forRoot({ + isGlobal: true, + }), + TypeOrmModule.forFeature([Notification, UserReputation]), + ], controllers: [UserController], providers: [UserService], }) diff --git a/src/user/user.service.ts b/src/user/user.service.ts index 95707d7..d38cb7f 100644 --- a/src/user/user.service.ts +++ b/src/user/user.service.ts @@ -1,11 +1,68 @@ -import { Injectable } from '@nestjs/common'; -import { CreateUserDto } from './dto/create-user.dto'; -import { UpdateUserDto } from './dto/update-user.dto'; - +import { BadRequestException, Injectable } from '@nestjs/common'; +import { ConfigService } from '@nestjs/config'; +import { InjectRepository } from '@nestjs/typeorm'; +import { Users } from 'src/socialLogin/entity/Users'; +import { Repository } from 'typeorm'; +import { CreateUserProfileDTO } from './dto/createUserProfile.dto'; +import { UserReputation } from './entities/UserReputation'; +import * as AWS from 'aws-sdk'; +import path from 'path'; @Injectable() export class UserService { - create(createUserDto: CreateUserDto) { - return 'This action adds a new user'; + private readonly awsS3: AWS.S3; + public readonly S3_BUCKET_NAME: string; + constructor( + private readonly configService: ConfigService, + @InjectRepository(Users) private readonly userRepository: Repository, + @InjectRepository(UserReputation) + private readonly userReputation: Repository, + ) { + this.awsS3 = new AWS.S3({ + accessKeyId: this.configService.get('AWS_ACCESS_KEY_ID'), + secretAccessKey: this.configService.get('AWS_SECRET_ACCESS_KEY'), + region: this.configService.get('AWS_REGION'), + }); + this.S3_BUCKET_NAME = this.configService.get('AWS_S3_BUCKET_NAME'); + } + + async createUserProfile( + folder: string, + userId: string, + file: Express.Multer.File, + createUserProfileDto: CreateUserProfileDTO, + ) { + // 사진을 s3에 넣는 로직.. 먼저 DB profileImg 컬럼에 변수 key값을 넣는다. + try { + const key = `${folder}/${Date.now()}_${path.basename( + file.originalname, + )}`.replace(/ /g, ''); + if (key) { + const newUserProfile = await this.userRepository + .createQueryBuilder('user') + .update(Users) + .set({ + nickname: createUserProfileDto.nickname, + portfolioUrl: createUserProfileDto.portfolioUrl, + profileImgUrl: key, + selfIntroduction: createUserProfileDto.selfIntroduction, + technologyStack: createUserProfileDto.technologyStack, + }) + .where('userId=:userId', { userId }) + .execute(); + + await this.awsS3 + .putObject({ + Bucket: this.S3_BUCKET_NAME, + Key: key, + Body: file.buffer, + ACL: 'public-read', + ContentType: file.mimetype, + }) + .promise(); + } + } catch (e) { + throw new BadRequestException(`File upload failed : ${e}`); + } } findAll() { From aed742c1f4e96998f620967d7fa88854c8f26ffa Mon Sep 17 00:00:00 2001 From: lshyun955 Date: Tue, 15 Mar 2022 21:19:08 +0900 Subject: [PATCH 2/3] =?UTF-8?q?[feat]=20=EB=82=B4=EA=B0=80=20Keep=ED=95=9C?= =?UTF-8?q?=20=EA=B8=80=20=EB=AA=A9=EB=A1=9D=20=EC=A1=B0=ED=9A=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/user/user.module.ts | 3 ++- src/user/user.service.ts | 50 +++++++++++++++++++++++++++++++--------- 2 files changed, 41 insertions(+), 12 deletions(-) diff --git a/src/user/user.module.ts b/src/user/user.module.ts index 8a6f056..c986924 100644 --- a/src/user/user.module.ts +++ b/src/user/user.module.ts @@ -5,13 +5,14 @@ import { UserController } from './user.controller'; import { Notification } from './entities/Notification'; import { UserReputation } from './entities/UserReputation'; import { ConfigModule } from '@nestjs/config'; +import { Users } from 'src/socialLogin/entity/Users'; @Module({ imports: [ ConfigModule.forRoot({ isGlobal: true, }), - TypeOrmModule.forFeature([Notification, UserReputation]), + TypeOrmModule.forFeature([Notification, UserReputation, Users]), ], controllers: [UserController], providers: [UserService], diff --git a/src/user/user.service.ts b/src/user/user.service.ts index d38cb7f..bc324ca 100644 --- a/src/user/user.service.ts +++ b/src/user/user.service.ts @@ -37,7 +37,7 @@ export class UserService { file.originalname, )}`.replace(/ /g, ''); if (key) { - const newUserProfile = await this.userRepository + await this.userRepository .createQueryBuilder('user') .update(Users) .set({ @@ -65,19 +65,47 @@ export class UserService { } } - findAll() { - return `This action returns all user`; - } + async getLovePosts(userId: string) { + const lovePosts = await this.userRepository + .createQueryBuilder('user') + .select(['informationPosts.title', 'informationPosts.createdAt']) + .leftJoin('user.informationLoves', 'informationLoves') + .leftJoin('informationLoves.imformationPosts', 'informationPosts') + .where('user.userId=:userId', { userId }) + .andWhere( + 'informationPosts.informationPostId=informationLoves.informationPostId', + ) + .getMany(); - findOne(id: number) { - return `This action returns a #${id} user`; + return lovePosts; } - update(id: number, updateUserDto: UpdateUserDto) { - return `This action updates a #${id} user`; - } + async getKeepPosts(userId: string) { + // 먼저 recruitKeeps 테이블의 recruitPostId를 뽑아낸다. 그리고 그 값들을 반복문을 통해 where문 조건값에 넣는다. + const getuser = await this.userRepository.createQueryBuilder('user'); + const keepPosts = getuser.leftJoinAndSelect( + 'recruitKeeps.recruitPosts', + 'recruitKeeps', + ); + const totalKeepPosts = []; - remove(id: number) { - return `This action removes a #${id} user`; + const recruitPostIdOfKeeps = getuser + .select(['recruitKeep.recruitPostId']) + .leftJoinAndSelect('user.recruitKeeps', 'recruitKeeps') + .where('user.userId=:userId', { userId }) + .getRawMany(); + for (const id in recruitPostIdOfKeeps) { + totalKeepPosts.push( + keepPosts + .select(['recruitPosts.title', 'recruitPosts.createdAt']) + .where('recruitPosts.recruitPostId=:recruitPostId', { + recruitPostId: id, + }), + ); + } + + return totalKeepPosts; } + + async getMyProfile(userId: string) {} } From 808c50473196a6dc60cfa7a1d32c6dad1515e0ff Mon Sep 17 00:00:00 2001 From: lshyun955 Date: Tue, 15 Mar 2022 21:33:39 +0900 Subject: [PATCH 3/3] =?UTF-8?q?[feat]=20=EB=82=B4=EA=B0=80=20Love=ED=95=9C?= =?UTF-8?q?=20=EA=B8=80=20=EB=AA=A9=EB=A1=9D=20=EC=A1=B0=ED=9A=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/user/user.service.ts | 46 +++++++++++++++++++++++++++------------- 1 file changed, 31 insertions(+), 15 deletions(-) diff --git a/src/user/user.service.ts b/src/user/user.service.ts index bc324ca..55e1490 100644 --- a/src/user/user.service.ts +++ b/src/user/user.service.ts @@ -66,34 +66,50 @@ export class UserService { } async getLovePosts(userId: string) { - const lovePosts = await this.userRepository - .createQueryBuilder('user') - .select(['informationPosts.title', 'informationPosts.createdAt']) - .leftJoin('user.informationLoves', 'informationLoves') - .leftJoin('informationLoves.imformationPosts', 'informationPosts') - .where('user.userId=:userId', { userId }) - .andWhere( - 'informationPosts.informationPostId=informationLoves.informationPostId', + const getUser = await this.userRepository.createQueryBuilder('user'); + const lovePosts = getUser.leftJoinAndSelect( + 'user.informationLoves', + 'informationLoves', + ); + + const totalLovePosts = []; + + const informationPostIdOfLoves = getUser + .select(['informationLoves.informationPostId']) + .leftJoinAndSelect( + 'informationLoves.informationPosts', + 'informationPosts', ) - .getMany(); + .where('user.userId=:userId', { userId }) + .getRawMany(); - return lovePosts; + for (const id in informationPostIdOfLoves) { + totalLovePosts.push( + lovePosts + .select(['informationPosts.title', 'informationPosts.createdAt']) + .where('informationPosts.informationPostId=:informationPostId', { + inforationPostId: id, + }), + ); + } + return totalLovePosts; } async getKeepPosts(userId: string) { // 먼저 recruitKeeps 테이블의 recruitPostId를 뽑아낸다. 그리고 그 값들을 반복문을 통해 where문 조건값에 넣는다. - const getuser = await this.userRepository.createQueryBuilder('user'); - const keepPosts = getuser.leftJoinAndSelect( - 'recruitKeeps.recruitPosts', + const getUser = await this.userRepository.createQueryBuilder('user'); + const keepPosts = getUser.leftJoinAndSelect( + 'user.recruitKeeps', 'recruitKeeps', ); const totalKeepPosts = []; - const recruitPostIdOfKeeps = getuser + const recruitPostIdOfKeeps = getUser .select(['recruitKeep.recruitPostId']) - .leftJoinAndSelect('user.recruitKeeps', 'recruitKeeps') + .leftJoinAndSelect('recruitKeeps.recruitPosts', 'recruitPosts') .where('user.userId=:userId', { userId }) .getRawMany(); + for (const id in recruitPostIdOfKeeps) { totalKeepPosts.push( keepPosts