index.js
import express from "express";
import cors from "cors";
import session from "express-session";
import dotenv from "dotenv";
import db from "./config/Database.js";
// import SequelizeStore from "connect-session-sequelize";
import UserRoute from "./routes/UserRoute.js";
import ProductRoute from "./routes/ProductRoute.js";
import AuthRoute from "./routes/AuthRoute.js";
dotenv.config();
const app = express();
// const sessionStore = SequelizeStore(session.Store);
// const store = new sessionStore({
// db: db
// });
// (async()=>{
// await db.sync();
// })();
app.use(session({
secret: process.env.SESS_SECRET,
resave: false,
saveUninitialized: true,
// store: store,
cookie: {
secure: 'auto'
}
}));
app.use(cors({
credentials: true,
origin: 'http://localhost:3000'
}));
app.use(express.json());
app.use(UserRoute);
app.use(ProductRoute);
app.use(AuthRoute);
// store.sync();
app.listen(process.env.APP_PORT, ()=> {
console.log('Server up and running...');
});
Routes
UserRoute.js
import express from "express";
import {
getUsers,
getUserById,
createUser,
updateUser,
deleteUser
} from "../controllers/Users.js";
import { verifyUser, adminOnly } from "../middleware/AuthUser.js";
const router = express.Router();
router.get('/users', verifyUser, getUsers);
router.get('/users/:id', verifyUser, getUserById);
router.post('/users', createUser);
router.patch('/users/:id', verifyUser, updateUser);
router.delete('/users/:id', verifyUser, deleteUser);
export default router;
Product Route
Productroute.js
import express from "express";
import {
getProducts,
getProductById,
createProduct,
updateProduct,
deleteProduct
} from "../controllers/Products.js";
import { verifyUser } from "../middleware/AuthUser.js";
const router = express.Router();
router.get('/products',verifyUser, getProducts);
router.get('/products/:id',verifyUser, getProductById);
router.post('/products',verifyUser, createProduct);
router.patch('/products/:id',verifyUser, updateProduct);
router.delete('/products/:id',verifyUser, deleteProduct);
export default router;
AuthRoute
authroute.js
import express from "express";
import {Login, logOut, Me} from "../controllers/Auth.js";
const router = express.Router();
router.get('/me', Me);
router.post('/login', Login);
router.delete('/logout', logOut);
export default router;
Model
UserModel.js
import { Sequelize } from "sequelize";
import db from "../config/Database.js";
const {DataTypes} = Sequelize;
const Users = db.define('users',{
uuid:{
type: DataTypes.STRING,
defaultValue: DataTypes.UUIDV4,
allowNull: false,
validate:{
notEmpty: true
}
},
name:{
type: DataTypes.STRING,
allowNull: false,
validate:{
notEmpty: true,
len: [3, 100]
}
},
email:{
type: DataTypes.STRING,
allowNull: false,
validate:{
notEmpty: true,
isEmail: true
}
},
password:{
type: DataTypes.STRING,
allowNull: false,
validate:{
notEmpty: true
}
},
role:{
type: DataTypes.STRING,
allowNull: false,
validate:{
notEmpty: true
}
}
},{
freezeTableName: true
});
export default Users;
ProductModel.js
import { Sequelize } from "sequelize";
import db from "../config/Database.js";
import Users from "./UserModel.js";
const {DataTypes} = Sequelize;
const Products = db.define('product',{
uuid:{
type: DataTypes.STRING,
defaultValue: DataTypes.UUIDV4,
allowNull: false,
validate:{
notEmpty: true
}
},
name:{
type: DataTypes.STRING,
allowNull: false,
validate:{
notEmpty: true,
len: [3, 100]
}
},
price:{
type: DataTypes.INTEGER,
allowNull: false,
validate:{
notEmpty: true
}
},
userId:{
type: DataTypes.INTEGER,
allowNull: false,
validate:{
notEmpty: true
}
}
},{
freezeTableName: true
});
Users.hasMany(Products);
Products.belongsTo(Users, {foreignKey: 'userId'});
export default Products;
Middleware
Authmiddleware.js
import User from "../models/UserModel.js";
export const verifyUser = async (req, res, next) =>{
if(!req.session.userId){
return res.status(401).json({msg: "Please login to your account!"});
}
const user = await User.findOne({
where: {
uuid: req.session.userId
}
});
if(!user) return res.status(404).json({msg: "User not found"});
req.userId = user.id;
req.role = user.role;
next();
}
export const adminOnly = async (req, res, next) =>{
const user = await User.findOne({
where: {
uuid: req.session.userId
}
});
if(!user) return res.status(404).json({msg: "User not found"});
if(user.role !== "admin") return res.status(403).json({msg: "Access prohibited"});
next();
}
Controller
User.js
import User from "../models/UserModel.js";
export const verifyUser = async (req, res, next) =>{
if(!req.session.userId){
return res.status(401).json({msg: "Please login to your account!"});
}
const user = await User.findOne({
where: {
uuid: req.session.userId
}
});
if(!user) return res.status(404).json({msg: "User not found"});
req.userId = user.id;
req.role = user.role;
next();
}
export const adminOnly = async (req, res, next) =>{
const user = await User.findOne({
where: {
uuid: req.session.userId
}
});
if(!user) return res.status(404).json({msg: "User not found"});
if(user.role !== "admin") return res.status(403).json({msg: "Access prohibited"});
next();
}
Products.js
import Product from "../models/ProductModel.js";
import User from "../models/UserModel.js";
import { Op } from "sequelize";
export const getProducts = async (req, res) => {
try {
let response;
if (req.role === "admin") {
response = await Product.findAll({
attributes: ['uuid', 'name', 'price'],
include: [{
model: User,
attributes: ['name', 'email']
}]
});
} else {
response = await Product.findAll({
attributes: ['uuid', 'name', 'price'],
where: {
userId: req.userId
},
include: [{
model: User,
attributes: ['name', 'email']
}]
});
}
res.status(200).json(response);
} catch (error) {
res.status(500).json({ msg: error.message });
}
}
export const getProductById = async (req, res) => {
try {
const product = await Product.findOne({
where: {
uuid: req.params.id
}
});
if (!product) return res.status(404).json({ msg: "Data tidak ditemukan" });
let response;
if (req.role === "admin") {
response = await Product.findOne({
attributes: ['uuid', 'name', 'price'],
where: {
id: product.id
},
include: [{
model: User,
attributes: ['name', 'email']
}]
});
} else {
response = await Product.findOne({
attributes: ['uuid', 'name', 'price'],
where: {
[Op.and]: [{ id: product.id }, { userId: req.userId }]
},
include: [{
model: User,
attributes: ['name', 'email']
}]
});
}
res.status(200).json(response);
} catch (error) {
res.status(500).json({ msg: error.message });
}
}
export const createProduct = async (req, res) => {
const { name, price } = req.body;
try {
await Product.create({
name: name,
price: price,
userId: req.userId
});
res.status(201).json({ msg: "Product Created Successfuly" });
} catch (error) {
res.status(500).json({ msg: error.message });
}
}
export const updateProduct = async (req, res) => {
try {
const product = await Product.findOne({
where: {
uuid: req.params.id
}
});
if (!product) return res.status(404).json({ msg: "Data tidak ditemukan" });
const { name, price } = req.body;
if (req.role === "admin") {
await Product.update({ name, price }, {
where: {
id: product.id
}
});
} else {
if (req.userId !== product.userId) return res.status(403).json({ msg: "Akses terlarang" });
await Product.update({ name, price }, {
where: {
[Op.and]: [{ id: product.id }, { userId: req.userId }]
}
});
}
res.status(200).json({ msg: "Product updated successfuly" });
} catch (error) {
res.status(500).json({ msg: error.message });
}
}
export const deleteProduct = async (req, res) => {
try {
const product = await Product.findOne({
where: {
uuid: req.params.id
}
});
if (!product) return res.status(404).json({ msg: "Data tidak ditemukan" });
const { name, price } = req.body;
if (req.role === "admin") {
await Product.destroy({
where: {
id: product.id
}
});
} else {
if (req.userId !== product.userId) return res.status(403).json({ msg: "Akses terlarang" });
await Product.destroy({
where: {
[Op.and]: [{ id: product.id }, { userId: req.userId }]
}
});
}
res.status(200).json({ msg: "Product deleted successfuly" });
} catch (error) {
res.status(500).json({ msg: error.message });
}
}
Auth.js
import User from "../models/UserModel.js";
import argon2 from "argon2";
export const Login = async (req, res) =>{
const user = await User.findOne({
where: {
email: req.body.email
}
});
if(!user) return res.status(404).json({msg: "User not found"});
const match = await argon2.verify(user.password, req.body.password);
if(!match) return res.status(400).json({msg: "Wrong Password"});
req.session.userId = user.uuid;
const uuid = user.uuid;
const name = user.name;
const email = user.email;
const role = user.role;
res.status(200).json({uuid, name, email, role});
}
export const Me = async (req, res) =>{
if(!req.session.userId){
return res.status(401).json({msg: "Please login to your account!!"});
}
const user = await User.findOne({
attributes:['uuid','name','email','role'],
where: {
uuid: req.session.userId
}
});
if(!user) return res.status(404).json({msg: "User not found"});
res.status(200).json(user);
}
export const logOut = (req, res) =>{
req.session.destroy((err)=>{
if(err) return res.status(400).json({msg: "Cannot log out"});
res.status(200).json({msg: "You have logged out"});
});
}
Config
Database.js
import {Sequelize} from "sequelize";
const db = new Sequelize('auth_db', 'root', '', {
host: "localhost",
dialect: "mysql"
});
export default db;
pakage.json
{
"name": "backend",
"version": "1.0.0",
"description": "",
"type": "module",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"argon2": "^0.28.7",
"connect-session-sequelize": "^7.1.4",
"cors": "^2.8.5",
"dotenv": "^16.0.1",
"express": "^4.18.1",
"express-session": "^1.17.3",
"mysql2": "^2.3.3",
"sequelize": "^6.21.3"
}
}
Top comments (0)