NestJS 수정2..

This commit is contained in:
최준흠 2022-09-01 15:55:55 +09:00
parent 61a12b66fd
commit c354f2f804
31 changed files with 120 additions and 860 deletions

4
.env
View File

@ -8,9 +8,5 @@ DATABASE_URL="mysql://root:@localhost:3306/test"
CORS_ALLOW_ORIGINS = ['http://localhost:8080']
CORS_ALLOW_METHOD = "GET,PUT,POST,DELETE,PATCH,OPTIONS"
JWT_SECURITY_KEY = "security_key"
JWT_EXPIRE_MAX = "600s"
AUTH_USERNAME_FIELD="email"
DEFAULT_TABLE_PERPAGE = 10
DEFAULT_TABLE_PAGE = 1

432
package-lock.json generated
View File

@ -11,14 +11,9 @@
"dependencies": {
"@nestjs/common": "^9.0.0",
"@nestjs/core": "^9.0.0",
"@nestjs/jwt": "^9.0.0",
"@nestjs/passport": "^9.0.0",
"@nestjs/platform-express": "^9.0.0",
"@prisma/client": "^4.1.1",
"cors": "^2.8.5",
"passport": "^0.6.0",
"passport-jwt": "^4.0.0",
"passport-local": "^1.0.0",
"reflect-metadata": "^0.1.13",
"rimraf": "^3.0.2",
"rxjs": "^7.2.0"
@ -1612,27 +1607,6 @@
}
}
},
"node_modules/@nestjs/jwt": {
"version": "9.0.0",
"resolved": "https://registry.npmjs.org/@nestjs/jwt/-/jwt-9.0.0.tgz",
"integrity": "sha512-ZsXGY/wMYKzEhymw2+dxiwrHTRKIKrGszx6r2EjQqNLypdXMQu0QrujwZJ8k3+XQV4snmuJwwNakQoA2ILfq8w==",
"dependencies": {
"@types/jsonwebtoken": "8.5.8",
"jsonwebtoken": "8.5.1"
},
"peerDependencies": {
"@nestjs/common": "^8.0.0 || ^9.0.0"
}
},
"node_modules/@nestjs/passport": {
"version": "9.0.0",
"resolved": "https://registry.npmjs.org/@nestjs/passport/-/passport-9.0.0.tgz",
"integrity": "sha512-Gnh8n1wzFPOLSS/94X1sUP4IRAoXTgG4odl7/AO5h+uwscEGXxJFercrZfqdAwkWhqkKWbsntM3j5mRy/6ZQDA==",
"peerDependencies": {
"@nestjs/common": "^8.0.0 || ^9.0.0",
"passport": "^0.4.0 || ^0.5.0 || ^0.6.0"
}
},
"node_modules/@nestjs/platform-express": {
"version": "9.0.8",
"resolved": "https://registry.npmjs.org/@nestjs/platform-express/-/platform-express-9.0.8.tgz",
@ -1787,7 +1761,7 @@
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-4.1.1.tgz",
"integrity": "sha512-DCw8L/SS0IXqmj5IW/fMxOXiifnsfjBzDfRhf0j3NFWqvMCh9OtfjmXQZxVgI2mwvJLc/5jzXhkiWT39qS09dA==",
"dev": true,
"devOptional": true,
"hasInstallScript": true
},
"node_modules/@prisma/engines-version": {
@ -2017,6 +1991,7 @@
"version": "8.5.8",
"resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-8.5.8.tgz",
"integrity": "sha512-zm6xBQpFDIDM6o9r6HSgDeIcLy82TKWctCXEPbJJcXb5AKmi5BNNdLXneixK4lplX3PqIVcwLBCGE/kAGnlD4A==",
"dev": true,
"dependencies": {
"@types/node": "*"
}
@ -2030,7 +2005,8 @@
"node_modules/@types/node": {
"version": "16.11.47",
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.47.tgz",
"integrity": "sha512-fpP+jk2zJ4VW66+wAMFoBJlx1bxmBKx4DUFf68UHgdGCOuyUTDlLWqsaNPJh7xhNDykyJ9eIzAygilP/4WoN8g=="
"integrity": "sha512-fpP+jk2zJ4VW66+wAMFoBJlx1bxmBKx4DUFf68UHgdGCOuyUTDlLWqsaNPJh7xhNDykyJ9eIzAygilP/4WoN8g==",
"dev": true
},
"node_modules/@types/parse-json": {
"version": "4.0.0",
@ -2984,11 +2960,6 @@
"ieee754": "^1.1.13"
}
},
"node_modules/buffer-equal-constant-time": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
"integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA=="
},
"node_modules/buffer-from": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
@ -3526,14 +3497,6 @@
"node": ">=6.0.0"
}
},
"node_modules/ecdsa-sig-formatter": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
"integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==",
"dependencies": {
"safe-buffer": "^5.0.1"
}
},
"node_modules/ee-first": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
@ -5872,54 +5835,6 @@
"graceful-fs": "^4.1.6"
}
},
"node_modules/jsonwebtoken": {
"version": "8.5.1",
"resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz",
"integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==",
"dependencies": {
"jws": "^3.2.2",
"lodash.includes": "^4.3.0",
"lodash.isboolean": "^3.0.3",
"lodash.isinteger": "^4.0.4",
"lodash.isnumber": "^3.0.3",
"lodash.isplainobject": "^4.0.6",
"lodash.isstring": "^4.0.1",
"lodash.once": "^4.0.0",
"ms": "^2.1.1",
"semver": "^5.6.0"
},
"engines": {
"node": ">=4",
"npm": ">=1.4.28"
}
},
"node_modules/jsonwebtoken/node_modules/semver": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
"bin": {
"semver": "bin/semver"
}
},
"node_modules/jwa": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz",
"integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==",
"dependencies": {
"buffer-equal-constant-time": "1.0.1",
"ecdsa-sig-formatter": "1.0.11",
"safe-buffer": "^5.0.1"
}
},
"node_modules/jws": {
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz",
"integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==",
"dependencies": {
"jwa": "^1.4.1",
"safe-buffer": "^5.0.1"
}
},
"node_modules/kleur": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz",
@ -5987,36 +5902,6 @@
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
"dev": true
},
"node_modules/lodash.includes": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz",
"integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w=="
},
"node_modules/lodash.isboolean": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz",
"integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg=="
},
"node_modules/lodash.isinteger": {
"version": "4.0.4",
"resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz",
"integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA=="
},
"node_modules/lodash.isnumber": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz",
"integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw=="
},
"node_modules/lodash.isplainobject": {
"version": "4.0.6",
"resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
"integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA=="
},
"node_modules/lodash.isstring": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz",
"integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw=="
},
"node_modules/lodash.memoize": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
@ -6029,11 +5914,6 @@
"integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
"dev": true
},
"node_modules/lodash.once": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz",
"integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg=="
},
"node_modules/log-symbols": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz",
@ -6271,7 +6151,8 @@
"node_modules/ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
"dev": true
},
"node_modules/multer": {
"version": "1.4.4-lts.1",
@ -6593,51 +6474,6 @@
"node": ">= 0.8"
}
},
"node_modules/passport": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/passport/-/passport-0.6.0.tgz",
"integrity": "sha512-0fe+p3ZnrWRW74fe8+SvCyf4a3Pb2/h7gFkQ8yTJpAO50gDzlfjZUZTO1k5Eg9kUct22OxHLqDZoKUWRHOh9ug==",
"dependencies": {
"passport-strategy": "1.x.x",
"pause": "0.0.1",
"utils-merge": "^1.0.1"
},
"engines": {
"node": ">= 0.4.0"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/jaredhanson"
}
},
"node_modules/passport-jwt": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/passport-jwt/-/passport-jwt-4.0.0.tgz",
"integrity": "sha512-BwC0n2GP/1hMVjR4QpnvqA61TxenUMlmfNjYNgK0ZAs0HK4SOQkHcSv4L328blNTLtHq7DbmvyNJiH+bn6C5Mg==",
"dependencies": {
"jsonwebtoken": "^8.2.0",
"passport-strategy": "^1.0.0"
}
},
"node_modules/passport-local": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/passport-local/-/passport-local-1.0.0.tgz",
"integrity": "sha512-9wCE6qKznvf9mQYYbgJ3sVOHmCWoUNMVFoZzNoznmISbhnNNPhN9xfY3sLmScHMetEJeoY7CXwfhCe7argfQow==",
"dependencies": {
"passport-strategy": "1.x.x"
},
"engines": {
"node": ">= 0.4.0"
}
},
"node_modules/passport-strategy": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/passport-strategy/-/passport-strategy-1.0.0.tgz",
"integrity": "sha512-CB97UUvDKJde2V0KDWWB3lyf6PC3FaZP7YxZ2G8OAtn9p4HI9j9JLP9qjOGZFvyl8uwNT8qM+hGnz/n16NI7oA==",
"engines": {
"node": ">= 0.4.0"
}
},
"node_modules/path-exists": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
@ -6684,11 +6520,6 @@
"node": ">=8"
}
},
"node_modules/pause": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/pause/-/pause-0.0.1.tgz",
"integrity": "sha512-KG8UEiEVkR3wGEb4m5yZkVCzigAD+cVEJck2CzYZO37ZGJfctvVptVO192MwrtPhzONn6go8ylnOdMhKqi4nfg=="
},
"node_modules/picocolors": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
@ -6856,7 +6687,7 @@
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/prisma/-/prisma-4.1.1.tgz",
"integrity": "sha512-yw50J8If2dKP4wYIi695zthsCASQFHiogGvUHHWd3falx/rpsD6Sb1LMLRV9nO3iGG3lozxNJ2PSINxK7xwdpg==",
"dev": true,
"devOptional": true,
"hasInstallScript": true,
"dependencies": {
"@prisma/engines": "4.1.1"
@ -8322,6 +8153,54 @@
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
"integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
},
"node_modules/webpack": {
"version": "5.74.0",
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.74.0.tgz",
"integrity": "sha512-A2InDwnhhGN4LYctJj6M1JEaGL7Luj6LOmyBHjcI8529cm5p6VXiTIW2sn6ffvEAKmveLzvu4jrihwXtPojlAA==",
"dev": true,
"peer": true,
"dependencies": {
"@types/eslint-scope": "^3.7.3",
"@types/estree": "^0.0.51",
"@webassemblyjs/ast": "1.11.1",
"@webassemblyjs/wasm-edit": "1.11.1",
"@webassemblyjs/wasm-parser": "1.11.1",
"acorn": "^8.7.1",
"acorn-import-assertions": "^1.7.6",
"browserslist": "^4.14.5",
"chrome-trace-event": "^1.0.2",
"enhanced-resolve": "^5.10.0",
"es-module-lexer": "^0.9.0",
"eslint-scope": "5.1.1",
"events": "^3.2.0",
"glob-to-regexp": "^0.4.1",
"graceful-fs": "^4.2.9",
"json-parse-even-better-errors": "^2.3.1",
"loader-runner": "^4.2.0",
"mime-types": "^2.1.27",
"neo-async": "^2.6.2",
"schema-utils": "^3.1.0",
"tapable": "^2.1.1",
"terser-webpack-plugin": "^5.1.3",
"watchpack": "^2.4.0",
"webpack-sources": "^3.2.3"
},
"bin": {
"webpack": "bin/webpack.js"
},
"engines": {
"node": ">=10.13.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/webpack"
},
"peerDependenciesMeta": {
"webpack-cli": {
"optional": true
}
}
},
"node_modules/webpack-node-externals": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/webpack-node-externals/-/webpack-node-externals-3.0.0.tgz",
@ -9738,20 +9617,6 @@
"uuid": "8.3.2"
}
},
"@nestjs/jwt": {
"version": "9.0.0",
"resolved": "https://registry.npmjs.org/@nestjs/jwt/-/jwt-9.0.0.tgz",
"integrity": "sha512-ZsXGY/wMYKzEhymw2+dxiwrHTRKIKrGszx6r2EjQqNLypdXMQu0QrujwZJ8k3+XQV4snmuJwwNakQoA2ILfq8w==",
"requires": {
"@types/jsonwebtoken": "8.5.8",
"jsonwebtoken": "8.5.1"
}
},
"@nestjs/passport": {
"version": "9.0.0",
"resolved": "https://registry.npmjs.org/@nestjs/passport/-/passport-9.0.0.tgz",
"integrity": "sha512-Gnh8n1wzFPOLSS/94X1sUP4IRAoXTgG4odl7/AO5h+uwscEGXxJFercrZfqdAwkWhqkKWbsntM3j5mRy/6ZQDA=="
},
"@nestjs/platform-express": {
"version": "9.0.8",
"resolved": "https://registry.npmjs.org/@nestjs/platform-express/-/platform-express-9.0.8.tgz",
@ -9845,7 +9710,7 @@
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-4.1.1.tgz",
"integrity": "sha512-DCw8L/SS0IXqmj5IW/fMxOXiifnsfjBzDfRhf0j3NFWqvMCh9OtfjmXQZxVgI2mwvJLc/5jzXhkiWT39qS09dA==",
"dev": true
"devOptional": true
},
"@prisma/engines-version": {
"version": "4.1.0-48.8d8414deb360336e4698a65aa45a1fbaf1ce13d8",
@ -10074,6 +9939,7 @@
"version": "8.5.8",
"resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-8.5.8.tgz",
"integrity": "sha512-zm6xBQpFDIDM6o9r6HSgDeIcLy82TKWctCXEPbJJcXb5AKmi5BNNdLXneixK4lplX3PqIVcwLBCGE/kAGnlD4A==",
"dev": true,
"requires": {
"@types/node": "*"
}
@ -10087,7 +9953,8 @@
"@types/node": {
"version": "16.11.47",
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.47.tgz",
"integrity": "sha512-fpP+jk2zJ4VW66+wAMFoBJlx1bxmBKx4DUFf68UHgdGCOuyUTDlLWqsaNPJh7xhNDykyJ9eIzAygilP/4WoN8g=="
"integrity": "sha512-fpP+jk2zJ4VW66+wAMFoBJlx1bxmBKx4DUFf68UHgdGCOuyUTDlLWqsaNPJh7xhNDykyJ9eIzAygilP/4WoN8g==",
"dev": true
},
"@types/parse-json": {
"version": "4.0.0",
@ -10476,13 +10343,15 @@
"version": "1.8.0",
"resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz",
"integrity": "sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==",
"dev": true
"dev": true,
"requires": {}
},
"acorn-jsx": {
"version": "5.3.2",
"resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
"integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
"dev": true
"dev": true,
"requires": {}
},
"acorn-walk": {
"version": "8.2.0",
@ -10813,11 +10682,6 @@
"ieee754": "^1.1.13"
}
},
"buffer-equal-constant-time": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
"integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA=="
},
"buffer-from": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
@ -11222,14 +11086,6 @@
"esutils": "^2.0.2"
}
},
"ecdsa-sig-formatter": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
"integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==",
"requires": {
"safe-buffer": "^5.0.1"
}
},
"ee-first": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
@ -11415,7 +11271,8 @@
"version": "8.5.0",
"resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.5.0.tgz",
"integrity": "sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q==",
"dev": true
"dev": true,
"requires": {}
},
"eslint-plugin-prettier": {
"version": "4.2.1",
@ -12632,7 +12489,8 @@
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz",
"integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==",
"dev": true
"dev": true,
"requires": {}
},
"jest-regex-util": {
"version": "28.0.2",
@ -12990,49 +12848,6 @@
"universalify": "^2.0.0"
}
},
"jsonwebtoken": {
"version": "8.5.1",
"resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz",
"integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==",
"requires": {
"jws": "^3.2.2",
"lodash.includes": "^4.3.0",
"lodash.isboolean": "^3.0.3",
"lodash.isinteger": "^4.0.4",
"lodash.isnumber": "^3.0.3",
"lodash.isplainobject": "^4.0.6",
"lodash.isstring": "^4.0.1",
"lodash.once": "^4.0.0",
"ms": "^2.1.1",
"semver": "^5.6.0"
},
"dependencies": {
"semver": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
}
}
},
"jwa": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz",
"integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==",
"requires": {
"buffer-equal-constant-time": "1.0.1",
"ecdsa-sig-formatter": "1.0.11",
"safe-buffer": "^5.0.1"
}
},
"jws": {
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz",
"integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==",
"requires": {
"jwa": "^1.4.1",
"safe-buffer": "^5.0.1"
}
},
"kleur": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz",
@ -13082,36 +12897,6 @@
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
"dev": true
},
"lodash.includes": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz",
"integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w=="
},
"lodash.isboolean": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz",
"integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg=="
},
"lodash.isinteger": {
"version": "4.0.4",
"resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz",
"integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA=="
},
"lodash.isnumber": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz",
"integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw=="
},
"lodash.isplainobject": {
"version": "4.0.6",
"resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
"integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA=="
},
"lodash.isstring": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz",
"integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw=="
},
"lodash.memoize": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
@ -13124,11 +12909,6 @@
"integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
"dev": true
},
"lodash.once": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz",
"integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg=="
},
"log-symbols": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz",
@ -13301,7 +13081,8 @@
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
"dev": true
},
"multer": {
"version": "1.4.4-lts.1",
@ -13533,38 +13314,6 @@
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
"integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ=="
},
"passport": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/passport/-/passport-0.6.0.tgz",
"integrity": "sha512-0fe+p3ZnrWRW74fe8+SvCyf4a3Pb2/h7gFkQ8yTJpAO50gDzlfjZUZTO1k5Eg9kUct22OxHLqDZoKUWRHOh9ug==",
"requires": {
"passport-strategy": "1.x.x",
"pause": "0.0.1",
"utils-merge": "^1.0.1"
}
},
"passport-jwt": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/passport-jwt/-/passport-jwt-4.0.0.tgz",
"integrity": "sha512-BwC0n2GP/1hMVjR4QpnvqA61TxenUMlmfNjYNgK0ZAs0HK4SOQkHcSv4L328blNTLtHq7DbmvyNJiH+bn6C5Mg==",
"requires": {
"jsonwebtoken": "^8.2.0",
"passport-strategy": "^1.0.0"
}
},
"passport-local": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/passport-local/-/passport-local-1.0.0.tgz",
"integrity": "sha512-9wCE6qKznvf9mQYYbgJ3sVOHmCWoUNMVFoZzNoznmISbhnNNPhN9xfY3sLmScHMetEJeoY7CXwfhCe7argfQow==",
"requires": {
"passport-strategy": "1.x.x"
}
},
"passport-strategy": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/passport-strategy/-/passport-strategy-1.0.0.tgz",
"integrity": "sha512-CB97UUvDKJde2V0KDWWB3lyf6PC3FaZP7YxZ2G8OAtn9p4HI9j9JLP9qjOGZFvyl8uwNT8qM+hGnz/n16NI7oA=="
},
"path-exists": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
@ -13599,11 +13348,6 @@
"integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
"dev": true
},
"pause": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/pause/-/pause-0.0.1.tgz",
"integrity": "sha512-KG8UEiEVkR3wGEb4m5yZkVCzigAD+cVEJck2CzYZO37ZGJfctvVptVO192MwrtPhzONn6go8ylnOdMhKqi4nfg=="
},
"picocolors": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
@ -13721,7 +13465,7 @@
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/prisma/-/prisma-4.1.1.tgz",
"integrity": "sha512-yw50J8If2dKP4wYIi695zthsCASQFHiogGvUHHWd3falx/rpsD6Sb1LMLRV9nO3iGG3lozxNJ2PSINxK7xwdpg==",
"dev": true,
"devOptional": true,
"requires": {
"@prisma/engines": "4.1.1"
}
@ -13997,7 +13741,8 @@
"version": "3.5.2",
"resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
"integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
"dev": true
"dev": true,
"requires": {}
},
"json-schema-traverse": {
"version": "0.4.1",
@ -14780,6 +14525,39 @@
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
"integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
},
"webpack": {
"version": "5.74.0",
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.74.0.tgz",
"integrity": "sha512-A2InDwnhhGN4LYctJj6M1JEaGL7Luj6LOmyBHjcI8529cm5p6VXiTIW2sn6ffvEAKmveLzvu4jrihwXtPojlAA==",
"dev": true,
"peer": true,
"requires": {
"@types/eslint-scope": "^3.7.3",
"@types/estree": "^0.0.51",
"@webassemblyjs/ast": "1.11.1",
"@webassemblyjs/wasm-edit": "1.11.1",
"@webassemblyjs/wasm-parser": "1.11.1",
"acorn": "^8.7.1",
"acorn-import-assertions": "^1.7.6",
"browserslist": "^4.14.5",
"chrome-trace-event": "^1.0.2",
"enhanced-resolve": "^5.10.0",
"es-module-lexer": "^0.9.0",
"eslint-scope": "5.1.1",
"events": "^3.2.0",
"glob-to-regexp": "^0.4.1",
"graceful-fs": "^4.2.9",
"json-parse-even-better-errors": "^2.3.1",
"loader-runner": "^4.2.0",
"mime-types": "^2.1.27",
"neo-async": "^2.6.2",
"schema-utils": "^3.1.0",
"tapable": "^2.1.1",
"terser-webpack-plugin": "^5.1.3",
"watchpack": "^2.4.0",
"webpack-sources": "^3.2.3"
}
},
"webpack-node-externals": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/webpack-node-externals/-/webpack-node-externals-3.0.0.tgz",

