├── Major-1 ├── .gitignore ├── Files │ └── FileWatchDog.zip ├── utils │ ├── catchAsync.js │ └── ExpressError.js ├── views │ ├── Partials │ │ ├── error.ejs │ │ ├── success.ejs │ │ ├── footer.ejs │ │ └── navbar.ejs │ ├── errorMessage.ejs │ ├── Pages │ │ ├── instructions.ejs │ │ ├── Register.ejs │ │ └── login.ejs │ ├── layouts │ │ └── boilerplate.ejs │ └── home.ejs ├── models │ └── register.js ├── package.json ├── schema.js └── app.js └── README.md /Major-1/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ -------------------------------------------------------------------------------- /Major-1/Files/FileWatchDog.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/swarajmutalik/Major-1/HEAD/Major-1/Files/FileWatchDog.zip -------------------------------------------------------------------------------- /Major-1/utils/catchAsync.js: -------------------------------------------------------------------------------- 1 | module.exports = (func) => { 2 | return (req, res, next) => { 3 | func(req, res, next).catch(next); 4 | }; 5 | }; 6 | -------------------------------------------------------------------------------- /Major-1/utils/ExpressError.js: -------------------------------------------------------------------------------- 1 | class ExpressError extends Error { 2 | constructor(message, statusCode) { 3 | super(); 4 | this.message = message; 5 | this.statusCode = statusCode; 6 | } 7 | } 8 | 9 | module.exports = ExpressError; 10 | -------------------------------------------------------------------------------- /Major-1/views/Partials/error.ejs: -------------------------------------------------------------------------------- 1 | <% if (errorMessage && errorMessage.length) { %> 2 | 8 | <% } %> -------------------------------------------------------------------------------- /Major-1/views/Partials/success.ejs: -------------------------------------------------------------------------------- 1 | <% if (successMessage && successMessage.length){ %> 2 | 8 | <% } %> -------------------------------------------------------------------------------- /Major-1/views/Partials/footer.ejs: -------------------------------------------------------------------------------- 1 | 8 | 14 | -------------------------------------------------------------------------------- /Major-1/views/errorMessage.ejs: -------------------------------------------------------------------------------- 1 | <% layout('layouts/boilerplate')%> 2 |
3 |
4 | 12 |
13 |
14 | -------------------------------------------------------------------------------- /Major-1/models/register.js: -------------------------------------------------------------------------------- 1 | const mongoose = require("mongoose"); 2 | const Schema = mongoose.Schema; 3 | 4 | const RegisterSchema = new Schema({ 5 | username: { 6 | type: String, 7 | required: [true, "Username cannot be left blank"], 8 | }, 9 | 10 | email: { 11 | type: String, 12 | required: [true, "Email cannot be left blank"], 13 | }, 14 | 15 | password: { 16 | type: String, 17 | required: [true, "Password cannot be left blank"], 18 | }, 19 | 20 | securePassword: { 21 | type: String, 22 | }, 23 | }); 24 | 25 | module.exports = mongoose.model("Register", RegisterSchema); 26 | -------------------------------------------------------------------------------- /Major-1/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "major-1", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "dev": "nodemon app.js" 9 | }, 10 | "keywords": [], 11 | "author": "", 12 | "license": "ISC", 13 | "dependencies": { 14 | "bcrypt": "^5.1.1", 15 | "body-parser": "^1.20.2", 16 | "connect-flash": "^0.1.1", 17 | "ejs": "^3.1.9", 18 | "ejs-mate": "^4.0.0", 19 | "express": "^4.18.2", 20 | "express-session": "^1.17.3", 21 | "firebase": "^10.3.0", 22 | "joi": "^17.11.0", 23 | "mongoose": "^7.4.3", 24 | "package.json": "^2.0.1" 25 | }, 26 | "devDependencies": { 27 | "nodemon": "^3.0.1" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Major-1/schema.js: -------------------------------------------------------------------------------- 1 | const Joi = require("joi"); 2 | 3 | const loginSchema = Joi.object({ 4 | username: Joi.string().min(3).max(30).required(), 5 | password: Joi.string().min(3).required(), 6 | }); 7 | 8 | const registrationSchema = Joi.object({ 9 | username: Joi.string().min(3).max(30).required(), 10 | email: Joi.string().email().required(), 11 | password: Joi.string().min(3).required(), 12 | }); 13 | 14 | const validateLogin = (req, res, next) => { 15 | const { username, password } = req.body; 16 | loginSchema 17 | .validateAsync({ username, password }) 18 | .then(() => next()) 19 | .catch(() => res.redirect("/login")); 20 | }; 21 | 22 | const validateRegistration = (req, res, next) => { 23 | const { username, email, password } = req.body; 24 | registrationSchema 25 | .validateAsync({ username, email, password }) 26 | .then(() => next()) 27 | .catch(() => res.redirect("/register")); 28 | }; 29 | 30 | module.exports = { validateLogin, validateRegistration }; 31 | -------------------------------------------------------------------------------- /Major-1/views/Pages/instructions.ejs: -------------------------------------------------------------------------------- 1 | <% layout('layouts/boilerplate') %> 2 | 12 |

Set of Instructions to be followed

13 |
14 |
15 |
16 |
    17 |
  1. 18 |

    19 | Paste the full Folder path where you want to check the integrity of files, in the 20 | folder_path.txt. 21 |

    22 |
  2. 23 |
  3. 24 |

    25 | Paste your User ID in the userId.txt file. 26 |

    27 |
  4. 28 |
    29 | 32 |
    33 |
34 |
35 |
36 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Major-1 2 |

File Integrity Monitor

3 |

This project includes the implementation of a robust system that diligently assesses the file integrity by employing continuous hash generations and subsequent comparsions.

4 |

The primary objective is to promptly identify the instances of a new file creation, modifications and deletions, thereby ensuring the security and the stability of the monitored system.

5 |

In addition to the core functionality, we aim to integrate an intuitive front-end interface in the form of a web page.This interface will serve as the user's window into the monitoring process,presenting data derived from the generated logs in a comprehensible manner.

6 |

In addition to this there are also additional features like filtering of some sort and plotting graphs on the web page for these detected changes.

7 | 8 |

Tech Stack Used

9 |

Front-end Tech Used

10 | 15 |

Development Tools

16 | 20 |

CSS Framework

21 | 24 |

Server-side Rendering

25 | 29 |

Server-side Frameworks

30 | 33 |

Database Integration

34 | 37 |

Middleware

38 | 41 | 42 | -------------------------------------------------------------------------------- /Major-1/views/layouts/boilerplate.ejs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | File Integrity Monitor 8 | 10 | 11 | 12 | 13 | 14 | <%- include('../Partials/navbar') %> 15 |
16 | <%- body %> 17 |
18 | <%- include('../Partials/footer') %> 19 | 20 | 21 | 22 | 25 | 28 | 29 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /Major-1/views/Partials/navbar.ejs: -------------------------------------------------------------------------------- 1 | 28 | 31 | 34 | 35 | 44 | -------------------------------------------------------------------------------- /Major-1/views/Pages/Register.ejs: -------------------------------------------------------------------------------- 1 | <% layout('layouts/boilerplate') %> 2 | 15 | 16 | <%- include('../Partials/error') %> 17 |
18 |

Register Form

19 |
20 |
21 |
22 | 23 | 24 |
25 | Looks good! 26 |
27 |
28 |
29 | 30 | 31 |
32 | Looks good! 33 |
34 |
35 |
36 | 37 | 38 |
39 | Looks good! 40 |
41 |
42 | 43 |
44 |
45 |
46 | -------------------------------------------------------------------------------- /Major-1/views/Pages/login.ejs: -------------------------------------------------------------------------------- 1 | <% layout('layouts/boilerplate') %> 2 | 15 | 16 | <%- include('../Partials/success') %> 17 | <%- include('../Partials/error') %> 18 |
19 |

Login Form

20 |
21 |
22 |
23 | 24 | 25 |
26 | Looks good! 27 |
28 |
29 |
30 | 31 | 32 |
33 | Looks good! 34 |
35 |
36 | 37 |
38 |

39 | New User - 40 | Register 41 |

42 |

43 | Forget Password ? 44 |

45 |
46 |
47 | -------------------------------------------------------------------------------- /Major-1/app.js: -------------------------------------------------------------------------------- 1 | const express = require("express"); 2 | const path = require("path"); 3 | const bodyParser = require("body-parser"); 4 | const mongoose = require("mongoose"); 5 | const ejsMate = require("ejs-mate"); 6 | const Register = require("./models/register"); 7 | const catchAsync = require("./utils/catchAsync"); 8 | const session = require("express-session"); 9 | const ExpressError = require("./utils/ExpressError"); 10 | const Joi = require("joi"); 11 | const flash = require("connect-flash"); 12 | const bcrypt = require("bcrypt"); 13 | 14 | 15 | const { validateLogin, validateRegistration } = require("./schema"); 16 | 17 | mongoose.connect("mongodb://127.0.0.1:27017/FIM", { 18 | useNewUrlParser: true, 19 | useUnifiedTopology: true, 20 | }); 21 | 22 | const db = mongoose.connection; 23 | db.on("error", console.error.bind(console, "connection error:")); 24 | db.once("open", () => { 25 | console.log("Database connected"); 26 | }); 27 | 28 | const app = express(); 29 | 30 | app.engine("ejs", ejsMate); 31 | app.set("view engine", "ejs"); 32 | app.set("views", path.join(__dirname, "views")); 33 | app.use(express.urlencoded({ extended: true })); 34 | 35 | app.use(flash()); 36 | 37 | app.use( 38 | session({ 39 | secret: "your-secret-key", 40 | resave: false, 41 | saveUninitialized: true, 42 | }) 43 | ); 44 | 45 | app.get("/", (req, res) => { 46 | const isLoggedIn = req.session.isLoggedIn; 47 | const username = req.session.username; 48 | const userId = req.session.userId; 49 | res.render("home", { isLoggedIn, username, userId }); 50 | }); 51 | 52 | app.get("/login", (req, res) => { 53 | res.render("Pages/login", { 54 | successMessage: req.flash("success"), 55 | errorMessage: req.flash("error"), 56 | }); 57 | }); 58 | 59 | app.get("/register", (req, res) => { 60 | res.render("Pages/Register", { 61 | successMessage: req.flash("success"), 62 | errorMessage: req.flash("error"), 63 | }); 64 | }); 65 | 66 | app.post( 67 | "/login", 68 | validateLogin, 69 | catchAsync(async (req, res) => { 70 | const { username, password } = req.body; 71 | const user = await Register.findOne({ username }); 72 | 73 | if (!user) { 74 | req.flash("error", "Username not found"); 75 | return res.redirect("/login"); 76 | } 77 | 78 | if (user.password !== password) { 79 | req.flash("error", "Incorrect Password, please try again"); 80 | return res.redirect("/login"); 81 | } 82 | req.session.isLoggedIn = true; 83 | req.session.username = username; 84 | req.session.userId = user._id; 85 | req.flash("success", `Successfully logged in. User ID: ${user._id}`); 86 | res.redirect("/"); 87 | }) 88 | ); 89 | 90 | app.post("/register", validateRegistration, async (req, res, next) => { 91 | const { username, email, password } = req.body; 92 | try { 93 | const existingEmailUser = await Register.findOne({ email }); 94 | const existingUsernameUser = await Register.findOne({ username }); 95 | const existingPassword = await Register.findOne({ password }); 96 | 97 | if (existingEmailUser && existingUsernameUser && existingPassword) { 98 | req.flash("error", "Username,email and password already exist"); 99 | return res.redirect("/register"); 100 | } else if (existingEmailUser) { 101 | req.flash("error", "Email already exists"); 102 | return res.redirect("/register"); 103 | } else if (existingUsernameUser) { 104 | req.flash("error", "Username already exists"); 105 | return res.redirect("/register"); 106 | } else if (existingPassword) { 107 | req.flash("error", "Password already exists"); 108 | return res.redirect("/register"); 109 | } 110 | 111 | const saltRounds = 10; 112 | const hashedPassword = await bcrypt.hash(password, saltRounds); 113 | 114 | const newRegisterUser = new Register({ 115 | username, 116 | email, 117 | password, 118 | securePassword: hashedPassword, 119 | }); 120 | 121 | await newRegisterUser.save(); 122 | req.flash("success", "Registration Successful. You can login"); 123 | res.redirect("/login"); 124 | } catch (err) { 125 | next(new catchAsync(err.message, 500)); 126 | } 127 | }); 128 | 129 | app.get("/instructions", (req, res) => { 130 | res.render("Pages/Instructions"); 131 | }); 132 | 133 | app.get("/download-file", (req, res) => { 134 | res.download("D:/Sem 7/Major-1/Files/FileWatchDog.zip"); 135 | }); 136 | 137 | app.all("*", (req, res, next) => { 138 | next(new ExpressError("Page not found", 404)); 139 | }); 140 | 141 | app.use((err, req, res, next) => { 142 | const { statusCode = 500 } = err; 143 | if (!err.message) err.message = "Oh no,Something went wrong"; 144 | res.status(statusCode).render("errorMessage", { err }); 145 | }); 146 | 147 | app.listen(3000, () => { 148 | console.log("Serving on port 3000"); 149 | }); 150 | -------------------------------------------------------------------------------- /Major-1/views/home.ejs: -------------------------------------------------------------------------------- 1 | <% layout('layouts/boilerplate') %> 2 | 3 | 4 | 5 | 6 | 7 | 8 | Home Page 9 | 10 | 11 | <% if (isLoggedIn) { %> 12 | 18 | <% } %> 19 | 20 | 21 | <% if(isLoggedIn) {%> 22 | 23 |
24 |