Showing
14 changed files
with
178 additions
and
36 deletions
actions/userActions.js
0 → 100644
1 | +const jwt = require("jsonwebtoken"); | ||
2 | +const bcrypt = require("bcryptjs"); | ||
3 | +const asyncHandler = require("express-async-handler"); | ||
4 | + | ||
5 | +// @desc Signup new user | ||
6 | +// @route POST /api/users | ||
7 | +// @access Public | ||
8 | +const signupUser = asyncHandler(async (req, res) => { | ||
9 | + const { username, email, password } = req.body; | ||
10 | + if (!name || !email || !password) { | ||
11 | + res.status(400); | ||
12 | + throw new Error("Please fill in all fields"); | ||
13 | + } | ||
14 | + | ||
15 | + // Check if user already exists | ||
16 | + | ||
17 | + // Hash password (bcrypt) | ||
18 | + | ||
19 | + // Create/Build user | ||
20 | + | ||
21 | + // Send response | ||
22 | +}); | ||
23 | + | ||
24 | +const loginUser = asyncHandler(async (req, res) => { | ||
25 | + const { email, password } = req.body; | ||
26 | + | ||
27 | + // Check for the user email | ||
28 | + | ||
29 | + // Send response | ||
30 | +}); | ||
31 | + | ||
32 | +module.exports = { | ||
33 | + signupUser, | ||
34 | + loginUser, | ||
35 | +}; |
... | @@ -11,6 +11,7 @@ | ... | @@ -11,6 +11,7 @@ |
11 | "@testing-library/jest-dom": "^5.16.4", | 11 | "@testing-library/jest-dom": "^5.16.4", |
12 | "@testing-library/react": "^13.2.0", | 12 | "@testing-library/react": "^13.2.0", |
13 | "@testing-library/user-event": "^13.5.0", | 13 | "@testing-library/user-event": "^13.5.0", |
14 | + "axios": "^0.27.2", | ||
14 | "react": "^18.1.0", | 15 | "react": "^18.1.0", |
15 | "react-dom": "^18.1.0", | 16 | "react-dom": "^18.1.0", |
16 | "react-router-dom": "^6.3.0", | 17 | "react-router-dom": "^6.3.0", |
... | @@ -4523,6 +4524,28 @@ | ... | @@ -4523,6 +4524,28 @@ |
4523 | "node": ">=12" | 4524 | "node": ">=12" |
4524 | } | 4525 | } |
4525 | }, | 4526 | }, |
4527 | + "node_modules/axios": { | ||
4528 | + "version": "0.27.2", | ||
4529 | + "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz", | ||
4530 | + "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==", | ||
4531 | + "dependencies": { | ||
4532 | + "follow-redirects": "^1.14.9", | ||
4533 | + "form-data": "^4.0.0" | ||
4534 | + } | ||
4535 | + }, | ||
4536 | + "node_modules/axios/node_modules/form-data": { | ||
4537 | + "version": "4.0.0", | ||
4538 | + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", | ||
4539 | + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", | ||
4540 | + "dependencies": { | ||
4541 | + "asynckit": "^0.4.0", | ||
4542 | + "combined-stream": "^1.0.8", | ||
4543 | + "mime-types": "^2.1.12" | ||
4544 | + }, | ||
4545 | + "engines": { | ||
4546 | + "node": ">= 6" | ||
4547 | + } | ||
4548 | + }, | ||
4526 | "node_modules/axobject-query": { | 4549 | "node_modules/axobject-query": { |
4527 | "version": "2.2.0", | 4550 | "version": "2.2.0", |
4528 | "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz", | 4551 | "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz", |
... | @@ -19468,6 +19491,27 @@ | ... | @@ -19468,6 +19491,27 @@ |
19468 | "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.4.2.tgz", | 19491 | "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.4.2.tgz", |
19469 | "integrity": "sha512-LVAaGp/wkkgYJcjmHsoKx4juT1aQvJyPcW09MLCjVTh3V2cc6PnyempiLMNH5iMdfIX/zdbjUx2KDjMLCTdPeA==" | 19492 | "integrity": "sha512-LVAaGp/wkkgYJcjmHsoKx4juT1aQvJyPcW09MLCjVTh3V2cc6PnyempiLMNH5iMdfIX/zdbjUx2KDjMLCTdPeA==" |
19470 | }, | 19493 | }, |
19494 | + "axios": { | ||
19495 | + "version": "0.27.2", | ||
19496 | + "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz", | ||
19497 | + "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==", | ||
19498 | + "requires": { | ||
19499 | + "follow-redirects": "^1.14.9", | ||
19500 | + "form-data": "^4.0.0" | ||
19501 | + }, | ||
19502 | + "dependencies": { | ||
19503 | + "form-data": { | ||
19504 | + "version": "4.0.0", | ||
19505 | + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", | ||
19506 | + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", | ||
19507 | + "requires": { | ||
19508 | + "asynckit": "^0.4.0", | ||
19509 | + "combined-stream": "^1.0.8", | ||
19510 | + "mime-types": "^2.1.12" | ||
19511 | + } | ||
19512 | + } | ||
19513 | + } | ||
19514 | + }, | ||
19471 | "axobject-query": { | 19515 | "axobject-query": { |
19472 | "version": "2.2.0", | 19516 | "version": "2.2.0", |
19473 | "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz", | 19517 | "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz", | ... | ... |
... | @@ -6,6 +6,7 @@ | ... | @@ -6,6 +6,7 @@ |
6 | "@testing-library/jest-dom": "^5.16.4", | 6 | "@testing-library/jest-dom": "^5.16.4", |
7 | "@testing-library/react": "^13.2.0", | 7 | "@testing-library/react": "^13.2.0", |
8 | "@testing-library/user-event": "^13.5.0", | 8 | "@testing-library/user-event": "^13.5.0", |
9 | + "axios": "^0.27.2", | ||
9 | "react": "^18.1.0", | 10 | "react": "^18.1.0", |
10 | "react-dom": "^18.1.0", | 11 | "react-dom": "^18.1.0", |
11 | "react-router-dom": "^6.3.0", | 12 | "react-router-dom": "^6.3.0", |
... | @@ -20,17 +21,10 @@ | ... | @@ -20,17 +21,10 @@ |
20 | "eject": "react-scripts eject" | 21 | "eject": "react-scripts eject" |
21 | }, | 22 | }, |
22 | "eslintConfig": { | 23 | "eslintConfig": { |
23 | - "extends": [ | 24 | + "extends": ["react-app", "react-app/jest"] |
24 | - "react-app", | ||
25 | - "react-app/jest" | ||
26 | - ] | ||
27 | }, | 25 | }, |
28 | "browserslist": { | 26 | "browserslist": { |
29 | - "production": [ | 27 | + "production": [">0.2%", "not dead", "not op_mini all"], |
30 | - ">0.2%", | ||
31 | - "not dead", | ||
32 | - "not op_mini all" | ||
33 | - ], | ||
34 | "development": [ | 28 | "development": [ |
35 | "last 1 chrome version", | 29 | "last 1 chrome version", |
36 | "last 1 firefox version", | 30 | "last 1 firefox version", | ... | ... |
client/src/lib/auth.js
0 → 100644
1 | +const axios = require("axios").default; | ||
2 | + | ||
3 | +export const handleLogin = (email, pwd) => { | ||
4 | + console.log(email, pwd); | ||
5 | + axios | ||
6 | + .post("http://localhost:8000/api/login", { | ||
7 | + email, | ||
8 | + pwd, | ||
9 | + }) | ||
10 | + .then(function (response) { | ||
11 | + console.log("login request sent"); | ||
12 | + console.log(response); | ||
13 | + }) | ||
14 | + .catch(function (err) { | ||
15 | + console.log(err); | ||
16 | + }); | ||
17 | +}; |
1 | +import { useState } from "react"; | ||
2 | +// lib | ||
3 | +import { handleLogin } from "../lib/auth"; | ||
1 | // styles | 4 | // styles |
2 | import { Link } from "react-router-dom"; | 5 | import { Link } from "react-router-dom"; |
3 | import "../styles/layout.scss"; | 6 | import "../styles/layout.scss"; |
4 | 7 | ||
5 | function Login() { | 8 | function Login() { |
9 | + const [email, setEmail] = useState(""); | ||
10 | + const [pwd, setPwd] = useState(""); | ||
11 | + | ||
6 | const handleSubmit = (e) => { | 12 | const handleSubmit = (e) => { |
7 | e.preventDefault(); | 13 | e.preventDefault(); |
8 | - console.log("login form submit called"); | 14 | + handleLogin(email, pwd); |
9 | }; | 15 | }; |
10 | 16 | ||
11 | return ( | 17 | return ( |
... | @@ -20,10 +26,22 @@ function Login() { | ... | @@ -20,10 +26,22 @@ function Login() { |
20 | 26 | ||
21 | <form className="authForm" onSubmit={(e) => handleSubmit(e)}> | 27 | <form className="authForm" onSubmit={(e) => handleSubmit(e)}> |
22 | <label htmlFor="email"> | 28 | <label htmlFor="email"> |
23 | - email: <input type="text" id="email" /> | 29 | + email:{" "} |
30 | + <input | ||
31 | + onChange={(e) => setEmail(e.target.value)} | ||
32 | + value={email} | ||
33 | + type="text" | ||
34 | + id="email" | ||
35 | + /> | ||
24 | </label> | 36 | </label> |
25 | <label htmlFor="password"> | 37 | <label htmlFor="password"> |
26 | - password: <input type="text" id="password" /> | 38 | + password:{" "} |
39 | + <input | ||
40 | + onChange={(e) => setPwd(e.target.value)} | ||
41 | + value={pwd} | ||
42 | + type="text" | ||
43 | + id="password" | ||
44 | + /> | ||
27 | </label> | 45 | </label> |
28 | <label htmlFor="submit"> | 46 | <label htmlFor="submit"> |
29 | <input type="submit" id="submit" /> | 47 | <input type="submit" id="submit" /> | ... | ... |
client/src/styles/lib/auth.js
0 → 100644
File mode changed
config/db.js
0 → 100644
middleware/errorMiddleware.js
0 → 100644
1 | +const errorHandler = (err, req, res, next) => { | ||
2 | + const statusCode = res.statusCode ? res.statusCode : 500; | ||
3 | + | ||
4 | + res.status(statusCode); | ||
5 | + res.json({ | ||
6 | + message: err.message, | ||
7 | + // stack from mongoDB (maybe...) | ||
8 | + stack: process.env.NODE_ENV === "production" ? null : err.stack, | ||
9 | + }); | ||
10 | +}; | ||
11 | + | ||
12 | +module.exports = { | ||
13 | + errorHandler, | ||
14 | +}; |
This diff is collapsed. Click to expand it.
1 | { | 1 | { |
2 | "name": "weather_chatbot", | 2 | "name": "weather_chatbot", |
3 | "version": "1.0.0", | 3 | "version": "1.0.0", |
4 | - "description": "", | 4 | + "description": "web-app weather chatbot", |
5 | - "main": "index.js", | 5 | + "main": "server.js", |
6 | "scripts": { | 6 | "scripts": { |
7 | - "test": "echo \"Error: no test specified\" && exit 1" | 7 | + "start": "node server.js", |
8 | + "dev": "nodemon server.js" | ||
8 | }, | 9 | }, |
9 | "repository": { | 10 | "repository": { |
10 | "type": "git", | 11 | "type": "git", |
... | @@ -13,7 +14,12 @@ | ... | @@ -13,7 +14,12 @@ |
13 | "author": "황선혁", | 14 | "author": "황선혁", |
14 | "license": "MIT", | 15 | "license": "MIT", |
15 | "dependencies": { | 16 | "dependencies": { |
16 | - "express": "^4.18.1" | 17 | + "bcryptjs": "^2.4.3", |
18 | + "dotenv": "^16.0.1", | ||
19 | + "express": "^4.18.1", | ||
20 | + "express-async-handler": "^1.2.0", | ||
21 | + "jsonwebtoken": "^8.5.1", | ||
22 | + "mongoose": "^6.3.4" | ||
17 | }, | 23 | }, |
18 | "devDependencies": { | 24 | "devDependencies": { |
19 | "nodemon": "^2.0.16" | 25 | "nodemon": "^2.0.16" | ... | ... |
routes/userRoutes.js
0 → 100644
server.js
0 → 100644
1 | +const express = require("express"); | ||
2 | +const dotenv = require("dotenv").config(); | ||
3 | +const { errorHandler } = require("./middleware/errorMiddleware"); | ||
4 | +const connectDB = require("./config/db"); | ||
5 | +const port = process.env.PORT || 8000; | ||
6 | + | ||
7 | +connectDB(); | ||
8 | +const app = express(); | ||
9 | + | ||
10 | +app.use(express.json()); | ||
11 | +app.use(express.urlencoded({ extended: false })); | ||
12 | + | ||
13 | +app.use("/api/users", require("./routes/userRoutes")); | ||
14 | + | ||
15 | +app.use(errorHandler); | ||
16 | + | ||
17 | +app.listen(port, () => { | ||
18 | + console.log(`Server started on port ${port}`); | ||
19 | +}); |
server/index.js
deleted
100644 → 0
1 | -const express = require("express"); | ||
2 | -const app = express(); | ||
3 | - | ||
4 | -const PORT = 8000; | ||
5 | - | ||
6 | -app.listen(PORT, () => { | ||
7 | - console.log(`App listening on port ${PORT}`); | ||
8 | -}); | ||
9 | - | ||
10 | -app.get("/", (req, res) => { | ||
11 | - res.send("Hello World!"); | ||
12 | -}); | ||
13 | - | ||
14 | -app.get("/login", (req, res) => { | ||
15 | - res.send("Hello World!"); | ||
16 | -}); | ||
17 | - | ||
18 | -app.get("/signup", (req, res) => { | ||
19 | - res.send("Hello World!"); | ||
20 | -}); |
-
Please register or login to post a comment