View File

@ -23,14 +23,9 @@
"dependencies": {
"@nestjs/common": "^9.0.0",
"@nestjs/core": "^9.0.0",
"@nestjs/jwt": "^9.0.0",
"@nestjs/passport": "^9.0.0",
"@nestjs/platform-express": "^9.0.0",
"@prisma/client": "^4.1.1",
"cors": "^2.8.5",
"passport": "^0.6.0",
"passport-jwt": "^4.0.0",
"passport-local": "^1.0.0",
"reflect-metadata": "^0.1.13",
"rimraf": "^3.0.2",
"rxjs": "^7.2.0"

View File

@ -1,26 +0,0 @@
-- CreateTable
CREATE TABLE `User` (
`id` INTEGER NOT NULL AUTO_INCREMENT,
`email` VARCHAR(191) NOT NULL,
`password` VARCHAR(191) NOT NULL,
`name` VARCHAR(191) NOT NULL,
`role` VARCHAR(191) NOT NULL DEFAULT 'USER',
`is_done` BOOLEAN NULL DEFAULT false,
`updatedAt` TIMESTAMP(0) NULL,
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
UNIQUE INDEX `User_email_key`(`email`),
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- CreateTable
CREATE TABLE `Todo` (
`id` INTEGER NOT NULL AUTO_INCREMENT,
`title` VARCHAR(191) NOT NULL,
`content` VARCHAR(191) NULL,
`is_done` BOOLEAN NULL DEFAULT false,
`updatedAt` TIMESTAMP(0) NULL,
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

View File

@ -0,0 +1,11 @@
-- CreateTable
CREATE TABLE `Todo` (
`id` INTEGER NOT NULL AUTO_INCREMENT,
`title` VARCHAR(191) NOT NULL,
`content` VARCHAR(191) NULL,
`is_done` BOOLEAN NULL DEFAULT false,
`updatedAt` TIMESTAMP(0) NULL,
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

View File

@ -11,17 +11,6 @@ datasource db {
url = env("DATABASE_URL")
}
model User {
id Int @id @default(autoincrement())
email String @unique
password String
name String
role String @default("USER")
is_done Boolean? @default(false)
updatedAt DateTime? @db.Timestamp(0)
createdAt DateTime @default(now())
}
//만들려는 모델
model Todo {
id Int @id @default(autoincrement())

View File

@ -4,42 +4,6 @@ const prisma = new PrismaClient()
//필요 설치 : npm install -D typescript ts-node @types/node
//Project 디렉토리에서 실행: npx prisma db seed
const userDatas: Prisma.UserCreateInput[] = [
{
email: 'choi.jh@idcjp.jp',
name: '최준흠',
password: '1234',
role: 'ADMIN'
},
{
email: 'user1@idcjp.jp',
name: '사용자1',
password: '1234',
role: 'USER'
},
{
email: 'user2@idcjp.jp',
name: '사용자2',
password: '1234',
role: 'USER'
},
{
email: 'user3@idcjp.jp',
name: '사용자3',
password: '1234',
role: 'USER'
}
]
const transferUser = async () => {
const users = []
for (const userData of userDatas) {
const user = prisma.user.create({ data: userData })
users.push(user)
}
return await prisma.$transaction(users)
}
const todoDatas: Prisma.TodoCreateInput[] = [
{
title: '타이틀_1',
@ -113,10 +77,6 @@ const transferTodo = async () => {
}
const main = async () => {
console.log(`Start User seeding ...`)
await transferUser()
console.log(`Seeding User finished.`)
console.log(`Start Todo seeding ...`)
await transferTodo()
console.log(`Seeding Todo finished.`)

View File

@ -2,11 +2,9 @@ import { Module } from '@nestjs/common'
import { AppController } from './app.controller'
import { AppService } from './app.service'
import { TodoModule } from './todo/todo.module'
import { AuthModule } from './auth/auth.module'
import { UsersModule } from './user/user.module'
@Module({
imports: [AuthModule, UsersModule, TodoModule],
imports: [TodoModule],
controllers: [AppController],
providers: [AppService]
})

View File

@ -1,18 +0,0 @@
import { Test, TestingModule } from '@nestjs/testing'
import { AuthController } from './auth.controller'
describe('AuthController', () => {
let controller: AuthController
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
controllers: [AuthController]
}).compile()
controller = module.get<AuthController>(AuthController)
})
it('should be defined', () => {
expect(controller).toBeDefined()
})
})

View File

@ -1,36 +0,0 @@
import { Controller, Get, Post, Request, UseGuards } from '@nestjs/common'
import { AuthService } from './auth.service'
import { JwtAuthGuard } from './guards/jwt.authguard'
import { LocalAuthGuard } from './guards/local-auth.guard'
@Controller('auth')
export class AuthController {
constructor(private authService: AuthService) {}
//local.strategy.ts 사용
// @UseGuards(AuthGuard('local'))
// @UseGuards(LocalAuthGuard)
// @Post('login')
// async login(@Request() req) {
// return req.user
// }
//Login용
//local-auth.guard.ts 사용
@UseGuards(LocalAuthGuard)
@Post('login')
async login(@Request() req) {
console.log(req.user)
const response = this.authService.login(req.user)
console.log(response)
return response
}
//Login여부 확인용
@UseGuards(JwtAuthGuard)
@Get('islogin')
getProfile(@Request() req) {
//console.log(req)
return req.user
}
}

View File

@ -1,27 +0,0 @@
//참고 : https://velog.io/@junguksim/NestJS-노트-3-Authentication
// https://docs.nestjs.com/security/authorization
import { Module } from '@nestjs/common'
import { PassportModule } from '@nestjs/passport'
import { UsersModule } from 'src/user/user.module'
import { AuthService } from './auth.service'
import { JwtModule } from '@nestjs/jwt'
import { jwtConstants } from './guards/constants'
import { AuthController } from './auth.controller'
import { LocalStrategy } from './guards/local.strategy'
import { JwtStrategy } from './guards/jwt.strategy'
@Module({
imports: [
UsersModule,
PassportModule,
JwtModule.register({
secret: jwtConstants.secret,
signOptions: { expiresIn: jwtConstants.expiresIn }
})
],
providers: [AuthService, LocalStrategy, JwtStrategy],
exports: [AuthService],
controllers: [AuthController]
})
export class AuthModule {}

View File

@ -1,18 +0,0 @@
import { Test, TestingModule } from '@nestjs/testing'
import { AuthService } from './auth.service'
describe('AuthService', () => {
let service: AuthService
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [AuthService]
}).compile()
service = module.get<AuthService>(AuthService)
})
it('should be defined', () => {
expect(service).toBeDefined()
})
})

