송용우

Merge commit '552b33f3' into develop

......@@ -3,5 +3,8 @@
# dotenv
.env
#access.log
access.log
# dependencies
/node_modules
......
......@@ -19,17 +19,17 @@
## API Table
| group | description | method | URL | Detail | Auth |
| ------- | ------------------------ | ------ | -------------------------- | -------- | --------- |
| ------- | --------------------------- | ------ | ------------------------ | -------- | --------- |
| user | 유저 등록 | POST | api/user | 바로가기 | JWT Token |
| user | 유저 삭제 | DELETE | api/user:id | 바로가기 | JWT Token |
| user | 특정 유저 조회 | GET | api/user:id | 바로가기 | None |
| user | 전체 유저 조회 | GET | api/user | 바로가기 | JWT Token |
| friend | 유저 친구 등록 | POST | api/friend | 바로가기 | JWT Token |
| friend | 유저의 친구 조회 | GET | api/friend:id | 바로가기 | None |
| profile | 유저가 푼 문제 조회 | GET | api/profile/solved:id | 바로가기 | None |
| profile | 유저가 푼 문제 동기화 | Update | api/profile/solved:id | 바로가기 | None |
| profile | 유저가 푼 문제 개수 조회 | GET | api/profile/solvednum:id | 바로가기 | None |
| profile | 추천 문제 조회 | GET | api/profile/recommendps:id | 바로가기 | None |
| profile | 유저가 푼 문제 조회(백준) | GET | api/profile/solvedBJ:id | 바로가기 | None |
| profile | 유저가 푼 문제 동기화(백준) | PATCH | api/profile/syncBJ | 바로가기 | None |
| profile | 유저 정보 수정 | POST | api/profile/setprofile | 바로가기 | JWT TOKEN |
| profile | 추천 문제 조회 | GET | api/profile/recommend:id | 바로가기 | None |
| notify | 슬랙 메시지 전송 요청 | POST | api/notify/slack | 바로가기 | Jwt Token |
| auth | 로그인 | POST | api/auth/login | 바로가기 | None |
| auth | 로그아웃 | GET | api/auth/logout | 바로가기 | JWT Token |
......
......@@ -2,6 +2,8 @@ const Koa = require("koa");
const Router = require("koa-router");
const bodyParser = require("koa-bodyparser");
const mongoose = require("mongoose");
const fs = require("fs");
const morgan = require("koa-morgan");
const jwtMiddleware = require("./src/lib/jwtMiddleware");
const api = require("./src/api");
......@@ -9,10 +11,13 @@ require("dotenv").config();
const app = new Koa();
const router = new Router();
const accessLogStream = fs.createWriteStream(__dirname + "/access.log", {
flags: "a",
});
require("dotenv").config();
app.use(bodyParser());
app.use(jwtMiddleware);
app.use(morgan("combined", { stream: accessLogStream }));
const { SERVER_PORT, MONGO_URL } = process.env;
router.use("/api", api.routes());
......
......@@ -1923,6 +1923,14 @@
}
}
},
"koa-morgan": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/koa-morgan/-/koa-morgan-1.0.1.tgz",
"integrity": "sha1-CAUuDODYOdPEMXi5CluzQkvvH5k=",
"requires": {
"morgan": "^1.6.1"
}
},
"koa-router": {
"version": "9.0.1",
"resolved": "https://registry.npmjs.org/koa-router/-/koa-router-9.0.1.tgz",
......
......@@ -17,6 +17,7 @@
"jsonwebtoken": "^8.5.1",
"koa": "^2.12.0",
"koa-bodyparser": "^4.3.0",
"koa-morgan": "^1.0.1",
"koa-router": "^9.0.1",
"mongoose": "^5.9.17",
"morgan": "^1.10.0",
......
const Joi = require("joi");
const User = require("../../models/user");
const Profile = require("../../models/profile");
/*
POST /api/auth/register
{
......@@ -27,10 +28,14 @@ exports.register = async (ctx) => {
ctx.status = 409;
return;
}
const profile = new Profile({
username,
});
const user = new User({
username,
});
await user.setPassword(password);
await profile.save();
await user.save();
ctx.body = user.serialize();
......
const Router = require("koa-router");
const profile = new Router();
const profileCtrl = require("./profile.ctrl");
profile.post("/solved:id");
profile.get("/solvednum:id");
profile.get("recommendps:id");
profile.get("/recommendps:id");
profile.patch("/syncBJ", profileCtrl.syncBJ);
profile.post("/setprofile", profileCtrl.setProfile);
module.exports = profile;
......
const Profile = require("../../models/profile");
const mongoose = require("mongoose");
const getBJ = require("../../util/getBJ");
const Joi = require("joi");
const { ObjectId } = mongoose.Types;
exports.checkObjectId = (ctx, next) => {
const { username } = ctx.request.body;
if (!ObjectId.isValid(username)) {
ctx.status = 400;
return;
}
return next();
};
/*
POST /api/proflie/setprofile
{
username: "username",
userBJID: "userBJID",
friendList: [String],
}
*/
exports.setProfile = async (ctx) => {
const schema = Joi.object()
.keys({
username: Joi.string(),
userBJID: Joi.string(),
//freindList: Joi.array().items(Joi.string()),
})
.unknown();
const result = Joi.validate(ctx.request.body, schema);
if (result.error) {
ctx.status = 400;
ctx.body = result.error;
return;
}
try {
const profile = await Profile.findOneAndUpdate(
{ username: ctx.request.body.username },
ctx.request.body,
{
new: true,
}
).exec();
if (!profile) {
ctx.status = 404;
return;
}
ctx.body = profile;
} catch (e) {
ctx.throw(500, e);
}
};
/*
PATCH /api/proflie/syncBJ
{
username: 'userid'
}
*/
exports.syncBJ = async function (ctx) {
const { username } = ctx.request.body;
if (!username) {
ctx.status = 401;
return;
}
try {
const profile = await Profile.findByUsername(username);
if (!profile) {
ctx.status = 401;
return;
}
const BJID = await profile.getBJID();
let BJdata = await getBJ.getBJ(BJID);
const updateprofile = await Profile.findOneAndUpdate(
{ username: username },
{ solvedBJ: BJdata },
{ new: true }
).exec();
ctx.body = updateprofile;
} catch (e) {
ctx.throw(500, e);
}
};
const mongoose = require("mongoose");
const { Schema } = mongoose;
const ProfileSchema = new Schema({
username: { type: String, required: true, unique: true },
userBJID: String,
solvedBJ: Object,
friendList: [String],
});
ProfileSchema.statics.findByUsername = function (username) {
return this.findOne({ username });
};
ProfileSchema.methods.getBJID = function () {
return this.userBJID;
};
ProfileSchema.methods.serialize = function () {
const data = this.toJSON();
return data;
};
const Profile = mongoose.model("Profile", ProfileSchema);
module.exports = Profile;
......@@ -3,7 +3,6 @@ const cheerio = require("cheerio");
const StringToDate = require("./StringToDate");
/*
ToDO
- 유저 네임 검증
- 예외 처리
*/
exports.getBJ = async function (userid) {
......