Commit 73060c65 authored by Sanjula Ranasinghe's avatar Sanjula Ranasinghe

Initial commit

parents
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/.pnp
.pnp.js
# testing
/coverage
# production
/build
# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local
npm-debug.log*
yarn-debug.log*
yarn-error.log*
const express = require("express");
const ErrorHandler = require("./middleware/error");
const app = express();
const cookieParser = require("cookie-parser");
const bodyParser = require("body-parser");
const cors = require("cors");
app.use(express.json());
app.use(cookieParser());
app.use(cors({
origin : "http://localhost:3000",
credentials: true,
}));
app.use("/", express.static("uploads"));
app.use(bodyParser.urlencoded({extended: true , limit: "50mb"}));
//config
if (process.env.NODE_ENV !== "PRODUCTION") {
require("dotenv").config({
path: "config/.env",
});
}
//import routes
const user = require("./controller/user");
app.use("/api/v2/user", user);
// it's for ErrorHandling
app.use(ErrorHandler);
module.exports = app;
\ No newline at end of file
PORT = 8000
DB_URL = "mongodb+srv://ceyloneezadmin:ceyloneez12345@cluster0.m1c223v.mongodb.net/?retryWrites=true&w=majority"
JWT_SECRET_KEY = "2FxXT1NTf2K1Mo4i6AOvtdI"
JWT_EXPIRES = 7d
ACTIVATION_SECRET = hghlsajsajdsdkjsdksddsadeeafafsad
SMPT_HOST = smtp.gmail.com
SMPT_PORT = 465
SMPT_PASSWORD = gratmrrxqbswkbwd
SMPT_MAIL = ceyloneezblogs@gmail.com
const express = require("express");
const path = require("path");
const User = require("../model/user");
const router = express.Router();
const {
upload
} = require("../multer");
const ErrorHandler = require("../utills/ErrorHandler");
const catchAsyncErrors = require("../middleware/catchAsyncErrors");
const fs = require("fs");
const jwt = require("jsonwebtoken");
const sendMail = require("../utills/sendMail");
const sendToken = require("../utills/jwtToken");
const {
isAuthenticated
} = require("../middleware/auth");
router.post("/create-user", upload.single("file"), async (req, res, next) => {
try {
const {
name,
email,
password
} = req.body;
const userEmail = await User.findOne({
email
});
if (userEmail) {
const filename = req.file.filename;
const filePath = `uploads/${filename}`;
fs.unlink(filePath, (err) => {
if (err) {
console.log(err);
res.status(500).json({
message: "Error deleting file"
});
} else {
res.json({
message: "File deleted successfully"
});
}
});
return next(new ErrorHandler("User already exists", 400));
}
const filename = req.file.filename;
const fileUrl = path.join(filename);
const user = {
name: name,
email: email,
password: password,
avatar: fileUrl,
};
// const newUser = await User.create(user);
// res.status(201).json({
// success: true,
// newUser,
// });
const activationToken = createActivationToken(user);
const activationUrl = `http://localhost:3000/act/activation/${activationToken}`;
try {
await sendMail({
email: user.email,
subject: "Activate your account",
message: `Hello ${user.name}, please click on the link to activate your account: ${activationUrl}`,
});
res.status(201).json({
success: true,
message: `please check your email:- ${user.email} to activate your account!`,
});
} catch (error) {
return next(new ErrorHandler(error.message, 500));
}
} catch (error) {
return next(new ErrorHandler(error.message, 400));
}
});
// create activation token
const createActivationToken = (user) => {
return jwt.sign(user, process.env.ACTIVATION_SECRET, {
expiresIn: "5m",
});
};
// activate user
router.post(
"/activation",
catchAsyncErrors(async (req, res, next) => {
try {
const {
activation_token
} = req.body;
const newUser = jwt.verify(
activation_token,
process.env.ACTIVATION_SECRET
);
if (!newUser) {
return next(new ErrorHandler("Invalid token", 400));
}
const {
name,
email,
password,
avatar
} = newUser;
let user = await User.findOne({
email
});
if (user) {
return next(new ErrorHandler("User already exists", 400));
}
user = await User.create({
name,
email,
avatar,
password,
});
sendToken(user, 201, res);
} catch (error) {
return next(new ErrorHandler(error.message, 500));
}
})
);
//login user
router.post(
"/login-user",
catchAsyncErrors(async (req, res, next) => {
try {
const {
email,
password
} = req.body;
if (!email || !password) {
return next(new ErrorHandler("Please provide the all fields!", 400));
}
const user = await User.findOne({
email
}).select("+password");
if (!user) {
return next(new ErrorHandler("User doesn't exists!", 400));
}
const isPasswordValid = await user.comparePassword(password);
if (!isPasswordValid) {
return next(
new ErrorHandler("Please provide the correct information", 400)
);
}
sendToken(user, 201, res);
} catch (error) {
return next(new ErrorHandler(error.message, 500));
}
})
);
// load user
router.get(
"/getuser",
isAuthenticated,
catchAsyncErrors(async (req, res, next) => {
try {
const user = await User.findById(req.user.id);
if (!user) {
return next(new ErrorHandler("User doesn't exists", 400));
}
res.status(200).json({
success: true,
user,
});
} catch (error) {
return next(new ErrorHandler(error.message, 500));
}
})
);
module.exports = router;
\ No newline at end of file
const mongoose = require("mongoose");
const connectDatabase = () => {
mongoose
.connect(process.env.DB_URL, {
useNewUrlParser: true,
useUnifiedTopology: true,
})
.then((data) => {
console.log(`mongod connected with server: ${data.connection.host}`);
});
};
module.exports = connectDatabase;
\ No newline at end of file
const ErrorHandler = require("../utills/ErrorHandler");
const catchAsyncErrors = require("./catchAsyncErrors");
const jwt = require("jsonwebtoken");
const User = require("../model/user");
exports.isAuthenticated = catchAsyncErrors(async(req,res,next) => {
const {token} = req.cookies;
if(!token){
return next(new ErrorHandler("Please login to continue", 401));
}
const decoded = jwt.verify(token, process.env.JWT_SECRET_KEY);
req.user = await User.findById(decoded.id);
next();
});
\ No newline at end of file
module.exports = (theFunc) => (req, res, next) => {
Promise.resolve(theFunc(req, res, next)).catch(next);
};
\ No newline at end of file
const ErrorHandler = require("../utills/ErrorHandler");
module.exports = (err, req, res, next) => {
err.statusCode = err.statusCode || 500;
err.message = err.message || "Internal server Error";
// wrong mongodb id error
if (err.name === "CastError") {
const message = `Resources not found with this id.. Invalid ${err.path}`;
err = new ErrorHandler(message, 400);
}
// Duplicate key error
if (err.code === 11000) {
const message = `Duplicate key ${Object.keys(err.keyValue)} Entered`;
err = new ErrorHandler(message, 400);
}
// wrong jwt error
if (err.name === "JsonWebTokenError") {
const message = `Your url is invalid please try again letter`;
err = new ErrorHandler(message, 400);
}
// jwt expired
if (err.name === "TokenExpiredError") {
const message = `Your Url is expired please try again letter!`;
err = new ErrorHandler(message, 400);
}
res.status(err.statusCode).json({
success: false,
message: err.message,
});
};
const mongoose = require("mongoose");
const bcrypt = require("bcryptjs");
const jwt = require("jsonwebtoken");
const userSchema = new mongoose.Schema({
name:{
type: String,
required: [true, "Please enter your name!"],
},
email:{
type: String,
required: [true, "Please enter your email!"],
},
password:{
type: String,
required: [true, "Please enter your password"],
minLength: [4, "Password should be greater than 4 characters"],
select: false,
},
phoneNumber:{
type: Number,
},
addresses:[
{
country: {
type: String,
},
city:{
type: String,
},
address1:{
type: String,
},
address2:{
type: String,
},
zipCode:{
type: Number,
},
addressType:{
type: String,
},
}
],
role:{
type: String,
default: "user",
},
avatar:{
type: String,
required: true,
},
createdAt:{
type: Date,
default: Date.now(),
},
resetPasswordToken: String,
resetPasswordTime: Date,
});
// Hash password
userSchema.pre("save", async function (next){
if(!this.isModified("password")){
next();
}
this.password = await bcrypt.hash(this.password, 10);
});
// jwt token
userSchema.methods.getJwtToken = function () {
return jwt.sign({ id: this._id}, process.env.JWT_SECRET_KEY,{
expiresIn: process.env.JWT_EXPIRES,
});
};
// compare password
userSchema.methods.comparePassword = async function (enteredPassword) {
return await bcrypt.compare(enteredPassword, this.password);
};
module.exports = mongoose.model("User", userSchema);
\ No newline at end of file
const multer = require("multer");
const path = require("path");
const storage = multer.diskStorage({
destination: function (req,res,cb){
cb(null, "uploads/");
},
filename: function (req,file,cb) {
const uniqueSuffix = Date.now() + "-" + Math.round(Math.random() * 1e9);
const filename = file.originalname.split(".")[0];
cb(null,filename + "-" + uniqueSuffix + ".png");
},
});
exports.upload = multer({storage: storage});
\ No newline at end of file
const app = require("./app");
const connectDatabase = require("./db/Database");
// Handling uncaught Exception
process.on("uncaughtException", (err) => {
console.log(`Error: ${err.message}`);
console.log(`shutting down the server for handling uncaught exception`);
});
// config
if (process.env.NODE_ENV !== "PRODUCTION") {
require("dotenv").config({
path: "backend/config/.env",
});
}
// connect db
connectDatabase();
// create server
const server = app.listen(process.env.PORT, () => {
console.log(
`Server is running on http://localhost:${process.env.PORT}`
);
});
// unhandled promise rejection
process.on("unhandledRejection", (err) => {
console.log(`Shutting down the server for ${err.message}`);
console.log(`shutting down the server for unhandle promise rejection`);
server.close(() => {
process.exit(1);
});
});
\ No newline at end of file
class ErrorHandler extends Error {
constructor(message, statusCode) {
super(message);
this.statusCode = statusCode;
Error.captureStackTrace(this, this.constructor);
}
}
module.exports = ErrorHandler;
// create token and saving that in cookies
const sendToken = (user, statusCode, res) => {
const token = user.getJwtToken();
// Options for cookies
const options = {
expires: new Date(Date.now() + 90 * 24 * 60 * 60 * 1000),
httpOnly: true,
// sameSite: "none",
// secure: true,
};
res.status(statusCode).cookie("token", token, options).json({
success: true,
user,
token,
});
};
module.exports = sendToken;
\ No newline at end of file
const nodemailer = require("nodemailer");
const sendMail = async (options) => {
const transporter = nodemailer.createTransport({
host: process.env.SMPT_HOST,
port: process.env.SMPT_PORT,
service: process.env.SMPT_SERVICE,
auth:{
user: process.env.SMPT_MAIL,
pass: process.env.SMPT_PASSWORD,
},
});
const mailOptions = {
from: process.env.SMPT_MAIL,
to: options.email,
subject: options.subject,
text: options.message,
};
await transporter.sendMail(mailOptions);
};
module.exports = sendMail;
\ No newline at end of file
frontend @ 24abbf2a
Subproject commit 24abbf2a1a133b4ed64881f499d113bad4f3290f
This diff is collapsed.
{
"name": "ceyloneez_com",
"version": "1.0.0",
"description": "",
"main": "backend/server.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "nodemon backend/server.js",
"start": "node backend/server.js"
},
"author": "sanjula ranasinghe",
"license": "ISC",
"dependencies": {
"bcrypt": "^5.1.0",
"bcryptjs": "^2.4.3",
"cookie-parser": "^1.4.6",
"cors": "^2.8.5",
"dotenv": "^16.0.3",
"express": "^4.18.2",
"jsonwebtoken": "^9.0.0",
"mongoose": "^7.1.0",
"multer": "^1.4.5-lts.1",
"nodemailer": "^6.9.1",
"nodemon": "^2.0.22"
}
}
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