View File

@ -1,35 +0,0 @@
import { Injectable } from '@nestjs/common'
import { UserService } from 'src/user/user.service'
import { JwtService } from '@nestjs/jwt'
@Injectable()
export class AuthService {
constructor(
private userService: UserService,
private jwtService: JwtService
) {}
//app.controller.ts에서 @UseGuards(AuthGuard('local'))용
async validateUser(email: string, password: string): Promise<any> {
const user = await this.userService.fetchOneByEmail(email)
if (user && user.password === password) {
const { password, ...result } = user
// result는 password 를 제외한 user의 모든 정보를 포함한다.
//console.log(result)
return result
}
return null
}
async login(user: any) {
//console.log(user)
const payload = {
id: user.id,
email: user.email,
name: user.name,
roles: [user.role]
}
// console.log(payload)
return { access_token: this.jwtService.sign(payload) }
}
}

View File

@ -1,4 +0,0 @@
import { SetMetadata } from '@nestjs/common'
import { Role } from '../guards/role.enum'
export const HasRoles = (...roles: Role[]) => SetMetadata('has-roles', roles)

View File

@ -1,6 +0,0 @@
import { env } from 'process'
export const jwtConstants = {
secret: env.JWT_SECURITY_KEY,
expiresIn: env.JWT_EXPIRE_MAX
}

