박유빈

edit README, change the front code flutter to ejs

...@@ -5,6 +5,28 @@ ...@@ -5,6 +5,28 @@
5 "version": "0.2.0", 5 "version": "0.2.0",
6 "configurations": [ 6 "configurations": [
7 { 7 {
8 + "name": "Launch via NPM",
9 + "request": "launch",
10 + "runtimeArgs": [
11 + "run-script",
12 + "debug"
13 + ],
14 + "runtimeExecutable": "npm run start:dev",
15 + "skipFiles": [
16 + "<node_internals>/**"
17 + ],
18 + "type": "pwa-node"
19 + },
20 + {
21 + "program": "${workspaceFolder}/app.js",
22 + "request": "launch",
23 + "skipFiles": [
24 + "<node_internals>/**"
25 + ],
26 + "type": "pwa-node"
27 + },
28 +
29 + {
8 "type": "pwa-node", 30 "type": "pwa-node",
9 "request": "launch", 31 "request": "launch",
10 "name": "Launch Program", 32 "name": "Launch Program",
......
...@@ -19,7 +19,7 @@ server use Node.js, Koa.js and frotend use flutter(Dart) ...@@ -19,7 +19,7 @@ server use Node.js, Koa.js and frotend use flutter(Dart)
19 * [Node.js](https://nodejs.org/) 19 * [Node.js](https://nodejs.org/)
20 * [Koa.js](https://koajs.com/) 20 * [Koa.js](https://koajs.com/)
21 21
22 -* [flutter](https://flutter.dev/) 22 +
23 23
24 24
25 25
...@@ -31,7 +31,6 @@ server use Node.js, Koa.js and frotend use flutter(Dart) ...@@ -31,7 +31,6 @@ server use Node.js, Koa.js and frotend use flutter(Dart)
31 ## Getting Started 31 ## Getting Started
32 32
33 Go to the Server [Project folder](http://khuhub.khu.ac.kr/2018102946/likeBack), and git clone. 33 Go to the Server [Project folder](http://khuhub.khu.ac.kr/2018102946/likeBack), and git clone.
34 -And go the Frontend [Project folder](http://khuhub.khu.ac.kr/2018102946/likefront)and git clone.
35 34
36 35
37 ### Installation 36 ### Installation
...@@ -72,7 +71,7 @@ _Below is an example of how you can instruct your audience on installing and set ...@@ -72,7 +71,7 @@ _Below is an example of how you can instruct your audience on installing and set
72 Your Name -- email@example.com 71 Your Name -- email@example.com
73 72
74 Project Link: [http://khuhub.khu.ac.kr/2018102946/likeBack](http://khuhub.khu.ac.kr/2018102946/likeBack) 73 Project Link: [http://khuhub.khu.ac.kr/2018102946/likeBack](http://khuhub.khu.ac.kr/2018102946/likeBack)
75 - [http://khuhub.khu.ac.kr/2018102946/likefront](http://khuhub.khu.ac.kr/2018102946/likefront) 74 +
76 75
77 <p align="right">(<a href="#top">back to top</a>)</p> 76 <p align="right">(<a href="#top">back to top</a>)</p>
78 77
......
1 +[debug] [2021-12-06T16:19:50.991Z] ----------------------------------------------------------------------
2 +[debug] [2021-12-06T16:19:50.996Z] Command: /usr/local/bin/node /usr/local/bin/firebase login
3 +[debug] [2021-12-06T16:19:50.997Z] CLI Version: 9.23.0
4 +[debug] [2021-12-06T16:19:50.997Z] Platform: linux
5 +[debug] [2021-12-06T16:19:50.998Z] Node Version: v16.13.0
6 +[debug] [2021-12-06T16:19:51.007Z] Time: Tue Dec 07 2021 01:19:50 GMT+0900 (Korean Standard Time)
7 +[debug] [2021-12-06T16:19:51.008Z] ----------------------------------------------------------------------
8 +[debug]
9 +[debug] [2021-12-06T16:19:51.014Z] >>> [apiv2][query] GET https://firebase-public.firebaseio.com/cli.json [none]
10 +[info] i Firebase optionally collects CLI usage and error reporting information to help improve our products. Data is collected in accordance with Google's privacy policy (https://policies.google.com/privacy) and is not used to identify you.
11 +
12 +[debug] [2021-12-06T16:19:52.476Z] <<< [apiv2][status] GET https://firebase-public.firebaseio.com/cli.json 200
13 +[debug] [2021-12-06T16:19:52.476Z] <<< [apiv2][body] GET https://firebase-public.firebaseio.com/cli.json {"cloudBuildErrorAfter":1594252800000,"cloudBuildWarnAfter":1590019200000,"defaultNode10After":1594252800000,"minVersion":"3.0.5","node8DeploysDisabledAfter":1613390400000,"node8RuntimeDisabledAfter":1615809600000,"node8WarnAfter":1600128000000}
14 +[info] i To change your data collection preference at any time, run `firebase logout` and log in again.
15 +[info]
16 +[info] Visit this URL on this device to log in:
17 +[info] https://accounts.google.com/o/oauth2/auth?client_id=563584335869-fgrhgmd47bqnekij5i8b5pr03ho849e6.apps.googleusercontent.com&scope=email%20openid%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcloudplatformprojects.readonly%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Ffirebase%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcloud-platform&response_type=code&state=406504610&redirect_uri=http%3A%2F%2Flocalhost%3A9005
18 +[info]
19 +[info] Waiting for authentication...
...@@ -21,12 +21,15 @@ ...@@ -21,12 +21,15 @@
21 "koa": "^2.13.4", 21 "koa": "^2.13.4",
22 "koa-body": "^4.2.0", 22 "koa-body": "^4.2.0",
23 "koa-bodyparser": "^4.3.0", 23 "koa-bodyparser": "^4.3.0",
24 + "koa-ejs": "^4.3.0",
25 + "koa-passport": "^4.1.4",
24 "koa-router": "^10.1.1", 26 "koa-router": "^10.1.1",
25 "koa-send": "^5.0.1", 27 "koa-send": "^5.0.1",
26 "mongoose": "^6.0.12", 28 "mongoose": "^6.0.12",
27 "nodemailer": "^6.7.1", 29 "nodemailer": "^6.7.1",
28 "passport": "^0.5.0", 30 "passport": "^0.5.0",
29 "passport-google-oauth": "^2.0.0", 31 "passport-google-oauth": "^2.0.0",
32 + "passport-local": "^1.0.0",
30 "spdy": "^4.0.2" 33 "spdy": "^4.0.2"
31 }, 34 },
32 "devDependencies": { 35 "devDependencies": {
...@@ -1109,6 +1112,11 @@ ...@@ -1109,6 +1112,11 @@
1109 "url": "https://github.com/chalk/ansi-styles?sponsor=1" 1112 "url": "https://github.com/chalk/ansi-styles?sponsor=1"
1110 } 1113 }
1111 }, 1114 },
1115 + "node_modules/any-promise": {
1116 + "version": "1.3.0",
1117 + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz",
1118 + "integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8="
1119 + },
1112 "node_modules/aproba": { 1120 "node_modules/aproba": {
1113 "version": "2.0.0", 1121 "version": "2.0.0",
1114 "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", 1122 "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz",
...@@ -1553,6 +1561,15 @@ ...@@ -1553,6 +1561,15 @@
1553 "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", 1561 "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
1554 "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" 1562 "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
1555 }, 1563 },
1564 + "node_modules/ejs": {
1565 + "version": "2.7.4",
1566 + "resolved": "https://registry.npmjs.org/ejs/-/ejs-2.7.4.tgz",
1567 + "integrity": "sha512-7vmuyh5+kuUyJKePhQfRQBhXV5Ce+RnaeeQArKu1EAMpL3WbgMt5WG6uQZpEVvYSSsxMXRKOewtDk9RaTKXRlA==",
1568 + "hasInstallScript": true,
1569 + "engines": {
1570 + "node": ">=0.10.0"
1571 + }
1572 + },
1556 "node_modules/emoji-regex": { 1573 "node_modules/emoji-regex": {
1557 "version": "8.0.0", 1574 "version": "8.0.0",
1558 "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", 1575 "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
...@@ -2620,6 +2637,39 @@ ...@@ -2620,6 +2637,39 @@
2620 "node": ">= 10" 2637 "node": ">= 10"
2621 } 2638 }
2622 }, 2639 },
2640 + "node_modules/koa-ejs": {
2641 + "version": "4.3.0",
2642 + "resolved": "https://registry.npmjs.org/koa-ejs/-/koa-ejs-4.3.0.tgz",
2643 + "integrity": "sha512-KK1B1YEeq8TOt7hrHwohfHxH03ZqsdhQWeFjmvcWk3arVI/uQOyE4FHQVlg0Ud9eXxlgUfkYqA2MJhfK4ADkAw==",
2644 + "dependencies": {
2645 + "debug": "^2.6.1",
2646 + "ejs": "^2.6.1",
2647 + "mz": "^2.6.0"
2648 + }
2649 + },
2650 + "node_modules/koa-passport": {
2651 + "version": "4.1.4",
2652 + "resolved": "https://registry.npmjs.org/koa-passport/-/koa-passport-4.1.4.tgz",
2653 + "integrity": "sha512-dJBCkl4X+zdYxbI2V2OtoGy0PUenpvp2ZLLWObc8UJhsId0iQpTFT8RVcuA0709AL2txGwRHnSPoT1bYNGa6Kg==",
2654 + "dependencies": {
2655 + "passport": "^0.4.0"
2656 + },
2657 + "engines": {
2658 + "node": ">= 4"
2659 + }
2660 + },
2661 + "node_modules/koa-passport/node_modules/passport": {
2662 + "version": "0.4.1",
2663 + "resolved": "https://registry.npmjs.org/passport/-/passport-0.4.1.tgz",
2664 + "integrity": "sha512-IxXgZZs8d7uFSt3eqNjM9NQ3g3uQCW5avD8mRNoXV99Yig50vjuaez6dQK2qC0kVWPRTujxY0dWgGfT09adjYg==",
2665 + "dependencies": {
2666 + "passport-strategy": "1.x.x",
2667 + "pause": "0.0.1"
2668 + },
2669 + "engines": {
2670 + "node": ">= 0.4.0"
2671 + }
2672 + },
2623 "node_modules/koa-router": { 2673 "node_modules/koa-router": {
2624 "version": "10.1.1", 2674 "version": "10.1.1",
2625 "resolved": "https://registry.npmjs.org/koa-router/-/koa-router-10.1.1.tgz", 2675 "resolved": "https://registry.npmjs.org/koa-router/-/koa-router-10.1.1.tgz",
...@@ -3102,6 +3152,16 @@ ...@@ -3102,6 +3152,16 @@
3102 "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 3152 "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
3103 "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" 3153 "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
3104 }, 3154 },
3155 + "node_modules/mz": {
3156 + "version": "2.7.0",
3157 + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz",
3158 + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==",
3159 + "dependencies": {
3160 + "any-promise": "^1.0.0",
3161 + "object-assign": "^4.0.1",
3162 + "thenify-all": "^1.0.0"
3163 + }
3164 + },
3105 "node_modules/natural-compare": { 3165 "node_modules/natural-compare": {
3106 "version": "1.4.0", 3166 "version": "1.4.0",
3107 "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", 3167 "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
...@@ -3192,6 +3252,14 @@ ...@@ -3192,6 +3252,14 @@
3192 "resolved": "https://registry.npmjs.org/oauth/-/oauth-0.9.15.tgz", 3252 "resolved": "https://registry.npmjs.org/oauth/-/oauth-0.9.15.tgz",
3193 "integrity": "sha1-vR/vr2hslrdUda7VGWQS/2DPucE=" 3253 "integrity": "sha1-vR/vr2hslrdUda7VGWQS/2DPucE="
3194 }, 3254 },
3255 + "node_modules/object-assign": {
3256 + "version": "4.1.1",
3257 + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
3258 + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
3259 + "engines": {
3260 + "node": ">=0.10.0"
3261 + }
3262 + },
3195 "node_modules/obuf": { 3263 "node_modules/obuf": {
3196 "version": "1.1.2", 3264 "version": "1.1.2",
3197 "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", 3265 "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz",
...@@ -3310,6 +3378,17 @@ ...@@ -3310,6 +3378,17 @@
3310 "node": ">= 0.4.0" 3378 "node": ">= 0.4.0"
3311 } 3379 }
3312 }, 3380 },
3381 + "node_modules/passport-local": {
3382 + "version": "1.0.0",
3383 + "resolved": "https://registry.npmjs.org/passport-local/-/passport-local-1.0.0.tgz",
3384 + "integrity": "sha1-H+YyaMkudWBmJkN+O5BmYsFbpu4=",
3385 + "dependencies": {
3386 + "passport-strategy": "1.x.x"
3387 + },
3388 + "engines": {
3389 + "node": ">= 0.4.0"
3390 + }
3391 + },
3313 "node_modules/passport-oauth1": { 3392 "node_modules/passport-oauth1": {
3314 "version": "1.2.0", 3393 "version": "1.2.0",
3315 "resolved": "https://registry.npmjs.org/passport-oauth1/-/passport-oauth1-1.2.0.tgz", 3394 "resolved": "https://registry.npmjs.org/passport-oauth1/-/passport-oauth1-1.2.0.tgz",
...@@ -3911,6 +3990,25 @@ ...@@ -3911,6 +3990,25 @@
3911 "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", 3990 "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=",
3912 "dev": true 3991 "dev": true
3913 }, 3992 },
3993 + "node_modules/thenify": {
3994 + "version": "3.3.1",
3995 + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz",
3996 + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==",
3997 + "dependencies": {
3998 + "any-promise": "^1.0.0"
3999 + }
4000 + },
4001 + "node_modules/thenify-all": {
4002 + "version": "1.6.0",
4003 + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz",
4004 + "integrity": "sha1-GhkY1ALY/D+Y+/I02wvMjMEOlyY=",
4005 + "dependencies": {
4006 + "thenify": ">= 3.1.0 < 4"
4007 + },
4008 + "engines": {
4009 + "node": ">=0.8"
4010 + }
4011 + },
3914 "node_modules/tmp": { 4012 "node_modules/tmp": {
3915 "version": "0.2.1", 4013 "version": "0.2.1",
3916 "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", 4014 "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz",
...@@ -5125,6 +5223,11 @@ ...@@ -5125,6 +5223,11 @@
5125 "color-convert": "^2.0.1" 5223 "color-convert": "^2.0.1"
5126 } 5224 }
5127 }, 5225 },
5226 + "any-promise": {
5227 + "version": "1.3.0",
5228 + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz",
5229 + "integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8="
5230 + },
5128 "aproba": { 5231 "aproba": {
5129 "version": "2.0.0", 5232 "version": "2.0.0",
5130 "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", 5233 "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz",
...@@ -5457,6 +5560,11 @@ ...@@ -5457,6 +5560,11 @@
5457 "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", 5560 "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
5458 "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" 5561 "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
5459 }, 5562 },
5563 + "ejs": {
5564 + "version": "2.7.4",
5565 + "resolved": "https://registry.npmjs.org/ejs/-/ejs-2.7.4.tgz",
5566 + "integrity": "sha512-7vmuyh5+kuUyJKePhQfRQBhXV5Ce+RnaeeQArKu1EAMpL3WbgMt5WG6uQZpEVvYSSsxMXRKOewtDk9RaTKXRlA=="
5567 + },
5460 "emoji-regex": { 5568 "emoji-regex": {
5461 "version": "8.0.0", 5569 "version": "8.0.0",
5462 "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", 5570 "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
...@@ -6329,6 +6437,35 @@ ...@@ -6329,6 +6437,35 @@
6329 "koa-compose": "^4.1.0" 6437 "koa-compose": "^4.1.0"
6330 } 6438 }
6331 }, 6439 },
6440 + "koa-ejs": {
6441 + "version": "4.3.0",
6442 + "resolved": "https://registry.npmjs.org/koa-ejs/-/koa-ejs-4.3.0.tgz",
6443 + "integrity": "sha512-KK1B1YEeq8TOt7hrHwohfHxH03ZqsdhQWeFjmvcWk3arVI/uQOyE4FHQVlg0Ud9eXxlgUfkYqA2MJhfK4ADkAw==",
6444 + "requires": {
6445 + "debug": "^2.6.1",
6446 + "ejs": "^2.6.1",
6447 + "mz": "^2.6.0"
6448 + }
6449 + },
6450 + "koa-passport": {
6451 + "version": "4.1.4",
6452 + "resolved": "https://registry.npmjs.org/koa-passport/-/koa-passport-4.1.4.tgz",
6453 + "integrity": "sha512-dJBCkl4X+zdYxbI2V2OtoGy0PUenpvp2ZLLWObc8UJhsId0iQpTFT8RVcuA0709AL2txGwRHnSPoT1bYNGa6Kg==",
6454 + "requires": {
6455 + "passport": "^0.4.0"
6456 + },
6457 + "dependencies": {
6458 + "passport": {
6459 + "version": "0.4.1",
6460 + "resolved": "https://registry.npmjs.org/passport/-/passport-0.4.1.tgz",
6461 + "integrity": "sha512-IxXgZZs8d7uFSt3eqNjM9NQ3g3uQCW5avD8mRNoXV99Yig50vjuaez6dQK2qC0kVWPRTujxY0dWgGfT09adjYg==",
6462 + "requires": {
6463 + "passport-strategy": "1.x.x",
6464 + "pause": "0.0.1"
6465 + }
6466 + }
6467 + }
6468 + },
6332 "koa-router": { 6469 "koa-router": {
6333 "version": "10.1.1", 6470 "version": "10.1.1",
6334 "resolved": "https://registry.npmjs.org/koa-router/-/koa-router-10.1.1.tgz", 6471 "resolved": "https://registry.npmjs.org/koa-router/-/koa-router-10.1.1.tgz",
...@@ -6684,6 +6821,16 @@ ...@@ -6684,6 +6821,16 @@
6684 "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 6821 "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
6685 "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" 6822 "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
6686 }, 6823 },
6824 + "mz": {
6825 + "version": "2.7.0",
6826 + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz",
6827 + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==",
6828 + "requires": {
6829 + "any-promise": "^1.0.0",
6830 + "object-assign": "^4.0.1",
6831 + "thenify-all": "^1.0.0"
6832 + }
6833 + },
6687 "natural-compare": { 6834 "natural-compare": {
6688 "version": "1.4.0", 6835 "version": "1.4.0",
6689 "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", 6836 "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
...@@ -6758,6 +6905,11 @@ ...@@ -6758,6 +6905,11 @@
6758 "resolved": "https://registry.npmjs.org/oauth/-/oauth-0.9.15.tgz", 6905 "resolved": "https://registry.npmjs.org/oauth/-/oauth-0.9.15.tgz",
6759 "integrity": "sha1-vR/vr2hslrdUda7VGWQS/2DPucE=" 6906 "integrity": "sha1-vR/vr2hslrdUda7VGWQS/2DPucE="
6760 }, 6907 },
6908 + "object-assign": {
6909 + "version": "4.1.1",
6910 + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
6911 + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
6912 + },
6761 "obuf": { 6913 "obuf": {
6762 "version": "1.1.2", 6914 "version": "1.1.2",
6763 "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", 6915 "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz",
...@@ -6851,6 +7003,14 @@ ...@@ -6851,6 +7003,14 @@
6851 "passport-oauth2": "1.x.x" 7003 "passport-oauth2": "1.x.x"
6852 } 7004 }
6853 }, 7005 },
7006 + "passport-local": {
7007 + "version": "1.0.0",
7008 + "resolved": "https://registry.npmjs.org/passport-local/-/passport-local-1.0.0.tgz",
7009 + "integrity": "sha1-H+YyaMkudWBmJkN+O5BmYsFbpu4=",
7010 + "requires": {
7011 + "passport-strategy": "1.x.x"
7012 + }
7013 + },
6854 "passport-oauth1": { 7014 "passport-oauth1": {
6855 "version": "1.2.0", 7015 "version": "1.2.0",
6856 "resolved": "https://registry.npmjs.org/passport-oauth1/-/passport-oauth1-1.2.0.tgz", 7016 "resolved": "https://registry.npmjs.org/passport-oauth1/-/passport-oauth1-1.2.0.tgz",
...@@ -7305,6 +7465,22 @@ ...@@ -7305,6 +7465,22 @@
7305 "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", 7465 "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=",
7306 "dev": true 7466 "dev": true
7307 }, 7467 },
7468 + "thenify": {
7469 + "version": "3.3.1",
7470 + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz",
7471 + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==",
7472 + "requires": {
7473 + "any-promise": "^1.0.0"
7474 + }
7475 + },
7476 + "thenify-all": {
7477 + "version": "1.6.0",
7478 + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz",
7479 + "integrity": "sha1-GhkY1ALY/D+Y+/I02wvMjMEOlyY=",
7480 + "requires": {
7481 + "thenify": ">= 3.1.0 < 4"
7482 + }
7483 + },
7308 "tmp": { 7484 "tmp": {
7309 "version": "0.2.1", 7485 "version": "0.2.1",
7310 "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", 7486 "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz",
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
6 "scripts": { 6 "scripts": {
7 "test": "echo \"Error: no test specified\" && exit 1", 7 "test": "echo \"Error: no test specified\" && exit 1",
8 "start": "node src", 8 "start": "node src",
9 - "start:dev": "nodemon --watch src/ src/index.js" 9 + "start:dev": "NODE_PATH=src nodemon --legacy-watch src/ src/index.js"
10 }, 10 },
11 "author": "", 11 "author": "",
12 "license": "ISC", 12 "license": "ISC",
...@@ -23,12 +23,15 @@ ...@@ -23,12 +23,15 @@
23 "koa": "^2.13.4", 23 "koa": "^2.13.4",
24 "koa-body": "^4.2.0", 24 "koa-body": "^4.2.0",
25 "koa-bodyparser": "^4.3.0", 25 "koa-bodyparser": "^4.3.0",
26 + "koa-ejs": "^4.3.0",
27 + "koa-passport": "^4.1.4",
26 "koa-router": "^10.1.1", 28 "koa-router": "^10.1.1",
27 "koa-send": "^5.0.1", 29 "koa-send": "^5.0.1",
28 "mongoose": "^6.0.12", 30 "mongoose": "^6.0.12",
29 "nodemailer": "^6.7.1", 31 "nodemailer": "^6.7.1",
30 "passport": "^0.5.0", 32 "passport": "^0.5.0",
31 "passport-google-oauth": "^2.0.0", 33 "passport-google-oauth": "^2.0.0",
34 + "passport-local": "^1.0.0",
32 "spdy": "^4.0.2" 35 "spdy": "^4.0.2"
33 }, 36 },
34 "devDependencies": { 37 "devDependencies": {
......
...@@ -6,6 +6,9 @@ const nodemailer = require('nodemailer'); ...@@ -6,6 +6,9 @@ const nodemailer = require('nodemailer');
6 const config = require('../../lib/config'); 6 const config = require('../../lib/config');
7 const { Mongoose } = require('mongoose'); 7 const { Mongoose } = require('mongoose');
8 const { exist, allow } = require('@hapi/joi'); 8 const { exist, allow } = require('@hapi/joi');
9 +const index = require('../../../src/index');
10 +const render = index.render;
11 +
9 const fs = require('fs'); 12 const fs = require('fs');
10 exports.test = async (ctx) => { 13 exports.test = async (ctx) => {
11 console.log('cookie'); 14 console.log('cookie');
...@@ -61,7 +64,7 @@ exports.signupLocal = async (ctx) => { ...@@ -61,7 +64,7 @@ exports.signupLocal = async (ctx) => {
61 64
62 // 응답할 데이터에서 hashedPassword 필드 제거 65 // 응답할 데이터에서 hashedPassword 필드 제거
63 ctx.status = 200; 66 ctx.status = 200;
64 - ctx.body = await account.serialize(); 67 + await ctx.render('users/new');
65 } catch (e) { 68 } catch (e) {
66 ctx.throw(500, e); 69 ctx.throw(500, e);
67 } 70 }
...@@ -97,6 +100,7 @@ exports.signinLocal = async (ctx) => { ...@@ -97,6 +100,7 @@ exports.signinLocal = async (ctx) => {
97 httpOnly: false, 100 httpOnly: false,
98 }); 101 });
99 ctx.status = 200; 102 ctx.status = 200;
103 + await ctx.render('users/index');
100 console.log('토큰나옴'); 104 console.log('토큰나옴');
101 } catch (e) { 105 } catch (e) {
102 ctx.throw(500, e); 106 ctx.throw(500, e);
......
...@@ -3,6 +3,7 @@ const Router = require("@koa/router"); ...@@ -3,6 +3,7 @@ const Router = require("@koa/router");
3 const authCtrl = require("./auth.ctrl"); 3 const authCtrl = require("./auth.ctrl");
4 const checkLoggedIn = require("../../lib/checkLoggedIn"); 4 const checkLoggedIn = require("../../lib/checkLoggedIn");
5 var passport = require('passport'); 5 var passport = require('passport');
6 +const User = require("../../models/user");
6 var GoogleStrategy = require('passport-google-oauth').OAuth2Strategy; 7 var GoogleStrategy = require('passport-google-oauth').OAuth2Strategy;
7 const auth = new Router(); 8 const auth = new Router();
8 9
...@@ -26,12 +27,72 @@ auth.get('/book',checkLoggedIn,authCtrl.getUserBook); ...@@ -26,12 +27,72 @@ auth.get('/book',checkLoggedIn,authCtrl.getUserBook);
26 auth.get('/user', checkLoggedIn,authCtrl.userinfo); // show user information 27 auth.get('/user', checkLoggedIn,authCtrl.userinfo); // show user information
27 auth.patch('/user', checkLoggedIn, authCtrl.updateUser); // modify user information 28 auth.patch('/user', checkLoggedIn, authCtrl.updateUser); // modify user information
28 auth.patch('/user/password', authCtrl.changePassword); // change password 29 auth.patch('/user/password', authCtrl.changePassword); // change password
29 - 30 +auth.post('/find/password', authCtrl.findPassword); // 비밀번호 찾기
30 auth.get('/favorite',checkLoggedIn, authCtrl.showFavorite); // show a list of user's favorites 31 auth.get('/favorite',checkLoggedIn, authCtrl.showFavorite); // show a list of user's favorites
31 auth.post('/favorite',checkLoggedIn, authCtrl.addFavorite); // add favorite 32 auth.post('/favorite',checkLoggedIn, authCtrl.addFavorite); // add favorite
32 auth.delete('/favorite',checkLoggedIn, authCtrl.delFavorite); // delete favorite 33 auth.delete('/favorite',checkLoggedIn, authCtrl.delFavorite); // delete favorite
33 34
34 auth.post('/find/password', authCtrl.findPassword); // 비밀번호 찾기 35 auth.post('/find/password', authCtrl.findPassword); // 비밀번호 찾기
36 +auth.get('/new', async (ctx) => {
37 + ctx.render('users/new');
38 + });
39 +
40 +
41 +auth.get('/', async (ctx) => {
42 + try{
43 + const user = await User.find({}).sort({email:-1}).exec();//1 오름차순 -1내림차순
44 + ctx.render('users/index', {users});
45 + }catch(e){
46 + ctx.throw(500, e);
47 + }
48 + }
49 +);
50 +
51 +
52 +// show
53 +auth.get('/:username', async (ctx) => {
54 + const user = await User.findOne({_id:ctx.params._id});
55 + ctx.render('users/show', {user});
56 + });
57 +
58 +
59 +
60 + // edit
61 + auth.get('/:username/edit', async (ctx) => {
62 + const user = await User.findOne({username:ctx.params.username});
63 + ctx.render('users/edit', {user:user});
64 + });
65 +
66 +
67 + // update // 2
68 + auth.post('/:username', async (ctx) => {
69 + await User.findOne({username:ctx.params.username}).select('password').exec();
70 +
71 +
72 + // update user object
73 + user.originalPassword = user.password;
74 + user.password = ctx.body.newPassword? ctx.body.newPassword : user.password; // 2-3
75 + for(var p in ctx.body) // 2-4
76 + user[p] = ctx.body[p];
77 +
78 +
79 + // save updated user
80 + await user.save();
81 +
82 + ctx.redirect('/users/'+user.nickname);
83 + });
84 +
85 +
86 + // destroy
87 + auth.delete('/:username',async (ctx) => {
88 + try{
89 + var username = ctx.params.username;
90 + await User.deleteOne({username:username});
91 + ctx.redirect('/users');
92 + }catch(e){
93 + ctx.throw(500, e);
94 + }
95 + });
35 96
36 97
37 module.exports = auth; 98 module.exports = auth;
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -9,13 +9,13 @@ exports.booklist = async (ctx) => { ...@@ -9,13 +9,13 @@ exports.booklist = async (ctx) => {
9 9
10 try { 10 try {
11 book = await Book.find() 11 book = await Book.find()
12 - .sort({created: -1}) 12 + .sort({createDate: -1})
13 .exec(); 13 .exec();
14 + await ctx.render('books/index', {book:book});
14 } catch (e) { 15 } catch (e) {
15 return ctx.throw(500, e); 16 return ctx.throw(500, e);
17 + console.log('get /book/booklist');
16 } 18 }
17 -
18 - ctx.body = book;
19 } 19 }
20 20
21 21
...@@ -55,12 +55,12 @@ exports.addBook = async (ctx) => { ...@@ -55,12 +55,12 @@ exports.addBook = async (ctx) => {
55 if (err) throw err; 55 if (err) throw err;
56 const user = await User.findById(ctx.state.user._id).exec(); 56 const user = await User.findById(ctx.state.user._id).exec();
57 console.log(book._id); 57 console.log(book._id);
58 - 58 + ctx.redirect('/books');
59 }); 59 });
60 } catch (e) { 60 } catch (e) {
61 ctx.throw(500, e); 61 ctx.throw(500, e);
62 } 62 }
63 - ctx.body = book; 63 + console.log('저장 성공!');
64 ctx.status = 200; 64 ctx.status = 200;
65 }; 65 };
66 66
...@@ -97,44 +97,67 @@ exports.updateBook = async (ctx) => { ...@@ -97,44 +97,67 @@ exports.updateBook = async (ctx) => {
97 ctx.request.body.cover = fs.readFileSync(file.image.path); 97 ctx.request.body.cover = fs.readFileSync(file.image.path);
98 else 98 else
99 ctx.request.body.cover = "" 99 ctx.request.body.cover = ""
100 -
101 var book = ctx.request.body; //require books's _id 100 var book = ctx.request.body; //require books's _id
102 try { 101 try {
103 const mybook = await Book.findOne({ _id: book._id }); 102 const mybook = await Book.findOne({ _id: book._id });
104 - 103 + if(ctx.state.user._id == mybook.author){
105 mybook.updateB(book); 104 mybook.updateB(book);
106 -
107 ctx.body = book._id; 105 ctx.body = book._id;
108 - } catch (e) { 106 + ctx.status = 200;}
109 - ctx.throw(500, e); 107 +
110 } 108 }
111 - ctx.body = book._id; 109 + catch (e) {
110 + ctx.throw(500, e);
112 111
113 - console.log(book); 112 + ctx.status = 400;
114 - ctx.status = 200; 113 + ctx.body = {
114 + message: "작성자가 아닙니다. " }
115 + }
115 }; 116 };
116 117
117 118
119 +
118 exports.deleteBook = async (ctx) => { 120 exports.deleteBook = async (ctx) => {
121 +
122 + let bookid = ctx.query.id;
119 try { 123 try {
120 - var b = await Book.find(ctx.params.id); 124 +
121 - await Page.deleteMany({"pages":{$in:b.pages}});//book에 있던 페이지 다 지우기 125 + //var foundB = await Book.findById(bookid).exec();
126 + //북작가에게서 책 정보 지우기
127 + var author = await User.findById(bookid);//북 작가.
128 + console.log(author);
129 + console.log(author.books);
130 + await User.delBook(ctx.state.user.email,bookid);
131 + //book에 있던 페이지 다 지우기
132 + await Page.deleteMany({"pages":{$in:b.pages}});
133 +
134 +
135 + //최종 book지우기
136 + var b = await Book.deleteOne({_id:bookid});
122 } catch (e) { 137 } catch (e) {
123 if(e.name === 'CastError') { 138 if(e.name === 'CastError') {
124 ctx.status = 400; 139 ctx.status = 400;
125 return; 140 return;
126 } 141 }
127 } 142 }
128 - ctx.status = 204; // No Content 143 + console.log('delete success');
144 + ctx.body = {
145 + message: "Delete"
146 + }
129 }; 147 };
130 148
131 exports.detailBook = async (ctx) => { 149 exports.detailBook = async (ctx) => {
132 - var ObjectId = require('mongodb').ObjectId; 150 + try{
133 - var id = req.params.book_id; 151 + var id = ctx.params.id;
134 - var o_id = new ObjectId(id); 152 + const book = await dBook.find({_id:id});
135 - const book = await db.Book.find({_id:o_id}); 153 + ctx.render('books/show', {book:book});
136 - ctx.body = book;
137 ctx.status = 200; 154 ctx.status = 200;
155 + } catch (e) {
156 + ctx.status = 400;
157 + console.log('북 삭제 오류');
158 + }
159 +
160 +
138 }; 161 };
139 162
140 exports.scrollBook = async (ctx) => { 163 exports.scrollBook = async (ctx) => {
...@@ -154,8 +177,4 @@ exports.scrollBook = async (ctx) => { ...@@ -154,8 +177,4 @@ exports.scrollBook = async (ctx) => {
154 ctx.throw(500, e); 177 ctx.throw(500, e);
155 } 178 }
156 } 179 }
157 -
158 - else if(filter === "추천순") { //추천순
159 -
160 - }
161 }; 180 };
......
...@@ -11,5 +11,7 @@ book.patch('/', checkLoggedIn, bookCtrl.updateBook); // modify book information ...@@ -11,5 +11,7 @@ book.patch('/', checkLoggedIn, bookCtrl.updateBook); // modify book information
11 book.delete('/',checkLoggedIn,bookCtrl.deleteBook); // delete book 11 book.delete('/',checkLoggedIn,bookCtrl.deleteBook); // delete book
12 book.get('/booklist',bookCtrl.booklist); 12 book.get('/booklist',bookCtrl.booklist);
13 book.get('/search',bookCtrl.scrollBook); 13 book.get('/search',bookCtrl.scrollBook);
14 - 14 +book.get('/new', async (ctx) => {
15 + ctx.render('books/new');
16 + });
15 module.exports = book; 17 module.exports = book;
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -2,8 +2,11 @@ const Router = require("@koa/router"); ...@@ -2,8 +2,11 @@ const Router = require("@koa/router");
2 const checkLoggedIn = require("../../lib/checkLoggedIn"); 2 const checkLoggedIn = require("../../lib/checkLoggedIn");
3 const pageCtrl = require("./page.ctrl"); 3 const pageCtrl = require("./page.ctrl");
4 const page = new Router(); 4 const page = new Router();
5 - 5 +const Page = require("../../models/page");
6 +const index = require('../../../src/index');
6 //Page api 7 //Page api
8 +
9 +/*
7 page.get('/',pageCtrl.getPage); // show a list of user's pages 10 page.get('/',pageCtrl.getPage); // show a list of user's pages
8 page.post('/',checkLoggedIn,pageCtrl.addPage); // add page 11 page.post('/',checkLoggedIn,pageCtrl.addPage); // add page
9 page.patch('/', checkLoggedIn,pageCtrl.updatePage); // modify page information 12 page.patch('/', checkLoggedIn,pageCtrl.updatePage); // modify page information
...@@ -11,12 +14,60 @@ page.delete('/',checkLoggedIn,pageCtrl.deletePage); // delete book ...@@ -11,12 +14,60 @@ page.delete('/',checkLoggedIn,pageCtrl.deletePage); // delete book
11 14
12 page.get('/search', pageCtrl.search); // /search?title=search_query&petType=petType 15 page.get('/search', pageCtrl.search); // /search?title=search_query&petType=petType
13 //page.post('/search/filter', pageCtrl.searchFilter); //아직 구현 안함 16 //page.post('/search/filter', pageCtrl.searchFilter); //아직 구현 안함
14 -page.post('/detail', pageCtrl.detailPage); // detail recipe page 17 +page.post('/:id', pageCtrl.detailPage); // detail recipe page
15 18
16 //page.get('/recipe/slide', pageCtrl.slidRecipe); // 5 recommended videos in main page 19 //page.get('/recipe/slide', pageCtrl.slidRecipe); // 5 recommended videos in main page
17 20
18 // /recipe/scroll?filter=filter_query&renewal=count (filter_query: 추천순 or 조회순) 21 // /recipe/scroll?filter=filter_query&renewal=count (filter_query: 추천순 or 조회순)
19 page.get('/recipe/scroll', pageCtrl.scrollPage); // video list sorted by 추천순 or 조회순 in main page 22 page.get('/recipe/scroll', pageCtrl.scrollPage); // video list sorted by 추천순 or 조회순 in main page
23 +*/
24 +
25 +
26 + page.get('/', async (ctx) => {
27 +
28 + const page = await Page.find({}).sort({createDate:-1}).exec();
29 + console.log(page);
30 + await ctx.render('posts/index', {page});
31 + });
32 +
33 +
34 + page.get('/new', async (ctx) => {
35 + ctx.render('posts/new');
36 + });
37 +
38 + // create
39 + page.post('/', async (ctx, next) => {
40 + await Page.create(ctx.body);
41 + ctx.redirect('/posts');
42 + });
43 +
44 +
45 +
46 + // show
47 + page.get('/:id', async (ctx, next) => {
48 + const page = await Page.findOne({_id:ctx.params.id});
49 + ctx.render('posts/show', {page});
50 + });
51 +
52 +
53 +// update
54 +page.post('/:id', async (ctx, next) => {
55 + ctx.body.updatedAt = Date.now(); //2
56 + const page = await Page.findOneAndUpdate({_id:ctx.params.id}, ctx.body);
57 + ctx.redirect("/posts/"+ctx.params.id);
58 + });
59 +
60 + // destroy
61 + page.delete('/:id', async (ctx, next) => {
62 + try{
63 + await Page.deleteOne({_id:ctx.params.id})
64 + ctx.redirect('/posts');
65 + }catch(e){
66 + ctx.throw(500, e);
67 + }
68 + });
69 +
70 +
20 71
21 //page.post('/postinfo', pageCtrl.uploadInfo); 72 //page.post('/postinfo', pageCtrl.uploadInfo);
22 //page.get('/info',pageCtrl.getbyurl);//url로 recipe정보 가져오기 (flutter 내 레시피에서 쓰임.) 73 //page.get('/info',pageCtrl.getbyurl);//url로 recipe정보 가져오기 (flutter 내 레시피에서 쓰임.)
......
...@@ -4,6 +4,8 @@ const Book = require("../../models/book"); ...@@ -4,6 +4,8 @@ const Book = require("../../models/book");
4 const Joi = require('@hapi/joi'); 4 const Joi = require('@hapi/joi');
5 const config = require('../../lib/config'); 5 const config = require('../../lib/config');
6 const { Mongoose } = require('mongoose'); 6 const { Mongoose } = require('mongoose');
7 +
8 +
7 exports.search = async (ctx) => { 9 exports.search = async (ctx) => {
8 const { title } = ctx.query; //search word 10 const { title } = ctx.query; //search word
9 console.log(title) 11 console.log(title)
...@@ -19,12 +21,18 @@ exports.search = async (ctx) => { ...@@ -19,12 +21,18 @@ exports.search = async (ctx) => {
19 21
20 22
21 exports.detailPage = async (ctx) => { 23 exports.detailPage = async (ctx) => {
24 + try{
22 var ObjectId = require('mongodb').ObjectId; 25 var ObjectId = require('mongodb').ObjectId;
23 - var id = req.params.page_id; 26 + var id = req.params.id;
24 var o_id = new ObjectId(id); 27 var o_id = new ObjectId(id);
25 const page = await db.Page.find({_id:o_id}); 28 const page = await db.Page.find({_id:o_id});
29 + await ctx.redirect('/api/page/detail/'+req.params.id);
26 ctx.body = page; 30 ctx.body = page;
27 ctx.status = 200; 31 ctx.status = 200;
32 + }catch(e){
33 + ctx.throw(500,e);
34 + }
35 +
28 }; 36 };
29 37
30 // parameters: array with book objects as elements 38 // parameters: array with book objects as elements
...@@ -149,19 +157,21 @@ exports.scrollPage = async (ctx) => { ...@@ -149,19 +157,21 @@ exports.scrollPage = async (ctx) => {
149 else 157 else
150 ctx.request.body.image = "" 158 ctx.request.body.image = ""
151 159
152 - var user = ctx.request.body; //require user id 160 + var page = ctx.request.body;
153 try { 161 try {
154 - const mybook = await Book.findOne({ _id: book._id }); 162 + const mypage = await Page.findOne({ _id: page._id });//require page's _id
163 + if(ctx.state.user._id == mypage.author){
164 + mypage.updateP(book);
165 + ctx.body = mypage;
166 + console.log(mypage);
167 + ctx.status = 200;}
155 168
156 - mybook.updateP(book);
157 -
158 - ctx.body = user._id;
159 } catch (e) { 169 } catch (e) {
160 ctx.throw(500, e); 170 ctx.throw(500, e);
171 + ctx.body = {
172 + message: "작성자가 아닙니다. " }
161 } 173 }
162 - ctx.body = user._id;
163 174
164 - console.log(user);
165 ctx.status = 200; 175 ctx.status = 200;
166 }; 176 };
167 177
...@@ -178,18 +188,3 @@ exports.deletePage = async (ctx) => { ...@@ -178,18 +188,3 @@ exports.deletePage = async (ctx) => {
178 } 188 }
179 ctx.status = 204; // No Content 189 ctx.status = 204; // No Content
180 }; 190 };
181 -
182 -exports.getPage = async (ctx) => {
183 - const pageid = ctx.request.body._id;
184 - try {
185 - const mypage = await Book.findById(pageid).exec();
186 - const user = await User.findById(mypage.author).exec();//작가정보
187 - const author_name = user.nickname;
188 - ctx.body = {mypage,author_name:author_name}
189 - console.log(mypage)
190 -
191 - } catch (e) {
192 - ctx.throw(500, e);
193 - }
194 -
195 -};
......
1 +
2 +$(function(){
3 + function get2digits (num){
4 + return ('0' + num).slice(-2);
5 + }
6 +
7 + function getDate(dateObj){
8 + if(dateObj instanceof Date)
9 + return dateObj.getFullYear() + '-' + get2digits(dateObj.getMonth()+1)+ '-' + get2digits(dateObj.getDate());
10 + }
11 +
12 + function getTime(dateObj){
13 + if(dateObj instanceof Date)
14 + return get2digits(dateObj.getHours()) + ':' + get2digits(dateObj.getMinutes())+ ':' + get2digits(dateObj.getSeconds());
15 + }
16 +
17 + function convertDate(){
18 + $('[data-date]').each(function(index,element){
19 + var dateString = $(element).data('date');
20 + if(dateString){
21 + var date = new Date(dateString);
22 + $(element).html(getDate(date));
23 + }
24 + });
25 + }
26 +
27 + function convertDateTime(){
28 + $('[data-date-time]').each(function(index,element){
29 + var dateString = $(element).data('date-time');
30 + if(dateString){
31 + var date = new Date(dateString);
32 + $(element).html(getDate(date)+' '+getTime(date));
33 + }
34 + });
35 + }
36 +
37 + convertDate();
38 + convertDateTime();
39 + });
...\ No newline at end of file ...\ No newline at end of file
1 +
2 +body {
3 + font-family: 'Open Sans', sans-serif;
4 + }
5 + .breadcrumb-item {
6 + font-size: 0.8em !important;
7 + }
8 + .ellipsis{
9 + display: block;
10 + width: 100%;
11 + white-space: nowrap;
12 + overflow: hidden;
13 + text-overflow: ellipsis; /* 1 */
14 + }
15 +
16 + .board-table {
17 + table-layout: fixed;
18 + }
19 + .board-table .date {
20 + width: 100px;
21 + }
22 +
23 + .post-body{
24 + white-space: pre-line; /* 2 */
25 + }
26 + .post-info{
27 + font-size: 0.8em;
28 + }
...\ No newline at end of file ...\ No newline at end of file
...@@ -9,8 +9,12 @@ const mongoose = require('mongoose'); ...@@ -9,8 +9,12 @@ const mongoose = require('mongoose');
9 const bodyParser = require('koa-bodyparser'); 9 const bodyParser = require('koa-bodyparser');
10 const port = process.env.PORT || 3000 10 const port = process.env.PORT || 3000
11 //443 11 //443
12 +const passport = require('koa-passport')
12 const app = new Koa(); 13 const app = new Koa();
13 const router = new Router() 14 const router = new Router()
15 +const render = require('koa-ejs');
16 +const path = require('path');
17 +
14 const send = require('koa-send'); 18 const send = require('koa-send');
15 var options = { 19 var options = {
16 key: fs.readFileSync('./server.key'), 20 key: fs.readFileSync('./server.key'),
...@@ -29,53 +33,72 @@ mongoose.connect(process.env.MONGO_URI).then( ...@@ -29,53 +33,72 @@ mongoose.connect(process.env.MONGO_URI).then(
29 console.error(e); 33 console.error(e);
30 }); 34 });
31 35
32 -var readFileThunk = function(src) { 36 +
33 - return new Promise(function (resolve, reject) {
34 - fs.readFile(src, {'encoding': 'utf8'}, function (err, data) {
35 - if(err) return reject(err);
36 - resolve(data);
37 - });
38 - });
39 -}
40 //app.use(router.routes()) 37 //app.use(router.routes())
41 /* 38 /*
42 app 39 app
43 .use(router.routes()) 40 .use(router.routes())
44 .use(router.allowedMethods()); 41 .use(router.allowedMethods());
45 */ 42 */
43 +
44 + render(app, {
45 + root: path.join(__dirname, 'views'),
46 + layout: false,
47 + viewExt: 'ejs',
48 + cache: false,
49 + debug: true
50 + });
51 +// app.use(async function (ctx) {
52 + // await ctx.render('home/welcome');
53 + // });
46 app 54 app
47 .use(jwtMiddleware) 55 .use(jwtMiddleware)
48 .use(bodyParser()) // bodyParser는 라우터 코드보다 상단에 있어야 합니다. 56 .use(bodyParser()) // bodyParser는 라우터 코드보다 상단에 있어야 합니다.
49 .use(router.routes()) 57 .use(router.routes())
50 - .use(router.allowedMethods()); 58 + .use(router.allowedMethods())
59 + .use(passport.initialize());
51 60
52 61
62 + router.get('/', async ctx =>{
63 + await ctx.render('home/welcome');
64 +});
53 65
54 -/* 66 +router.get('/about', async ctx =>{
55 -router.get('/', (ctx, next) => { 67 + await ctx.render('home/about');
56 - ctx.body = '루트 페이지 입니다.'; 68 +});
69 +
70 +router.get('/login', async ctx =>{
71 + await ctx.render('users/index');
57 }); 72 });
58 -*/ 73 +
74 +router.get('/signup', async ctx =>{
75 + await ctx.render('users/new');
76 +});
77 +
78 +
79 +
80 +
59 /* 81 /*
60 router.get('/', async (ctx, next) => { 82 router.get('/', async (ctx, next) => {
61 const rawContent = fs.readFileSync('index.html').toString('utf8') 83 const rawContent = fs.readFileSync('index.html').toString('utf8')
62 ctx.body = rawContent 84 ctx.body = rawContent
63 })*/ 85 })*/
64 86
65 -router.get('/', function *(){ 87 +
66 - this.body = yield readFileThunk(__dirname + '/public/index.html');
67 -})
68 //router.use(api.routes()); 88 //router.use(api.routes());
69 //app.use(router.routes()).use(router.allowedMethods()) 89 //app.use(router.routes()).use(router.allowedMethods())
70 router.use('/api', api.routes()); 90 router.use('/api', api.routes());
71 -app.use(router.routes()).use(router.allowedMethods()); 91 +//app.use(router.routes()).use(router.allowedMethods());
92 +
72 93
73 http2 94 http2
74 .createSecureServer(options, app.callback()) 95 .createSecureServer(options, app.callback())
75 .listen(port, () => console.log("listening on port %i", port)); 96 .listen(port, () => console.log("listening on port %i", port));
76 -//app.listen(port, function () {
77 -//console.log('server listening on port %d', port);
78 - //});
79 97
98 +/*
99 + app.listen(port, function () {
100 +console.log('server listening on port %d', port);
101 + });
80 102
81 103
104 + */
...\ No newline at end of file ...\ No newline at end of file
......
1 const config = { 1 const config = {
2 mailer: { 2 mailer: {
3 - user: "yoobinpark@khu.ac.kr", 3 + user: "like01test@gmail.com",
4 - password: "1q2w3e4r!@", 4 + password: "like1412",
5 expiresIn: 60 * 5, 5 expiresIn: 60 * 5,
6 }, 6 },
7 }; 7 };
......
...@@ -5,9 +5,9 @@ const { Schema } = mongoose; ...@@ -5,9 +5,9 @@ const { Schema } = mongoose;
5 5
6 const bookSchema = new Schema({ 6 const bookSchema = new Schema({
7 id: mongoose.Schema.Types.ObjectId,//unique number of page 7 id: mongoose.Schema.Types.ObjectId,//unique number of page
8 - pages:[{type:String}],//book contains several pages. pages is the list of page id 8 + pages:[{type:mongoose.Schema.Types.ObjectId, ref:'page', required:false}],//book contains several pages. pages is the list of page id
9 title: {type:String, require:true}, // book title 9 title: {type:String, require:true}, // book title
10 - author: [{type:String, require:true, default:user.user}],//작가복수 가능 10 + author: [{type:mongoose.Schema.Types.ObjectId, ref:'user', required:true}],//작가복수 가능
11 contents: {type:String}, // book subtitle or detail 11 contents: {type:String}, // book subtitle or detail
12 createDate: {type:Date, require:true, default:Date.now}, 12 createDate: {type:Date, require:true, default:Date.now},
13 updateDate: {type:Date, default:Date.now}, 13 updateDate: {type:Date, default:Date.now},
...@@ -103,4 +103,5 @@ const bookSchema = new Schema({ ...@@ -103,4 +103,5 @@ const bookSchema = new Schema({
103 103
104 104
105 105
106 +
106 module.exports = mongoose.model("Book", bookSchema); 107 module.exports = mongoose.model("Book", bookSchema);
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -4,9 +4,9 @@ const { Schema } = mongoose; ...@@ -4,9 +4,9 @@ const { Schema } = mongoose;
4 4
5 const PageSchema = new Schema({ 5 const PageSchema = new Schema({
6 id: mongoose.Schema.Types.ObjectId,//unique number of page 6 id: mongoose.Schema.Types.ObjectId,//unique number of page
7 - book:{type:String},//book contains several pages 7 + book:[{type:mongoose.Schema.Types.ObjectId, ref:'book', required:false}],//book contains several pages
8 title: {type:String, require:true}, // title of post 8 title: {type:String, require:true}, // title of post
9 - author: [{type:String, require:true, default:user.user}], 9 + author: [{type:mongoose.Schema.Types.ObjectId, ref:'user', required:true}],
10 contents: {type:String}, // contents of page 10 contents: {type:String}, // contents of page
11 createDate: {type:Date, require:true, default:Date.now}, 11 createDate: {type:Date, require:true, default:Date.now},
12 updateDate: {type:Date, default:Date.now}, 12 updateDate: {type:Date, default:Date.now},
......
...@@ -12,10 +12,10 @@ const UserSchema = new Schema({ ...@@ -12,10 +12,10 @@ const UserSchema = new Schema({
12 password: String, 12 password: String,
13 token: String, 13 token: String,
14 //user info 14 //user info
15 - username: String,
16 phone: {type: String, require: true}, 15 phone: {type: String, require: true},
17 nickname: {type: String, default: ""}, 16 nickname: {type: String, default: ""},
18 - books: [{type: String}],//array of bookid 17 + books: [{type:mongoose.Schema.Types.ObjectId, ref:'book', required:false}],//array of bookid
18 + pages:[{type:mongoose.Schema.Types.ObjectId, ref:'page', required:false}],
19 favorite: [{ type: String }],//String of url(book, page) 19 favorite: [{ type: String }],//String of url(book, page)
20 }); 20 });
21 21
......
1 +<head>
2 + <%- include('../partials/head') %>
3 + </head>
4 + <body>
5 + <%- include('../partials/nav') %>
6 +
7 + <div class="container mb-3">
8 +
9 + <nav aria-label="breadcrumb">
10 + <ol class="breadcrumb p-1 pl-2 pr-2">
11 + <li class="breadcrumb-item"><a href="/">Home</a></li>
12 + <li class="breadcrumb-item"><a href="/api/page">Board</a></li>
13 + <li class="breadcrumb-item"><a href="/api/page/<%= page._id %>"><%= page.title %></a></li>
14 + <li class="breadcrumb-item active" aria-current="page">Edit Post</li>
15 + </ol>
16 + </nav>
17 +
18 + <form action="/api/page/<%= page._id %>?_method=put" method="post">
19 +
20 + <div class="form-group">
21 + <label for="title">Title</label>
22 + <input type="text" id="title" name="title" value="<%= page.title %>" class="form-control">
23 + </div>
24 +
25 + <div class="form-group">
26 + <label for="body">Body</label>
27 + <textarea id="body" name="body" rows="5" class="form-control"><%= post.contents %></textarea>
28 + </div>
29 +
30 + <div>
31 + <a class="btn btn-primary" href="/api/page/<%= page._id %>">Back</a>
32 + <button type="submit" class="btn btn-primary">Submit</button>
33 + </div>
34 +
35 + </form>
36 +
37 + </div>
38 + </body>
39 +</html>
...\ No newline at end of file ...\ No newline at end of file
1 +<!DOCTYPE html>
2 +<html>
3 + <head>
4 + <%- include('../partials/head') %>
5 + </head>
6 + <body>
7 + <%- include('../partials/nav') %>
8 +
9 + <div class="container mb-3">
10 +
11 + <h2 class="mb-3">Board</h2>
12 +
13 + <table class="board-table table table-sm border-bottom">
14 +
15 + <thead class="thead-light">
16 + <tr>
17 + <th scope="col">Title</th>
18 + <th scope="col" class="date">Date</th>
19 + </tr>
20 + </thead>
21 +
22 + <tbody>
23 + <% if(page == null || page.length == 0){ %>
24 + <tr>
25 + <td colspan=2> There is no data to show :( </td>
26 + </tr>
27 + <% } %>
28 + <% page.forEach(function(page) { %>
29 + <tr>
30 + <td>
31 + <a href="/api/page/<%= page._id %>"><div class="ellipsis"><%= page.title %></div></a>
32 + </td>
33 + <td class="date">
34 + <span data-date="<%= page.createDate %>"></span> <!-- 1 -->
35 + </td>
36 + </tr>
37 + <% }) %>
38 + </tbody>
39 +
40 + </table>
41 +
42 + <div>
43 + <a class="btn btn-primary" href="/api/page/new">New</a>
44 + </div>
45 +
46 + </div>
47 + </body>
48 +</html>
...\ No newline at end of file ...\ No newline at end of file
1 +<!DOCTYPE html>
2 +<html>
3 + <head>
4 + <%- include('../partials/head') %>
5 + </head>
6 + <body>
7 + <%- include('../partials/nav') %>
8 +
9 + <div class="container mb-3">
10 +
11 + <nav aria-label="breadcrumb"> <!-- 1 -->
12 + <ol class="breadcrumb p-1 pl-2 pr-2">
13 + <li class="breadcrumb-item"><a href="/">Home</a></li>
14 + <li class="breadcrumb-item"><a href="/api/page">Board</a></li>
15 + <li class="breadcrumb-item active" aria-current="page">New Post</li>
16 + </ol>
17 + </nav>
18 +
19 + <form action="/api/page/" method="post">
20 +
21 + <div class="form-group">
22 + <label for="title">Title</label>
23 + <input type="text" id="title" name="title" value="" class="form-control">
24 + </div>
25 +
26 + <div class="form-group">
27 + <label for="body">Body</label>
28 + <textarea id="body" name="body" rows="5" class="form-control"></textarea>
29 + </div>
30 +
31 + <div>
32 + <a class="btn btn-primary" href="/api/page">Back</a>
33 + <button type="submit" class="btn btn-primary">Submit</button>
34 + </div>
35 +
36 + </form>
37 +
38 + </div>
39 + </body>
40 +</html>
...\ No newline at end of file ...\ No newline at end of file
1 +<!DOCTYPE html>
2 +<html>
3 + <head>
4 + <%- include('../partials/head') %>
5 + </head>
6 + <body>
7 + <%- include('../partials/nav') %>
8 +
9 + <div class="container mb-3">
10 +
11 + <nav aria-label="breadcrumb">
12 + <ol class="breadcrumb p-1 pl-2 pr-2">
13 + <li class="breadcrumb-item"><a href="/">Home</a></li>
14 + <li class="breadcrumb-item"><a href="/api/book">Book</a></li>
15 + <li class="breadcrumb-item active" aria-current="page"><%= page.title %></li>
16 + </ol>
17 + </nav>
18 +
19 + <div class="card">
20 + <h5 class="card-header p-2"><%= page.title %></h5>
21 + <div class="row"> <!-- 1 -->
22 +
23 + <div class="col-md-7 col-lg-8 col-xl-9 order-sm-2 order-md-1"> <!-- 1 -->
24 + <div class="post-body p-2"><%= page.contents %></div>
25 + </div>
26 +
27 + <div class="col-md-5 col-lg-4 col-xl-3 order-sm-1 order-md-2"> <!-- 1 -->
28 + <div class="post-info card m-2 p-2">
29 + <div><span>Created</span> : <span data-date-time="<%= page.createDate %>"></span></div> <!-- 2 -->
30 + <% if(page.updateDate) { %>
31 + <div><span>Updated</span> : <span data-date-time="<%= page.updateDate %>"></span></div> <!-- 2 -->
32 + <% } %>
33 + </div>
34 + </div>
35 +
36 + </div>
37 + </div>
38 +
39 + <div class="mt-3">
40 + <a class="btn btn-primary" href="/api/page">Back</a>
41 + <a class="btn btn-primary" href="/api/page/<%= page._id %>/edit">Edit</a>
42 + <form action="/api/page/<%= page._id %>?_method=delete" method="post" class="d-inline">
43 + <a class="btn btn-primary" href="javascript:void(0)" onclick="confirm('Do you want to delete this?')?this.parentElement.submit():null;">Delete</a>
44 + </form>
45 + </div>
46 +
47 + </div>
48 + </body>
49 +</html>
...\ No newline at end of file ...\ No newline at end of file
1 +<!DOCTYPE html>
2 +<html>
3 + <head>
4 + <%- include('../partials/head') %>
5 + </head>
6 + <body>
7 + <%- include('../partials/nav') %>
8 +
9 + <div class="container mb-3">
10 +
11 + <h2 class="mb-3">About</h2>
12 +
13 + <P>이 사이트는 Like Project 임시 페이지 입니다. </p>
14 +
15 + </div>
16 + </body>
17 +</html>
...\ No newline at end of file ...\ No newline at end of file
1 +<!DOCTYPE html>
2 +<html>
3 + <head>
4 + <%- include('../partials/head') %>
5 + </head>
6 + <body>
7 + <%- include('../partials/nav') %>
8 +
9 + <div class="container">
10 +
11 + <h3 class="mb-3">Login</h3>
12 +
13 + <form class="user-form" action="/login" method="post">
14 +
15 + <div class="form-group row">
16 + <label for="username" class="col-sm-3 col-form-label">Username</label>
17 + <div class="col-sm-9">
18 + <input type="text" id="username" name="username" value="<%= username %>" class="form-control <%= (errors.username)?'is-invalid':'' %>">
19 + <% if(errors.username){ %>
20 + <span class="invalid-feedback"><%= errors.username %></span>
21 + <% } %>
22 + </div>
23 + </div>
24 +
25 + <div class="form-group row">
26 + <label for="password" class="col-sm-3 col-form-label">Password</label>
27 + <div class="col-sm-9">
28 + <input type="password" id="password" name="password" value="" class="form-control <%= (errors.password)?'is-invalid':'' %>">
29 + <% if(errors.password){ %>
30 + <span class="invalid-feedback"><%= errors.password %></span>
31 + <% } %>
32 + </div>
33 + </div>
34 +
35 + <% if(errors.login){ %>
36 + <div class="invalid-feedback d-block"><%= errors.login %></div>
37 + <% } %>
38 +
39 + <div class="mt-3">
40 + <input class="btn btn-primary" type="submit" value="Submit">
41 + </div>
42 +
43 + </form>
44 +
45 + </div>
46 + </body>
47 +</html>
...\ No newline at end of file ...\ No newline at end of file
1 +<!DOCTYPE html>
2 +<html>
3 + <head>
4 + <%- include('../partials/head') %>
5 + </head>
6 + <body>
7 + <%- include('../partials/nav') %>
8 +
9 + <div class="container mb-3">
10 +
11 + <div class="jumbotron">
12 + <h1>My Website</h1>
13 + <P>제 웹사이트를 방문해 주셔서 감사합니다!</p>
14 + </div>
15 +
16 + </div>
17 + </body>
18 +</html>
...\ No newline at end of file ...\ No newline at end of file
1 +<!-- views/partials/head.ejs -->
2 +
3 +<meta name="viewport" content="width=device-width,initial-scale=1">
4 +
5 +<!-- jquery & bootstrap -->
6 +<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
7 +<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
8 +<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
9 +<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
10 +
11 +<!-- web font --> <!-- 1 -->
12 +<link href="https://fonts.googleapis.com/css?family=Open+Sans&display=swap" rel="stylesheet">
13 +
14 +<!-- my css -->
15 +<script src="/src/api/page/script.js"></script>
16 +
17 +<title>My Website</title>
...\ No newline at end of file ...\ No newline at end of file
1 +<nav class="navbar navbar-expand-sm navbar-light bg-light mb-3">
2 + <div class="container">
3 + <div class="navbar-brand"></a>Like</div>
4 + <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent">
5 + <span class="navbar-toggler-icon"></span>
6 + </button>
7 + <div class="collapse navbar-collapse" id="navbarSupportedContent">
8 + <ul class="navbar-nav">
9 + <li class="nav-item"><a href="/" class="nav-link">Home</a></li>
10 + <li class="nav-item"><a href="/about" class="nav-link">About</a></li>
11 + <li class="nav-item"><a href="/api/book" class="nav-link">Book</a></li>
12 + <li class="nav-item"><a href="/api/page" class="nav-link">Page</a></li>
13 + </ul>
14 + <ul class="navbar-nav ml-auto">
15 +
16 + <li class="nav-item"><a href="/api/auth" class="nav-link">Sign Up</a></li>
17 + <li class="nav-item"><a href="/api/auth/new" class="nav-link">Login</a></li>
18 +
19 + </ul>
20 + </div>
21 + </div>
22 + </nav>
...\ No newline at end of file ...\ No newline at end of file
1 +<!DOCTYPE html>
2 +<html>
3 + <head>
4 + <%- include('../partials/head') %>
5 + </head>
6 + <body>
7 + <%- include('../partials/nav') %>
8 +
9 + <div class="container mb-3">
10 +
11 + <nav aria-label="breadcrumb">
12 + <ol class="breadcrumb p-1 pl-2 pr-2">
13 + <li class="breadcrumb-item"><a href="/">Home</a></li>
14 + <li class="breadcrumb-item"><a href="/api/page">Board</a></li>
15 + <li class="breadcrumb-item"><a href="/api/page/<%= page._id %>"><%= page.title %></a></li>
16 + <li class="breadcrumb-item active" aria-current="page">Edit Post</li>
17 + </ol>
18 + </nav>
19 +
20 + <form action="/api/page/<%= page._id %>?_method=put" method="post">
21 +
22 + <div class="form-group">
23 + <label for="title">Title</label>
24 + <input type="text" id="title" name="title" value="<%= page.title %>" class="form-control">
25 + </div>
26 +
27 + <div class="form-group">
28 + <label for="body">Body</label>
29 + <textarea id="body" name="body" rows="5" class="form-control"><%= post.contents %></textarea>
30 + </div>
31 +
32 + <div>
33 + <a class="btn btn-primary" href="/api/page/<%= page._id %>">Back</a>
34 + <button type="submit" class="btn btn-primary">Submit</button>
35 + </div>
36 +
37 + </form>
38 +
39 + </div>
40 + </body>
41 +</html>
...\ No newline at end of file ...\ No newline at end of file
1 +<!-- views/posts/index.ejs -->
2 +
3 +<!DOCTYPE html>
4 +<html>
5 + <head>
6 + <%- include('../partials/head') %>
7 + </head>
8 + <body>
9 + <%- include('../partials/nav') %>
10 +
11 + <div class="container mb-3">
12 +
13 + <h2 class="mb-3">Board</h2>
14 +
15 + <table class="board-table table table-sm border-bottom">
16 +
17 + <thead class="thead-light">
18 + <tr>
19 + <th scope="col">Title</th>
20 + <th scope="col" class="date">Date</th>
21 + </tr>
22 + </thead>
23 +
24 + <tbody>
25 + <% if(page == null || page.length == 0){ %>
26 + <tr>
27 + <td colspan=2> There is no data to show :( </td>
28 + </tr>
29 + <% } %>
30 + <% page.forEach(function(page) { %>
31 + <tr>
32 + <td>
33 + <a href="/api/page/<%= page._id %>"><div class="ellipsis"><%= page.title %></div></a>
34 + </td>
35 + <td class="date">
36 + <span data-date="<%= page.createDate %>"></span> <!-- 1 -->
37 + </td>
38 + </tr>
39 + <% }) %>
40 + </tbody>
41 +
42 + </table>
43 +
44 + <div>
45 + <a class="btn btn-primary" href="/api/page/new">New</a>
46 + </div>
47 +
48 + </div>
49 + </body>
50 +</html>
...\ No newline at end of file ...\ No newline at end of file
1 +<!DOCTYPE html>
2 +<html>
3 + <head>
4 + <%- include('../partials/head') %>
5 + </head>
6 + <body>
7 + <%- include('../partials/nav') %>
8 +
9 + <div class="container mb-3">
10 +
11 + <nav aria-label="breadcrumb"> <!-- 1 -->
12 + <ol class="breadcrumb p-1 pl-2 pr-2">
13 + <li class="breadcrumb-item"><a href="/">Home</a></li>
14 + <li class="breadcrumb-item"><a href="/api/page">Board</a></li>
15 + <li class="breadcrumb-item active" aria-current="page">New Post</li>
16 + </ol>
17 + </nav>
18 +
19 + <form action="/api/page/" method="post">
20 +
21 + <div class="form-group">
22 + <label for="title">Title</label>
23 + <input type="text" id="title" name="title" value="" class="form-control">
24 + </div>
25 +
26 + <div class="form-group">
27 + <label for="body">Body</label>
28 + <textarea id="body" name="body" rows="5" class="form-control"></textarea>
29 + </div>
30 +
31 + <div>
32 + <a class="btn btn-primary" href="/api/page">Back</a>
33 + <button type="submit" class="btn btn-primary">Submit</button>
34 + </div>
35 +
36 + </form>
37 +
38 + </div>
39 + </body>
40 +</html>
...\ No newline at end of file ...\ No newline at end of file
1 +
2 +<!DOCTYPE html>
3 +<html>
4 + <head>
5 + <%- include('../partials/head') %>
6 + </head>
7 + <body>
8 + <%- include('../partials/nav') %>
9 +
10 + <div class="container mb-3">
11 +
12 + <nav aria-label="breadcrumb">
13 + <ol class="breadcrumb p-1 pl-2 pr-2">
14 + <li class="breadcrumb-item"><a href="/">Home</a></li>
15 + <li class="breadcrumb-item"><a href="/api/book">Book</a></li>
16 + <li class="breadcrumb-item active" aria-current="page"><%= page.title %></li>
17 + </ol>
18 + </nav>
19 +
20 + <div class="card">
21 + <h5 class="card-header p-2"><%= page.title %></h5>
22 + <div class="row"> <!-- 1 -->
23 +
24 + <div class="col-md-7 col-lg-8 col-xl-9 order-sm-2 order-md-1"> <!-- 1 -->
25 + <div class="post-body p-2"><%= page.contents %></div>
26 + </div>
27 +
28 + <div class="col-md-5 col-lg-4 col-xl-3 order-sm-1 order-md-2"> <!-- 1 -->
29 + <div class="post-info card m-2 p-2">
30 + <div><span>Created</span> : <span data-date-time="<%= page.createDate %>"></span></div> <!-- 2 -->
31 + <% if(page.updateDate) { %>
32 + <div><span>Updated</span> : <span data-date-time="<%= page.updateDate %>"></span></div> <!-- 2 -->
33 + <% } %>
34 + </div>
35 + </div>
36 +
37 + </div>
38 + </div>
39 +
40 + <div class="mt-3">
41 + <a class="btn btn-primary" href="/api/page">Back</a>
42 + <a class="btn btn-primary" href="/api/page/<%= page._id %>/edit">Edit</a>
43 + <form action="/api/page/<%= page._id %>?_method=delete" method="post" class="d-inline">
44 + <a class="btn btn-primary" href="javascript:void(0)" onclick="confirm('Do you want to delete this?')?this.parentElement.submit():null;">Delete</a>
45 + </form>
46 + </div>
47 +
48 + </div>
49 + </body>
50 +</html>
...\ No newline at end of file ...\ No newline at end of file
1 +
2 +<!DOCTYPE html>
3 +<html>
4 + <head>
5 + <%- include('../partials/head') %>
6 + </head>
7 + <body>
8 + <%- include('../partials/nav') %>
9 +
10 + <div class="container mb-3">
11 +
12 + <h3 class="mb-3">Edit User</h3>
13 +
14 + <form action="/api/auth/users/<%= user.username %>?_method=put" method="post">
15 +
16 + <div class="form-group row">
17 + <label for="currentPassword" class="col-sm-3 col-form-label">Current Password*</label>
18 + <div class="col-sm-9 col-sm-offset-3">
19 + <input type="password" id="currentPassword" name="currentPassword" value="" class="form-control">
20 + </div>
21 + </div>
22 +
23 + <hr></hr>
24 +
25 + <div class="form-group row">
26 + <label for="username" class="col-sm-3 col-form-label">Username*</label>
27 + <div class="col-sm-9">
28 + <input type="text" id="username" name="username" value="<%= user.nickname %>" class="form-control">
29 + </div>
30 + </div>
31 +
32 + <div class="form-group row">
33 + <label for="name" class="col-sm-3 col-form-label">Name*</label>
34 + <div class="col-sm-9">
35 + <input type="text" id="name" name="name" value="<%= user.email %>" class="form-control">
36 + </div>
37 + </div>
38 +
39 + <div class="form-group row">
40 + <label for="email" class="col-sm-3 col-form-label">Email</label>
41 + <div class="col-sm-9">
42 + <input type="text" id="email" name="email" value="<%= user.email %>" class="form-control">
43 + </div>
44 + </div>
45 +
46 + <div class="form-group row">
47 + <label for="newPassword" class="col-sm-3 col-form-label">New Password</label>
48 + <div class="col-sm-9 col-sm-offset-3">
49 + <input type="password" id="newPassword" name="newPassword" value="" class="form-control">
50 + </div>
51 + </div>
52 +
53 + <div class="form-group row">
54 + <label for="passwordConfirmation" class="col-sm-3 col-form-label">Password Confirmation</label>
55 + <div class="col-sm-9 col-sm-offset-3">
56 + <input type="password" id="passwordConfirmation" name="passwordConfirmation" value="" class="form-control">
57 + </div>
58 + </div>
59 +
60 + <p>
61 + <small>*Required</small>
62 + </p>
63 +
64 + <div class="buttons">
65 + <a class="btn btn-primary" href="/api/auth/users/<%= user.username %>">Back</a>
66 + <button type="submit" class="btn btn-primary">Submit</button>
67 + </div>
68 +
69 + </form>
70 +
71 + </div>
72 + </body>
73 +</html>
...\ No newline at end of file ...\ No newline at end of file
1 +
2 +<!DOCTYPE html>
3 +<html>
4 + <head>
5 + <%- include('../partials/head') %>
6 + </head>
7 + <body>
8 + <%- include('../partials/nav') %>
9 +
10 + <div class="container mb-3">
11 +
12 + <h3 class="mb-3">Users</h3>
13 +
14 + <ul class="list-group">
15 + <% if(user == null || user.length == 0){ %>
16 + <li class="list-group-item"> There is no user yet.</li>
17 + <% } %>
18 + <% user.forEach(function(user) { %>
19 + <li class="list-group-item">
20 + <a href="/api/auth/userlist/<%= user._id %>"><%= user.nickname %></a>
21 + </li>
22 + <% }) %>
23 + </ul>
24 +
25 + </div>
26 + </body>
27 +</html>
...\ No newline at end of file ...\ No newline at end of file
1 +
2 +
3 +<!DOCTYPE html>
4 +<html>
5 + <head>
6 + <%- include('../partials/head') %>
7 + </head>
8 + <body>
9 + <%- include('../partials/nav') %>
10 +
11 + <div class="container mb-3">
12 +
13 + <h3 class="contentBoxTop mb-3">New User</h3>
14 +
15 + <form action="/api/auth/signin" method="post">
16 +
17 + <div class="form-group row">
18 + <label for="nickname" class="col-sm-3 col-form-label">Username*</label>
19 + <div class="col-sm-9">
20 + <input type="text" id="nickname" name="nickname" value="" class="form-control">
21 + </div>
22 + </div>
23 + <div class="form-group row">
24 + <label for="email" class="col-sm-3 col-form-label">Email</label>
25 + <div class="col-sm-9">
26 + <input type="text" id="email" name="email" value="" class="form-control">
27 + </div>
28 + </div>
29 + <div class="form-group row">
30 + <label for="password" class="col-sm-3 col-form-label">Password*</label>
31 + <div class="col-sm-9">
32 + <input type="password" id="password" name="password" value="" class="form-control">
33 + </div>
34 + </div>
35 + <div class="form-group row">
36 + <label for="passwordConfirmation" class="col-sm-3 col-form-label">Password Confirmation*</label>
37 + <div class="col-sm-9 col-sm-offset-3">
38 + <input type="password" id="passwordConfirmation" name="passwordConfirmation" value="" class="form-control">
39 + </div>
40 + </div>
41 + <p>
42 + <small>*Required</small>
43 + </p>
44 +
45 + <div class="form-group">
46 + <button type="submit" class="btn btn-primary">Submit</button>
47 + </div>
48 + </form>
49 +
50 + </div>
51 + </body>
52 +</html>
...\ No newline at end of file ...\ No newline at end of file
1 +
2 +
3 +<!DOCTYPE html>
4 +<html>
5 + <head>
6 + <%- include('../partials/head') %>
7 + </head>
8 + <body>
9 + <%- include('../partials/nav') %>
10 +
11 + <div class="container mb-3">
12 +
13 + <h3 class="contentBoxTop"><%= user.nickname</h3>
14 +
15 + <form class="user-form" action="/users" method="post">
16 + <fieldset disabled>
17 + <div class="form-group row">
18 + <label for="name" class="col-sm-3 col-form-label">Name</label>
19 + <div class="col-sm-9">
20 + <input class="form-control" type="text" id="name" name="name" value="<%= user.name %>">
21 + </div>
22 + </div>
23 + <div class="form-group row">
24 + <label for="email" class="col-sm-3 col-form-label">Email</label>
25 + <div class="col-sm-9">
26 + <input class="form-control" type="text" id="email" name="email" value="<%= user.email %>">
27 + </div>
28 + </div>
29 + </fieldset>
30 + </form>
31 +
32 + <div>
33 + <a class="btn btn-primary" href="/api/auth/users">Back</a>
34 + <a class="btn btn-primary" href="/api/auth/users/<%= user.email %>/edit">Edit</a>
35 + <form action="/users/<%= user.email %>?_method=delete" method="post" class="d-inline">
36 + <a class="btn btn-primary" href="javascript:void(0)" onclick="confirm('Do you want to delete this?')?this.parentElement.submit():null;">Delete</a>
37 + </form>
38 + </div>
39 +
40 + </div>
41 + </body>
42 +</html>
...\ No newline at end of file ...\ No newline at end of file