A members-only message board where users can post anonymous messages. Only verified members can see who wrote each message and when. Built with Node.js, Express, EJS, and custom JWT authentication.
This project demonstrates role-based access control with three user levels:
- Guest - Can view messages (content only)
- Member - Can see usernames and timestamps
- Admin - Can delete any message
| Technology | Purpose |
|---|---|
| Node.js | JavaScript runtime |
| Express.js 5 | Web framework |
| EJS | Templating engine |
| JWT (jsonwebtoken) | Stateless authentication & authorization |
| bcrypt | Password hashing |
| cookie-parser | HTTP cookie parsing |
| Neon | Serverless Postgres hosting |
| @neondatabase/serverless | Neon's serverless driver |
| Render | Deployment |
- User Authentication - Sign up and login with secure password hashing
- JWT Authorization - Stateless authentication using HTTP-only cookies
- Role-Based Access - Three levels: Guest, Member, Admin
- Become a Member - Enter a secret code to unlock member privileges
- Become an Admin - Enter admin code to gain message deletion rights
- Create Messages - Post new messages (logged-in users only)
- View Message Details - Click the eye icon to see full message details
- Delete Messages - Admins can delete any message
- Responsive Design - Fully responsive on all devices
- Serverless Database - Powered by Neon's serverless PostgreSQL
the-clubhouse/
βββ app.js # Express application entry point
βββ .env # Environment variables (JWT_SECRET, MEMBER_CODE, ADMIN_CODE)
βββ .gitignore # Git ignore file
βββ package.json # Dependencies and scripts
β
βββ db/
β βββ pool.js # Neon database connection
β
βββ routes/
β βββ index.js # All route handlers with JWT middleware
β
βββ views/
β βββ partials/
β β βββ head.ejs # HTML head partial
β β βββ footer.ejs # Footer partial
β βββ index.ejs # Main message board page
β βββ login.ejs # Login form
β βββ signup.ejs # Signup form
β βββ new-msg-form.ejs # New message form
β βββ message.ejs # Message detail page
β βββ become-member.ejs # Member secret code form
β βββ become-admin.ejs # Admin secret code form
β
βββ public/
β βββ styles.css # All CSS styles
β βββ favicon.ico # Favicon files
β βββ ... # Other static assets
- Node.js (v18+)
- A Neon PostgreSQL database
-
Clone the repository
git clone https://github.com/roshhi/mini-msg-board.git cd mini-msg-board -
Install dependencies
npm install
-
Set up environment variables
Create a
.envfile in the root directory:DATABASE_URL=postgresql://username:password@your-neon-host/database?sslmode=require JWT_SECRET=your-super-secret-jwt-key MEMBER_CODE=clubhouse ADMIN_CODE=admin123
-
Create the database tables
Run this SQL in your Neon console:
CREATE TABLE users ( id SERIAL PRIMARY KEY, username VARCHAR(20) UNIQUE NOT NULL, password VARCHAR(255) NOT NULL, is_member BOOLEAN DEFAULT FALSE, is_admin BOOLEAN DEFAULT FALSE ); CREATE TABLE messages ( msg_id SERIAL PRIMARY KEY, user_id INTEGER REFERENCES users(id), msg_text VARCHAR(200) NOT NULL, date_added TIMESTAMP DEFAULT NOW() );
-
Start the server
node app.js
-
Open in browser
http://localhost:3000
Through building this project, I learned:
- Custom JWT Authentication - Implementing stateless auth with JSON Web Tokens stored in HTTP-only cookies
- Role-Based Authorization - Protecting routes and conditionally rendering UI based on user roles
- Password Security - Using bcrypt to hash and compare passwords securely
- EJS Templating - Dynamic HTML rendering with embedded JavaScript
- Neon Serverless - Using Neon's serverless driver for edge-compatible database connections
- MVC Architecture - Separating concerns with routes, views, and database logic
Contributions are welcome! Feel free to open an issue or submit a pull request.
This project is open source and available under the MIT License.
- The Odin Project for the curriculum
- Neon for serverless PostgreSQL