A back-end task management application built with Node.js/Express (backend), featuring multiple authentication methods including local registration/login and OAuth integration with Google and Discord.
- Multi-Authentication System
- Local registration and login with email/password
- Google OAuth 2.0 integration
- Discord OAuth integration
- Task Management (planned/in development)
- User Session Management
- MySQL Database Integration
- Type-Safe Development with TypeScript
- RESTful API Architecture
PLANIFY_ME
├── backend
│ ├── node_modules
│ └── src
│ ├── auth
│ │ ├── Oauth
│ │ │ ├── discord.ts # Discord OAuth strategy
│ │ │ └── google.ts # Google OAuth strategy
│ │ ├── auth.controller.ts # Authentication logic
│ │ ├── auth.routes.ts # Auth route definitions
│ │ ├── validate-login-req.ts # Middleware to validate login requests
│ │ └── validate-register-req.ts # Middleware to validate register requests
│ ├── controllers
│ │ ├── events.controller.ts # User events logic
│ │ ├── notes.controller.ts # User notes logic
│ │ └── tasks.controller.ts # User tasks logic
│ ├── middlewares
│ │ └── auth.middleware.ts # Middleware to protect the routes
│ ├── routes
│ │ ├── events.routes.ts # User events routes
│ │ ├── notes.routes.ts # User notes routes
│ │ └── tasks.routes.ts # User tasks routes
│ ├── types
│ │ ├── events-types
│ │ │ └── events.types.ts # TypeScript type definitions
│ │ ├── notes-types
│ │ │ └── notes.types.ts
│ │ ├── tasks-types
│ │ │ └── tasks.types.ts
│ │ ├── login-user.ts
│ │ └── register-user.ts
│ ├── utils
│ │ ├── date-formatter.ts # Util to convert Date object to MySQL DATETIME
│ │ ├── generate-token.ts # Util to generate authentication token
│ │ ├── validate-body-req.ts # Util to validate the `req.body` object
│ │ └── validate-notes-body.ts # Util to validate the create note request
│ ├── conn.ts # Database connection
│ └── index.ts # Express server setup
- Node.js - Runtime environment
- Express.js - Web framework
- TypeScript - Type safety
- Passport.js - Authentication middleware
- MySQL2 - Database driver
- bcrypt - Password hashing
- JWT - Token-based authentication
- dotenv - Environment variable management
- MySQL - Relational database
- Node.js (v14 or higher)
- MySQL database
- Google OAuth credentials
- Discord OAuth credentials
Create a .env file in the backend directory:
# Database Configuration
DB_HOST=localhost
DB_USER=your_db_user
DB_PASSWORD=your_db_password
DB_NAME=planify_me
# JWT Configuration
JWT_SECRET=your_jwt_secret
# Google OAuth
GOOGLE_CLIENT_ID=your_google_client_id
GOOGLE_CLIENT_SECRET=your_google_client_secret
GOOGLE_CALLBACK_URL=http://localhost:3000/api/auth/google/redirect
# Discord OAuth
DISCORD_CLIENT_ID=your_discord_client_id
DISCORD_CLIENT_SECRET=your_discord_client_secret
DISCORD_CALLBACK_URL=http://localhost:3000/api/auth/discord/redirect
# Server Configuration
NODE_ENV=development
PORT=3000CREATE DATABASE planify_me;
USE planify_me;
CREATE TABLE Users (
user_id INT PRIMARY KEY AUTO_INCREMENT,
first_name VARCHAR(255),
last_name VARCHAR(255),
email VARCHAR(255) UNIQUE NOT NULL,
username VARCHAR(255),
password VARCHAR(255),
auth_provider ENUM('local', 'google', 'discord') DEFAULT 'local',
google_id VARCHAR(255) UNIQUE,
discord_id VARCHAR(255) UNIQUE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);cd backend
npm install
npm run dev- Endpoint:
POST /api/auth/register - Body:
{
"firstName": "John",
"lastName": "Doe",
"email": "[email protected]",
"password": "securePassword123"
}- Endpoint:
POST /api/auth/login - Body:
{
"email": "[email protected]",
"password": "securePassword123"
}- Initiate:
GET /api/auth/google - Callback:
GET /api/auth/google/redirect
- Initiate:
GET /api/auth/discord - Callback:
GET /api/auth/discord/redirect
The application uses Passport.js for session management:
// User serialization for session storage
passport.serializeUser((user: Express.User, done) => {
done(null, user.user_id);
});
// User deserialization from session
passport.deserializeUser(async (id: number, done) => {
// Fetch user from database
const user = await getUserById(id);
done(null, user);
});| Method | Endpoint | Description |
|---|---|---|
| POST | /register |
User registration |
| POST | /login |
Local login |
| POST | /logout |
User logout |
| GET | /google |
Initiate Google OAuth |
| GET | /google/redirect |
Google OAuth callback |
| GET | /discord |
Initiate Discord OAuth |
| GET | /discord/redirect |
Discord OAuth callback |
- MySQL connection pool setup
- Environment-based configuration
- Connection error handling
createLoginHandler(provider): Generic login handler for different providersregister(): User registration with password hashinglogout(): Session termination
- Google Strategy: Handles Google OAuth 2.0 flow
- Discord Strategy: Handles Discord OAuth flow
- User creation/retrieval logic
- Profile data mapping to database schema
- TypeScript interfaces for request/response objects
- User model definitions
- Provider enum definitions
- Password Hashing: bcrypt with salt rounds
- JWT Tokens: Secure token-based authentication
- Environment Variables: Sensitive data protection
- Input Validation: Request validation for all endpoints
- Session Security: Passport.js session management
- OAuth Security: Secure OAuth 2.0 implementation
The application implements comprehensive error handling:
// Example error response structure
{
"success": `false`
"error": "Unauthorized access",
"code": TaskErrorCode.UNAUTHORIZED,
"status": 401
}- Invalid credentials
- User already exists
- Database connection errors
- OAuth provider errors
- Missing required fields
# Backend
cd backend
npm run dev
### TypeScript Compilation
```bash
# Backend
npm run build
# Type checking
npm run type-check- User submits registration form
- Server validates input data
- Password is hashed using bcrypt
- User record created in database
- Success response sent to client
- User submits credentials
- Server validates email/password
- Password comparison using bcrypt
- JWT token generated
- Token sent as HTTP-only cookie
- User session established
- User clicks OAuth provider button
- Redirect to provider's authorization server
- User grants permissions
- Provider redirects back with authorization code
- Server exchanges code for access token
- User profile fetched from provider
- User created/updated in database
- Session established
- Team collaboration features
- Real-time notifications
- Advanced user permissions
- File attachments
- Activity logging