From eff2a31561c5e51c541b8813170c4fe7ce4d5c22 Mon Sep 17 00:00:00 2001 From: Jung SongYi Date: Sun, 2 May 2021 15:49:53 +0900 Subject: [PATCH 1/7] Move #3 #28 add middleware and separate route board and comment --- app.ts | 2 +- controller/board.ts | 6 ------ controller/board_comment.ts | 13 +++++++++++++ routes/board.ts | 16 +++++++++------- routes/user.ts | 2 ++ routes/workspace.ts | 1 + 6 files changed, 26 insertions(+), 14 deletions(-) create mode 100644 controller/board_comment.ts diff --git a/app.ts b/app.ts index f76fd71..f29d253 100644 --- a/app.ts +++ b/app.ts @@ -2,7 +2,7 @@ import express from 'express'; import cors from 'cors'; import './init/mongo'; import 'dotenv/config'; -import devRouter from './routes/dev'; +//import devRouter from './routes/dev'; import boardRouter from './routes/board'; import userRouter from './routes/user'; import workspaceRouter from './routes/workspace'; diff --git a/controller/board.ts b/controller/board.ts index 93d1920..a79c5ec 100644 --- a/controller/board.ts +++ b/controller/board.ts @@ -14,12 +14,6 @@ const boardController = { boardDelete: (req: Request, res: Response) => { // 게시글 삭제하기 }, - commentAdd: (req: Request, res: Response) => { - // 댓글 추가하기 - }, - commentDelete: (req: Request, res: Response) => { - // 댓글 삭제하기 - }, }; export { boardController }; diff --git a/controller/board_comment.ts b/controller/board_comment.ts new file mode 100644 index 0000000..49e9d6d --- /dev/null +++ b/controller/board_comment.ts @@ -0,0 +1,13 @@ +import { Request, Response } from 'express'; +import { Boards } from '../src/db/models/board'; + +const commentController = { + commentAdd: (req: Request, res: Response) => { + // 댓글 추가하기 + }, + commentDelete: (req: Request, res: Response) => { + // 댓글 삭제하기 + }, +}; + +export { commentController }; diff --git a/routes/board.ts b/routes/board.ts index df6766f..1d138be 100644 --- a/routes/board.ts +++ b/routes/board.ts @@ -1,24 +1,26 @@ import app from '../app'; import { authChecker } from './../middleware/authChecker'; import { boardController } from '../controller/board'; +import { commentController } from '../controller/board_comment'; import express from 'express'; const boardRouter = express.Router(); -// 실제 요청 처리하기 전 access token 확인 -boardRouter.use('/board', authChecker); + +// authChecker - 실제 요청 처리하기 전 access token 확인 +//boardRouter.use('/board', authChecker); // 게시판 글 목록 데이터 보내주기 -boardRouter.get('/board', boardController.boardAll); +boardRouter.get('/board', authChecker, boardController.boardAll); // 게시글 상세 내용 + 댓글 데이터 보내주기 -boardRouter.get('/board/:board_id', boardController.boardOne); +boardRouter.get('/board/:board_id', authChecker, boardController.boardOne); // 게시글 삭제하기 -boardRouter.delete('/board/:board_id', boardController.boardDelete); +boardRouter.delete('/board/:board_id', authChecker, boardController.boardDelete); // 댓글 추가하기 -boardRouter.post('/board/:board_id/comment', boardController.commentAdd); +boardRouter.post('/board/:board_id/comment', authChecker, commentController.commentAdd); // 댓글 삭제하기 -boardRouter.delete('/board/:board_id/:comment_id', boardController.commentDelete); +boardRouter.delete('/board/:board_id/:comment_id', authChecker, commentController.commentDelete); export default boardRouter; diff --git a/routes/user.ts b/routes/user.ts index f81e95d..a8eec4e 100644 --- a/routes/user.ts +++ b/routes/user.ts @@ -5,8 +5,10 @@ import { emailAuthController } from '../controller/emailauth'; import { oauthController } from '../controller/loginOAuth'; import { userController } from '../controller/user'; const userRouter = express.Router(); + // 로그인 userRouter.post('/login', userController.login); +// 로그인 - nodemailer userRouter.post('/mail', emailController); userRouter.post('/emailauth', emailAuthController.authorizationCode); // 로그인 - OAuth 방식: google, github diff --git a/routes/workspace.ts b/routes/workspace.ts index a858ed8..deba8f6 100644 --- a/routes/workspace.ts +++ b/routes/workspace.ts @@ -3,6 +3,7 @@ import { authChecker } from './../middleware/authChecker'; import { workspaceController } from '../controller/workspace'; import express from 'express'; const workspaceRouter = express.Router(); + // 실제 요청 처리하기 전 access token 확인 workspaceRouter.use('/workspace', authChecker); From 6e14b66cfcaba08cad55d671be20c2d21e877171 Mon Sep 17 00:00:00 2001 From: Jung SongYi Date: Sun, 2 May 2021 17:20:21 +0900 Subject: [PATCH 2/7] Add #47 controller 'get /board' logic and fix database models 'board.ts' --- controller/board.ts | 8 +++++++- src/db/models/board.ts | 6 +++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/controller/board.ts b/controller/board.ts index a79c5ec..9d78ba0 100644 --- a/controller/board.ts +++ b/controller/board.ts @@ -1,9 +1,15 @@ import { Request, Response } from 'express'; import { Boards } from '../src/db/models/board'; +import { Users } from '../src/db/models/user'; const boardController = { - boardAll: (req: Request, res: Response) => { + boardAll: async (req: Request, res: Response) => { // 게시판 글 목록 데이터 보내주기 + console.log('💜boardAll'); + let boardList = await Boards.findAll(); + res.status(200).json({ + boardList, + }); }, boardOne: (req: Request, res: Response) => { // 게시글 상세 내용 + 댓글 데이터 보내주기 diff --git a/src/db/models/board.ts b/src/db/models/board.ts index 8f70e36..ca4d6ac 100644 --- a/src/db/models/board.ts +++ b/src/db/models/board.ts @@ -14,10 +14,13 @@ import { import { sequelize } from './index'; import { Users } from './user'; interface BoardAttributes { + writer: string; title: string; } export class Boards extends Model { + public readonly id!: number; + public writer!: string; public title!: string; static associations: { boardBelongsToUser: Association; @@ -26,6 +29,7 @@ export class Boards extends Model { } Boards.init( { + writer: DataTypes.STRING, title: DataTypes.STRING, }, { @@ -35,7 +39,7 @@ Boards.init( ); Boards.belongsTo(Users, { - foreignKey: 'writer', + foreignKey: 'user_id', targetKey: 'id', }); From 0c98a49943adcc501153abeb8f9955b0a70ce1bb Mon Sep 17 00:00:00 2001 From: Jung SongYi Date: Sun, 2 May 2021 20:25:49 +0900 Subject: [PATCH 3/7] Add #40 middleware-authChecker save data into req about user_id --- middleware/authChecker.ts | 31 +++++++++++++++++++++++++++++-- src/customType/express.d.ts | 3 ++- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/middleware/authChecker.ts b/middleware/authChecker.ts index 548c2a0..4f62647 100644 --- a/middleware/authChecker.ts +++ b/middleware/authChecker.ts @@ -2,6 +2,7 @@ import jwt, { VerifyErrors } from 'jsonwebtoken'; import axios from 'axios'; import { Request, Response, NextFunction } from 'express'; import { accessTokenGenerator } from '../Auth/GenerateAccessToken'; +import { Users } from '../src/db/models/user'; import * as dotenv from 'dotenv'; dotenv.config(); @@ -40,6 +41,7 @@ export const authChecker = async (req: Request, res: Response, next: NextFunctio const email = decoded.email; const newAccessToken = await accessTokenGenerator(id, email); req.newAccessToken = newAccessToken; + req.user_id = id; req.user_email = email; } }, @@ -92,7 +94,19 @@ export const authChecker = async (req: Request, res: Response, next: NextFunctio console.log(err.message); res.redirect(`${process.env.CLIENT_URL}/login`); }); - req.user_email = resInfo; + const userInfo = await Users.findOne({ + where: { + email: resInfo, + }, + }); + if (userInfo !== null) { + console.log('find userInfo', userInfo); + req.user_email = resInfo; + req.user_id = userInfo.id; + } else { + // 유저 정보를 찾을 수 없음 -> 인증 불가 -> 다시 로그인해야함 + res.redirect(`${process.env.CLIENT_URL}/login`); + } } else if (LoginType === 'github') { // 로그인 방식 - github // refresh token이 없음, 로그아웃 하기 전까지 access token 계속 사용 가능 @@ -114,7 +128,20 @@ export const authChecker = async (req: Request, res: Response, next: NextFunctio console.log(err.message); res.redirect(`${process.env.CLIENT_URL}/login`); }); - req.user_email = `${resInfo}@github.com`; + const email = `${resInfo}@github.com`; + const userInfo = await Users.findOne({ + where: { + email, + }, + }); + if (userInfo !== null) { + console.log('find userInfo', userInfo); + req.user_email = email; + req.user_id = userInfo.id; + } else { + // 유저 정보를 찾을 수 없음 -> 인증 불가 -> 다시 로그인해야함 + res.redirect(`${process.env.CLIENT_URL}/login`); + } } // 실제 요청으로 넘어감 // req.user_email: 유저 이메일 정보 저장, 실제 요청에서 사용 가능 diff --git a/src/customType/express.d.ts b/src/customType/express.d.ts index b868f69..e8a4bdf 100644 --- a/src/customType/express.d.ts +++ b/src/customType/express.d.ts @@ -2,7 +2,8 @@ export declare global { namespace Express { interface Request { newAccessToken?: string; - user_email?: string; + user_id?: number | undefined; + user_email?: string | undefined; } } } From 7ceab886d8a9d82adeb264be492761755e6bc2b7 Mon Sep 17 00:00:00 2001 From: Jung SongYi Date: Sun, 2 May 2021 20:30:22 +0900 Subject: [PATCH 4/7] Add #48 #3 controller 'post /board' logic & route board and fix database models 'board.ts' --- controller/board.ts | 23 ++++++++++++++++++++++- routes/board.ts | 3 +++ src/db/models/board.ts | 4 +++- 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/controller/board.ts b/controller/board.ts index 9d78ba0..d7c6c64 100644 --- a/controller/board.ts +++ b/controller/board.ts @@ -14,8 +14,29 @@ const boardController = { boardOne: (req: Request, res: Response) => { // 게시글 상세 내용 + 댓글 데이터 보내주기 }, - boardAdd: (req: Request, res: Response) => { + boardAdd: async (req: Request, res: Response) => { // 게시글 등록하기 + console.log('💜boardAdd ', req.body, req.user_email, req.user_id); + const title = req.body.title; + if (title !== '') { + const writer = req.user_email; + const user_id = req.user_id; + const newBoard = await Boards.create({ + title, + writer, + user_id, + }); + const board_id = newBoard.id; + // board_id를 key로 가지는 칸반보드 데이터 저장 + // board_id를 key로 가지는 댓글 데이터 저장(빈파일? 생성) + res.status(200).json({ + board_id, + }); + } else { + res.status(400).json({ + message: 'no input title Error!', + }); + } }, boardDelete: (req: Request, res: Response) => { // 게시글 삭제하기 diff --git a/routes/board.ts b/routes/board.ts index 1d138be..0f3cdf2 100644 --- a/routes/board.ts +++ b/routes/board.ts @@ -11,6 +11,9 @@ const boardRouter = express.Router(); // 게시판 글 목록 데이터 보내주기 boardRouter.get('/board', authChecker, boardController.boardAll); +// 게시글 등록하기 +boardRouter.post('/board', authChecker, boardController.boardAdd); + // 게시글 상세 내용 + 댓글 데이터 보내주기 boardRouter.get('/board/:board_id', authChecker, boardController.boardOne); diff --git a/src/db/models/board.ts b/src/db/models/board.ts index ca4d6ac..216b33f 100644 --- a/src/db/models/board.ts +++ b/src/db/models/board.ts @@ -14,8 +14,9 @@ import { import { sequelize } from './index'; import { Users } from './user'; interface BoardAttributes { - writer: string; + writer: string | undefined; title: string; + user_id: number | undefined; } export class Boards extends Model { @@ -31,6 +32,7 @@ Boards.init( { writer: DataTypes.STRING, title: DataTypes.STRING, + user_id: DataTypes.NUMBER, }, { sequelize, From 739c302275b937c513656b2337b0229a0a0347b4 Mon Sep 17 00:00:00 2001 From: Jung SongYi Date: Sun, 2 May 2021 20:58:32 +0900 Subject: [PATCH 5/7] Add #50 controller 'delete /board/:board_id' logic --- controller/board.ts | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/controller/board.ts b/controller/board.ts index d7c6c64..9413e77 100644 --- a/controller/board.ts +++ b/controller/board.ts @@ -38,8 +38,20 @@ const boardController = { }); } }, - boardDelete: (req: Request, res: Response) => { + boardDelete: async (req: Request, res: Response) => { // 게시글 삭제하기 + console.log('💜boardDelete ', req.params); + const board_id = Number(req.params.board_id); + await Boards.destroy({ + where: { + id: board_id, + }, + }); + // board_id를 key로 가지는 칸반보드 데이터 삭제 + // board_id를 key로 가지는 댓글 데이터 삭제 + res.status(200).json({ + message: `delete ${board_id} complete`, + }); }, }; From 6ce776e18ca1f7915ebf533477438dd73bd65a63 Mon Sep 17 00:00:00 2001 From: Jung SongYi Date: Sun, 2 May 2021 21:19:20 +0900 Subject: [PATCH 6/7] Add #51 controller 'get /board/:board_id' logic --- controller/board.ts | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/controller/board.ts b/controller/board.ts index 9413e77..d84b6af 100644 --- a/controller/board.ts +++ b/controller/board.ts @@ -11,8 +11,28 @@ const boardController = { boardList, }); }, - boardOne: (req: Request, res: Response) => { + boardOne: async (req: Request, res: Response) => { // 게시글 상세 내용 + 댓글 데이터 보내주기 + console.log('💜boardOne ', req.params); + const board_id = Number(req.params.board_id); + const boardData = await Boards.findOne({ + where: { + id: board_id, + }, + }); + if (boardData === null) { + res.status(403).json({ + message: 'no board data Error!', + }); + } else { + // board_id를 key로 가지는 칸반보드 데이터 불러오기 + // board_id를 key로 가지는 댓글 데이터 불러오기 + res.status(200).json({ + ...boardData, // 여기 좀더 고민 + //content + //comment + }); + } }, boardAdd: async (req: Request, res: Response) => { // 게시글 등록하기 From 91084b4b77eaa38754dbed99001f03ae9e672841 Mon Sep 17 00:00:00 2001 From: Jung SongYi Date: Sun, 2 May 2021 23:53:37 +0900 Subject: [PATCH 7/7] Fix #53 if use primary key occur error -> solved --- controller/board.ts | 3 ++- middleware/authChecker.ts | 5 +++-- src/db/models/board.ts | 8 +++++++- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/controller/board.ts b/controller/board.ts index d84b6af..409c94d 100644 --- a/controller/board.ts +++ b/controller/board.ts @@ -42,11 +42,12 @@ const boardController = { const writer = req.user_email; const user_id = req.user_id; const newBoard = await Boards.create({ + id: undefined, title, writer, user_id, }); - const board_id = newBoard.id; + const board_id = newBoard.get('id'); // board_id를 key로 가지는 칸반보드 데이터 저장 // board_id를 key로 가지는 댓글 데이터 저장(빈파일? 생성) res.status(200).json({ diff --git a/middleware/authChecker.ts b/middleware/authChecker.ts index 4f62647..de5926b 100644 --- a/middleware/authChecker.ts +++ b/middleware/authChecker.ts @@ -102,7 +102,7 @@ export const authChecker = async (req: Request, res: Response, next: NextFunctio if (userInfo !== null) { console.log('find userInfo', userInfo); req.user_email = resInfo; - req.user_id = userInfo.id; + req.user_id = userInfo.get('id') as number; } else { // 유저 정보를 찾을 수 없음 -> 인증 불가 -> 다시 로그인해야함 res.redirect(`${process.env.CLIENT_URL}/login`); @@ -137,7 +137,7 @@ export const authChecker = async (req: Request, res: Response, next: NextFunctio if (userInfo !== null) { console.log('find userInfo', userInfo); req.user_email = email; - req.user_id = userInfo.id; + req.user_id = userInfo.get('id') as number; } else { // 유저 정보를 찾을 수 없음 -> 인증 불가 -> 다시 로그인해야함 res.redirect(`${process.env.CLIENT_URL}/login`); @@ -146,6 +146,7 @@ export const authChecker = async (req: Request, res: Response, next: NextFunctio // 실제 요청으로 넘어감 // req.user_email: 유저 이메일 정보 저장, 실제 요청에서 사용 가능 // 나중에 응답 보낼때 accessToken에 req.newAccessToken을 넣어주면 됨 + console.log('💖authChecker ', LoginType, req.user_id, req.user_email, req.newAccessToken); next(); } else { // access token이 없을 때 -> 로그인 페이지로 돌아감 diff --git a/src/db/models/board.ts b/src/db/models/board.ts index 216b33f..ddb6ce3 100644 --- a/src/db/models/board.ts +++ b/src/db/models/board.ts @@ -14,6 +14,7 @@ import { import { sequelize } from './index'; import { Users } from './user'; interface BoardAttributes { + id: number | undefined; writer: string | undefined; title: string; user_id: number | undefined; @@ -30,9 +31,14 @@ export class Boards extends Model { } Boards.init( { + id: { + type: DataTypes.INTEGER, + autoIncrement: true, + primaryKey: true, + }, writer: DataTypes.STRING, title: DataTypes.STRING, - user_id: DataTypes.NUMBER, + user_id: DataTypes.INTEGER, }, { sequelize,