This is a full-stack Lost & Found web app built with Node.js, Express, EJS, Passport, and MongoDB.
Users can:
- register/login
- post lost/found notices with optional images
- browse and search notices
- reply to notices
- manage their profile (nickname, email, password, profile image)
- Backend: Node.js, Express
- Database: MongoDB + Mongoose
- Views: EJS
- Auth: Passport Local + express-session
- File Upload: Multer
- UI: Bootstrap 5 + custom CSS
integrated_project/
├─ config/
│ ├─ db.js
│ └─ passport.js
├─ controllers/
│ ├─ authController.js
│ ├─ noticeController.js
│ └─ profileController.js
├─ middleware/
│ └─ authMiddleware.js
├─ models/
│ ├─ User.js
│ └─ Notice.js
├─ public/
│ ├─ css/styles.css
│ └─ js/
│ ├─ main.js
│ └─ profile.js
├─ routes/
│ ├─ authRoutes.js
│ ├─ noticeRoutes.js
│ └─ profileRoutes.js
├─ utils/
│ └─ passwordPolicy.js
├─ views/
│ ├─ layout.ejs
│ ├─ index.ejs
│ ├─ login.ejs
│ ├─ register.ejs
│ ├─ notices.ejs
│ ├─ notice_form.ejs
│ └─ profile.ejs
├─ server.js
└─ package.json
Create a .env file in the project root:
PORT=3000
MONGO_URI=your_mongodb_connection_string
SESSION_SECRET=your_session_secretnpm install
npm run devOr production mode:
npm startOpen: http://localhost:3000
- Register with
login_id,nickname,email,password, optional profile image - Login via Passport local strategy (
login_id+password) - Session-based auth with persistent login
- Create lost/found notices (
type,date,venue,contact,description, optional image) - View all notices or only your notices
- Reply to notices
- Delete only your own notices
- Client-side search filter on notices page
- Update nickname/email (requires current password)
- Update password (current password, confirm check, policy check, and must differ from old password)
- Update profile image by clicking existing image/placeholder
Password validation is centralized in:
utils/passwordPolicy.js
Current default:
- minimum length = 8
Used by:
- registration (
controllers/authController.js) - password change (
controllers/profileController.js)
UI text in register/profile pages uses passwordMinLength exposed from server.js (res.locals.passwordMinLength), so changing policy constants updates display hints consistently.
GET /homeGET /registerregister pagePOST /registerregister user (+ optional profile image upload)GET /loginlogin pagePOST /loginloginGET /logoutlogout
GET /noticesall noticesGET /notices/mycurrent user's notices (auth required)GET /notices/newcreate form (auth required)POST /notices/newcreate notice (auth required, optional image upload)POST /notices/:id/replyreply to notice (auth required)DELETE /notices/:iddelete own notice (auth required + ownership)
GET /profileprofile page (auth required)POST /profile/updateupdate nickname/email (auth required)POST /profile/update-passwordchange password (auth required)POST /profile/update-imagechange profile image (auth required, image upload)
- Max image size:
2MB - Only MIME types starting with
image/ - Uploaded under
public/uploads/
login_id(unique, required)nickname(required)email(unique, required)profile_image(optional)password(required, hashed with bcrypt pre-save hook)
type(lostorfound, required)date(required)venue,contact,description,imageowner(User ref)responses[]withuser,message,date
- Flash messages are auto-dismissed on frontend.
- Notice image supports modal/lightbox preview.
- Active navbar link is highlighted in
public/js/main.js. - Existing
README.mdmay be outdated in a few details (this file reflects current implementation).