View File

@ -1,23 +0,0 @@
import {
ExecutionContext,
Injectable,
UnauthorizedException
} from '@nestjs/common'
import { AuthGuard } from '@nestjs/passport'
@Injectable()
export class JwtAuthGuard extends AuthGuard('jwt') {
canActivate(context: ExecutionContext) {
// Add your custom authentication logic here
// for example, call super.logIn(request) to establish a session.
return super.canActivate(context)
}
handleRequest(err, user, info) {
// You can throw an exception based on either "info" or "err" arguments
if (err || !user) {
throw err || new UnauthorizedException()
}
return user
}
}

View File

@ -1,24 +0,0 @@
import { ExtractJwt, Strategy } from 'passport-jwt'
import { PassportStrategy } from '@nestjs/passport'
import { Injectable } from '@nestjs/common'
import { jwtConstants } from './constants'
@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
constructor() {
super({
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
ignoreExpiration: false,
secretOrKey: jwtConstants.secret
})
}
async validate(payload: any) {
return {
id: payload.id,
email: payload.email,
name: payload.name,
roles: payload.roles
}
}
}

View File

@ -1,5 +0,0 @@
import { Injectable } from '@nestjs/common'
import { AuthGuard } from '@nestjs/passport'
@Injectable()
export class LocalAuthGuard extends AuthGuard('local') {}

