Commit b6377a90 authored by Egor Kremnev's avatar Egor Kremnev

add interceptor for request. add secureRoute middleware. fix use localStorage

parent 7c08e9a7
const User = require("../models/User");
const secureRoute = async (req, res, next) => {
const token = req.get('Authorization');
if (!token) return res
.status(401)
.send({error: 'No token present'});
const user = await User.findOne({token});
if (!user) return res
.status(401)
.send('Token is wrong');
next();
}
module.exports = secureRoute;
const router = require('express').Router(); const router = require('express').Router();
const Category = require('../models/Category'); const Category = require('../models/Category');
const secureRoute = require("../middleware/secureRoute");
router.get('/', async (req, res) => { router.get('/', async (req, res) => {
try { try {
...@@ -9,7 +10,7 @@ router.get('/', async (req, res) => { ...@@ -9,7 +10,7 @@ router.get('/', async (req, res) => {
} }
}); });
router.post('/', async (req, res) => { router.post('/', secureRoute, async (req, res) => {
const category = new Category(req.body); const category = new Category(req.body);
try { try {
......
...@@ -5,7 +5,7 @@ const multer = require('multer'); ...@@ -5,7 +5,7 @@ const multer = require('multer');
const path = require('path'); const path = require('path');
const {uploadPath} = require('./../config'); const {uploadPath} = require('./../config');
const Product = require('../models/Product'); const Product = require('../models/Product');
const User = require("../models/User"); const secureRoute = require("../middleware/secureRoute");
const storage = multer.diskStorage({ const storage = multer.diskStorage({
destination: (req, file, cb) => { destination: (req, file, cb) => {
...@@ -19,19 +19,7 @@ const storage = multer.diskStorage({ ...@@ -19,19 +19,7 @@ const storage = multer.diskStorage({
const upload = multer({storage}); const upload = multer({storage});
const createRoutes = () => { const createRoutes = () => {
router.post('/', upload.single('image'), async (req, res) => { router.post('/', upload.single('image'), secureRoute, async (req, res) => {
const token = req.get('Authorization');
if (!token) return res
.status(401)
.send({error: 'No token present'});
const user = await User.findOne({token});
if (!user) return res
.status(401)
.send('Token is wrong');
const productData = {...req.body}; const productData = {...req.body};
if (req.file) productData.image = req.file.filename; if (req.file) productData.image = req.file.filename;
......
const router = require('express').Router(); const router = require('express').Router();
const User = require('../models/User'); const User = require('../models/User');
const secureRoute = require("../middleware/secureRoute");
router.post('/', async (req, res) => { router.post('/', async (req, res) => {
try { try {
...@@ -37,34 +38,20 @@ router.post('/login', async (req, res) => { ...@@ -37,34 +38,20 @@ router.post('/login', async (req, res) => {
} }
}); });
router.get('/profile', async (req, res) => { router.get('/profile', secureRoute, async (req, res) => {
const token = req.get('Authorization'); const token = req.get('Authorization');
if (!token) return res
.status(401)
.send({error: 'No token present'});
const user = await User.findOne({token}); const user = await User.findOne({token});
if (!user) return res
.status(401)
.send('Token is wrong');
res.send({ res.send({
message: "Большой большой сикрет", message: "Большой большой сикрет",
username: user.username username: user.username
}); });
}); });
router.delete('/logout', async (req, res) => { router.delete('/logout', secureRoute, async (req, res) => {
const token = req.get('Authorization'); const token = req.get('Authorization');
const success = {message: 'Success'}; const success = {message: 'Success'};
const user = await User.findOne({token});
if (!token) return res.send(success);
const user = await User.findOne({token});
if (!user) return res.send(success);
user.token = null; user.token = null;
user.save(); user.save();
......
...@@ -3,7 +3,7 @@ import {Route, Routes} from "react-router-dom"; ...@@ -3,7 +3,7 @@ import {Route, Routes} from "react-router-dom";
import {LOGIN, PRODUCT_ADD, PRODUCT_LIST, PRODUCT_VIEW, REGISTER} from "./constants/routes"; import {LOGIN, PRODUCT_ADD, PRODUCT_LIST, PRODUCT_VIEW, REGISTER} from "./constants/routes";
import Layout from "./components/Layout/Layout"; import Layout from "./components/Layout/Layout";
import Products from "./containers/Products/Products"; import Products from "./containers/Products/Products";
import AddProduct from "./containers/Addproduct/AddProduct"; import AddProduct from "./containers/AddProduct/AddProduct";
import Register from "./containers/Auth/Register/Register"; import Register from "./containers/Auth/Register/Register";
import Login from "./containers/Auth/Login/Login"; import Login from "./containers/Auth/Login/Login";
import {useSelector} from "react-redux"; import {useSelector} from "react-redux";
......
...@@ -5,4 +5,14 @@ const instance = axios.create({ ...@@ -5,4 +5,14 @@ const instance = axios.create({
baseURL: apiUrl + "/api/v1" baseURL: apiUrl + "/api/v1"
}); });
instance.interceptors.request.use(function (config) {
if (localStorage.getItem('user') !== null) {
config.headers.Authorization = JSON.parse(localStorage.getItem('user')).token;
}
return config;
}, function(error) {
return Promise.reject(error);
});
export default instance; export default instance;
...@@ -9,9 +9,8 @@ const AddProduct = () => { ...@@ -9,9 +9,8 @@ const AddProduct = () => {
const dispatch = useDispatch(); const dispatch = useDispatch();
const navigate = useNavigate(); const navigate = useNavigate();
const onProductFormSubmit = async productData => { const onProductFormSubmit = async data => {
await dispatch(createProduct(productData)); await dispatch(createProduct({data, callback: () => navigate('/')}));
navigate('/');
}; };
return ( return (
......
import {useState} from "react"; import {useEffect, useState} from "react";
import {Avatar, Button, Container, Grid, Typography, Link, Box, CssBaseline, Alert} from "@mui/material"; import {Avatar, Button, Container, Grid, Typography, Link, Box, CssBaseline, Alert} from "@mui/material";
import { createTheme, ThemeProvider } from '@mui/material/styles'; import { createTheme, ThemeProvider } from '@mui/material/styles';
import LockOutlinedIcon from '@mui/icons-material/LockOutlined'; import LockOutlinedIcon from '@mui/icons-material/LockOutlined';
import {Link as RouterLink, useNavigate} from 'react-router-dom'; import {Link as RouterLink, useLocation, useNavigate} from 'react-router-dom';
import {REGISTER} from "../../../constants/routes"; import {REGISTER} from "../../../constants/routes";
import {useDispatch, useSelector} from "react-redux"; import {useDispatch, useSelector} from "react-redux";
import {loginUser} from "../../../store/actions/usersActions"; import {loginUser} from "../../../store/actions/usersActions";
import TextInput from "../../../components/UI/Form/FormElement/TextInput/TextInput"; import TextInput from "../../../components/UI/Form/FormElement/TextInput/TextInput";
import {setLoginError} from "../../../store/services/usersSlice";
const theme = createTheme(); const theme = createTheme();
...@@ -19,6 +20,12 @@ const Login = () => { ...@@ -19,6 +20,12 @@ const Login = () => {
password: "" password: ""
}); });
const location = useLocation();
useEffect(() => {
dispatch(setLoginError(null));
}, [location]);
const inputChangeHandler = (e) => { const inputChangeHandler = (e) => {
const {name, value} = e.currentTarget; const {name, value} = e.currentTarget;
......
import {useState} from "react"; import {useEffect, useState} from "react";
import {Avatar, Button, Container, Grid, Typography, Link, Box, CssBaseline} from "@mui/material"; import {Avatar, Button, Container, Grid, Typography, Link, Box, CssBaseline} from "@mui/material";
import { createTheme, ThemeProvider } from '@mui/material/styles'; import { createTheme, ThemeProvider } from '@mui/material/styles';
import LockOutlinedIcon from '@mui/icons-material/LockOutlined'; import LockOutlinedIcon from '@mui/icons-material/LockOutlined';
import {Link as RouterLink, useNavigate} from 'react-router-dom'; import {Link as RouterLink, useLocation, useNavigate} from 'react-router-dom';
import {LOGIN} from "../../../constants/routes"; import {LOGIN} from "../../../constants/routes";
import {useDispatch, useSelector} from "react-redux"; import {useDispatch, useSelector} from "react-redux";
import {registerUser} from "../../../store/actions/usersActions"; import {registerUser} from "../../../store/actions/usersActions";
import TextInput from "../../../components/UI/Form/FormElement/TextInput/TextInput"; import TextInput from "../../../components/UI/Form/FormElement/TextInput/TextInput";
import {setRegisterError} from "../../../store/services/usersSlice";
const theme = createTheme(); const theme = createTheme();
...@@ -19,6 +20,12 @@ const Register = () => { ...@@ -19,6 +20,12 @@ const Register = () => {
password: "" password: ""
}); });
const location = useLocation();
useEffect(() => {
dispatch(setRegisterError(null));
}, [location]);
const inputChangeHandler = (e) => { const inputChangeHandler = (e) => {
const {name, value} = e.currentTarget; const {name, value} = e.currentTarget;
......
...@@ -11,12 +11,18 @@ import {BrowserRouter} from "react-router-dom"; ...@@ -11,12 +11,18 @@ import {BrowserRouter} from "react-router-dom";
const localStorageMiddleware = ({getState}) => next => action => { const localStorageMiddleware = ({getState}) => next => action => {
const result = next(action); const result = next(action);
localStorage.setItem('user', JSON.stringify(getState().usersState.user)); if (getState().usersState.user) {
localStorage.setItem('user', JSON.stringify(getState().usersState.user));
} else {
localStorage.removeItem('user');
}
return result; return result;
}; };
const reHydrateStore = () => { const reHydrateStore = () => {
if (localStorage.getItem('user') !== null) { const userLocalStorage = localStorage.getItem('user');
if (userLocalStorage !== null || userLocalStorage !== 'null' || userLocalStorage !== '') {
return { return {
usersState: { usersState: {
user: JSON.parse(localStorage.getItem('user')) user: JSON.parse(localStorage.getItem('user'))
......
...@@ -8,7 +8,7 @@ export const fetchProducts = createAsyncThunk( ...@@ -8,7 +8,7 @@ export const fetchProducts = createAsyncThunk(
export const createProduct = createAsyncThunk( export const createProduct = createAsyncThunk(
'products/create', 'products/create',
async (data) => await axios async ({data, callback}) => await axios
.post('/products', data) .post('/products', data)
.then(res => res.data) .then(res => callback())
); );
...@@ -16,7 +16,7 @@ export const registerUser = createAsyncThunk( ...@@ -16,7 +16,7 @@ export const registerUser = createAsyncThunk(
export const loginUser = createAsyncThunk( export const loginUser = createAsyncThunk(
'users/login', 'users/login',
async ({data, callback}, {dispatch, getState}) => await axiosApi async ({data, callback}, {dispatch}) => await axiosApi
.post('/users/login', data) .post('/users/login', data)
.then(res => { .then(res => {
dispatch(setUser(res.data)); dispatch(setUser(res.data));
...@@ -31,11 +31,8 @@ export const loginUser = createAsyncThunk( ...@@ -31,11 +31,8 @@ export const loginUser = createAsyncThunk(
export const logoutUser = createAsyncThunk( export const logoutUser = createAsyncThunk(
'users/logout', 'users/logout',
async (payload, {dispatch, getState}) => await axiosApi async (payload, {dispatch}) => await axiosApi
.delete( .delete('/users/logout')
'/users/logout',
{headers: {Authorization: getState().usersState.user.token}}
)
.then(res => { .then(res => {
dispatch(setUser(null)); dispatch(setUser(null));
payload.callback(); payload.callback();
......
import {createSlice} from "@reduxjs/toolkit"; import {createSlice} from "@reduxjs/toolkit";
import {createProduct, fetchProducts} from "../actions/productsActions"; import {fetchProducts} from "../actions/productsActions";
const initialState = { const initialState = {
products: [] products: []
...@@ -16,14 +16,6 @@ const productsSlice = createSlice({ ...@@ -16,14 +16,6 @@ const productsSlice = createSlice({
state.products = action.payload || []; state.products = action.payload || [];
} }
); );
builder
.addCase(
createProduct.fulfilled,
(state, action) => {
state.products.push(action.payload);
}
);
} }
}); });
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment