송용우

Fixed untracked files

1 -SERVER_PORT=4000
2 -MONGO_URL=mongodb://localhost:27017/jaksimsamil
3 -JWT_SECERET=fcbyHhPCxQYLLh98b97hdyAC6tGctHQ7rQDissQx
...\ No newline at end of file ...\ No newline at end of file
1 -{
2 - "parser": "babel-eslint",
3 - "env": {
4 - "commonjs": true,
5 - "es6": true,
6 - "node": true
7 - },
8 - "extends": "eslint:recommended",
9 - "globals": {
10 - "Atomics": "readonly",
11 - "SharedArrayBuffer": "readonly"
12 - },
13 - "parserOptions": {
14 - "ecmaVersion": 11
15 - },
16 - "rules": {}
17 -}
1 -# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 -
3 -# dotenv
4 -.env
5 -
6 -# dependencies
7 -/node_modules
1 -# Jaksimsamil API Documentation
2 -
3 -## Overview
4 -
5 -- TBA
6 -
7 -## URL
8 -
9 -- TBA
10 -
11 -## Usage
12 -
13 -- TBA
14 -
15 -## Example
16 -
17 -- TBA
18 -
19 -## API Table
20 -
21 -| group | description | method | URL | Detail | Auth |
22 -| ------- | ------------------------ | ------ | -------------------------- | -------- | --------- |
23 -| user | 유저 등록 | POST | api/user | 바로가기 | JWT Token |
24 -| user | 유저 삭제 | DELETE | api/user:id | 바로가기 | JWT Token |
25 -| user | 특정 유저 조회 | GET | api/user:id | 바로가기 | None |
26 -| user | 전체 유저 조회 | GET | api/user | 바로가기 | JWT Token |
27 -| friend | 유저 친구 등록 | POST | api/friend | 바로가기 | JWT Token |
28 -| friend | 유저의 친구 조회 | GET | api/friend:id | 바로가기 | None |
29 -| profile | 유저가 푼 문제 조회 | GET | api/profile/solved:id | 바로가기 | None |
30 -| profile | 유저가 푼 문제 개수 조회 | GET | api/profile/solvednum:id | 바로가기 | None |
31 -| profile | 추천 문제 조회 | GET | api/profile/recommendps:id | 바로가기 | None |
32 -| notify | 슬랙 메시지 전송 요청 | POST | api/notify/slack | 바로가기 | Jwt Token |
33 -| auth | 로그인 | POST | api/auth/login | 바로가기 | None |
34 -| auth | 로그아웃 | GET | api/auth/logout | 바로가기 | JWT Token |
35 -| auth | 회원가입 | POST | api/auth/register | 바로가기 | None |
36 -| auth | 로그인 확인 | GET | api/auth/check | 바로가기 | None |
1 -const express = require("express");
2 -const morgan = require("morgan");
3 -const mongoose = require("mongoose");
4 -const app = express();
5 -const bodyParser = require("body-parser");
6 -const api = require("./src/api");
7 -const jwtMiddleware = require("./src/lib/jwtMiddleware");
8 -require("dotenv").config();
9 -const { SERVER_PORT, MONGO_URL } = process.env;
10 -app.use(morgan("dev"));
11 -app.use(express.json());
12 -app.use(express.urlencoded({ extended: false }));
13 -app.use(bodyParser());
14 -app.use(jwtMiddleware);
15 -
16 -app.use("/api", api);
17 -mongoose
18 - .connect(MONGO_URL, { useNewUrlParser: true, useFindAndModify: false })
19 - .then(() => {
20 - console.log("Connected to MongoDB");
21 - })
22 - .catch((e) => {
23 - console.log(e);
24 - });
25 -app.listen(SERVER_PORT, () => {
26 - console.log("Server is running on port", process.env.SERVER_PORT);
27 -});
1 -{
2 - "name": "jaksimsamil-server",
3 - "version": "1.0.0",
4 - "main": "index.js",
5 - "license": "MIT",
6 - "dependencies": {
7 - "bcrypt": "^4.0.1",
8 - "body-parser": "^1.19.0",
9 - "dotenv": "^8.2.0",
10 - "eslint-config-prettier": "^6.11.0",
11 - "express": "^4.17.1",
12 - "fs": "^0.0.1-security",
13 - "joi": "^14.3.1",
14 - "jsonwebtoken": "^8.5.1",
15 - "mongoose": "^5.9.17",
16 - "morgan": "^1.10.0",
17 - "path": "^0.12.7"
18 - },
19 - "devDependencies": {
20 - "babel-eslint": "^10.1.0",
21 - "eslint": "^7.1.0",
22 - "nodemon": "^2.0.4"
23 - },
24 - "scripts": {
25 - "start": "node src",
26 - "start:dev": "nodemon --watch src/ src/index.js"
27 - }
28 -}
1 -const Joi = require("joi");
2 -const User = require("../../models/user");
3 -/*
4 -POST /api/auth/register
5 -{
6 - username: 'userid'
7 - password: 'userpassword'
8 -}
9 -*/
10 -exports.register = async (ctx) => {
11 - const schema = Joi.object().keys({
12 - username: Joi.string().alphanum().min(3).max(20).required(),
13 - password: Joi.string().required(),
14 - });
15 - const result = Joi.validate(ctx.request.body, schema);
16 - if (result.error) {
17 - ctx.status = 400;
18 - ctx.body = result.error;
19 - return;
20 - }
21 -
22 - const { username, password } = ctx.request.body;
23 - try {
24 - const isNameExist = await User.findByUsername(username);
25 - if (isNameExist) {
26 - ctx.status = 409;
27 - return;
28 - }
29 - const user = new User({
30 - username,
31 - });
32 - await user.setPassword(password);
33 - await user.save();
34 - ctx.body = user.serialize();
35 -
36 - const token = user.generateToekn();
37 - ctx.cookies.set("acces_token", token, {
38 - //3일동안 유효
39 - maxAge: 1000 * 60 * 60 * 24 * 3,
40 - httpOnly: true,
41 - });
42 - } catch (e) {
43 - ctx.throw(500, e);
44 - }
45 -};
46 -/*
47 -POST /api/auth/login
48 -{
49 - username: 'userid'
50 - password: 'userpassword'
51 -}
52 - */
53 -exports.login = async (ctx) => {
54 - const { username, password } = ctx.request.body;
55 - if (!username || !password) {
56 - ctx.status = 401;
57 - return;
58 - }
59 - try {
60 - const user = await User.findByUsername(username);
61 - if (!user) {
62 - ctx.status = 401;
63 - return;
64 - }
65 - const isPasswordValid = await user.checkPassword(password);
66 - if (!isPasswordValid) {
67 - ctx.status = 401;
68 - return;
69 - }
70 - ctx.body = user.serialize();
71 - const token = user.generateToken();
72 - ctx.cookies.set("acces_token", token, {
73 - //7일동안 유효
74 - maxAge: 1000 * 60 * 60 * 24 * 7,
75 - httpOnly: true,
76 - });
77 - } catch (e) {
78 - ctx.throw(500, e);
79 - }
80 -};
81 -/*
82 -GET api/auth/check
83 -*/
84 -exports.check = async (ctx) => {
85 - const { user } = ctx.state;
86 - if (!user) {
87 - ctx.status = 401;
88 - return;
89 - }
90 - ctx.body = user;
91 -};
92 -/*
93 -POST /api/auth/logout
94 -*/
95 -exports.logout = async (ctx) => {
96 - ctx.cookies.set("access_token");
97 - ctx.status = 204;
98 -};
1 -const express = require("express");
2 -const router = express.Router();
3 -
4 -router.post("/login");
5 -router.get("/logout");
6 -router.post("/register");
7 -
8 -
9 -
10 -
11 -module.exports = router;
1 -const express = require("express");
2 -const router = express.Router();
3 -
4 -router.post("/");
5 -router.delete("/:id");
6 -router.get("/:id");
7 -router.get("");
8 -
9 -module.exports = router;
1 -const express = require("express");
2 -const app = express();
3 -
4 -const auth = require("./auth");
5 -const friend = require("./friend");
6 -const notify = require("./profile");
7 -const user = require("./user");
8 -const profile = require("./profile");
9 -
10 -app.use("/auth", auth);
11 -app.use("/friend", friend);
12 -app.use("/notify", notify);
13 -app.use("/user", user);
14 -app.use("/profile", profile);
15 -
16 -module.exports = app;
1 -const express = require("express");
2 -const router = express.Router();
3 -
4 -router.post("/slack");
5 -
6 -module.exports = router;
1 -const express = require("express");
2 -const router = express.Router();
3 -
4 -router.post("/solved:id");
5 -router.get("/solvednum:id");
6 -router.get("recommendps:id");
7 -
8 -module.exports = router;
1 -const express = require("express");
2 -const router = express.Router();
3 -
4 -router.post("/");
5 -router.delete("/:id");
6 -router.get("/:id");
7 -router.get("");
8 -
9 -module.exports = router;
1 -const jwt = require("jsonwebtoken");
2 -const User = require("../models/user");
3 -const jwtMiddleware = async (ctx, next) => {
4 - const token = ctx.cookies.get("access_token");
5 - if (!token) {
6 - //토큰이 없을 때
7 - return next();
8 - }
9 - try {
10 - const decoded = jwt.verify(token, process.env.JWT_TOKEN);
11 - ctx.state.user = {
12 - _id: decoded._id,
13 - username: decoded.username,
14 - };
15 - //토큰의 남은 유효 기간이 2일 이하라면 재발급
16 - if (decoded.exp - Date.now() / 1000 < 60 * 60 * 24 * 2) {
17 - const user = await User.findById(decoded._id);
18 - const token = user.generateToken();
19 - ctx.cookies.set("access_token", token, {
20 - maxAge: 1000 * 60 * 60 * 24 * 7,
21 - httpOnly: true,
22 - });
23 - }
24 - return next();
25 - } catch (e) {
26 - return next();
27 - }
28 -};
29 -
30 -module.exports = jwtMiddleware;
1 -const mongoose = require("mongoose");
2 -const bcrypt = require("bcrypt");
3 -const jwt = require("jsonwebtoken");
4 -const Schema = mongoose.Schema;
5 -
6 -const UserSchema = new Schema({
7 - username: String,
8 - hashedPassword: String,
9 -});
10 -
11 -UserSchema.methods.setPassword = async function (password) {
12 - const hash = await bcrypt.hash(password, 10);
13 - this.hashedPassword = hash;
14 -};
15 -UserSchema.methodss.checkPassword = async function (password) {
16 - const result = await bcrypt.compare(password, this.hashedPassword);
17 - return result;
18 -};
19 -UserSchema.statics.findByUsername = function (username) {
20 - return this.findOne({ username });
21 -};
22 -UserSchema.methods.serialize = function () {
23 - const data = this.toJSON();
24 - delete data.hashedPassword;
25 - return data;
26 -};
27 -UserSchema.methods.generateToken = function () {
28 - const token = jwt.sign(
29 - {
30 - _id: this.id,
31 - username: this.username,
32 - },
33 - process.env.JWT_SECRET,
34 - {
35 - expiresIn: "7d",
36 - }
37 - );
38 - return token;
39 -};
40 -const User = mongoose.model("User", UserSchema);
41 -module.exports = User;
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.