View File

@ -1,22 +0,0 @@
import { Strategy } from 'passport-local'
import { PassportStrategy } from '@nestjs/passport'
import { Injectable, UnauthorizedException } from '@nestjs/common'
import { AuthService } from 'src/auth/auth.service'
import { env } from 'process'
@Injectable()
export class LocalStrategy extends PassportStrategy(Strategy) {
constructor(private authService: AuthService) {
//super()
//If you want to check user authenticate with custom column like 'email', try pass it.
super({ usernameField: env.AUTH_USERNAME_FIELD })
}
async validate(email: string, password: string): Promise<any> {
const user = await this.authService.validateUser(email, password)
if (!user) {
throw new UnauthorizedException()
}
return user
}
}

View File

@ -1,4 +0,0 @@
export enum Role {
USER = 'USER',
ADMIN = 'ADMIN'
}

View File

@ -1,7 +0,0 @@
import { RolesGuard } from './roles.guard'
describe('RolesGuard', () => {
it('should be defined', () => {
expect(new RolesGuard()).toBeDefined()
})
})

View File

@ -1,27 +0,0 @@
import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common'
import { Reflector } from '@nestjs/core'
import { Observable } from 'rxjs'
import { Role } from './role.enum'
//참고: https://shpota.com/2022/07/16/role-based-authorization-with-jwt-using-nestjs.html
@Injectable()
export class RolesGuard implements CanActivate {
constructor(private reflector: Reflector) {}
canActivate(
context: ExecutionContext
): boolean | Promise<boolean> | Observable<boolean> {
const requiredRoles = this.reflector.getAllAndOverride<Role[]>(
'has-roles',
[context.getHandler(), context.getClass()]
)
if (!requiredRoles) {
return true
}
const { user } = context.switchToHttp().getRequest()
//console.log(requiredRoles)
//console.log(user)
return requiredRoles.some((role) => user?.roles?.includes(role))
//return true
}
}

