<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Abdur Rakib Rony</title>
    <description>The latest articles on DEV Community by Abdur Rakib Rony (@ronyfr3a).</description>
    <link>https://dev.to/ronyfr3a</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F446352%2F4ffe74a2-f8ff-49cc-a136-e04c28e80ae9.jpg</url>
      <title>DEV Community: Abdur Rakib Rony</title>
      <link>https://dev.to/ronyfr3a</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ronyfr3a"/>
    <language>en</language>
    <item>
      <title>Express js authentication &amp; authorization code</title>
      <dc:creator>Abdur Rakib Rony</dc:creator>
      <pubDate>Thu, 20 Jan 2022 11:57:04 +0000</pubDate>
      <link>https://dev.to/ronyfr3/express-js-authentication-authorization-code-4cdd</link>
      <guid>https://dev.to/ronyfr3/express-js-authentication-authorization-code-4cdd</guid>
      <description>&lt;p&gt;&lt;em&gt;if you need full code follow my github repository&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://github.com/ronyfr3"&gt;https://github.com/ronyfr3&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  server/index.js
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//handling uncaught exceptions, if something is undefined/uncaught then this will handled
process.on("uncaughtException", (err) =&amp;gt; {
  console.log(
    `server is shutting down due to uncaught exception: ${err.message} ${err.stack}`
  );
});

require("dotenv").config();
const express = require("express");
const cors = require("cors");
const cookieParser = require("cookie-parser");

//app initialization
const app = express();
//require db
const connect = require("./config/db");
connect();

//body-parser
app.use(express.json());
//cookieParser
app.use(cookieParser());

//cors
app.use(cors());

//destructure env object
let { SERVER_DEV_NAME } = process.env;

app.get("/", (req, res) =&amp;gt; {
  res
    .status(200)
    .send(`${SERVER_DEV_NAME} is running the server at port: ${PORT}`);
});

// Routes
app.use("/api/user", require("./routes/User"));

let PORT = process.env.PORT || 8080;
const server = app.listen(PORT, () =&amp;gt;
  console.log(`server is running at port ${PORT}`)
);

