HyeonJun Jeon

[Modify] Migrate scheduleData to DB

This diff is collapsed. Click to expand it.
...@@ -9,10 +9,12 @@ ...@@ -9,10 +9,12 @@
9 "axios": "^0.27.2", 9 "axios": "^0.27.2",
10 "body-parser": "^1.20.0", 10 "body-parser": "^1.20.0",
11 "cors": "^2.8.5", 11 "cors": "^2.8.5",
12 + "crypto-js": "^4.1.1",
12 "express": "^4.18.1", 13 "express": "^4.18.1",
13 "fs": "^0.0.1-security", 14 "fs": "^0.0.1-security",
14 "localforage": "^1.10.0", 15 "localforage": "^1.10.0",
15 "mysql": "^2.18.1", 16 "mysql": "^2.18.1",
17 + "mysql2": "^2.3.3",
16 "puppeteer": "^14.1.1", 18 "puppeteer": "^14.1.1",
17 "react": "^18.1.0", 19 "react": "^18.1.0",
18 "react-dom": "^18.1.0", 20 "react-dom": "^18.1.0",
......
1 const express = require("express"); 1 const express = require("express");
2 -const mysql = require("mysql"); 2 +const mysql = require("mysql2/promise");
3 const fs = require("fs"); 3 const fs = require("fs");
4 const router = express.Router(); 4 const router = express.Router();
5 5
6 -const [id, pw] = fs 6 +async function route() {
7 - .readFileSync("server/libs/sql.pvdata", "utf8") 7 + const [id, pw] = fs
8 - .split("\r\n"); 8 + .readFileSync("server/libs/sql.pvdata", "utf8")
9 - 9 + .split("\r\n");
10 -const connection = mysql.createConnection({ 10 + const connection = await mysql.createConnection({
11 - host: "localhost", 11 + host: "localhost",
12 - user: id, 12 + user: id,
13 - password: pw, 13 + password: pw,
14 - database: "mydb", 14 + database: "db",
15 -});
16 -
17 -router.get("/", (req, res) => {
18 - res.send("DB Root");
19 -});
20 -
21 -router.get("/mytable", (req, res) => {
22 - connection.query("SELECT * from mytable", (error, rows) => {
23 - if (error) throw error;
24 - console.log(rows);
25 - res.send(rows);
26 }); 15 });
27 -}); 16 +
17 + // (userID, date) => schedules
18 + router.get("/schedules_date", async (req, res) => {
19 + console.log("/db/schedules_date");
20 + try {
21 + const queryString = `
22 + SELECT sc.label, sc.type, sc.description, sc.url, sc.detail, sbj.name, us.color
23 + FROM schedules_date sc
24 + INNER JOIN \`user-subject\` us
25 + ON sc.userID = us.userID
26 + AND sc.subjectID = us.subjectID
27 + AND us.status = 1
28 + INNER JOIN subjects sbj
29 + ON sc.subjectID = sbj.ID
30 + WHERE sc.date = "${req.query.date}"
31 + AND sc.userID = ${req.query.userID}
32 + AND sc.status = 1`;
33 + const [results] = await connection.query(queryString);
34 + res.send(results);
35 + } catch (e) {
36 + console.log(e);
37 + res.end();
38 + }
39 + });
40 +
41 + // (ID) => null | name //unused
42 + router.get("/subjects", async (req, res) => {
43 + console.log("/db/subjects");
44 + try {
45 + const queryString = `
46 + SELECT name FROM subjects sbj
47 + WHERE sbj.ID = ${req.query.ID}`;
48 + const [results] = await connection.query(queryString);
49 + res.send(results.length && results[0].name);
50 + } catch (e) {
51 + console.log(e);
52 + res.end();
53 + }
54 + });
55 +
56 + // (loginID) => null | ID(str)
57 + router.get("/users", async (req, res) => {
58 + console.log("/db/users");
59 + try {
60 + const queryString = `
61 + SELECT ID FROM users us
62 + WHERE us.loginID = '${req.query.loginID}'`;
63 + const [results] = await connection.query(queryString);
64 + res.send(results.length ? results[0].ID.toString() : null);
65 + } catch (e) {
66 + console.log(e);
67 + res.end();
68 + }
69 + });
70 +
71 + // (loginID, loginPW) => null | "correct"
72 + router.get("/users/check", async (req, res) => {
73 + console.log("/db/users/check");
74 + try {
75 + const queryString = `
76 + SELECT loginPW FROM users us
77 + WHERE us.loginID = '${req.query.loginID}'`;
78 + const [results] = await connection.query(queryString);
79 + res.send(results[0].loginPW === req.query.loginPW ? "correct" : null);
80 + } catch (e) {
81 + console.log(e);
82 + res.end();
83 + }
84 + });
85 +
86 + // (userID) => subjects
87 + router.get("/user-subject", async (req, res) => {
88 + console.log("/db/user-subject");
89 + try {
90 + const queryString = `
91 + SELECT subjectID, nickname, status, color FROM \`user-subject\` us
92 + WHERE us.userID = ${req.query.userID}`;
93 + const [results] = await connection.query(queryString);
94 + res.send(results);
95 + } catch (e) {
96 + console.log(e);
97 + res.end();
98 + }
99 + });
100 +
101 + router.get("*", (req, res) => {
102 + console.log("/db/*");
103 + res.end();
104 + });
105 +}
106 +
107 +route();
28 108
29 module.exports = router; 109 module.exports = router;
......
...@@ -15,8 +15,10 @@ app.use( ...@@ -15,8 +15,10 @@ app.use(
15 credentials: true, 15 credentials: true,
16 }) 16 })
17 ); 17 );
18 -app.use(bodyParser.urlencoded({ extended: false })); 18 +// app.use(bodyParser.urlencoded({ extended: false }));
19 -app.use(bodyParser.json()); 19 +// app.use(bodyParser.json());
20 +app.use(express.json());
21 +app.use(express.urlencoded({ extended: true }));
20 22
21 app.post("/", (req, res) => { 23 app.post("/", (req, res) => {
22 res.send({ body: req.body }); 24 res.send({ body: req.body });
......
1 import { useContext, useEffect, useState } from "react"; 1 import { useContext, useEffect, useState } from "react";
2 +import localforage from "localforage";
2 3
3 import { toYMD, toYMDStr } from "../utils/Dates"; 4 import { toYMD, toYMDStr } from "../utils/Dates";
4 import { scheForage } from "../utils/LocalForage"; 5 import { scheForage } from "../utils/LocalForage";
5 6
6 import { CalendarStateContext } from "../pages/Calendar"; 7 import { CalendarStateContext } from "../pages/Calendar";
7 import ScheduleItem from "./ScheduleItem"; 8 import ScheduleItem from "./ScheduleItem";
9 +import axios from "axios";
8 10
9 const GridItem = ({ targetDate }) => { 11 const GridItem = ({ targetDate }) => {
10 const { state } = useContext(CalendarStateContext); 12 const { state } = useContext(CalendarStateContext);
...@@ -14,7 +16,14 @@ const GridItem = ({ targetDate }) => { ...@@ -14,7 +16,14 @@ const GridItem = ({ targetDate }) => {
14 16
15 useEffect(() => { 17 useEffect(() => {
16 async function loadScheduleItems() { 18 async function loadScheduleItems() {
17 - setSchedules(await scheForage.getItem(toYMDStr(targetDate))); 19 + const userID = await localforage.getItem("userID");
20 + const res = await axios.get("http://localhost:3001/db/schedules_date", {
21 + params: {
22 + userID,
23 + date: toYMDStr(targetDate, "-"),
24 + },
25 + });
26 + setSchedules(res.data);
18 } 27 }
19 loadScheduleItems(); 28 loadScheduleItems();
20 }, [targetDate]); 29 }, [targetDate]);
......
1 +import localforage from "localforage";
1 import { useContext } from "react"; 2 import { useContext } from "react";
2 import { useNavigate } from "react-router-dom"; 3 import { useNavigate } from "react-router-dom";
3 4
4 import { CalendarStateContext } from "../pages/Calendar"; 5 import { CalendarStateContext } from "../pages/Calendar";
5 import "../styles/Header.css"; 6 import "../styles/Header.css";
6 import { moveDate, toYMD } from "../utils/Dates"; 7 import { moveDate, toYMD } from "../utils/Dates";
7 -import { dataForage } from "../utils/LocalForage";
8 8
9 const Header = () => { 9 const Header = () => {
10 const { state, setState } = useContext(CalendarStateContext); 10 const { state, setState } = useContext(CalendarStateContext);
...@@ -93,7 +93,7 @@ const Header = () => { ...@@ -93,7 +93,7 @@ const Header = () => {
93 <button 93 <button
94 className="hrb_r" 94 className="hrb_r"
95 onClick={async () => { 95 onClick={async () => {
96 - await dataForage.setItem("session", ""); 96 + await localforage.setItem("session", null);
97 navigate("/"); 97 navigate("/");
98 }} 98 }}
99 > 99 >
......
...@@ -5,14 +5,17 @@ import zoomSymbol from "../assets/zoom.png"; ...@@ -5,14 +5,17 @@ import zoomSymbol from "../assets/zoom.png";
5 import ecampusSymbol from "../assets/e-Campus.png"; 5 import ecampusSymbol from "../assets/e-Campus.png";
6 6
7 const ScheduleItem = ({ schedule }) => { 7 const ScheduleItem = ({ schedule }) => {
8 - const { subCode, type, category, label, start, end } = schedule; 8 + const {
9 - const { subsObj } = useContext(CalendarStateContext); 9 + name: subjectName,
10 - const subject = subsObj[subCode]; 10 + color: subjectColor,
11 - if (!subject) { 11 + type,
12 - console.log("can't find " + subCode); 12 + label,
13 - return; 13 + description,
14 - } 14 + url,
15 - if (!subject.selected) return; 15 + detail,
16 + startTime = null,
17 + endTime = null,
18 + } = schedule;
16 19
17 const selectSymbol = () => { 20 const selectSymbol = () => {
18 let symbol; 21 let symbol;
...@@ -20,7 +23,7 @@ const ScheduleItem = ({ schedule }) => { ...@@ -20,7 +23,7 @@ const ScheduleItem = ({ schedule }) => {
20 case "zoom": 23 case "zoom":
21 symbol = zoomSymbol; 24 symbol = zoomSymbol;
22 break; 25 break;
23 - case "ecampus": 26 + case "assignment":
24 symbol = ecampusSymbol; 27 symbol = ecampusSymbol;
25 break; 28 break;
26 default: 29 default:
...@@ -29,11 +32,15 @@ const ScheduleItem = ({ schedule }) => { ...@@ -29,11 +32,15 @@ const ScheduleItem = ({ schedule }) => {
29 }; 32 };
30 33
31 return ( 34 return (
32 - <div className="ScheduleItem" style={{ borderColor: subject.color }}> 35 + <div className="ScheduleItem" style={{ borderColor: subjectColor }}>
33 <img className="s_symbol" src={selectSymbol()} alt="404" /> 36 <img className="s_symbol" src={selectSymbol()} alt="404" />
34 - {start && <span className="s_start">{start[0] + ":" + start[1]}</span>} 37 + {startTime && (
35 - {end && <span className="s_end">{end[0] + ":" + end[1]}</span>} 38 + <span className="s_start">{startTime[0] + ":" + startTime[1]}</span>
36 - <span className="s_category">{category}</span> 39 + )}
40 + {endTime && (
41 + <span className="s_end">{endTime[0] + ":" + endTime[1]}</span>
42 + )}
43 + {/* <span className="s_category">{subjectName}</span> */}
37 <span className="s_slabel">{label}</span> 44 <span className="s_slabel">{label}</span>
38 </div> 45 </div>
39 ); 46 );
......
1 import React, { useEffect, useReducer, useState } from "react"; 1 import React, { useEffect, useReducer, useState } from "react";
2 import { useNavigate, Route, Routes } from "react-router-dom"; 2 import { useNavigate, Route, Routes } from "react-router-dom";
3 3
4 -import { initTempSubjects } from "../utils/Test"; 4 +import { subForage } from "../utils/LocalForage";
5 -import { dataForage, subForage } from "../utils/LocalForage";
6 5
7 import Month from "../components/Month"; 6 import Month from "../components/Month";
8 import Header from "../components/Header"; 7 import Header from "../components/Header";
9 import Side from "../components/Side"; 8 import Side from "../components/Side";
9 +import localforage from "localforage";
10 +import axios from "axios";
10 11
11 export const CalendarStateContext = React.createContext(); 12 export const CalendarStateContext = React.createContext();
12 13
...@@ -36,12 +37,17 @@ const Calendar = () => { ...@@ -36,12 +37,17 @@ const Calendar = () => {
36 const navigate = useNavigate(); 37 const navigate = useNavigate();
37 useEffect(() => { 38 useEffect(() => {
38 async function onMount() { 39 async function onMount() {
39 - if (!(await dataForage.getItem("session"))) return navigate("/login"); 40 + if (!(await localforage.getItem("session"))) return navigate("/login");
40 - 41 + // get user's subjects
41 - if (!(await dataForage.getItem("Subjects"))) await initTempSubjects(); 42 + const userID = await localforage.getItem("userID");
43 + const subjects = await axios.get(
44 + "http://localhost:3001/db/user-subject",
45 + { params: { userID } }
46 + ).data;
47 + console.log(subjects);
42 let tsubsObj = {}; 48 let tsubsObj = {};
43 - for (const code of await dataForage.getItem("Subjects")) { 49 + for (const sub of subjects) {
44 - tsubsObj[code] = await subForage.getItem(code); 50 + tsubsObj[sub.subjectID] = sub;
45 } 51 }
46 dispatch({ type: "INIT", subsObj: tsubsObj }); 52 dispatch({ type: "INIT", subsObj: tsubsObj });
47 } 53 }
......
1 +import localforage from "localforage";
1 import { useEffect } from "react"; 2 import { useEffect } from "react";
2 import { useNavigate } from "react-router-dom"; 3 import { useNavigate } from "react-router-dom";
3 4
4 -import { dataForage } from "../utils/LocalForage";
5 -
6 const Home = () => { 5 const Home = () => {
7 console.log("visit Home"); 6 console.log("visit Home");
8 7
...@@ -10,7 +9,7 @@ const Home = () => { ...@@ -10,7 +9,7 @@ const Home = () => {
10 useEffect(() => { 9 useEffect(() => {
11 async function where() { 10 async function where() {
12 let destination; 11 let destination;
13 - if (await dataForage.getItem("session")) { 12 + if (await localforage.getItem("session")) {
14 destination = "/calendar/month"; 13 destination = "/calendar/month";
15 } else { 14 } else {
16 destination = "/login"; 15 destination = "/login";
......
1 import { useEffect, useState } from "react"; 1 import { useEffect, useState } from "react";
2 import { useNavigate } from "react-router-dom"; 2 import { useNavigate } from "react-router-dom";
3 +import localforage from "localforage";
3 4
4 -import { dataForage } from "../utils/LocalForage";
5 import "../styles/Login.css"; 5 import "../styles/Login.css";
6 import axios from "axios"; 6 import axios from "axios";
7 +import cryptoJs from "crypto-js";
7 8
8 const Login = () => { 9 const Login = () => {
9 console.log("visit Login"); 10 console.log("visit Login");
10 const [state, setState] = useState({ 11 const [state, setState] = useState({
11 id: "", 12 id: "",
12 pw: "", 13 pw: "",
14 + btn: "Login",
13 }); 15 });
14 16
15 const handleChangeState = (e) => { 17 const handleChangeState = (e) => {
...@@ -21,21 +23,57 @@ const Login = () => { ...@@ -21,21 +23,57 @@ const Login = () => {
21 23
22 const navigate = useNavigate(); 24 const navigate = useNavigate();
23 const login = async () => { 25 const login = async () => {
24 - const res = await axios.post("http://localhost:3001/login/", { 26 + setState({ ...state, btn: "Login..." });
25 - id: state.id, 27 + const { data: userDBID } = await axios.get(
26 - pw: state.pw, 28 + "http://localhost:3001/db/users",
27 - }); 29 + {
30 + params: {
31 + loginID: state.id,
32 + },
33 + }
34 + );
28 35
29 - if (res.data === "login failed") alert("ID/PW를 확인해주세요"); 36 + if (userDBID) {
30 - else { 37 + //pass crawling
31 - await dataForage.setItem("session", true); 38 + const hashpw = cryptoJs.SHA256(state.pw).toString();
32 - navigate("/"); 39 + const { data: isCorrectPW } = await axios.get(
40 + "http://localhost:3001/db/users/check",
41 + {
42 + params: { loginID: state.id, loginPW: hashpw },
43 + }
44 + );
45 + if (isCorrectPW) await localforage.setItem("userID", Number(userDBID));
46 + else {
47 + setState({ ...state, btn: "Login" });
48 + alert("ID/PW를 확인해주세요");
49 + return;
50 + }
51 + } else {
52 + //crawling
53 + const { data: loginResult } = await axios.post(
54 + "http://localhost:3001/login/",
55 + {
56 + id: state.id,
57 + pw: state.pw,
58 + }
59 + );
60 + if (loginResult === "login failed") {
61 + setState({ ...state, btn: "Login" });
62 + alert("ID/PW를 확인해주세요");
63 + return;
64 + }
65 + // + else (성공시) localforage에 userID추가
33 } 66 }
67 + // + localforage에 id pw 추가
68 + await localforage.setItem("id", state.id);
69 + await localforage.setItem("pw", state.pw);
70 + await localforage.setItem("session", true);
71 + navigate("/");
34 }; 72 };
35 73
36 useEffect(() => { 74 useEffect(() => {
37 async function ifAlreadyLogined() { 75 async function ifAlreadyLogined() {
38 - if (await dataForage.getItem("session")) navigate("/"); 76 + if (await localforage.getItem("session")) navigate("/");
39 } 77 }
40 ifAlreadyLogined(); 78 ifAlreadyLogined();
41 }, [navigate]); 79 }, [navigate]);
...@@ -61,7 +99,7 @@ const Login = () => { ...@@ -61,7 +99,7 @@ const Login = () => {
61 type="password" 99 type="password"
62 /> 100 />
63 </div> 101 </div>
64 - <button onClick={login}>Login</button> 102 + <button onClick={login}>{state.btn}</button>
65 </div> 103 </div>
66 ); 104 );
67 }; 105 };
......
1 +import localforage from "localforage";
1 import { Navigate, useNavigate } from "react-router-dom"; 2 import { Navigate, useNavigate } from "react-router-dom";
2 3
3 import "../styles/Settings.css"; 4 import "../styles/Settings.css";
4 -import { dataForage } from "../utils/LocalForage";
5 5
6 const Settings = () => { 6 const Settings = () => {
7 console.log("visit Settings"); 7 console.log("visit Settings");
8 8
9 - const session = dataForage.getItem("session"); 9 + const session = localforage.getItem("session");
10 10
11 const navigate = useNavigate(); 11 const navigate = useNavigate();
12 12
......
...@@ -12,7 +12,9 @@ ...@@ -12,7 +12,9 @@
12 12
13 .GridItem { 13 .GridItem {
14 border: solid thin lightgray; 14 border: solid thin lightgray;
15 - height: 150px; 15 + display: flex;
16 + flex-direction: column;
17 + /* height: 150px; */
16 padding: 5px; 18 padding: 5px;
17 } 19 }
18 20
......
...@@ -6,12 +6,12 @@ function toYMD(dateObj) { ...@@ -6,12 +6,12 @@ function toYMD(dateObj) {
6 return { year, month, date }; 6 return { year, month, date };
7 } 7 }
8 8
9 -function toYMDStr(dateObj) { 9 +function toYMDStr(dateObj, joint) {
10 return [ 10 return [
11 dateObj.getFullYear(), 11 dateObj.getFullYear(),
12 dateObj.getMonth() + 1, 12 dateObj.getMonth() + 1,
13 dateObj.getDate(), 13 dateObj.getDate(),
14 - ].join("/"); 14 + ].join(joint);
15 } 15 }
16 16
17 function toSunday(dateObj) { 17 function toSunday(dateObj) {
......
1 +const CryptoJS = require("crypto-js");
2 +
3 +function createHashed(str) {
4 + var hash = CryptoJS.SHA256(str);
5 + console.log("암호화된 값 : " + hash);
6 +
7 + // base64
8 + // var key = CryptoJS.enc.Utf8.parse(str);
9 + // var base64 = CryptoJS.enc.Base64.stringify(key); //encoded
10 + // var decrypt = CryptoJS.enc.Base64.parse(base64);
11 + // var hashData = decrypt.toString(CryptoJS.enc.Utf8); //decoded
12 +}
13 +
14 +createHashed("Happy2468!");
15 +
16 +module.exports = createHashed;
...@@ -19,9 +19,9 @@ async function initTempSubjects() { ...@@ -19,9 +19,9 @@ async function initTempSubjects() {
19 }, 19 },
20 ]; 20 ];
21 21
22 - await scheForage.setItem(toYMDStr(new Date("2022-5-20")), tempsch); 22 + await scheForage.setItem(toYMDStr(new Date("2022-5-20"), "/"), tempsch);
23 - await scheForage.setItem(toYMDStr(new Date("2022-5-27")), tempsch); 23 + await scheForage.setItem(toYMDStr(new Date("2022-5-27"), "/"), tempsch);
24 - await scheForage.setItem(toYMDStr(new Date("2022-6-3")), tempsch); 24 + await scheForage.setItem(toYMDStr(new Date("2022-6-3"), "/"), tempsch);
25 25
26 let tcolors = [ 26 let tcolors = [
27 "red", 27 "red",
......