View File

@ -1,37 +1,12 @@
//참고 : https://wikidocs.net/book/7059
import { HttpException, HttpStatus } from '@nestjs/common'
import { NestFactory } from '@nestjs/core'
import { AppModule } from './app.module'
async function bootstrap() {
const app = await NestFactory.create(AppModule)
//Enable All CORS Requests : https://docs.nestjs.com/security/cors
app.enableCors({
origin: (origin, callback) => {
//origin URL이 허용된 경우 또는 orgin자체가 없는 경우(postman tool) 통과
if (process.env.CORS_ALLOW_ORIGINS.indexOf(origin) !== -1 || !origin) {
console.log('Allowed Origin URL: ' + origin)
callback(null, true)
} else {
callback(
new HttpException(
{
status: HttpStatus.FORBIDDEN,
error: origin + '에서는 접근이 허용되지 않습니다.'
},
HttpStatus.FORBIDDEN
)
)
}
},
methods: process.env.CORS_ALLOW_METHOD,
credentials: true
})
await app.listen(3000, function () {
console.log(
'[CORS-enabled->npm install -g webpack webpack-cli] web server listening on port 3000'
)
console.log('listening on port 3000')
})
}
bootstrap()

View File

@ -6,14 +6,9 @@ import {
Param,
Post,
Put,
Query,
UseGuards
Query
} from '@nestjs/common'
import { Todo } from '@prisma/client'
import { HasRoles } from 'src/auth/decorators/has-roles.decorator'
import { JwtAuthGuard } from 'src/auth/guards/jwt.authguard'
import { Role } from 'src/auth/guards/role.enum'
import { RolesGuard } from 'src/auth/guards/roles.guard'
import { TodoDTO } from './dtos/todo.dto'
import { TodoService } from './todo.service'
@ -126,23 +121,16 @@ export class TodoController {
return result
}
@HasRoles(Role.USER)
@UseGuards(JwtAuthGuard, RolesGuard)
@Get(':id')
async fetchOne(@Param('id') id: string): Promise<Todo | undefined> {
return await this.todoService.fetchOne({ id: Number(id) })
}
// @HasRoles(Role.USER)
// @UseGuards(JwtAuthGuard, RolesGuard)
//@UseGuards(JwtAuthGuard)
@Post()
async add(@Body() data: TodoDTO): Promise<Todo> {
return await this.todoService.add(data)
}
@HasRoles(Role.USER)
@UseGuards(JwtAuthGuard, RolesGuard)
@Put(':id')
async update(@Param('id') id: string, @Body() data: TodoDTO): Promise<Todo> {
data.updatedAt = new Date()
@ -152,8 +140,6 @@ export class TodoController {
})
}
@HasRoles(Role.USER)
@UseGuards(JwtAuthGuard, RolesGuard)
@Delete(':id')
async delete(@Param('id') id: string): Promise<Todo | undefined> {
return await this.todoService.remove({ id: Number(id) })

View File

@ -24,6 +24,7 @@ export class TodoService {
})
}
//전체조회
async fetchAll(params: {
skip?: number
take?: number

View File

@ -1,7 +0,0 @@
export class UserDTO {
email: string
password: string
name: string
role: string
is_done: boolean
}

View File

@ -1,18 +0,0 @@
import { Test, TestingModule } from '@nestjs/testing'
import { UserController } from './user.controller'
describe('UserController', () => {
let controller: UserController
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
controllers: [UserController]
}).compile()
controller = module.get<UserController>(UserController)
})
it('should be defined', () => {
expect(controller).toBeDefined()
})
})

