A secure authentication system built with Node.js, Express, Handlebars, MySQL, sessions, email verification, password reset functionality, and Tailwind CSS.
- User registration and login
- Secure password hashing with bcrypt
- Session-based authentication
- Email verification via SMTP
- Forgot password and reset password flow
- Protected routes and dashboard access
- Contact form with email notifications
- Flash messages for authentication feedback
- Rate limiting on sensitive endpoints
- Responsive UI with Tailwind CSS
- Node.js
- Express.js
- Handlebars (
hbs) - MySQL / MariaDB
mysql2express-sessionconnect-flashbcryptnodemailer- Tailwind CSS
- PostCSS
.
├── app.js
├── database/
│ └── db.js
├── routes/
│ └── auth.js
├── views/
│ ├── login.hbs
│ ├── register.hbs
│ ├── dashboard.hbs
│ ├── forgot.hbs
│ ├── reset.hbs
│ ├── valid.hbs
│ ├── contact.hbs
│ └── partials/
├── public/
│ ├── css/
│ ├── js/
│ └── images/
├── package.json
├── tailwind.config.js
└── postcss.config.js
- Node.js 18+
- npm
- MySQL or MariaDB
- SMTP credentials for email services
Install dependencies:
npm installCreate a .env file in the root directory:
PORT=1111
MYSQL_HOST=localhost
MYSQL_USER=your_mysql_username
MYSQL_PASSWORD=your_mysql_password
MYSQL_DATABASE=your_database_name
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_USER=your_email@gmail.com
SMTP_SECRET=your_app_passwordRun the following SQL queries:
CREATE TABLE IF NOT EXISTS users (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
first_name VARCHAR(100) NOT NULL,
last_name VARCHAR(100) NOT NULL,
email VARCHAR(255) NOT NULL,
username VARCHAR(100) NOT NULL,
password VARCHAR(255) NOT NULL,
token VARCHAR(128) NOT NULL,
verified TINYINT(1) NOT NULL DEFAULT 0,
token_created_at DATETIME NULL,
created_at DATETIME NULL,
updated_at DATETIME NULL,
PRIMARY KEY (id),
UNIQUE KEY users_email_unique (email),
UNIQUE KEY users_username_unique (username),
UNIQUE KEY users_token_unique (token)
);
CREATE TABLE IF NOT EXISTS contact (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
name VARCHAR(150) NOT NULL,
email VARCHAR(255) NOT NULL,
message TEXT NOT NULL,
created_at DATETIME NULL,
PRIMARY KEY (id)
);Start the application:
npm startRun in development mode with Nodemon:
npm run serverBuild Tailwind CSS:
npm run build:csshttp://localhost:1111
| Method | Route | Description |
|---|---|---|
| GET | / |
Protected dashboard |
| GET | /user/login |
Login page |
| POST | /user/login |
Login request |
| GET | /user/register |
Registration page |
| POST | /user/register |
Registration request |
| GET | /user/verify/:token |
Email verification |
| GET | /user/forgot |
Forgot password page |
| POST | /user/forgot |
Send reset password email |
| GET | /user/forgot/:token |
Reset password page |
| POST | /user/pass |
Update password |
| POST | /user/logout |
Logout user session |
| GET | /contact |
Contact page |
| POST | /user/contact |
Submit contact form |
Licensed under the ISC License.





