type wrangling
This commit is contained in:
@@ -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() {
|
||||
|
||||
@@ -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<string>();
|
||||
const [password, setPassword] = useState<string>();
|
||||
function LoginForm() {
|
||||
const [state, dispatch] = useReducer(reducer, initialState);
|
||||
|
||||
const [username, setUsername] = useState('');
|
||||
const [password, setPassword] = useState('');
|
||||
const [showPass, setShowPass] = useState<PassVisible>(PassVisible.hide);
|
||||
|
||||
const displaySession = async () => {
|
||||
if (username === '' || password === '') return;
|
||||
|
||||
const headers = handleLogin(username, password)
|
||||
.then(res => res?.json());
|
||||
|
||||
if (headers) console.log(headers);
|
||||
}
|
||||
|
||||
return (
|
||||
<Page classes="login light-page">
|
||||
<h1>Welcome back to my store!</h1>
|
||||
@@ -42,12 +55,9 @@ function LoginForm() {
|
||||
onClick={() => setShowPass((showPass === PassVisible.hide) ? PassVisible.show : PassVisible.hide)}
|
||||
>Show password</button>
|
||||
</div>
|
||||
|
||||
<p>Username is: {username}</p>
|
||||
<p>Password is: {password}</p>
|
||||
</form>
|
||||
|
||||
|
||||
<button onClick={displaySession}>Log In</button>
|
||||
</section>
|
||||
|
||||
<section className="link-to-register">
|
||||
|
||||
@@ -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)
|
||||
export const AppContext = createContext(initialState)
|
||||
|
||||
36
client/src/store/store_types.ts
Normal file
36
client/src/store/store_types.ts
Normal file
@@ -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: []
|
||||
}
|
||||
1
client/src/types/main.d.ts
vendored
1
client/src/types/main.d.ts
vendored
@@ -3,6 +3,7 @@ export type userInfo = {
|
||||
id?: number;
|
||||
name: string;
|
||||
password: string;
|
||||
headers: object
|
||||
}
|
||||
|
||||
export type Product = {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
79
package-lock.json
generated
79
package-lock.json
generated
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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 {
|
||||
|
||||
12
server.js
12
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);
|
||||
|
||||
Reference in New Issue
Block a user