{{post.title}}
28 |{{{post.content}}}
29 |├── .env
├── README.md
├── controllers
├── createPost.js
├── createUser.js
├── getPosts.js
├── homePage.js
├── login.js
├── loginStore.js
├── logout.js
├── postsNew.js
└── userStore.js
├── index.js
├── middleware
├── auth.js
├── redirect.js
└── storePost.js
├── models
├── Post.js
└── User.js
├── package-lock.json
├── package.json
├── public
├── assets
│ ├── favicon.ico
│ └── img
│ │ ├── about-bg.jpg
│ │ ├── contact-bg.jpg
│ │ ├── home-bg.jpg
│ │ ├── post-bg.jpg
│ │ └── post-sample-image.jpg
├── css
│ └── styles.css
├── js
│ └── scripts.js
└── posts
│ ├── + (3).png
│ ├── photo_2021-11-18_22-28-27.jpg
│ ├── photo_2021-11-20_16-01-01.jpg
│ ├── photo_2021-11-20_16-01-05.jpg
│ ├── photo_2021-11-20_16-01-07.jpg
│ └── Дизайн без названия (2).png
└── views
├── create.edge
├── index.edge
├── layouts
└── app.edge
├── login.edge
├── not_found.edge
├── post.edge
└── register.edge
/.env:
--------------------------------------------------------------------------------
1 | MongoUrl='mongodb+srv://samar:zozmS9hwVNIpdsGr@cluster0.bbfkm.mongodb.net/node-blog'
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # NodeJS-Blog
2 | Demo https://blog-node-rest-api.herokuapp.com/
3 |
4 | Description: A large static online store and a complex REST API application. The project includes a huge amount of functions in which users can buy goods, sell or only show description and compare price with others. For every user having a profile page with this can change any information or add an avatar. If you add some goods with wrong information, it is no problem to change it. You can see more in the demo website, link below.
5 |
--------------------------------------------------------------------------------
/controllers/createPost.js:
--------------------------------------------------------------------------------
1 | const Post = require("../models/Post");
2 | const path = require("path");
3 |
4 | module.exports = (req, res) => {
5 | const {image} = req.files;
6 | image.mv(path.resolve(__dirname, "..", "public/posts", image.name), (err) => {
7 | if(err) {
8 | console.log(err)
9 | }
10 | Post.create({...req.body, image: `/posts/${image.name}`, author: req.session.userId}, (err, post) => {
11 | res.redirect('/');
12 | })
13 | })
14 | }
--------------------------------------------------------------------------------
/controllers/createUser.js:
--------------------------------------------------------------------------------
1 | module.exports = (req, res) => {
2 | res.render("register", {
3 | errors: req.flash("registrationError"),
4 | data: req.flash("data")[0]
5 | });
6 | }
--------------------------------------------------------------------------------
/controllers/getPosts.js:
--------------------------------------------------------------------------------
1 | const Post = require("../models/Post");
2 |
3 | module.exports = async (req, res) => {
4 | const post = await Post.findById(req.params.id).populate("author", "username");
5 | res.render("post", {post})
6 | }
--------------------------------------------------------------------------------
/controllers/homePage.js:
--------------------------------------------------------------------------------
1 | const Post = require("../models/Post");
2 |
3 | module.exports = async (req, res) => {
4 | console.log(req.session);
5 | const posts = await Post.find().populate("author", "username");
6 | console.log(posts);
7 | res.render("index", {posts});
8 | }
--------------------------------------------------------------------------------
/controllers/login.js:
--------------------------------------------------------------------------------
1 | module.exports = (req, res) => {
2 | res.render("login");
3 | }
--------------------------------------------------------------------------------
/controllers/loginStore.js:
--------------------------------------------------------------------------------
1 | const bcrypt = require('bcrypt')
2 | const User = require('../models/User')
3 |
4 | module.exports = (req, res) => {
5 | const { email, password } = req.body;
6 | User.findOne({ email }, async (error, user) => {
7 | if (user) {
8 | const validPassword = await bcrypt.compare(password, user.password);
9 | if(validPassword) {
10 | req.session.userId = user._id;
11 | res.redirect("/");
12 | }else{
13 | res.redirect("/login");
14 | }
15 | } else {
16 | return res.redirect('/login')
17 | }
18 | })
19 | }
--------------------------------------------------------------------------------
/controllers/logout.js:
--------------------------------------------------------------------------------
1 | module.exports = (req, res) => {
2 | req.session.destroy(() => {
3 | res.redirect("/");
4 | })
5 | }
--------------------------------------------------------------------------------
/controllers/postsNew.js:
--------------------------------------------------------------------------------
1 | module.exports = (req, res) => {
2 | res.render("create");
3 | }
--------------------------------------------------------------------------------
/controllers/userStore.js:
--------------------------------------------------------------------------------
1 | const User = require("../models/User");
2 | const bcrypt = require("bcrypt");
3 |
4 | module.exports = (req, res) => {
5 | User.create(req.body, async (err, user) => {
6 | if(err) {
7 | const registrationError = Object.keys(err.errors).map(key => err.errors[key].message);
8 | req.flash("registrationError", registrationError);
9 | req.flash("data", req.body);
10 |
11 | return res.redirect("/reg")
12 | }
13 | const salt = await bcrypt.genSalt(10);
14 | user.password = await bcrypt.hash(user.password, salt);
15 | user.save();
16 | res.redirect("/login");
17 | })
18 | }
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | const express = require("express");
2 | const expressEdge = require("express-edge");
3 | const mongoose = require("mongoose");
4 | const fileUpload = require("express-fileupload");
5 | const expressSession = require("express-session");
6 | const mongoStore = require("connect-mongo");
7 | const connectFlash = require("connect-flash");
8 |
9 | const homePageController = require("./controllers/homePage");
10 | const getPostsController = require("./controllers/getPosts");
11 | const postsNewController = require("./controllers/postsNew");
12 | const createPostController = require("./controllers/createPost");
13 | const createUserController = require("./controllers/createUser");
14 | const storeUserController = require("./controllers/userStore");
15 | const loginController = require("./controllers/login");
16 | const loginStoreController = require("./controllers/loginStore");
17 | const logoutController = require("./controllers/logout");
18 |
19 | const app = express();
20 |
21 | const storePostMiddleware = require("./middleware/storePost");
22 | const authMiddleware = require("./middleware/auth");
23 | const redirectIfAuth = require("./middleware/redirect");
24 |
25 | const MongoUrl = process.env.MongoUrl
26 |
27 | mongoose.connect(MongoUrl);
28 |
29 | app.use(expressSession({
30 | secret: "samar",
31 | store: mongoStore.create({mongoUrl: MongoUrl})
32 | }));
33 | app.use(fileUpload());
34 | app.use(express.static("public"));
35 | app.use(expressEdge.engine);
36 | app.use(express.json());
37 | app.use(express.urlencoded({extended: true}));
38 | app.use(connectFlash())
39 |
40 | app.set("views", `${__dirname}/views`);
41 |
42 | app.use((req, res, next) => {
43 | app.locals.auth = req.session.userId;
44 | next();
45 | })
46 |
47 | app.get("/", homePageController);
48 | app.get("/post/:id", getPostsController);
49 | app.get("/logout", authMiddleware, logoutController);
50 | app.get("/posts/new", authMiddleware, postsNewController);
51 | app.post("/posts/create", authMiddleware, storePostMiddleware, createPostController);
52 | app.get("/reg", redirectIfAuth, createUserController);
53 | app.post("/auth/reg", storeUserController);
54 | app.get("/login", redirectIfAuth, loginController);
55 | app.post("/auth/log", loginStoreController);
56 | app.use((req, res) => res.render("not_found"));
57 |
58 | app.listen(5000, () => {console.log("Server has been started on Port 5000...")});
--------------------------------------------------------------------------------
/middleware/auth.js:
--------------------------------------------------------------------------------
1 | const User = require("../models/User");
2 |
3 | module.exports = (req, res, next) => {
4 | User.findById(req.session.userId, (err, user) => {
5 | if(err || !user) {
6 | return res.redirect("/")
7 | }
8 | next();
9 | })
10 | }
--------------------------------------------------------------------------------
/middleware/redirect.js:
--------------------------------------------------------------------------------
1 | module.exports = (req, res, next) => {
2 | if(req.session.userId) {
3 | return res.redirect("/");
4 | }
5 | next();
6 | }
--------------------------------------------------------------------------------
/middleware/storePost.js:
--------------------------------------------------------------------------------
1 | module.exports = (req, res, next) => {
2 | if(!(req.files && req.files.image) || !req.body.title || !req.body.description || !req.body.content) {
3 | return res.redirect("/posts/new")
4 | }
5 | next();
6 | }
7 |
--------------------------------------------------------------------------------
/models/Post.js:
--------------------------------------------------------------------------------
1 | const mongoose = require("mongoose");
2 |
3 | const PostSchema = new mongoose.Schema({
4 | title: String,
5 | description: String,
6 | content: String,
7 | author: {
8 | type: mongoose.Schema.ObjectId,
9 | ref: "User",
10 | required: true
11 | },
12 | image: String,
13 | createdAt: {
14 | type: Date,
15 | default: new Date()
16 | }
17 | })
18 |
19 | const Post = mongoose.model("Post", PostSchema);
20 | module.exports = Post;
--------------------------------------------------------------------------------
/models/User.js:
--------------------------------------------------------------------------------
1 | const mongoose = require("mongoose");
2 | const bcrypt = require("bcrypt");
3 |
4 | const UserSchema = mongoose.Schema({
5 | username: {
6 | type: String,
7 | required: [true, "Please, provide your username"]
8 | },
9 | email: {
10 | type: String,
11 | required: [true, "Please, provide your email"],
12 | unique: true
13 | },
14 | password: {
15 | type: String,
16 | required: [true, "Please, provide your password"]
17 | }
18 | })
19 |
20 | const User = mongoose.model("User", UserSchema);
21 | module.exports = User;
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "blog",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "start": "node index.js",
8 | "dev": "nodemon index.js"
9 | },
10 | "keywords": [],
11 | "author": "Samar Badriddinov",
12 | "license": "ISC",
13 | "dependencies": {
14 | "bcrypt": "^5.0.1",
15 | "connect-flash": "^0.1.1",
16 | "connect-mongo": "^4.6.0",
17 | "edge.js": "^5.3.2",
18 | "express": "^4.17.1",
19 | "express-edge": "^2.0.2",
20 | "express-fileupload": "^1.2.1",
21 | "express-session": "^1.17.2",
22 | "mongoose": "^6.0.13"
23 | },
24 | "devDependencies": {
25 | "nodemon": "^2.0.15"
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/public/assets/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SameerBadriddinov/NodeJS-Blog/26ae776a76c2283ad6e361ebfa5c2443e3124fa5/public/assets/favicon.ico
--------------------------------------------------------------------------------
/public/assets/img/about-bg.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SameerBadriddinov/NodeJS-Blog/26ae776a76c2283ad6e361ebfa5c2443e3124fa5/public/assets/img/about-bg.jpg
--------------------------------------------------------------------------------
/public/assets/img/contact-bg.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SameerBadriddinov/NodeJS-Blog/26ae776a76c2283ad6e361ebfa5c2443e3124fa5/public/assets/img/contact-bg.jpg
--------------------------------------------------------------------------------
/public/assets/img/home-bg.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SameerBadriddinov/NodeJS-Blog/26ae776a76c2283ad6e361ebfa5c2443e3124fa5/public/assets/img/home-bg.jpg
--------------------------------------------------------------------------------
/public/assets/img/post-bg.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SameerBadriddinov/NodeJS-Blog/26ae776a76c2283ad6e361ebfa5c2443e3124fa5/public/assets/img/post-bg.jpg
--------------------------------------------------------------------------------
/public/assets/img/post-sample-image.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SameerBadriddinov/NodeJS-Blog/26ae776a76c2283ad6e361ebfa5c2443e3124fa5/public/assets/img/post-sample-image.jpg
--------------------------------------------------------------------------------
/public/js/scripts.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * Start Bootstrap - Clean Blog v6.0.7 (https://startbootstrap.com/theme/clean-blog)
3 | * Copyright 2013-2021 Start Bootstrap
4 | * Licensed under MIT (https://github.com/StartBootstrap/startbootstrap-clean-blog/blob/master/LICENSE)
5 | */
6 | window.addEventListener('DOMContentLoaded', () => {
7 | let scrollPos = 0;
8 | const mainNav = document.getElementById('mainNav');
9 | const headerHeight = mainNav.clientHeight;
10 | window.addEventListener('scroll', function() {
11 | const currentTop = document.body.getBoundingClientRect().top * -1;
12 | if ( currentTop < scrollPos) {
13 | // Scrolling Up
14 | if (currentTop > 0 && mainNav.classList.contains('is-fixed')) {
15 | mainNav.classList.add('is-visible');
16 | } else {
17 | console.log(123);
18 | mainNav.classList.remove('is-visible', 'is-fixed');
19 | }
20 | } else {
21 | // Scrolling Down
22 | mainNav.classList.remove(['is-visible']);
23 | if (currentTop > headerHeight && !mainNav.classList.contains('is-fixed')) {
24 | mainNav.classList.add('is-fixed');
25 | }
26 | }
27 | scrollPos = currentTop;
28 | });
29 | })
30 |
--------------------------------------------------------------------------------
/public/posts/+ (3).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SameerBadriddinov/NodeJS-Blog/26ae776a76c2283ad6e361ebfa5c2443e3124fa5/public/posts/+ (3).png
--------------------------------------------------------------------------------
/public/posts/photo_2021-11-18_22-28-27.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SameerBadriddinov/NodeJS-Blog/26ae776a76c2283ad6e361ebfa5c2443e3124fa5/public/posts/photo_2021-11-18_22-28-27.jpg
--------------------------------------------------------------------------------
/public/posts/photo_2021-11-20_16-01-01.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SameerBadriddinov/NodeJS-Blog/26ae776a76c2283ad6e361ebfa5c2443e3124fa5/public/posts/photo_2021-11-20_16-01-01.jpg
--------------------------------------------------------------------------------
/public/posts/photo_2021-11-20_16-01-05.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SameerBadriddinov/NodeJS-Blog/26ae776a76c2283ad6e361ebfa5c2443e3124fa5/public/posts/photo_2021-11-20_16-01-05.jpg
--------------------------------------------------------------------------------
/public/posts/photo_2021-11-20_16-01-07.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SameerBadriddinov/NodeJS-Blog/26ae776a76c2283ad6e361ebfa5c2443e3124fa5/public/posts/photo_2021-11-20_16-01-07.jpg
--------------------------------------------------------------------------------
/public/posts/Дизайн без названия (2).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SameerBadriddinov/NodeJS-Blog/26ae776a76c2283ad6e361ebfa5c2443e3124fa5/public/posts/Дизайн без названия (2).png
--------------------------------------------------------------------------------
/views/create.edge:
--------------------------------------------------------------------------------
1 | @layout('layouts.app')
2 |
3 | @section("content")
4 | Create Post
10 | You can say everythink what do you want...
11 |
{{{post.content}}}
29 |