View File

@ -1,51 +0,0 @@
import {
Body,
Controller,
Delete,
Get,
Param,
Post,
Put,
Query
} from '@nestjs/common'
import { User } from '@prisma/client'
import { UserDTO } from './dtos/user.dto'
import { UserService } from './user.service'
@Controller('user')
export class UserController {
constructor(private readonly userService: UserService) {}
@Get()
async fetchAll(@Query() query): Promise<User[]> {
const sql = {
take: isNaN(query.per_page) ? 20 : Number(query.per_page),
skip: isNaN(query.page) ? 0 : Number(query.page) * query.per_page,
//where: { is_done: true },
orderBy: { id: 'desc' }
}
//console.log(query)
//console.log(sql)
return this.userService.fetchAll(sql)
}
@Get(':id')
async fetchOne(@Param('id') id: number): Promise<User | undefined> {
return this.userService.fetchOne(id)
}
@Delete(':id')
async delete(@Param('id') id: number): Promise<User | undefined> {
return this.userService.remove(id)
}
@Post()
async add(@Body() data: User): Promise<User> {
return this.userService.add(data)
}
@Put(':id')
async update(@Param('id') id: number, @Body() data: UserDTO): Promise<User> {
return this.userService.update(id, data)
}
}

View File

@ -1,11 +0,0 @@
import { Module } from '@nestjs/common'
import { PrismaService } from 'src/prisma.service'
import { UserService } from './user.service'
import { UserController } from './user.controller'
@Module({
controllers: [UserController],
providers: [UserService, PrismaService],
exports: [UserService]
})
export class UsersModule {}