//unhandled promise rejection handling
process.on("unhandledRejection", (err) =&amp;gt; {
  console.log(
    "shutting down server due to unhandled promise rejection. Error: " +
      err.message
  );
  server.close(() =&amp;gt; {
    process.exit(1);
  });
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  server/controllers/User.js
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const bcrypt = require("bcrypt");
const jwt = require("jsonwebtoken");
const { google } = require("googleapis");
const fetch = require("node-fetch");

const { OAuth2 } = google.auth;
const sendMail = require("../utils/sendMail");
const User = require("../Model/User");

const client = new OAuth2(process.env.MAILING_SERVICE_CLIENT_ID);
const { CLIENT_URL } = process.env;

const ErrorHandler = require("../utils/errorHandler");
const AsyncErrorHandler = require("../Middleware/catchAsyncError");

const userCtrl = {
  //user/register
  register: AsyncErrorHandler(async (req, res, next) =&amp;gt; {
    // console.log(req.body);
    const { name, email, password } = req.body;

    if (!name || !email || !password)
      return next(new ErrorHandler("Please fill in all fields.", 406));

    if (!validateEmail(email))
      return next(new ErrorHandler("Invalid emails.", 406));

    const user = await User.findOne({ email });
    if (user) return next(new ErrorHandler("Email already exists.", 409));

    if (password.length &amp;lt; 6)
      return next(
        new ErrorHandler("Password must be at least 6 characters.", 406)
      );

    //HASHED PASSWORD
    const passwordHash = await bcrypt.hash(password, 12);

    const newUser = await User.create({
      name,
      email,
      password: passwordHash,
    });

    // return new user
    res.status(201).json({
      message: "Registration Successfull",
      newUser,
    });
  }),
  //user/login
  login: AsyncErrorHandler(async (req, res, next) =&amp;gt; {
    // console.log(req.body);
    const { email, password } = req.body;

    if (!email || !password)
      return next(new ErrorHandler("Please fill in all fields.", 406));

    const user = await User.findOne({ email });

    if (!user) return next(new ErrorHandler("Email does not exist.", 400));

    //PASSWORD MATCH CHECK
    const isMatch = await bcrypt.compare(password, user.password);

    if (!isMatch) return next(new ErrorHandler("Password is incorrect.", 400));

    const refresh_token = createRefreshToken({ id: user._id });

    //HANDLE REFRESH TOKEN USING COOKIES
    res.cookie("refreshtoken", refresh_token, {
      sameSite: "strict",
      httpOnly: true,
      // secure: true, //only work for production
      path: "/user/refresh_token",
      maxAge: 900000, //3min=180sec=180000 milliseconds
    });
    // Cookies that have not been signed
    // console.log("Cookies: ", req.cookies);

    // Cookies that have been signed
    // console.log("Signed Cookies: ", req.signedCookies);

    res.status(200).json({
      message: "Login Successfull",
      refreshToken: refresh_token,
      data: {
        name: user.name,
        email: user.email,
        isAdmin: user.isAdmin,
      },
    });
  }),
  //user/logout
  logout: AsyncErrorHandler(async (req, res) =&amp;gt; {
    res.clearCookie("refreshtoken", { path: "/user/refresh_token" });
    return res.status(200).json({ message: "You are logged out!" });
  }),
  //user/refresh_token
  getAccessToken: AsyncErrorHandler(async (req, res, next) =&amp;gt; {
    const rf_token = req.cookies.refreshtoken;

    if (!rf_token) return next(new ErrorHandler("Please login now!", 400));

    jwt.verify(rf_token, process.env.REFRESH_TOKEN_SECRET, (err, user) =&amp;gt; {
      if (err) return next(new ErrorHandler("Please login now!", 400));

      const access_token = createAccessToken({ id: user.id });
      res
        .status(200)
        .json({ message: "user is already logged in", access_token });
    });
  }),
  //user/forgot
  forgotPassword: AsyncErrorHandler(async (req, res, next) =&amp;gt; {
    const { email } = req.body;
    const user = await User.findOne({ email });
    if (!user) return next(new ErrorHandler("Email does not exist.", 400));

    const access_token = createAccessToken({ id: user._id });
    const url = `${CLIENT_URL}/user/reset/${access_token}`;

    //NODEMAILER SENDING EMAIL
    sendMail(email, url, "Reset your password");

    res.json({
      message: `Re-send the password, please check your email ${access_token}`,
    });
  }),
  //user/reset
  resetPassword: AsyncErrorHandler(async (req, res, next) =&amp;gt; {
    const { password } = req.body;
    // console.log(password);
    if (!password)
      return next(new ErrorHandler("please enter your password", 400));

    const passwordHash = await bcrypt.hash(password, 12);

    await User.findOneAndUpdate(
      { _id: req.user.id },
      {
        password: passwordHash,
      }
    );

    res.status(200).json({ msg: "Password successfully changed!" });
  }),
  //user/user_info/:id
  getUser: AsyncErrorHandler(async (req, res, next) =&amp;gt; {
    if (!mongoose.Types.ObjectId.isValid(req.params.id)) {
      return next(
        new ErrorHandler(`No user found with id:${req.params.id}`, 404)
      );
    }
    const user = await User.findById(req.params.id).select("-password");
    res.status(200).json(user);
  }),
  //user/all_user get access_token from hitting user/refresh_token paste the token in headers Authorization
  getUsers: AsyncErrorHandler(async (req, res) =&amp;gt; {
    const users = await User.find().select("-password");
    res.status(200).json(users);
  }),
  //user/update_user patch req
  updateUser: AsyncErrorHandler(async (req, res) =&amp;gt; {
    const { name, avatar, email } = req.body;
    await User.findOneAndUpdate(
      { _id: req.user.id },
      //update can be a single item just put one of them in body and send req
      {
        email,
        name,
        avatar,
      }
    );
    res.status(200).json({ msg: "Update Success!" });
  }),
  //user//update_role/:id
  updateUsersRole: AsyncErrorHandler(async (req, res) =&amp;gt; {
    const { isAdmin } = req.body;

    await User.findOneAndUpdate(
      { _id: req.params.id },
      {
        isAdmin,
      }
    );
    res.status(200).json({ msg: "Update Success!" });
  }),
  //user/delete/:id
  deleteUser: AsyncErrorHandler(async (req, res, next) =&amp;gt; {
    if (!mongoose.Types.ObjectId.isValid(req.params.id)) {
      return next(
        new ErrorHandler(`No user found with id:${req.params.id}`, 404)
      );
    }
    await User.findByIdAndDelete(req.params.id);
    res.status(200).json({ msg: "Deleted Success!" });
  }),
  //user/google_login
  googleLogin: AsyncErrorHandler(async (req, res, next) =&amp;gt; {
    const { tokenId } = req.body;
    // console.log(tokenId);
    if (!tokenId)
      return next(new ErrorHandler("you need to provide a token id", 400));

    const verify = await client.verifyIdToken({
      idToken: tokenId,
      audience:
        "779648521547-gjlsus2l9aud4kosqdtc5gu5icmumqlp.apps.googleusercontent.com", //google client_id
    });
    const { email_verified, email, name, picture } = verify.payload;
    console.log(email); //google pop up selected email
    console.log("email_verified", email_verified); //return true / false

    if (!email_verified)
      return res.status(400).json({ msg: "Email verification failed." });

    //hashed password
    const password = email + process.env.GOOGLE_SECRET;
    const passwordHash = await bcrypt.hash(password, 12);

    const user = await User.findOne({ email });

    if (user) {
      const isMatch = await bcrypt.compare(password, user.password);

      if (!isMatch)
        return res.status(400).json({ msg: "Password is incorrect." });

      const refresh_token = createRefreshToken({ id: user._id });

      res.cookie("refreshtoken", refresh_token, {
        httpOnly: true,
        path: "/user/refresh_token",
        secure: true,
        maxAge: 180000,
      });

      res.status(200).json({
        message: "Login Successfull",
        refreshToken: refresh_token,
        data: {
          name: user.name,
          email: user.email,
          avatar: user.avatar,
          isAdmin: user.isAdmin,
        },
      });
    } else {
      const newUser = new User({
        name,
        email,
        password: passwordHash,
        avatar: picture,
      });

      const userData = await newUser.save();

      const refresh_token = createRefreshToken({ id: newUser._id });

      res.cookie("refreshtoken", refresh_token, {
        httpOnly: true,
        path: "/user/refresh_token",
        secure: true,
        maxAge: 180000,
      });

      res.status(200).json({
        message: "Login Success",
        refreshToken: refresh_token,
        data: {
          name: userData.name,
          email: userData.email,
          avatar: userData.avatar,
          isAdmin: userData.isAdmin,
        },
      });
    }
  }),
  //user/facebook_login
  facebookLogin: AsyncErrorHandler(async (req, res, next) =&amp;gt; {
    const { accessToken, userID } = req.body;
    //developers.facebook.com/docs/graph-api/overview/ --&amp;gt;versions curl -i X GET \
    const URL = `https://graph.facebook.com/v2.9/${userID}/?fields=id,name,email,picture&amp;amp;access_token=${accessToken}`;

    const data = await fetch(URL)
      .then((res) =&amp;gt; res.json())
      .then((res) =&amp;gt; {
        return res;
      });

    const { email, name, picture } = data;

    const password = email + process.env.FACEBOOK_SECRET;

    const passwordHash = await bcrypt.hash(password, 12);

    const user = await User.findOne({ email });

    if (user) {
      const isMatch = await bcrypt.compare(password, user.password);
      if (!isMatch)
        return next(new ErrorHandler("Password is incorrect.", 400));

      const refresh_token = createRefreshToken({ id: user._id });
      res.cookie("refreshtoken", refresh_token, {
        httpOnly: true,
        path: "/user/refresh_token",
        secure: true,
        maxAge: 180000,
      });

      res.status(200).json({
        message: "Login Successfull",
        refreshToken: refresh_token,
        data: {
          name: user.name,
          email: user.email,
          avatar: user.avatar,
          isAdmin: user.isAdmin,
        },
      });
    } else {
      const newUser = new Users({
        name,
        email,
        password: passwordHash,
        avatar: picture.data.url,
      });

      const fbUserData = await newUser.save();

      const refresh_token = createRefreshToken({ id: newUser._id });
      res.cookie("refreshtoken", refresh_token, {
        httpOnly: true,
        path: "/user/refresh_token",
        secure: true,
        maxAge: 180000,
      });

      res.status(200).json({
        message: "Login Success",
        refreshToken: refresh_token,
        data: {
          name: fbUserData.name,
          email: fbUserData.email,
          avatar: fbUserData.avatar,
          isAdmin: fbUserData.isAdmin,
        },
      });
    }
  }),
};

function validateEmail(email) {
  const re =
    /^(([^&amp;lt;&amp;gt;()[\]\\.,;:\s@\"]+(\.[^&amp;lt;&amp;gt;()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
  return re.test(email);
}

const createActivationToken = (payload) =&amp;gt; {
  return jwt.sign(payload, process.env.ACTIVATION_TOKEN_SECRET, {
    expiresIn: "3m",
  });
};

const createAccessToken = (payload) =&amp;gt; {
  // return jwt.sign(payload, process.env.ACCESS_TOKEN_SECRET, {
  return jwt.sign(payload, "123456", {
    expiresIn: "3m",
  });
};

const createRefreshToken = (payload) =&amp;gt; {
  //payload = user._id
  // return jwt.sign(payload, process.env.REFRESH_TOKEN_SECRET, {
  return jwt.sign(payload, "123456", {
    expiresIn: "3m",
  });
};

module.exports = userCtrl;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  server/Model/Users.js
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const mongoose = require("mongoose");

const userSchema = new mongoose.Schema(
  {
    name: {
      type: String,
      required: [true, "Please enter your name!"],
      trim: true,
    },
    email: {
      type: String,
      required: [true, "Please enter your email!"],
      trim: true,
      unique: true,
    },
    password: {
      type: String,
      required: [true, "Please enter your password!"],
    },
    isAdmin: {
      type: Boolean,
      default: false,
    },
    avatar: {
      type: String,
      default:
        "https://cdn.pixabay.com/photo/2016/08/08/09/17/avatar-1577909_960_720.png",
    },
    totalBuyCost: {
      type: Number,
      default: 0,
    },
  },
  {
    timestamps: true,
  }
);

module.exports = mongoose.model("User", userSchema);

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  server/routes/Users.js
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const router = require('express').Router()
const userCtrl = require('../controllers/User')
const { protect, admin } = require("../middleware/auth");

//for protect routes you need token to attach in headers

router.post('/register', userCtrl.register)
router.post('/login', userCtrl.login)
router.post('/logout', userCtrl.logout)
router.post('/refresh_token', userCtrl.getAccessToken)
router.post('/forgot',protect, userCtrl.forgotPassword)
router.post('/reset', protect, userCtrl.resetPassword)
router.get('/user_info/:id',protect, userCtrl.getUser)
router.get('/all_user', protect, admin, userCtrl.getUsers)
router.patch('/update_user', protect, userCtrl.updateUser)
router.patch('/update_role/:id', protect, admin, userCtrl.updateUsersRole)
router.delete('/delete_user/:id', protect, admin, userCtrl.deleteUser)

// Social Login
router.post('/google_login', userCtrl.googleLogin)
router.post('/facebook_login', userCtrl.facebookLogin)

module.exports = router
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  server/Middleware/auth
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const jwt = require("jsonwebtoken");
const AsyncErrorHandler = require("../Middleware/catchAsyncError");
const User = require("../Model/User");

const protect = AsyncErrorHandler(async (req, res, next) =&amp;gt; {
  try {
    const token = req.header("Authorization");
    if (!token) return res.status(401).json({ message: "you are not authorized" });

    const decoded = jwt.verify(token, process.env.ACCESS_TOKEN_SECRET);
    // console.log(`decoded user`,decoded)
    req.user = await User.findById(decoded.id).select("-password");
    // console.log(req.user)
    next();
  } catch (error) {
    return res.status(401).json({message: "you are not authorized", error: error.message });
  }
});

const admin = (req, res, next) =&amp;gt; {
  console.log(req.user);
  if (req.user &amp;amp;&amp;amp; req.user.isAdmin) {
    next();
  } else {
    return res.status(401).json({message: "Not authorized as an admin"});
  }
};

module.exports = { protect, admin };

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  server/middleware/catchAsyncError.js
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;module.exports = (acceptedFunction) =&amp;gt; (req,res,next) =&amp;gt; {    Promise.resolve(acceptedFunction(req,res,next)).catch(next)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  server/middleware/error.js
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const ErrorHandler = require("../utils/errorHandler");

module.exports = (err, req, res, next) =&amp;gt; {
  console.log(`err`, err.message);
  let error = { ...err };
  error.message = err.message;

  //mongodb bad objectId
  if (err.name === "CastError") {
    const message = "Resource not found";
    error = new ErrorHandler(message, 404);
  }
  //mongodb duplicate field error
  if (err.code === 11000) {
    const message = "duplicate field value entered";
    error = new ErrorHandler(message, 404);
  }
  //mongodb validation error
  if (err.name === "ValidationError") {
    const message = Object.values(err.errors).map((value) =&amp;gt; value.message);
    error = new ErrorHandler(message, 404);
  }

  res.status(error.statusCode || 500).json({
    success: false,
    message: error.message || "server error",
  });
};

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  server/config/db.js
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const mongoose =require("mongoose");

const connectDB = async () =&amp;gt; {
  // Connecting to the database
  const { MONGO_URI } = process.env;
  mongoose
    .connect(MONGO_URI, {
      useNewUrlParser: true,
      useUnifiedTopology: true,
      // useFindAndModify: false,
    })
    .then((data) =&amp;gt; {
      console.log(`mongodb connection established with server: ${data.connection.host}`);
    })
};

module.exports = connectDB;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>javascript</category>
      <category>node</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>React Nodejs Multiple Image Upload Using Multer</title>
      <dc:creator>Abdur Rakib Rony</dc:creator>
      <pubDate>Wed, 17 Nov 2021 16:59:28 +0000</pubDate>
      <link>https://dev.to/ronyfr3/react-nodejs-multiple-image-upload-using-multer-hh4</link>
      <guid>https://dev.to/ronyfr3/react-nodejs-multiple-image-upload-using-multer-hh4</guid>
      <description>&lt;h1&gt;
  
  
  Frontend Code
&lt;/h1&gt;

&lt;h3&gt;
  
  
  package
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"axios": "^0.24.0",
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;src/components/FileUpload&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import axios from 'axios';
import React, { Fragment, useState } from 'react';

const FileUpload = () =&amp;gt; {
  const [files, setFiles] = useState([]);

  const onChange = e =&amp;gt; {
    console.log(e.target.files);
    setFiles(e.target.files)
  };
  console.log(files);
  const onSubmit = async e =&amp;gt; {
    e.preventDefault();
    const formData = new FormData();
    Object.values(files).forEach(file=&amp;gt;{
      formData.append("uploadImages", file);
    });

    try {
      const res = await axios.post('/api/upload', formData, {
        headers: {
          'Content-Type': 'multipart/form-data'
        },
      });
      console.log(res);
    } catch (err) {
      if (err.response.status === 500) {
        console.log(err);
      } else {
        console.log(err.response.data.msg);
      }
    }
  };

  return (
    &amp;lt;Fragment&amp;gt;
      &amp;lt;form onSubmit={onSubmit}&amp;gt;
        &amp;lt;div&amp;gt;
          &amp;lt;input
            type='file'
            id='file'
            name="uploadImages"
            multiple
            onChange={onChange}
          /&amp;gt;
        &amp;lt;/div&amp;gt;
        &amp;lt;input
          type='submit'
          value='Upload'
        /&amp;gt;
      &amp;lt;/form&amp;gt;
    &amp;lt;/Fragment&amp;gt;
  );
};

export default FileUpload;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;src/App&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from 'react';
import FileUpload from './components/FileUpload';

const App = () =&amp;gt; (
  &amp;lt;div className=''&amp;gt;
    &amp;lt;FileUpload /&amp;gt;
  &amp;lt;/div&amp;gt;
);

export default App;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Backend Code
&lt;/h1&gt;

&lt;h3&gt;
  
  
  package
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"dependencies": {
    "cors": "^2.8.5",
    "express": "^4.17.1",
    "multer": "^1.4.3",
    "nodemon": "^2.0.15"
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;index.js&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const express = require('express');
const cors = require('cors');
const path = require('path');
const multer = require('multer');
const app = express();
const port = 5000;
// app.use(express.static('uploads'))
const storage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, path.join(__dirname, './uploads'));
  },
  filename: function (req, file, cb) {
    cb(
      null,
      file.fieldname + '-' + Date.now() + file.originalname.match(/\..*$/)[0],
    );
  },
});
const multi_upload = multer({
  storage,
  fileFilter: (req, file, cb) =&amp;gt; {
    if (
      file.mimetype == 'image/png' ||
      file.mimetype == 'image/jpeg' ||
      file.mimetype == 'image/jpg'
    ) {
      cb(null, true);
    } else {
      cb(null, false);
      const err = new Error('Only .jpg .jpeg .png images are supported!');
      err.name = 'ExtensionError';
      return cb(err);
    }
  },
}).array('uploadImages', 10);
app.post('/api/upload', (req, res) =&amp;gt; {
    multi_upload(req, res, function (err) {
      console.log(req.files);
    //multer error
    if (err instanceof multer.MulterError) {
      console.log(err);
      res
        .status(500)
        .send({
          error: { msg: `multer uploading error: ${err.message}` },
        })
        .end();
      return;
    } else if (err) {
      //unknown error
      if (err.name == 'ExtensionError') {
        res
          .status(413)
          .send({ error: { msg: `${err.message}` } })
          .end();
      } else {
        res
          .status(500)
          .send({ error: { msg: `unknown uploading error: ${err.message}` } })
          .end();
      }
      return;
    }
    res.status(200).send('file uploaded');
  });
});
app.listen(port, () =&amp;gt;
  console.log(`server is listening on url http://localhost:${port}`),
);

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Note: Create a uploads folder in Backend root directory
&lt;/h3&gt;

</description>
    </item>
    <item>
      <title>React Input Tags Component</title>
      <dc:creator>Abdur Rakib Rony</dc:creator>
      <pubDate>Mon, 15 Nov 2021 11:55:53 +0000</pubDate>
      <link>https://dev.to/ronyfr3/react-input-tags-component-i06</link>
      <guid>https://dev.to/ronyfr3/react-input-tags-component-i06</guid>
      <description>&lt;h1&gt;
  
  
  Simple React Component
&lt;/h1&gt;

&lt;p&gt;&lt;em&gt;src/App.js&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from "react";

const App = () =&amp;gt; {
  const [tags, setTags] = React.useState([]);
  console.log(tags);
  let tagInput
  const removeTag = (i) =&amp;gt; {
    const newTags = [...tags];
    newTags.splice(i, 1);
    // Call the defined function setTags which will replace tags with the new value.
    setTags(newTags);
  };

  const inputKeyDown = (e) =&amp;gt; {
    const val = e.target.value;
    if (e.key === "Enter" &amp;amp;&amp;amp; val) {
      if (tags.find((tag) =&amp;gt; tag.toLowerCase() === val.toLowerCase())) {
        return;
      }
      setTags([...tags, val]);
      tagInput.value = null;
    } else if (e.key === "Backspace" &amp;amp;&amp;amp; !val) {
      removeTag(tags.length - 1);
    }
  };
  return (
    &amp;lt;div className="input-tag"&amp;gt;
      &amp;lt;ul className="input-tag__tags"&amp;gt;
        {tags.map((tag, i) =&amp;gt; (
          &amp;lt;li key={tag}&amp;gt;
            {tag}
            &amp;lt;button
              type="button"
              onClick={() =&amp;gt; {
                removeTag(i);
              }}
            &amp;gt;
              delete
            &amp;lt;/button&amp;gt;
          &amp;lt;/li&amp;gt;
        ))}
        &amp;lt;li className="input-tag__tags__input"&amp;gt;
          &amp;lt;input
            type="text"
            onKeyDown={inputKeyDown}
            ref={(c) =&amp;gt; {
              tagInput = c;
            }}
          /&amp;gt;
        &amp;lt;/li&amp;gt;
      &amp;lt;/ul&amp;gt;
    &amp;lt;/div&amp;gt;
  );
};

export default App;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;*src/index.js&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from "react";
import ReactDOM from "react-dom";
import App from './App'

ReactDOM.render(
  &amp;lt;div&amp;gt;
     &amp;lt;App /&amp;gt;
  &amp;lt;/div&amp;gt;,
  document.getElementById('root')
);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;src/index.css&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;* {
  font-family: sans-serif;
  font-size: 17px;
}

body {
  background: #f2f2f2;
  padding: 20px;
}

.input-tag {
  background: white;
  border: 1px solid #d6d6d6;
  border-radius: 2px;
  display: flex;
  flex-wrap: wrap;
  padding: 5px 5px 0;
}

.input-tag input {
  border: none;
  width: 100%;
}

.input-tag__tags {
  display: inline-flex;
  flex-wrap: wrap;
  margin: 0;
  padding: 0;
  width: 100%;
}

.input-tag__tags li {
  align-items: center;
  background: #85A3BF;
  border-radius: 2px;
  color: white;
  display: flex;
  font-weight: 300;
  list-style: none;
  margin-bottom: 5px;
  margin-right: 5px;
  padding: 5px 10px;
}

.input-tag__tags li button {
  align-items: center;
  appearance: none;
  background: #333333;
  border: none;
  border-radius: 50%;
  color: white;
  cursor: pointer;
  display: inline-flex;
  font-size: 12px;
  height: 15px;
  justify-content: center;
  line-height: 0;
  margin-left: 8px;
  padding: 0;
  transform: rotate(45deg);
  width: 15px;
}

.input-tag__tags li.input-tag__tags__input {
  background: none;
  flex-grow: 1;
  padding: 0;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
    </item>
  </channel>
</rss>
