Showing
18 changed files
with
223 additions
and
97 deletions
... | @@ -84,10 +84,10 @@ app | ... | @@ -84,10 +84,10 @@ app |
84 | }); | 84 | }); |
85 | 85 | ||
86 | router.get('/about', async ctx =>{ | 86 | router.get('/about', async ctx =>{ |
87 | - ctx.render('home/about'); | 87 | + await ctx.render('home/about'); |
88 | }); | 88 | }); |
89 | router.get('/auth', async ctx =>{ | 89 | router.get('/auth', async ctx =>{ |
90 | - ctx.render('users/login'); | 90 | + await ctx.render('users/login'); |
91 | }); | 91 | }); |
92 | 92 | ||
93 | //router.use('/', api.routes()); | 93 | //router.use('/', api.routes()); | ... | ... |
... | @@ -8,7 +8,7 @@ const bookSchema = new Schema({ | ... | @@ -8,7 +8,7 @@ const bookSchema = new Schema({ |
8 | pages:[{type:mongoose.Schema.Types.ObjectId, ref:'page', required:false}],//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:mongoose.Schema.Types.ObjectId, ref:'user', required:true}],//작가복수 가능 | 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}, |
14 | views: {type: Number, default: 0},//how many people open this book | 14 | views: {type: Number, default: 0},//how many people open this book | ... | ... |
... | @@ -3,6 +3,7 @@ var Schema = mongoose.Schema; | ... | @@ -3,6 +3,7 @@ var Schema = mongoose.Schema; |
3 | const bcrypt = require("bcrypt"); | 3 | const bcrypt = require("bcrypt"); |
4 | const jwt = require("jsonwebtoken"); | 4 | const jwt = require("jsonwebtoken"); |
5 | const crypto = require('crypto'); | 5 | const crypto = require('crypto'); |
6 | +const { exist, allow } = require('@hapi/joi'); | ||
6 | //const Pet = require("./pet"); | 7 | //const Pet = require("./pet"); |
7 | 8 | ||
8 | const UserSchema = new Schema({ | 9 | const UserSchema = new Schema({ | ... | ... |
... | @@ -237,3 +237,7 @@ input[type="password"] { | ... | @@ -237,3 +237,7 @@ input[type="password"] { |
237 | border-top-left-radius: 0; | 237 | border-top-left-radius: 0; |
238 | border-top-right-radius: 0; | 238 | border-top-right-radius: 0; |
239 | } | 239 | } |
240 | + | ||
241 | +.user-form { | ||
242 | + width: 400px; | ||
243 | +} | ||
... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
... | @@ -2,15 +2,18 @@ const Router = require("@koa/router"); | ... | @@ -2,15 +2,18 @@ const Router = require("@koa/router"); |
2 | const checkLoggedIn = require("../../src/lib/checkLoggedIn"); | 2 | const checkLoggedIn = require("../../src/lib/checkLoggedIn"); |
3 | //const bookCtrl = require("./book.ctrl"); | 3 | //const bookCtrl = require("./book.ctrl"); |
4 | const book = new Router(); | 4 | const book = new Router(); |
5 | -const User = require("../models/user") | 5 | +const User = require("../models/user"); |
6 | const Book = require("../models/book"); | 6 | const Book = require("../models/book"); |
7 | +const Joi = require('@hapi/joi'); | ||
7 | //북id params로 전달. Render books/show | 8 | //북id params로 전달. Render books/show |
8 | book.get('/:id', async (ctx) => { | 9 | book.get('/:id', async (ctx) => { |
9 | const bookid = ctx.params.id;//bookid by parameter | 10 | const bookid = ctx.params.id;//bookid by parameter |
10 | console.log(bookid); | 11 | console.log(bookid); |
11 | try { | 12 | try { |
12 | const book = await Book.findOne({_id:ctx.params.id}); | 13 | const book = await Book.findOne({_id:ctx.params.id}); |
13 | - ctx.render('books/show', {book}); | 14 | + const page = await Page.findById(book.pages); |
15 | + const user = await User.findById(book.author).exec(); | ||
16 | + await ctx.render('books/show', {book,user,page}); | ||
14 | //ctx.body.authorname = user.nickname; | 17 | //ctx.body.authorname = user.nickname; |
15 | //ctx.body = mybook; | 18 | //ctx.body = mybook; |
16 | } catch (e) { | 19 | } catch (e) { |
... | @@ -55,7 +58,7 @@ book.post('/',checkLoggedIn,async (ctx) => { | ... | @@ -55,7 +58,7 @@ book.post('/',checkLoggedIn,async (ctx) => { |
55 | if (err) throw err; | 58 | if (err) throw err; |
56 | const user = await User.findById(ctx.state.user._id).exec(); | 59 | const user = await User.findById(ctx.state.user._id).exec(); |
57 | console.log(book._id); | 60 | console.log(book._id); |
58 | - ctx.redirect('/books'); | 61 | + await ctx.redirect('/books'); |
59 | }); | 62 | }); |
60 | } catch (e) { | 63 | } catch (e) { |
61 | ctx.throw(500, e); | 64 | ctx.throw(500, e); |
... | @@ -127,7 +130,7 @@ book.delete('/:id',checkLoggedIn,async (ctx) => { | ... | @@ -127,7 +130,7 @@ book.delete('/:id',checkLoggedIn,async (ctx) => { |
127 | book.get('/',async (ctx) => { | 130 | book.get('/',async (ctx) => { |
128 | try { | 131 | try { |
129 | const books = await Book.find({}).sort({createDate: -1}).exec(); | 132 | const books = await Book.find({}).sort({createDate: -1}).exec(); |
130 | - ctx.render('books/index', {books:books}); | 133 | + await ctx.render('books/index', {books:books}); |
131 | } catch (e) { | 134 | } catch (e) { |
132 | return ctx.throw(500, e); | 135 | return ctx.throw(500, e); |
133 | } | 136 | } |
... | @@ -149,6 +152,21 @@ book.get('/search', async (ctx) => { | ... | @@ -149,6 +152,21 @@ book.get('/search', async (ctx) => { |
149 | }); | 152 | }); |
150 | 153 | ||
151 | book.get('/new', async (ctx) => { | 154 | book.get('/new', async (ctx) => { |
152 | - ctx.render('books/new'); | 155 | + try{ |
156 | + await ctx.render('books/new'); | ||
157 | + }catch(e){ | ||
158 | + ctx.throw(500, e); | ||
159 | + } | ||
153 | }); | 160 | }); |
161 | +//test용 | ||
162 | + book.get('/booklist',async (ctx) => { | ||
163 | + try { | ||
164 | + const books = await Book.find({}).sort({createDate: -1}).exec(); | ||
165 | + ctx.body = books; | ||
166 | + } catch (e) { | ||
167 | + return ctx.throw(500, e); | ||
168 | + } | ||
169 | + } | ||
170 | +); | ||
171 | + | ||
154 | module.exports = book; | 172 | module.exports = book; |
... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
1 | const Router = require("@koa/router"); | 1 | const Router = require("@koa/router"); |
2 | const checkLoggedIn = require("../../src/lib/checkLoggedIn"); | 2 | const checkLoggedIn = require("../../src/lib/checkLoggedIn"); |
3 | // const pageCtrl = require("./page.ctrl"); | 3 | // const pageCtrl = require("./page.ctrl"); |
4 | - | 4 | +const Joi = require('@hapi/joi'); |
5 | const page = new Router(); | 5 | const page = new Router(); |
6 | const Page = require("../models/page"); | 6 | const Page = require("../models/page"); |
7 | +const User = require("../models/user"); | ||
7 | //const index = require('../../../src/index'); | 8 | //const index = require('../../../src/index'); |
8 | //const render = require('koa-ejs'); | 9 | //const render = require('koa-ejs'); |
9 | //Page api | 10 | //Page api |
... | @@ -23,22 +24,37 @@ page.post('/:id', pageCtrl.detailPage); // detail recipe page | ... | @@ -23,22 +24,37 @@ page.post('/:id', pageCtrl.detailPage); // detail recipe page |
23 | // /recipe/scroll?filter=filter_query&renewal=count (filter_query: 추천순 or 조회순) | 24 | // /recipe/scroll?filter=filter_query&renewal=count (filter_query: 추천순 or 조회순) |
24 | page.get('/recipe/scroll', pageCtrl.scrollPage); // video list sorted by 추천순 or 조회순 in main page | 25 | page.get('/recipe/scroll', pageCtrl.scrollPage); // video list sorted by 추천순 or 조회순 in main page |
25 | */ | 26 | */ |
27 | +//For test | ||
28 | +page.get('/pagelist', async (ctx) => { | ||
29 | + | ||
30 | + try{ | ||
31 | + const page = await Page.find({}).sort({createDate:-1}).exec(); | ||
32 | + ctx.body = page; | ||
33 | + }catch(e){ | ||
34 | + ctx.throw(500, e); | ||
35 | + } | ||
36 | + }); | ||
26 | 37 | ||
27 | -page.get('/tset', async (ctx) => { | ||
28 | 38 | ||
29 | - console.log('testtest'); | ||
30 | -}); | ||
31 | 39 | ||
32 | page.get('/', async (ctx) => { | 40 | page.get('/', async (ctx) => { |
33 | 41 | ||
34 | - const page = await Page.find({}).sort({createDate:-1}).exec(); | 42 | + try{ |
43 | + const page = await Page.find({}).sort({createDate:-1}).exec(); | ||
35 | console.log(page); | 44 | console.log(page); |
36 | await ctx.render('posts/index', {page}); | 45 | await ctx.render('posts/index', {page}); |
46 | + }catch(e){ | ||
47 | + ctx.throw(500, e); | ||
48 | + } | ||
37 | }); | 49 | }); |
38 | 50 | ||
39 | 51 | ||
40 | page.get('/new', async (ctx) => { | 52 | page.get('/new', async (ctx) => { |
53 | + try{ | ||
41 | await ctx.render('posts/new'); | 54 | await ctx.render('posts/new'); |
55 | + }catch(e){ | ||
56 | + ctx.throw(500, e); | ||
57 | + } | ||
42 | }); | 58 | }); |
43 | 59 | ||
44 | // create | 60 | // create |
... | @@ -73,7 +89,7 @@ page.get('/tset', async (ctx) => { | ... | @@ -73,7 +89,7 @@ page.get('/tset', async (ctx) => { |
73 | if (err) throw err; | 89 | if (err) throw err; |
74 | const user = await User.findById(ctx.state.user._id).exec(); | 90 | const user = await User.findById(ctx.state.user._id).exec(); |
75 | console.log(book._id); | 91 | console.log(book._id); |
76 | - ctx.redirect('/page'); | 92 | + await ctx.redirect('/page'); |
77 | }); | 93 | }); |
78 | } catch (e) { | 94 | } catch (e) { |
79 | ctx.throw(500, e); | 95 | ctx.throw(500, e); |
... | @@ -81,7 +97,7 @@ page.get('/tset', async (ctx) => { | ... | @@ -81,7 +97,7 @@ page.get('/tset', async (ctx) => { |
81 | console.log('저장 성공!'); | 97 | console.log('저장 성공!'); |
82 | ctx.status = 200; | 98 | ctx.status = 200; |
83 | 99 | ||
84 | - ctx.redirect('/page'); | 100 | + await ctx.redirect('/page'); |
85 | }); | 101 | }); |
86 | 102 | ||
87 | 103 | ||
... | @@ -91,7 +107,8 @@ page.get('/tset', async (ctx) => { | ... | @@ -91,7 +107,8 @@ page.get('/tset', async (ctx) => { |
91 | try{ | 107 | try{ |
92 | var id = ctx.params.id; | 108 | var id = ctx.params.id; |
93 | const page = await Page.findById(id).exec(); | 109 | const page = await Page.findById(id).exec(); |
94 | - await ctx.render('posts/show', {page:page}); | 110 | + const user = await User.findById(page.author).exec(); |
111 | + await ctx.render('posts/show', {page:page,user:user}); | ||
95 | ctx.status = 200; | 112 | ctx.status = 200; |
96 | }catch(e){ | 113 | }catch(e){ |
97 | ctx.throw(500,e); | 114 | ctx.throw(500,e); |
... | @@ -113,10 +130,10 @@ page.patch('/:id',checkLoggedIn, async (ctx, next) => { | ... | @@ -113,10 +130,10 @@ page.patch('/:id',checkLoggedIn, async (ctx, next) => { |
113 | try { | 130 | try { |
114 | const mypage = await Page.findOne({ _id: id });//require page's _id | 131 | const mypage = await Page.findOne({ _id: id });//require page's _id |
115 | if(ctx.state.user._id == mypage.author){ | 132 | if(ctx.state.user._id == mypage.author){ |
116 | - mypage.updateP(page); | 133 | + await mypage.updateP(page); |
117 | 134 | ||
118 | console.log(mypage); | 135 | console.log(mypage); |
119 | - ctx.redirect("/page/"+id); | 136 | + await ctx.redirect("/page/"+id); |
120 | ctx.status = 200;} | 137 | ctx.status = 200;} |
121 | 138 | ||
122 | } catch (e) { | 139 | } catch (e) { |
... | @@ -129,8 +146,8 @@ page.patch('/:id',checkLoggedIn, async (ctx, next) => { | ... | @@ -129,8 +146,8 @@ page.patch('/:id',checkLoggedIn, async (ctx, next) => { |
129 | // destroy | 146 | // destroy |
130 | page.delete('/:id', async (ctx, next) => { | 147 | page.delete('/:id', async (ctx, next) => { |
131 | try{ | 148 | try{ |
132 | - await Page.deleteOne({_id:ctx.params.id}) | 149 | + const page = await Page.deleteOne({_id:ctx.params.id}) |
133 | - ctx.redirect('/page'); | 150 | + //await ctx.redirect('/page'); |
134 | }catch(e){ | 151 | }catch(e){ |
135 | ctx.throw(500, e); | 152 | ctx.throw(500, e); |
136 | } | 153 | } | ... | ... |
... | @@ -6,41 +6,12 @@ const checkLoggedIn = require("../../src/lib/checkLoggedIn"); | ... | @@ -6,41 +6,12 @@ const checkLoggedIn = require("../../src/lib/checkLoggedIn"); |
6 | const User = require("../models/user"); | 6 | const User = require("../models/user"); |
7 | //var GoogleStrategy = require('passport-google-oauth').OAuth2Strategy; | 7 | //var GoogleStrategy = require('passport-google-oauth').OAuth2Strategy; |
8 | const auth = new Router(); | 8 | const auth = new Router(); |
9 | - | 9 | +const nodemailer = require('nodemailer'); |
10 | -// 회원가입- 로컬 이메일 인증번호 발송 POST auth/signup/email/demand | 10 | +const config = require('../lib/config'); |
11 | -// 회원가입 이메일 인증번호 확인 POST auth/signup/email/verify | 11 | +const Joi = require('@hapi/joi'); |
12 | -// 로그인 "소셜 로그인 | ||
13 | -// (페이스북 구글 네이버 카카오)" POST auth/signin/social | ||
14 | -// 회원정보갱신 설문이나 설정에서 개인정보 바꾸면 적용 PATCH auth/update/pet | ||
15 | -// 회원정보갱신 설문이나 설정에서 개인정보 바꾸면 적용 PATCH auth/update/user | ||
16 | /* | 12 | /* |
17 | -auth.get('/userlist', authCtrl.userlist); | ||
18 | -auth.get('/test', authCtrl.test); | ||
19 | -auth.post('/signup', authCtrl.signupLocal); | ||
20 | -auth.post('/signin', authCtrl.signinLocal); | ||
21 | -auth.get('/signout',checkLoggedIn, authCtrl.signout); | ||
22 | -auth.get('/check', authCtrl.check2); | ||
23 | -auth.delete('/user',checkLoggedIn,authCtrl.Withdrawal); // 회원 탈퇴 | ||
24 | -auth.post('/validate', authCtrl.exists); | ||
25 | -auth.post('/checkpassword', authCtrl.checkPassword); | ||
26 | -auth.get('/book',checkLoggedIn,authCtrl.getUserBook); | ||
27 | -auth.get('/user', checkLoggedIn,authCtrl.userinfo); // show user information | ||
28 | -auth.patch('/user', checkLoggedIn, authCtrl.updateUser); // modify user information | ||
29 | -auth.patch('/user/password', authCtrl.changePassword); // change password | ||
30 | -auth.post('/find/password', authCtrl.findPassword); // 비밀번호 찾기 | ||
31 | -auth.get('/favorite',checkLoggedIn, authCtrl.showFavorite); // show a list of user's favorites | ||
32 | -auth.post('/favorite',checkLoggedIn, authCtrl.addFavorite); // add favorite | ||
33 | -auth.delete('/favorite',checkLoggedIn, authCtrl.delFavorite); // delete favorite | ||
34 | - | ||
35 | -auth.post('/find/password', authCtrl.findPassword); // 비밀번호 찾기 | ||
36 | -*/ | ||
37 | -auth.get('/new', async (ctx) => { | ||
38 | - ctx.render('users/new'); | ||
39 | - }); | ||
40 | 13 | ||
41 | -auth.get('/test', async (ctx) => { | 14 | +*/ |
42 | - ctx.render('users/login'); | ||
43 | - }); | ||
44 | 15 | ||
45 | 16 | ||
46 | // show | 17 | // show |
... | @@ -61,7 +32,14 @@ auth.get('/login', async (ctx) => { | ... | @@ -61,7 +32,14 @@ auth.get('/login', async (ctx) => { |
61 | }); | 32 | }); |
62 | 33 | ||
63 | 34 | ||
64 | - | 35 | +auth.get('/new', async (ctx) => { |
36 | + try{ | ||
37 | + await ctx.render('users/new'); | ||
38 | + }catch(e){ | ||
39 | + console.log(e); | ||
40 | + } | ||
41 | + }); | ||
42 | + | ||
65 | // edit | 43 | // edit |
66 | auth.get('/:id/edit', async (ctx) => { | 44 | auth.get('/:id/edit', async (ctx) => { |
67 | const user = await User.find({email:ctx.params.email}).exec(); | 45 | const user = await User.find({email:ctx.params.email}).exec(); |
... | @@ -74,9 +52,9 @@ auth.get('/login', async (ctx) => { | ... | @@ -74,9 +52,9 @@ auth.get('/login', async (ctx) => { |
74 | const errors =''; | 52 | const errors =''; |
75 | //handle error | 53 | //handle error |
76 | if (!email || !password) { | 54 | if (!email || !password) { |
77 | - ctx.status = 401; //Unauthorized | 55 | + //Unauthorized |
78 | - errors= '비밀번호, 이메일 중 하나가 틀렸습니다. ' | 56 | + alert( '비밀번호, 이메일 중 하나가 틀렸습니다. '); |
79 | - return; | 57 | + await ctx.redirect('/auth/login'); |
80 | } | 58 | } |
81 | try { | 59 | try { |
82 | //const user = User.findOne({ email: email }); | 60 | //const user = User.findOne({ email: email }); |
... | @@ -100,6 +78,7 @@ auth.get('/login', async (ctx) => { | ... | @@ -100,6 +78,7 @@ auth.get('/login', async (ctx) => { |
100 | httpOnly: false, | 78 | httpOnly: false, |
101 | }); | 79 | }); |
102 | ctx.status = 200; | 80 | ctx.status = 200; |
81 | + ctx.state.user = user; | ||
103 | ctx.redirect('/page'); | 82 | ctx.redirect('/page'); |
104 | console.log('토큰나옴, 로그인'); | 83 | console.log('토큰나옴, 로그인'); |
105 | } catch (e) { | 84 | } catch (e) { |
... | @@ -149,42 +128,105 @@ auth.get('/login', async (ctx) => { | ... | @@ -149,42 +128,105 @@ auth.get('/login', async (ctx) => { |
149 | } catch (e) { | 128 | } catch (e) { |
150 | ctx.throw(500, e); | 129 | ctx.throw(500, e); |
151 | } | 130 | } |
152 | - ctx.cookies.set('access_token', token, { maxAge: 1000 * 60 * 60 * 24 * 7 ,httpOnly: true,}); | 131 | + await ctx.cookies.set('access_token', token, { maxAge: 1000 * 60 * 60 * 24 * 7 ,httpOnly: true,}); |
153 | console.log('set cookie ok'); | 132 | console.log('set cookie ok'); |
154 | 133 | ||
155 | // 응답할 데이터에서 hashedPassword 필드 제거 | 134 | // 응답할 데이터에서 hashedPassword 필드 제거 |
156 | ctx.status = 200; | 135 | ctx.status = 200; |
157 | - await ctx.render('users/new'); | 136 | + await ctx.render('users/show'); |
158 | } catch (e) { | 137 | } catch (e) { |
159 | ctx.throw(500, e); | 138 | ctx.throw(500, e); |
160 | }}); | 139 | }}); |
161 | 140 | ||
162 | // update // 2 | 141 | // update // 2 |
163 | - auth.post('/:id', async (ctx) => { | 142 | + auth.patch('/:id', async (ctx) => { |
164 | - await User.findOne({username:ctx.params.username}).select('password').exec(); | 143 | + const schema = Joi.object().keys({ |
165 | - | 144 | + // password: Joi.string().min(6).max(20).required(), |
145 | + username: Joi.string().allow(null, ''), | ||
146 | + phone: Joi.string().allow(null, ''), | ||
147 | + nickname: Joi.string().allow(null, ''), | ||
148 | + fcmToken: Joi.string(), | ||
149 | + // birth: Joi.date() | ||
150 | + }); | ||
151 | + | ||
152 | + try { | ||
153 | + const value = await schema.validateAsync(ctx.request.body); | ||
154 | + } catch (err) { | ||
155 | + console.log(err); | ||
156 | + ctx.status = 400; | ||
157 | + return; | ||
158 | + } | ||
166 | 159 | ||
167 | - // update user object | 160 | + ctx.request.body.email = ctx.state.user.email; |
168 | - user.originalPassword = user.password; | ||
169 | - user.password = ctx.body.newPassword? ctx.body.newPassword : user.password; // 2-3 | ||
170 | - for(var p in ctx.body) // 2-4 | ||
171 | - user[p] = ctx.body[p]; | ||
172 | - | ||
173 | 161 | ||
174 | - // save updated user | 162 | + try { |
175 | - await user.save(); | 163 | + await User.updateUser(ctx.request.body); |
176 | - | 164 | + } catch (e) { |
177 | - ctx.redirect('/users/'+user.nickname); | 165 | + ctx.throw(500, e); |
166 | + } | ||
167 | + ctx.status = 200; | ||
168 | + await ctx.redirect('/users/'+user.nickname); | ||
178 | }); | 169 | }); |
179 | 170 | ||
180 | 171 | ||
181 | // destroy | 172 | // destroy |
182 | auth.get('/logout', async (ctx) => { | 173 | auth.get('/logout', async (ctx) => { |
183 | - ctx.cookies.set('access_token'); | 174 | + await ctx.cookies.set('access_token'); |
184 | - ctx.status = 204; | 175 | + ctx.status = 204; |
185 | - ctx.redirect('/'); | 176 | + await ctx.redirect('/'); |
186 | }); | 177 | }); |
178 | + | ||
179 | + function getRandomInt(min, max) { //min ~ max 사이의 임의의 정수 반환 | ||
180 | + return Math.floor(Math.random() * (max - min)) + min; | ||
181 | +} | ||
182 | + | ||
183 | + | ||
184 | + | ||
185 | + | ||
186 | + auth.post('/findPassword', async (ctx) => { | ||
187 | + var status = 400; | ||
188 | + | ||
189 | + // 전송 옵션 설정 | ||
190 | + // trainsporter: is going to be an object that is able to send mail | ||
191 | + let transporter = nodemailer.createTransport({ | ||
192 | + service: 'gmail', | ||
193 | + host: 'smtp.gmail.com', | ||
194 | + // port: 587, | ||
195 | + port: 465, | ||
196 | + secure: true, | ||
197 | + auth: { | ||
198 | + user: config.mailer.user, //gmail주소입력 | ||
199 | + pass: config.mailer.password, //gmail패스워드 입력 | ||
200 | + }, | ||
201 | + }); | ||
202 | + var numsend = getRandomInt(100000,999999); | ||
203 | + var mailOptions = { | ||
204 | + from: `"Like project"<${config.mailer.user}>`, //enter the send's name and email | ||
205 | + to: ctx.request.body.email, // recipient's email | ||
206 | + subject: 'Like password', // title of mail | ||
207 | + html: `안녕하세요, 글을 나누는 즐거움 Like 입니다. | ||
208 | + <br /> | ||
209 | + 인증번호는 다음과 같습니다. (임시) | ||
210 | + <br /> | ||
211 | + ${numsend}`, | ||
212 | + }; | ||
187 | 213 | ||
214 | + try { | ||
215 | + await transporter.sendMail(mailOptions, async function (error, info) { | ||
216 | + if (error) { | ||
217 | + ctx.status = 401; | ||
218 | + return; | ||
219 | + } else { | ||
220 | + console.log('Email sent: ' + info.response); | ||
221 | + ctx.body = { success: true }; | ||
222 | + status = 200; | ||
223 | + } | ||
224 | + }); | ||
225 | + } catch (e) { | ||
226 | + ctx.throw(500, e); | ||
227 | + } | ||
228 | + ctx.status = 200; | ||
229 | + }); | ||
188 | 230 | ||
189 | module.exports = auth; | 231 | module.exports = auth; |
190 | 232 | ... | ... |
... | @@ -24,10 +24,13 @@ | ... | @@ -24,10 +24,13 @@ |
24 | </div> | 24 | </div> |
25 | 25 | ||
26 | <div class="form-group"> | 26 | <div class="form-group"> |
27 | - <label for="body">Body</label> | 27 | + <label for="contents">Body</label> |
28 | - <textarea id="body" name="body" rows="5" class="form-control"></textarea> | 28 | + <textarea id="contents" name="contents" rows="5" class="form-control"></textarea> |
29 | + </div> | ||
30 | + <div class="form-group"> | ||
31 | + <label for="contents">Body</label> | ||
32 | + <textarea id="contents" name="contents" rows="5" class="form-control"></textarea> | ||
29 | </div> | 33 | </div> |
30 | - | ||
31 | <div> | 34 | <div> |
32 | <a class="btn btn-primary" href="/api/book">Back</a> | 35 | <a class="btn btn-primary" href="/api/book">Back</a> |
33 | <button type="submit" class="btn btn-primary">Submit</button> | 36 | <button type="submit" class="btn btn-primary">Submit</button> | ... | ... |
... | @@ -11,8 +11,8 @@ | ... | @@ -11,8 +11,8 @@ |
11 | <nav aria-label="breadcrumb"> | 11 | <nav aria-label="breadcrumb"> |
12 | <ol class="breadcrumb p-1 pl-2 pr-2"> | 12 | <ol class="breadcrumb p-1 pl-2 pr-2"> |
13 | <li class="breadcrumb-item"><a href="/">Home</a></li> | 13 | <li class="breadcrumb-item"><a href="/">Home</a></li> |
14 | - <li class="breadcrumb-item"><a href="/api/page">Page</a></li> | 14 | + <li class="breadcrumb-item"><a href="/page">Page</a></li> |
15 | - <li class="breadcrumb-item active" aria-current="page"><%= book.title %></li> | 15 | + <li class="breadcrumb-item active" aria-current="book"><%= book.title %></li> |
16 | </ol> | 16 | </ol> |
17 | </nav> | 17 | </nav> |
18 | 18 | ||
... | @@ -37,9 +37,9 @@ | ... | @@ -37,9 +37,9 @@ |
37 | </div> | 37 | </div> |
38 | 38 | ||
39 | <div class="mt-3"> | 39 | <div class="mt-3"> |
40 | - <a class="btn btn-primary" href="/api/book">Back</a> | 40 | + <a class="btn btn-primary" href="/book">Back</a> |
41 | - <a class="btn btn-primary" href="/api/book/<%= book._id %>/edit">Edit</a> | 41 | + <a class="btn btn-primary" href="/book/<%= book._id %>/edit">Edit</a> |
42 | - <form action="/api/book/<%= book._id %>?_method=delete" method="post" class="d-inline"> | 42 | + <form action="/book/<%= book._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> | 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> | 44 | </form> |
45 | </div> | 45 | </div> | ... | ... |
... | @@ -11,7 +11,9 @@ | ... | @@ -11,7 +11,9 @@ |
11 | <h2 class="mb-3">About</h2> | 11 | <h2 class="mb-3">About</h2> |
12 | 12 | ||
13 | <P>이 사이트는 Like Project 임시 페이지 입니다. </p> | 13 | <P>이 사이트는 Like Project 임시 페이지 입니다. </p> |
14 | + | ||
14 | 15 | ||
15 | </div> | 16 | </div> |
17 | + | ||
16 | </body> | 18 | </body> |
17 | </html> | 19 | </html> |
... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
... | @@ -17,7 +17,7 @@ | ... | @@ -17,7 +17,7 @@ |
17 | <div class="container"> | 17 | <div class="container"> |
18 | <div class="wrapper"> | 18 | <div class="wrapper"> |
19 | <form action="/auth/login" method="post" name="Login_Form" class="form-signin"> | 19 | <form action="/auth/login" method="post" name="Login_Form" class="form-signin"> |
20 | - <h3 class="form-signin-heading">Welcome! Please Sign In</h3> | 20 | + <h3 class="form-signin-heading">안녕하세요. 로그인 부탁드립니다.</h3> |
21 | 21 | ||
22 | <input type="text" class="form-control" name="email" placeholder="Email Address" required="" autofocus="" /> | 22 | <input type="text" class="form-control" name="email" placeholder="Email Address" required="" autofocus="" /> |
23 | <input type="password" class="form-control" name="password" placeholder="Password" required=""/> | 23 | <input type="password" class="form-control" name="password" placeholder="Password" required=""/> |
... | @@ -25,6 +25,15 @@ | ... | @@ -25,6 +25,15 @@ |
25 | <button class="btn btn-lg btn-primary btn-block" name="Submit" value="Login" type="Submit">Login</button> | 25 | <button class="btn btn-lg btn-primary btn-block" name="Submit" value="Login" type="Submit">Login</button> |
26 | </form> | 26 | </form> |
27 | </div> | 27 | </div> |
28 | + <form action="/auth/findPassword" method="post"> | ||
29 | + <a href="/auth/findPassword">비밀번호를 까먹으셨나요?</a> | ||
30 | + | ||
31 | + <div class="form-group"> | ||
32 | + <label for="title">이메일을 적으시면 메일이 갑니다. </label> | ||
33 | + <input type="text" id="email" name="email" class="form-control"> | ||
34 | + <button type="submit" class="btn btn-primary">Submit</button> | ||
35 | + </div> | ||
36 | + </form> | ||
28 | </div> | 37 | </div> |
29 | </body> | 38 | </body> |
30 | </html> | 39 | </html> |
... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
... | @@ -15,7 +15,8 @@ | ... | @@ -15,7 +15,8 @@ |
15 | 15 | ||
16 | <li class="nav-item"><a href="/auth/new" class="nav-link">Sign Up</a></li> | 16 | <li class="nav-item"><a href="/auth/new" class="nav-link">Sign Up</a></li> |
17 | <li class="nav-item"><a href="/auth/login" class="nav-link">Login</a></li> | 17 | <li class="nav-item"><a href="/auth/login" class="nav-link">Login</a></li> |
18 | - | 18 | + <li class="nav-item"><a href="/auth/logout" class="nav-link">Logout</a></li> |
19 | + | ||
19 | </ul> | 20 | </ul> |
20 | </div> | 21 | </div> |
21 | </div> | 22 | </div> | ... | ... |
... | @@ -30,11 +30,12 @@ | ... | @@ -30,11 +30,12 @@ |
30 | <% page.forEach(function(page) { %> | 30 | <% page.forEach(function(page) { %> |
31 | <tr> | 31 | <tr> |
32 | <td> | 32 | <td> |
33 | - <a href="/page/<%= page._id %>"><div class="ellipsis"><%= page.title %></div></a> | 33 | + <a href="/page/<%= page._id %>"><div class="ellipsis"><%= page.title %> author:<%= page.author.email %></div></a> |
34 | </td> | 34 | </td> |
35 | <td class="date"> | 35 | <td class="date"> |
36 | <span data-date="<%= page.createDate %>"></span> <!-- 1 --> | 36 | <span data-date="<%= page.createDate %>"></span> <!-- 1 --> |
37 | </td> | 37 | </td> |
38 | + <a href="/auth/<%= page.author._id %>"><div class="ellipsis"><%= page.author.nickname %></div></a> | ||
38 | </tr> | 39 | </tr> |
39 | <% }) %> | 40 | <% }) %> |
40 | </tbody> | 41 | </tbody> | ... | ... |
... | @@ -20,6 +20,7 @@ | ... | @@ -20,6 +20,7 @@ |
20 | 20 | ||
21 | <div class="card"> | 21 | <div class="card"> |
22 | <h5 class="card-header p-2"><%= page.title %></h5> | 22 | <h5 class="card-header p-2"><%= page.title %></h5> |
23 | + <h3 class="card-header p-2"><%= user.nickname %><%= user.email%></h3> | ||
23 | <div class="row"> <!-- 1 --> | 24 | <div class="row"> <!-- 1 --> |
24 | 25 | ||
25 | <div class="col-md-7 col-lg-8 col-xl-9 order-sm-2 order-md-1"> <!-- 1 --> | 26 | <div class="col-md-7 col-lg-8 col-xl-9 order-sm-2 order-md-1"> <!-- 1 --> | ... | ... |
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 | + <h3 class="mb-3">Users</h3> | ||
12 | + | ||
13 | + <ul class="list-group"> | ||
14 | + <% if(users == null || users.length == 0){ %> | ||
15 | + <li class="list-group-item"> There is no user yet.</li> | ||
16 | + <% } %> | ||
17 | + <% users.forEach(function(user) { %> | ||
18 | + <li class="list-group-item"> | ||
19 | + <a href="/users/<%= user.username %>"><%= user.username %></a> | ||
20 | + </li> | ||
21 | + <% }) %> | ||
22 | + </ul> | ||
23 | + | ||
24 | + </div> | ||
25 | + </body> | ||
26 | +</html> | ||
... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
... | @@ -12,10 +12,10 @@ | ... | @@ -12,10 +12,10 @@ |
12 | 12 | ||
13 | <h3 class="contentBoxTop mb-3">New User</h3> | 13 | <h3 class="contentBoxTop mb-3">New User</h3> |
14 | 14 | ||
15 | - <form action="/auth/signin" method="post"> | 15 | + <form action="/auth/signup" method="post"> |
16 | 16 | ||
17 | <div class="form-group row"> | 17 | <div class="form-group row"> |
18 | - <label for="nickname" class="col-sm-3 col-form-label">Username*</label> | 18 | + <label for="nickname" class="col-sm-3 col-form-label">Nickanme*</label> |
19 | <div class="col-sm-9"> | 19 | <div class="col-sm-9"> |
20 | <input type="text" id="nickname" name="nickname" value="" class="form-control"> | 20 | <input type="text" id="nickname" name="nickname" value="" class="form-control"> |
21 | </div> | 21 | </div> |
... | @@ -32,12 +32,7 @@ | ... | @@ -32,12 +32,7 @@ |
32 | <input type="password" id="password" name="password" value="" class="form-control"> | 32 | <input type="password" id="password" name="password" value="" class="form-control"> |
33 | </div> | 33 | </div> |
34 | </div> | 34 | </div> |
35 | - <div class="form-group row"> | 35 | + |
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> | 36 | <p> |
42 | <small>*Required</small> | 37 | <small>*Required</small> |
43 | </p> | 38 | </p> | ... | ... |
... | @@ -12,13 +12,19 @@ | ... | @@ -12,13 +12,19 @@ |
12 | 12 | ||
13 | <h3 class="contentBoxTop">usefname</h3> | 13 | <h3 class="contentBoxTop">usefname</h3> |
14 | 14 | ||
15 | + | ||
15 | <form class="user-form" action="/users" method="post"> | 16 | <form class="user-form" action="/users" method="post"> |
16 | <fieldset disabled> | 17 | <fieldset disabled> |
17 | - | 18 | + <div class="form-group row"> |
19 | + <label for="name" class="col-sm-3 col-form-label">Name</label> | ||
20 | + <div class="col-sm-9"> | ||
21 | + <input class="form-control" type="text" id="name" name="name" value="<%= user.name %>"> | ||
22 | + </div> | ||
23 | + </div> | ||
18 | <div class="form-group row"> | 24 | <div class="form-group row"> |
19 | <label for="email" class="col-sm-3 col-form-label">Email</label> | 25 | <label for="email" class="col-sm-3 col-form-label">Email</label> |
20 | <div class="col-sm-9"> | 26 | <div class="col-sm-9"> |
21 | - <input class="form-control" type="text" id="email" name="email" value="<%= 9 %>"> | 27 | + <input class="form-control" type="text" id="email" name="email" value="<%= user.email %>"> |
22 | </div> | 28 | </div> |
23 | </div> | 29 | </div> |
24 | </fieldset> | 30 | </fieldset> | ... | ... |
-
Please register or login to post a comment