diff --git a/src/server/auth/auth.controller.js b/src/server/auth/auth.controller.js index a43e1ddcb4b719039aac8d6ab588a624afe528c1..5a910443e70266bd202f6791a15d8e5b210e560c 100644 --- a/src/server/auth/auth.controller.js +++ b/src/server/auth/auth.controller.js @@ -48,8 +48,11 @@ const requireSignin = expressJwt({ }) const hasAuthorization = (req, res, next) => { - const authorized = req.profile && req.auth && req.profile._id === req.auth._id + // console.log('profile:', req.profile, 'auth:', req.auth); + // console.log('id is equal?:', req.profile._id === req.auth._id); + const authorized = req.profile && req.auth && req.profile._id == req.auth._id if (!authorized) { + // console.log('authorized?', authorized); return res.status(403).json({ error: 'User is not authorized' }) diff --git a/src/server/auth/auth.routes.js b/src/server/auth/auth.routes.js index 28c0d7f06cf1fafd3a4fa84ec16204a439707106..3690c99e865131616df771606fd19c4b6c4503ec 100644 --- a/src/server/auth/auth.routes.js +++ b/src/server/auth/auth.routes.js @@ -1,5 +1,5 @@ import express from 'express' -import authCtrl from './auth.controller' +import authCtrl from './auth.controller.js' const router = express.Router() diff --git a/src/server/express.js b/src/server/express.js index 962e4f58cc9ac7ea3987883a32e5746c9172e331..ad3430f6109f2dc97a5ba2c91625e9b1515255e8 100644 --- a/src/server/express.js +++ b/src/server/express.js @@ -1,13 +1,17 @@ import express from 'express' import bodyParser from 'body-parser' import userRoutes from './user/user.routes.js' +import authRoutes from './auth/auth.routes.js' +import quizRoutes from './quiz/quiz.routes.js' const app = express() app.use(bodyParser.json()) app.use(bodyParser.urlencoded({ extended: true })) +app.use('/', authRoutes) app.use('/', userRoutes) +app.use('/', quizRoutes) app.use((err, req, res, next) => { if (err.name === 'UnauthorizedError') { diff --git a/src/server/quiz/answer.model.js b/src/server/quiz/answer.model.js new file mode 100644 index 0000000000000000000000000000000000000000..42708a6921e41013fe1c8abf2e45b21ab50f4fe9 --- /dev/null +++ b/src/server/quiz/answer.model.js @@ -0,0 +1,14 @@ +import mongoose from 'mongoose' + +const AnswerSchema = new mongoose.Schema({ + questionId: { + type: mongoose.Schema.Types.ObjectId, + ref: 'Question', + }, + type: String, // single/multiple choice? + score: Number, // 맞힌 점수 + points: Number, // Question.score와 자동 연결 필요 + content: String, // 기록한 답 +}) + +export default mongoose.model('Answer', AnswerSchema) \ No newline at end of file diff --git a/src/server/quiz/question.model.js b/src/server/quiz/question.model.js new file mode 100644 index 0000000000000000000000000000000000000000..c96d25ecb0c07743661a3a14cf540924627725ee --- /dev/null +++ b/src/server/quiz/question.model.js @@ -0,0 +1,21 @@ +import mongoose from 'mongoose' + +const QuestionSchema = new mongoose.Schema({ + type: String, // 객관식, 주관식 single/multiple choice + created: { + type: Date, + default: Date.now + }, + updated: Date, + level: String, + category: [String], + score: Number, //문제당 할당 점수 + content: String, //질문 + choices: [String], // 선택형 항목 + correct: { + type: mongoose.Schema.Types.ObjectId, + ref: 'Answer' + }, // 정답; Answer Model 객체 +}) + +export default mongoose.model('Question', QuestionSchema) \ No newline at end of file diff --git a/src/server/quiz/quiz.controller.js b/src/server/quiz/quiz.controller.js new file mode 100644 index 0000000000000000000000000000000000000000..90c968b42fb96d7fb6e9d147633f6d8329db39f5 --- /dev/null +++ b/src/server/quiz/quiz.controller.js @@ -0,0 +1,35 @@ +import formidable from 'formidable' +import fs from 'fs' +import quizModel from './quiz.model.js' + +const create = async (req, res) => { + const form = new formidable.IncomingForm() + form.keepExtensions = true + form.parse(req, async (err, fields, files) => { + if (err) { + return res.status(400).json({ + error: 'Image could not be uploaded' + }) + } + + const quiz = new quizModel(fields) + quiz.author = req.profile + if (files.image) { + quiz.image.data = fs.readFileSync(files.image.path) + quiz.image.contentType = files.image.type + } + + try { + const result = await quiz.save() + res.json(result) + } catch (error) { + return res.status(400).json({ + error: 'Quiz save db error' + }) + } + }) +} + +export default { + create, +} \ No newline at end of file diff --git a/src/server/quiz/quiz.model.js b/src/server/quiz/quiz.model.js new file mode 100644 index 0000000000000000000000000000000000000000..f766dec78024617ee5bd87090b86221d0c3c4a23 --- /dev/null +++ b/src/server/quiz/quiz.model.js @@ -0,0 +1,26 @@ +import mongoose from 'mongoose' + +const QuizSchema = new mongoose.Schema({ + author: { + type: mongoose.SchemaTypes.ObjectId, + ref: 'User' + }, + title: String, + score: Number, + published: Boolean, + created: { + type: Date, + default: Date.now + }, + updated: Date, + publishedAt: Date, + startAt: Date, + endAt: Date, + questions: [], // Question Schemas + image: { + type: Buffer, + contentType: String, + } +}) + +export default mongoose.model('Quiz', QuizSchema) \ No newline at end of file diff --git a/src/server/quiz/quiz.routes.js b/src/server/quiz/quiz.routes.js new file mode 100644 index 0000000000000000000000000000000000000000..61dbcd141d2eba2a021836baae69019c960e3df5 --- /dev/null +++ b/src/server/quiz/quiz.routes.js @@ -0,0 +1,13 @@ +import express from 'express' +import authCtrl from '../auth/auth.controller.js' +import userCtrl from '../user/user.controller.js' +import quizCtrl from './quiz.controller.js' + +const router = express.Router() + +router.route('/api/quiz/:userId') + .post(authCtrl.requireSignin, authCtrl.hasAuthorization, userCtrl.isInstructor, quizCtrl.create) + + +router.param('userId', userCtrl.userById) +export default router \ No newline at end of file diff --git a/src/server/user/user.controller.js b/src/server/user/user.controller.js index ca70b154cd0a5c50300ae069137ecf7c48d22bd7..8f319230cdf52154b74ca7fb680005a60d84f134 100644 --- a/src/server/user/user.controller.js +++ b/src/server/user/user.controller.js @@ -1,6 +1,6 @@ import User from './user.model.js' import formidable from 'formidable' -import extend from 'lodash/extend' +import extend from 'lodash/extend.js' import fs from 'fs' const create = async (req, res) => { @@ -34,7 +34,7 @@ const read = (req, res) => { return res.json(req.profile) } -const update = async (req, res) => { +const update = (req, res) => { let form = new formidable.IncomingForm() form.keepExtensions = true form.parse(req, async (err, fields, files) => { @@ -78,6 +78,16 @@ const remove = async (req, res) => { } } +const isInstructor = (req, res, next) => { + const instructor = req.profile && req.profile.instructor + if (!instructor) { + return res.status(403).json({ + error: 'User is not an instructor' + }) + } + next() +} + const userById = async (req, res, next, id) => { try { let user = await User.findById(id) @@ -102,5 +112,6 @@ export default { read, update, remove, + isInstructor, userById, } \ No newline at end of file diff --git a/src/server/user/user.model.js b/src/server/user/user.model.js index fc9c398645ff8aa8e02e8de916dfd491554e5a64..f7b7c063f067162b8db365763a386a6958b3341c 100644 --- a/src/server/user/user.model.js +++ b/src/server/user/user.model.js @@ -28,6 +28,10 @@ const UserSchema = new mongoose.Schema({ data: Buffer, contentType: String, }, + instructor: { + type: Boolean, + default: false, + }, }) UserSchema.virtual('password')