diff --git a/client/src/components/Navbar.tsx b/client/src/components/Navbar.tsx index 0026489..9bf0627 100644 --- a/client/src/components/Navbar.tsx +++ b/client/src/components/Navbar.tsx @@ -1,5 +1,6 @@ import { useReducer, useState } from "react"; -import { initialState, reducer, ActionType } from "../store/store"; +import { initialState, reducer } from "../store/store"; +import { ActionType } from "../store/store_types"; import { useNavigate } from 'react-router-dom'; function NavBar() { diff --git a/client/src/components/User/LoginForm.tsx b/client/src/components/User/LoginForm.tsx index 929987e..96f41ec 100644 --- a/client/src/components/User/LoginForm.tsx +++ b/client/src/components/User/LoginForm.tsx @@ -1,16 +1,29 @@ -import { useState } from "react"; +import { useState, useReducer } from "react"; +import { reducer, initialState } from "../../store/store"; +import { handleLogin } from "../../util/apiUtils"; import Page from "../../util/Page"; -function LoginForm() { - enum PassVisible { - hide = 'password', - show = 'text' - } +enum PassVisible { + hide = 'password', + show = 'text' +} - const [username, setUsername] = useState(); - const [password, setPassword] = useState(); +function LoginForm() { + const [state, dispatch] = useReducer(reducer, initialState); + + const [username, setUsername] = useState(''); + const [password, setPassword] = useState(''); const [showPass, setShowPass] = useState(PassVisible.hide); + const displaySession = async () => { + if (username === '' || password === '') return; + + const headers = handleLogin(username, password) + .then(res => res?.json()); + + if (headers) console.log(headers); + } + return (

Welcome back to my store!

@@ -42,12 +55,9 @@ function LoginForm() { onClick={() => setShowPass((showPass === PassVisible.hide) ? PassVisible.show : PassVisible.hide)} >Show password - -

Username is: {username}

-

Password is: {password}

- +
diff --git a/client/src/store/store.ts b/client/src/store/store.ts index 1f40c8b..ecfc5fb 100644 --- a/client/src/store/store.ts +++ b/client/src/store/store.ts @@ -1,39 +1,5 @@ import { createContext } from "react"; -import { userInfo, Cart, } from "../types/main"; - -// type definitions for reducer -export enum ActionType { - GETALL, - GETCATEGORY, - REGISTERNEW, - UPDATEONE, - SEARCH, -} - -export interface userAction { - type: ActionType; - payload: any; -} - -export interface appState { - searchTerm: string, - user: userInfo, - cart: Cart -} - -// empty object templates for initial state -const undefinedUser: userInfo = { - email: '', - name: '', - password: '' -} - -const emptyCart: Cart = { - cartID: 0, - userInfo: undefinedUser, - checkedOut: false, - contents: [] -} +import { ActionType,userAction, appState, undefinedUser, emptyCart } from './store_types'; export const initialState: appState = { searchTerm: '', @@ -53,14 +19,13 @@ export const reducer = (state: appState, action: userAction) => { case ActionType.UPDATEONE: return state; case ActionType.SEARCH: - let newState = { + return { ...state, searchTerm: payload } - state = newState; - console.log(state.searchTerm); + default: return state; } } -export const AppContext = createContext(initialState) \ No newline at end of file +export const AppContext = createContext(initialState) diff --git a/client/src/store/store_types.ts b/client/src/store/store_types.ts new file mode 100644 index 0000000..32be20f --- /dev/null +++ b/client/src/store/store_types.ts @@ -0,0 +1,36 @@ +import { userInfo, Cart } from '../types/main'; + +// type definitions for reducer +export enum ActionType { + GETALL, + GETCATEGORY, + REGISTERNEW, + UPDATEONE, + SEARCH, +} + +export interface userAction { + type: ActionType; + payload: any; +} + +export interface appState { + searchTerm: string, + user: userInfo, + cart: Cart +} + +// empty object templates for initial state +export const undefinedUser: userInfo = { + email: '', + name: '', + password: '', + headers: {} +} + +export const emptyCart: Cart = { + cartID: 0, + userInfo: undefinedUser, + checkedOut: false, + contents: [] +} diff --git a/client/src/types/main.d.ts b/client/src/types/main.d.ts index 5148c6c..8ec5411 100644 --- a/client/src/types/main.d.ts +++ b/client/src/types/main.d.ts @@ -3,6 +3,7 @@ export type userInfo = { id?: number; name: string; password: string; + headers: object } export type Product = { diff --git a/client/src/util/apiUtils.ts b/client/src/util/apiUtils.ts index 8cc63e2..93f7512 100644 --- a/client/src/util/apiUtils.ts +++ b/client/src/util/apiUtils.ts @@ -16,5 +16,17 @@ export const registerNewUser = async (user: userInfo) => { body: JSON.stringify(user) }); - if (serverCall.ok) return 'User added successfully.'; + if (serverCall.ok) console.log('User added successfully.'); +} + +export const handleLogin = async (email: string, password: string) => { + let serverCall = await fetch('http://localhost:8088/login', { + method: "POST", + headers: { + "Content-Type": "application/json" + }, + body: JSON.stringify({ email: email, password: password }) + }); + + if (serverCall.ok) return serverCall; } diff --git a/package-lock.json b/package-lock.json index 68de2ff..4cba98e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,6 +14,7 @@ "cors": "^2.8.5", "dotenv": "^16.0.0", "express": "^4.17.3", + "express-session": "^1.17.3", "helmet": "^5.1.0", "oauth2-server": "^3.1.1", "passport": "^0.6.0", @@ -430,6 +431,24 @@ "node": ">= 0.10.0" } }, + "node_modules/express-session": { + "version": "1.17.3", + "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.17.3.tgz", + "integrity": "sha512-4+otWXlShYlG1Ma+2Jnn+xgKUZTMJ5QD3YvfilX3AcocOAbIkVylSWEklzALe/+Pu4qV6TYBj5GwOBFfdKqLBw==", + "dependencies": { + "cookie": "0.4.2", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~2.0.0", + "on-headers": "~1.0.2", + "parseurl": "~1.3.3", + "safe-buffer": "5.2.1", + "uid-safe": "~2.1.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/express/node_modules/body-parser": { "version": "1.19.2", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.2.tgz", @@ -1001,6 +1020,14 @@ "node": ">= 0.8" } }, + "node_modules/on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -1229,6 +1256,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/random-bytes": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/random-bytes/-/random-bytes-1.0.0.tgz", + "integrity": "sha1-T2ih3Arli9P7lYSMMDJNt11kNgs=", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/range-parser": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", @@ -1514,6 +1549,17 @@ "node": ">= 0.6" } }, + "node_modules/uid-safe": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/uid-safe/-/uid-safe-2.1.5.tgz", + "integrity": "sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA==", + "dependencies": { + "random-bytes": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", @@ -1971,6 +2017,21 @@ } } }, + "express-session": { + "version": "1.17.3", + "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.17.3.tgz", + "integrity": "sha512-4+otWXlShYlG1Ma+2Jnn+xgKUZTMJ5QD3YvfilX3AcocOAbIkVylSWEklzALe/+Pu4qV6TYBj5GwOBFfdKqLBw==", + "requires": { + "cookie": "0.4.2", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~2.0.0", + "on-headers": "~1.0.2", + "parseurl": "~1.3.3", + "safe-buffer": "5.2.1", + "uid-safe": "~2.1.5" + } + }, "finalhandler": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", @@ -2329,6 +2390,11 @@ "ee-first": "1.1.1" } }, + "on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==" + }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -2497,6 +2563,11 @@ "side-channel": "^1.0.4" } }, + "random-bytes": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/random-bytes/-/random-bytes-1.0.0.tgz", + "integrity": "sha1-T2ih3Arli9P7lYSMMDJNt11kNgs=" + }, "range-parser": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", @@ -2710,6 +2781,14 @@ "mime-types": "~2.1.24" } }, + "uid-safe": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/uid-safe/-/uid-safe-2.1.5.tgz", + "integrity": "sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA==", + "requires": { + "random-bytes": "~1.0.0" + } + }, "unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", diff --git a/package.json b/package.json index d060d02..a4f3703 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "cors": "^2.8.5", "dotenv": "^16.0.0", "express": "^4.17.3", + "express-session": "^1.17.3", "helmet": "^5.1.0", "oauth2-server": "^3.1.1", "passport": "^0.6.0", diff --git a/routes/login.js b/routes/login.js index 0329f8b..d36d671 100644 --- a/routes/login.js +++ b/routes/login.js @@ -12,9 +12,15 @@ loginRouter.route('/').post(async (req, res) => { let hash = await newClient.query("SELECT password FROM users WHERE email = ($1)", [email]); hash = hash.rows[0].password; - let match = await bcrypt.compare(password, hash); + const match = bcrypt.compare(password, hash); - if (match) res.send("Login successful!"); + if (!match) res.status(403).json({ msg: "Login unsuccessful. Please try again" }); + if (match) { + req.session.authenticated = true; + req.session.user = { email: email, password: password } + + res.send(req.session); + } } catch(e) { console.log(e); } finally { diff --git a/server.js b/server.js index 3f66ded..64bff1c 100644 --- a/server.js +++ b/server.js @@ -4,7 +4,7 @@ const app = express(); const session = require('express-session'); -require('dotenv').config({ path: './config.env' }); +require('dotenv').config({ path: './.env' }); const PORT = process.env.PORT; app.use(cors()); @@ -14,10 +14,14 @@ app.use(express.urlencoded({ extended: true })); +const store = new session.MemoryStore(); app.use(session({ - secret: 'secret', - cookie: { maxAge: 300000000, secure: false } -})) + secret: process.env.EXPRESS_SECRET, + cookie: { maxAge: 300000000, secure: false }, + resave: false, + saveUninitialized: false, + store, +})); const apiRouter = require('./routes/API'); app.use(apiRouter);