View File

@ -1,18 +0,0 @@
import { Test, TestingModule } from '@nestjs/testing'
import { UserService } from './user.service'
describe('UserService', () => {
let service: UserService
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [UserService]
}).compile()
service = module.get<UserService>(UserService)
})
it('should be defined', () => {
expect(service).toBeDefined()
})
})

View File

@ -1,42 +0,0 @@
import { Injectable } from '@nestjs/common'
import { User } from '@prisma/client'
import { PrismaService } from 'src/prisma.service'
import { UserDTO } from './dtos/user.dto'
@Injectable()
export class UserService {
constructor(private prisma: PrismaService) {}
//단일 조회 ByEmail
async fetchOneByEmail(email: string): Promise<User | undefined> {
return this.prisma.user.findUnique({ where: { email: email } })
}
//전체조회
async fetchAll(sql: any): Promise<User[]> {
return this.prisma.user.findMany(sql)
}
//단일 조회
async fetchOne(id: number): Promise<User | undefined> {
return this.prisma.user.findUnique({ where: { id: Number(id) } })
}
//단일 삭제
async remove(id: number): Promise<User | undefined> {
return this.prisma.user.delete({ where: { id: Number(id) } })
}
//단일 추가
async add(data: User): Promise<User> {
return this.prisma.user.create({ data: data })
}
//단일 수정
async update(id: number, data: UserDTO): Promise<User | undefined> {
return this.prisma.user.update({
where: { id: Number(id) },
data: data
})
}
}