송용우

Merge commit '552b33f3' into develop

...@@ -3,5 +3,8 @@ ...@@ -3,5 +3,8 @@
3 # dotenv 3 # dotenv
4 .env 4 .env
5 5
6 +#access.log
7 +access.log
8 +
6 # dependencies 9 # dependencies
7 /node_modules 10 /node_modules
......
...@@ -19,17 +19,17 @@ ...@@ -19,17 +19,17 @@
19 ## API Table 19 ## API Table
20 20
21 | group | description | method | URL | Detail | Auth | 21 | group | description | method | URL | Detail | Auth |
22 -| ------- | ------------------------ | ------ | -------------------------- | -------- | --------- | 22 +| ------- | --------------------------- | ------ | ------------------------ | -------- | --------- |
23 | user | 유저 등록 | POST | api/user | 바로가기 | JWT Token | 23 | user | 유저 등록 | POST | api/user | 바로가기 | JWT Token |
24 | user | 유저 삭제 | DELETE | api/user:id | 바로가기 | JWT Token | 24 | user | 유저 삭제 | DELETE | api/user:id | 바로가기 | JWT Token |
25 | user | 특정 유저 조회 | GET | api/user:id | 바로가기 | None | 25 | user | 특정 유저 조회 | GET | api/user:id | 바로가기 | None |
26 | user | 전체 유저 조회 | GET | api/user | 바로가기 | JWT Token | 26 | user | 전체 유저 조회 | GET | api/user | 바로가기 | JWT Token |
27 | friend | 유저 친구 등록 | POST | api/friend | 바로가기 | JWT Token | 27 | friend | 유저 친구 등록 | POST | api/friend | 바로가기 | JWT Token |
28 | friend | 유저의 친구 조회 | GET | api/friend:id | 바로가기 | None | 28 | friend | 유저의 친구 조회 | GET | api/friend:id | 바로가기 | None |
29 -| profile | 유저가 푼 문제 조회 | GET | api/profile/solved:id | 바로가기 | None | 29 +| profile | 유저가 푼 문제 조회(백준) | GET | api/profile/solvedBJ:id | 바로가기 | None |
30 -| profile | 유저가 푼 문제 동기화 | Update | api/profile/solved:id | 바로가기 | None | 30 +| profile | 유저가 푼 문제 동기화(백준) | PATCH | api/profile/syncBJ | 바로가기 | None |
31 -| profile | 유저가 푼 문제 개수 조회 | GET | api/profile/solvednum:id | 바로가기 | None | 31 +| profile | 유저 정보 수정 | POST | api/profile/setprofile | 바로가기 | JWT TOKEN |
32 -| profile | 추천 문제 조회 | GET | api/profile/recommendps:id | 바로가기 | None | 32 +| profile | 추천 문제 조회 | GET | api/profile/recommend:id | 바로가기 | None |
33 | notify | 슬랙 메시지 전송 요청 | POST | api/notify/slack | 바로가기 | Jwt Token | 33 | notify | 슬랙 메시지 전송 요청 | POST | api/notify/slack | 바로가기 | Jwt Token |
34 | auth | 로그인 | POST | api/auth/login | 바로가기 | None | 34 | auth | 로그인 | POST | api/auth/login | 바로가기 | None |
35 | auth | 로그아웃 | GET | api/auth/logout | 바로가기 | JWT Token | 35 | auth | 로그아웃 | GET | api/auth/logout | 바로가기 | JWT Token |
......
...@@ -2,6 +2,8 @@ const Koa = require("koa"); ...@@ -2,6 +2,8 @@ const Koa = require("koa");
2 const Router = require("koa-router"); 2 const Router = require("koa-router");
3 const bodyParser = require("koa-bodyparser"); 3 const bodyParser = require("koa-bodyparser");
4 const mongoose = require("mongoose"); 4 const mongoose = require("mongoose");
5 +const fs = require("fs");
6 +const morgan = require("koa-morgan");
5 const jwtMiddleware = require("./src/lib/jwtMiddleware"); 7 const jwtMiddleware = require("./src/lib/jwtMiddleware");
6 const api = require("./src/api"); 8 const api = require("./src/api");
7 9
...@@ -9,10 +11,13 @@ require("dotenv").config(); ...@@ -9,10 +11,13 @@ require("dotenv").config();
9 11
10 const app = new Koa(); 12 const app = new Koa();
11 const router = new Router(); 13 const router = new Router();
12 - 14 +const accessLogStream = fs.createWriteStream(__dirname + "/access.log", {
15 + flags: "a",
16 +});
17 +require("dotenv").config();
13 app.use(bodyParser()); 18 app.use(bodyParser());
14 app.use(jwtMiddleware); 19 app.use(jwtMiddleware);
15 - 20 +app.use(morgan("combined", { stream: accessLogStream }));
16 const { SERVER_PORT, MONGO_URL } = process.env; 21 const { SERVER_PORT, MONGO_URL } = process.env;
17 22
18 router.use("/api", api.routes()); 23 router.use("/api", api.routes());
......
...@@ -1923,6 +1923,14 @@ ...@@ -1923,6 +1923,14 @@
1923 } 1923 }
1924 } 1924 }
1925 }, 1925 },
1926 + "koa-morgan": {
1927 + "version": "1.0.1",
1928 + "resolved": "https://registry.npmjs.org/koa-morgan/-/koa-morgan-1.0.1.tgz",
1929 + "integrity": "sha1-CAUuDODYOdPEMXi5CluzQkvvH5k=",
1930 + "requires": {
1931 + "morgan": "^1.6.1"
1932 + }
1933 + },
1926 "koa-router": { 1934 "koa-router": {
1927 "version": "9.0.1", 1935 "version": "9.0.1",
1928 "resolved": "https://registry.npmjs.org/koa-router/-/koa-router-9.0.1.tgz", 1936 "resolved": "https://registry.npmjs.org/koa-router/-/koa-router-9.0.1.tgz",
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
17 "jsonwebtoken": "^8.5.1", 17 "jsonwebtoken": "^8.5.1",
18 "koa": "^2.12.0", 18 "koa": "^2.12.0",
19 "koa-bodyparser": "^4.3.0", 19 "koa-bodyparser": "^4.3.0",
20 + "koa-morgan": "^1.0.1",
20 "koa-router": "^9.0.1", 21 "koa-router": "^9.0.1",
21 "mongoose": "^5.9.17", 22 "mongoose": "^5.9.17",
22 "morgan": "^1.10.0", 23 "morgan": "^1.10.0",
......
1 const Joi = require("joi"); 1 const Joi = require("joi");
2 const User = require("../../models/user"); 2 const User = require("../../models/user");
3 +const Profile = require("../../models/profile");
3 /* 4 /*
4 POST /api/auth/register 5 POST /api/auth/register
5 { 6 {
...@@ -27,10 +28,14 @@ exports.register = async (ctx) => { ...@@ -27,10 +28,14 @@ exports.register = async (ctx) => {
27 ctx.status = 409; 28 ctx.status = 409;
28 return; 29 return;
29 } 30 }
31 + const profile = new Profile({
32 + username,
33 + });
30 const user = new User({ 34 const user = new User({
31 username, 35 username,
32 }); 36 });
33 await user.setPassword(password); 37 await user.setPassword(password);
38 + await profile.save();
34 await user.save(); 39 await user.save();
35 ctx.body = user.serialize(); 40 ctx.body = user.serialize();
36 41
......
1 const Router = require("koa-router"); 1 const Router = require("koa-router");
2 const profile = new Router(); 2 const profile = new Router();
3 +const profileCtrl = require("./profile.ctrl");
3 4
4 profile.post("/solved:id"); 5 profile.post("/solved:id");
5 profile.get("/solvednum:id"); 6 profile.get("/solvednum:id");
6 -profile.get("recommendps:id"); 7 +profile.get("/recommendps:id");
7 - 8 +profile.patch("/syncBJ", profileCtrl.syncBJ);
9 +profile.post("/setprofile", profileCtrl.setProfile);
8 module.exports = profile; 10 module.exports = profile;
......
1 +const Profile = require("../../models/profile");
2 +const mongoose = require("mongoose");
3 +const getBJ = require("../../util/getBJ");
4 +const Joi = require("joi");
5 +
6 +const { ObjectId } = mongoose.Types;
7 +
8 +exports.checkObjectId = (ctx, next) => {
9 + const { username } = ctx.request.body;
10 + if (!ObjectId.isValid(username)) {
11 + ctx.status = 400;
12 + return;
13 + }
14 + return next();
15 +};
16 +/*
17 +POST /api/proflie/setprofile
18 +{
19 + username: "username",
20 + userBJID: "userBJID",
21 + friendList: [String],
22 +}
23 + */
24 +exports.setProfile = async (ctx) => {
25 + const schema = Joi.object()
26 + .keys({
27 + username: Joi.string(),
28 + userBJID: Joi.string(),
29 + //freindList: Joi.array().items(Joi.string()),
30 + })
31 + .unknown();
32 +
33 + const result = Joi.validate(ctx.request.body, schema);
34 + if (result.error) {
35 + ctx.status = 400;
36 + ctx.body = result.error;
37 + return;
38 + }
39 +
40 + try {
41 + const profile = await Profile.findOneAndUpdate(
42 + { username: ctx.request.body.username },
43 + ctx.request.body,
44 + {
45 + new: true,
46 + }
47 + ).exec();
48 +
49 + if (!profile) {
50 + ctx.status = 404;
51 + return;
52 + }
53 + ctx.body = profile;
54 + } catch (e) {
55 + ctx.throw(500, e);
56 + }
57 +};
58 +/*
59 +PATCH /api/proflie/syncBJ
60 +{
61 + username: 'userid'
62 +}
63 + */
64 +exports.syncBJ = async function (ctx) {
65 + const { username } = ctx.request.body;
66 +
67 + if (!username) {
68 + ctx.status = 401;
69 + return;
70 + }
71 +
72 + try {
73 + const profile = await Profile.findByUsername(username);
74 + if (!profile) {
75 + ctx.status = 401;
76 + return;
77 + }
78 + const BJID = await profile.getBJID();
79 + let BJdata = await getBJ.getBJ(BJID);
80 + const updateprofile = await Profile.findOneAndUpdate(
81 + { username: username },
82 + { solvedBJ: BJdata },
83 + { new: true }
84 + ).exec();
85 + ctx.body = updateprofile;
86 + } catch (e) {
87 + ctx.throw(500, e);
88 + }
89 +};
1 +const mongoose = require("mongoose");
2 +
3 +const { Schema } = mongoose;
4 +
5 +const ProfileSchema = new Schema({
6 + username: { type: String, required: true, unique: true },
7 + userBJID: String,
8 + solvedBJ: Object,
9 + friendList: [String],
10 +});
11 +ProfileSchema.statics.findByUsername = function (username) {
12 + return this.findOne({ username });
13 +};
14 +ProfileSchema.methods.getBJID = function () {
15 + return this.userBJID;
16 +};
17 +
18 +ProfileSchema.methods.serialize = function () {
19 + const data = this.toJSON();
20 + return data;
21 +};
22 +const Profile = mongoose.model("Profile", ProfileSchema);
23 +module.exports = Profile;
...@@ -3,7 +3,6 @@ const cheerio = require("cheerio"); ...@@ -3,7 +3,6 @@ const cheerio = require("cheerio");
3 const StringToDate = require("./StringToDate"); 3 const StringToDate = require("./StringToDate");
4 /* 4 /*
5 ToDO 5 ToDO
6 -- 유저 네임 검증
7 - 예외 처리 6 - 예외 처리
8 */ 7 */
9 exports.getBJ = async function (userid) { 8 exports.getBJ = async function (userid) {
......