Initial commit: Complete NodeJS-native setup
- Migrated from Python pre-commit to NodeJS-native solution - Reorganized documentation structure - Set up Husky + lint-staged for efficient pre-commit hooks - Fixed Dockerfile healthcheck issue - Added comprehensive documentation index
This commit is contained in:
839
docs/development/API.md
Normal file
839
docs/development/API.md
Normal file
@@ -0,0 +1,839 @@
|
||||
# API Documentation
|
||||
|
||||
## 📚 API Reference for Medication Reminder App
|
||||
|
||||
### **Base URL**
|
||||
|
||||
- Development: `http://localhost:5173`
|
||||
- Production: `http://localhost:8080`
|
||||
|
||||
### **Authentication**
|
||||
|
||||
All authenticated endpoints require a valid session token.
|
||||
|
||||
#### **Headers**
|
||||
|
||||
```http
|
||||
Authorization: Bearer <token>
|
||||
Content-Type: application/json
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔐 Authentication Endpoints
|
||||
|
||||
### **Register User**
|
||||
|
||||
Create a new user account with email verification.
|
||||
|
||||
**Endpoint:** `POST /auth/register`
|
||||
|
||||
**Request Body:**
|
||||
|
||||
```json
|
||||
{
|
||||
"email": "user@example.com",
|
||||
"password": "SecurePassword123!",
|
||||
"username": "JohnDoe"
|
||||
}
|
||||
```
|
||||
|
||||
**Response:**
|
||||
|
||||
```json
|
||||
{
|
||||
"user": {
|
||||
"_id": "user-uuid",
|
||||
"email": "user@example.com",
|
||||
"username": "JohnDoe",
|
||||
"status": "PENDING",
|
||||
"emailVerified": false,
|
||||
"role": "USER",
|
||||
"createdAt": "2025-09-05T12:00:00Z"
|
||||
},
|
||||
"verificationToken": {
|
||||
"token": "verification-token-uuid",
|
||||
"expiresAt": "2025-09-05T13:00:00Z"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Status Codes:**
|
||||
|
||||
- `201` - User created successfully
|
||||
- `400` - Invalid input data
|
||||
- `409` - Email already exists
|
||||
|
||||
---
|
||||
|
||||
### **Login User**
|
||||
|
||||
Authenticate user with email and password.
|
||||
|
||||
**Endpoint:** `POST /auth/login`
|
||||
|
||||
**Request Body:**
|
||||
|
||||
```json
|
||||
{
|
||||
"email": "user@example.com",
|
||||
"password": "SecurePassword123!"
|
||||
}
|
||||
```
|
||||
|
||||
**Response:**
|
||||
|
||||
```json
|
||||
{
|
||||
"user": {
|
||||
"_id": "user-uuid",
|
||||
"email": "user@example.com",
|
||||
"username": "JohnDoe",
|
||||
"status": "ACTIVE",
|
||||
"emailVerified": true,
|
||||
"role": "USER"
|
||||
},
|
||||
"accessToken": "jwt-access-token",
|
||||
"refreshToken": "jwt-refresh-token"
|
||||
}
|
||||
```
|
||||
|
||||
**Status Codes:**
|
||||
|
||||
- `200` - Login successful
|
||||
- `401` - Invalid credentials
|
||||
- `403` - Account not verified or suspended
|
||||
|
||||
---
|
||||
|
||||
### **OAuth Login**
|
||||
|
||||
Authenticate using OAuth providers (Google, GitHub).
|
||||
|
||||
**Endpoint:** `POST /auth/oauth`
|
||||
|
||||
**Request Body:**
|
||||
|
||||
```json
|
||||
{
|
||||
"provider": "google",
|
||||
"userData": {
|
||||
"email": "user@example.com",
|
||||
"username": "John Doe",
|
||||
"avatar": "https://example.com/avatar.jpg"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Response:**
|
||||
|
||||
```json
|
||||
{
|
||||
"user": {
|
||||
"_id": "user-uuid",
|
||||
"email": "user@example.com",
|
||||
"username": "John Doe",
|
||||
"status": "ACTIVE",
|
||||
"emailVerified": true,
|
||||
"role": "USER",
|
||||
"avatar": "https://example.com/avatar.jpg"
|
||||
},
|
||||
"accessToken": "jwt-access-token",
|
||||
"refreshToken": "jwt-refresh-token"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### **Verify Email**
|
||||
|
||||
Activate user account using verification token.
|
||||
|
||||
**Endpoint:** `POST /auth/verify-email`
|
||||
|
||||
**Request Body:**
|
||||
|
||||
```json
|
||||
{
|
||||
"token": "verification-token-uuid"
|
||||
}
|
||||
```
|
||||
|
||||
**Response:**
|
||||
|
||||
```json
|
||||
{
|
||||
"user": {
|
||||
"_id": "user-uuid",
|
||||
"email": "user@example.com",
|
||||
"username": "JohnDoe",
|
||||
"status": "ACTIVE",
|
||||
"emailVerified": true,
|
||||
"role": "USER"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### **Change Password**
|
||||
|
||||
Change user password (requires current password).
|
||||
|
||||
**Endpoint:** `POST /auth/change-password`
|
||||
|
||||
**Request Body:**
|
||||
|
||||
```json
|
||||
{
|
||||
"userId": "user-uuid",
|
||||
"currentPassword": "OldPassword123!",
|
||||
"newPassword": "NewPassword456!"
|
||||
}
|
||||
```
|
||||
|
||||
**Response:**
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"message": "Password changed successfully"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### **Request Password Reset**
|
||||
|
||||
Request password reset email.
|
||||
|
||||
**Endpoint:** `POST /auth/request-password-reset`
|
||||
|
||||
**Request Body:**
|
||||
|
||||
```json
|
||||
{
|
||||
"email": "user@example.com"
|
||||
}
|
||||
```
|
||||
|
||||
**Response:**
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"message": "Password reset email sent"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### **Reset Password**
|
||||
|
||||
Reset password using reset token.
|
||||
|
||||
**Endpoint:** `POST /auth/reset-password`
|
||||
|
||||
**Request Body:**
|
||||
|
||||
```json
|
||||
{
|
||||
"token": "reset-token-uuid",
|
||||
"newPassword": "NewPassword123!"
|
||||
}
|
||||
```
|
||||
|
||||
**Response:**
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"message": "Password reset successful"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 💊 Medication Management
|
||||
|
||||
### **Add Medication**
|
||||
|
||||
Add a new medication to user's list.
|
||||
|
||||
**Endpoint:** `POST /medications`
|
||||
|
||||
**Request Body:**
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "Aspirin",
|
||||
"dosage": "100mg",
|
||||
"frequency": "Daily",
|
||||
"startTime": "08:00",
|
||||
"notes": "Take with food",
|
||||
"icon": "💊"
|
||||
}
|
||||
```
|
||||
|
||||
**Response:**
|
||||
|
||||
```json
|
||||
{
|
||||
"_id": "medication-uuid",
|
||||
"name": "Aspirin",
|
||||
"dosage": "100mg",
|
||||
"frequency": "Daily",
|
||||
"startTime": "08:00",
|
||||
"notes": "Take with food",
|
||||
"icon": "💊",
|
||||
"userId": "user-uuid",
|
||||
"createdAt": "2025-09-05T12:00:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### **Get Medications**
|
||||
|
||||
Retrieve user's medications.
|
||||
|
||||
**Endpoint:** `GET /medications`
|
||||
|
||||
**Query Parameters:**
|
||||
|
||||
- `active` (boolean) - Filter active medications only
|
||||
|
||||
**Response:**
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"_id": "medication-uuid",
|
||||
"name": "Aspirin",
|
||||
"dosage": "100mg",
|
||||
"frequency": "Daily",
|
||||
"startTime": "08:00",
|
||||
"notes": "Take with food",
|
||||
"icon": "💊"
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### **Update Medication**
|
||||
|
||||
Update existing medication.
|
||||
|
||||
**Endpoint:** `PUT /medications/:id`
|
||||
|
||||
**Request Body:**
|
||||
|
||||
```json
|
||||
{
|
||||
"dosage": "200mg",
|
||||
"notes": "Take with plenty of water"
|
||||
}
|
||||
```
|
||||
|
||||
**Response:**
|
||||
|
||||
```json
|
||||
{
|
||||
"_id": "medication-uuid",
|
||||
"name": "Aspirin",
|
||||
"dosage": "200mg",
|
||||
"frequency": "Daily",
|
||||
"startTime": "08:00",
|
||||
"notes": "Take with plenty of water",
|
||||
"icon": "💊"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### **Delete Medication**
|
||||
|
||||
Remove medication from user's list.
|
||||
|
||||
**Endpoint:** `DELETE /medications/:id`
|
||||
|
||||
**Response:**
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"message": "Medication deleted successfully"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ⏰ Reminder Management
|
||||
|
||||
### **Add Custom Reminder**
|
||||
|
||||
Create a custom reminder.
|
||||
|
||||
**Endpoint:** `POST /reminders`
|
||||
|
||||
**Request Body:**
|
||||
|
||||
```json
|
||||
{
|
||||
"title": "Doctor Appointment",
|
||||
"message": "Annual checkup with Dr. Smith",
|
||||
"scheduledFor": "2025-09-15T14:00:00Z",
|
||||
"recurrence": "yearly"
|
||||
}
|
||||
```
|
||||
|
||||
**Response:**
|
||||
|
||||
```json
|
||||
{
|
||||
"_id": "reminder-uuid",
|
||||
"title": "Doctor Appointment",
|
||||
"message": "Annual checkup with Dr. Smith",
|
||||
"scheduledFor": "2025-09-15T14:00:00Z",
|
||||
"recurrence": "yearly",
|
||||
"userId": "user-uuid",
|
||||
"isActive": true
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### **Get Reminders**
|
||||
|
||||
Retrieve user's reminders.
|
||||
|
||||
**Endpoint:** `GET /reminders`
|
||||
|
||||
**Query Parameters:**
|
||||
|
||||
- `date` (string) - Filter by specific date (YYYY-MM-DD)
|
||||
- `active` (boolean) - Filter active reminders only
|
||||
|
||||
**Response:**
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"_id": "reminder-uuid",
|
||||
"title": "Doctor Appointment",
|
||||
"message": "Annual checkup with Dr. Smith",
|
||||
"scheduledFor": "2025-09-15T14:00:00Z",
|
||||
"recurrence": "yearly",
|
||||
"isActive": true
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📊 Dose Tracking
|
||||
|
||||
### **Record Taken Dose**
|
||||
|
||||
Mark a dose as taken.
|
||||
|
||||
**Endpoint:** `POST /doses/taken`
|
||||
|
||||
**Request Body:**
|
||||
|
||||
```json
|
||||
{
|
||||
"medicationId": "medication-uuid",
|
||||
"scheduledTime": "2025-09-05T08:00:00Z",
|
||||
"takenAt": "2025-09-05T08:15:00Z",
|
||||
"notes": "Took with breakfast"
|
||||
}
|
||||
```
|
||||
|
||||
**Response:**
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"dose": {
|
||||
"id": "medication-uuid-2025-09-05",
|
||||
"medicationId": "medication-uuid",
|
||||
"scheduledTime": "2025-09-05T08:00:00Z",
|
||||
"takenAt": "2025-09-05T08:15:00Z",
|
||||
"status": "TAKEN",
|
||||
"notes": "Took with breakfast"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### **Get Dose History**
|
||||
|
||||
Retrieve dose history for analytics.
|
||||
|
||||
**Endpoint:** `GET /doses`
|
||||
|
||||
**Query Parameters:**
|
||||
|
||||
- `medicationId` (string) - Filter by medication
|
||||
- `startDate` (string) - Start date (YYYY-MM-DD)
|
||||
- `endDate` (string) - End date (YYYY-MM-DD)
|
||||
- `status` (string) - Filter by status (TAKEN, MISSED, UPCOMING)
|
||||
|
||||
**Response:**
|
||||
|
||||
```json
|
||||
{
|
||||
"doses": [
|
||||
{
|
||||
"id": "medication-uuid-2025-09-05",
|
||||
"medicationId": "medication-uuid",
|
||||
"scheduledTime": "2025-09-05T08:00:00Z",
|
||||
"takenAt": "2025-09-05T08:15:00Z",
|
||||
"status": "TAKEN"
|
||||
}
|
||||
],
|
||||
"stats": {
|
||||
"totalDoses": 30,
|
||||
"takenDoses": 28,
|
||||
"missedDoses": 2,
|
||||
"adherenceRate": 93.3
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 👑 Admin Endpoints
|
||||
|
||||
### **Get All Users**
|
||||
|
||||
Retrieve all users (admin only).
|
||||
|
||||
**Endpoint:** `GET /admin/users`
|
||||
|
||||
**Query Parameters:**
|
||||
|
||||
- `status` (string) - Filter by status
|
||||
- `role` (string) - Filter by role
|
||||
- `page` (number) - Pagination page
|
||||
- `limit` (number) - Items per page
|
||||
|
||||
**Response:**
|
||||
|
||||
```json
|
||||
{
|
||||
"users": [
|
||||
{
|
||||
"_id": "user-uuid",
|
||||
"email": "user@example.com",
|
||||
"username": "JohnDoe",
|
||||
"status": "ACTIVE",
|
||||
"role": "USER",
|
||||
"emailVerified": true,
|
||||
"createdAt": "2025-09-05T12:00:00Z",
|
||||
"lastLoginAt": "2025-09-05T15:30:00Z"
|
||||
}
|
||||
],
|
||||
"pagination": {
|
||||
"page": 1,
|
||||
"limit": 20,
|
||||
"total": 150,
|
||||
"pages": 8
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### **Update User Status**
|
||||
|
||||
Change user account status (admin only).
|
||||
|
||||
**Endpoint:** `PUT /admin/users/:id/status`
|
||||
|
||||
**Request Body:**
|
||||
|
||||
```json
|
||||
{
|
||||
"status": "SUSPENDED"
|
||||
}
|
||||
```
|
||||
|
||||
**Response:**
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"user": {
|
||||
"_id": "user-uuid",
|
||||
"status": "SUSPENDED"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### **Delete User**
|
||||
|
||||
Delete user account (admin only).
|
||||
|
||||
**Endpoint:** `DELETE /admin/users/:id`
|
||||
|
||||
**Response:**
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"message": "User deleted successfully"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📈 Analytics
|
||||
|
||||
### **User Statistics**
|
||||
|
||||
Get user's medication adherence statistics.
|
||||
|
||||
**Endpoint:** `GET /analytics/stats`
|
||||
|
||||
**Query Parameters:**
|
||||
|
||||
- `period` (string) - Time period (7d, 30d, 90d, 1y)
|
||||
|
||||
**Response:**
|
||||
|
||||
```json
|
||||
{
|
||||
"adherence": {
|
||||
"overall": 92.5,
|
||||
"trend": "improving",
|
||||
"streak": 7
|
||||
},
|
||||
"medications": [
|
||||
{
|
||||
"medicationId": "medication-uuid",
|
||||
"name": "Aspirin",
|
||||
"taken": 28,
|
||||
"missed": 2,
|
||||
"adherence": 93.3
|
||||
}
|
||||
],
|
||||
"dailyStats": [
|
||||
{
|
||||
"date": "2025-09-05",
|
||||
"adherence": 100,
|
||||
"totalDoses": 3,
|
||||
"takenDoses": 3
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔧 User Settings
|
||||
|
||||
### **Get User Settings**
|
||||
|
||||
Retrieve user preferences.
|
||||
|
||||
**Endpoint:** `GET /settings`
|
||||
|
||||
**Response:**
|
||||
|
||||
```json
|
||||
{
|
||||
"notifications": {
|
||||
"email": true,
|
||||
"push": false,
|
||||
"reminderSound": true
|
||||
},
|
||||
"preferences": {
|
||||
"theme": "dark",
|
||||
"timezone": "UTC-5",
|
||||
"dateFormat": "MM/DD/YYYY"
|
||||
},
|
||||
"privacy": {
|
||||
"shareStats": false,
|
||||
"anonymousUsage": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### **Update User Settings**
|
||||
|
||||
Update user preferences.
|
||||
|
||||
**Endpoint:** `PUT /settings`
|
||||
|
||||
**Request Body:**
|
||||
|
||||
```json
|
||||
{
|
||||
"notifications": {
|
||||
"email": false,
|
||||
"push": true
|
||||
},
|
||||
"preferences": {
|
||||
"theme": "light"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Response:**
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"settings": {
|
||||
"notifications": {
|
||||
"email": false,
|
||||
"push": true,
|
||||
"reminderSound": true
|
||||
},
|
||||
"preferences": {
|
||||
"theme": "light",
|
||||
"timezone": "UTC-5",
|
||||
"dateFormat": "MM/DD/YYYY"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📁 File Upload
|
||||
|
||||
### **Upload Avatar**
|
||||
|
||||
Upload user avatar image.
|
||||
|
||||
**Endpoint:** `POST /upload/avatar`
|
||||
|
||||
**Request:** Multipart form data
|
||||
|
||||
- `avatar` (file) - Image file (JPEG, PNG, max 2MB)
|
||||
|
||||
**Response:**
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"avatarUrl": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQ..."
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔍 Search
|
||||
|
||||
### **Search Medications**
|
||||
|
||||
Search for medications by name.
|
||||
|
||||
**Endpoint:** `GET /search/medications`
|
||||
|
||||
**Query Parameters:**
|
||||
|
||||
- `q` (string) - Search query
|
||||
- `limit` (number) - Max results
|
||||
|
||||
**Response:**
|
||||
|
||||
```json
|
||||
{
|
||||
"results": [
|
||||
{
|
||||
"name": "Aspirin",
|
||||
"commonDosages": ["100mg", "325mg", "500mg"],
|
||||
"category": "Pain Reliever"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ❌ Error Responses
|
||||
|
||||
### **Error Format**
|
||||
|
||||
```json
|
||||
{
|
||||
"error": {
|
||||
"code": "VALIDATION_ERROR",
|
||||
"message": "Invalid input data",
|
||||
"details": {
|
||||
"email": "Invalid email format",
|
||||
"password": "Password too weak"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### **Common Error Codes**
|
||||
|
||||
- `VALIDATION_ERROR` (400) - Invalid input data
|
||||
- `UNAUTHORIZED` (401) - Authentication required
|
||||
- `FORBIDDEN` (403) - Insufficient permissions
|
||||
- `NOT_FOUND` (404) - Resource not found
|
||||
- `CONFLICT` (409) - Resource already exists
|
||||
- `RATE_LIMITED` (429) - Too many requests
|
||||
- `INTERNAL_ERROR` (500) - Server error
|
||||
|
||||
---
|
||||
|
||||
## 📊 Rate Limiting
|
||||
|
||||
### **Limits**
|
||||
|
||||
- Authentication endpoints: 5 requests/minute
|
||||
- General API: 100 requests/minute
|
||||
- Upload endpoints: 10 requests/minute
|
||||
|
||||
### **Headers**
|
||||
|
||||
```http
|
||||
X-RateLimit-Limit: 100
|
||||
X-RateLimit-Remaining: 95
|
||||
X-RateLimit-Reset: 1693929600
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔒 Security
|
||||
|
||||
### **Authentication**
|
||||
|
||||
- JWT tokens with 24-hour expiration
|
||||
- Refresh tokens for automatic renewal
|
||||
- Secure password hashing with bcrypt
|
||||
|
||||
### **Authorization**
|
||||
|
||||
- Role-based access control (USER, ADMIN)
|
||||
- Resource-level permissions
|
||||
- Account status validation
|
||||
|
||||
### **Data Protection**
|
||||
|
||||
- Input validation and sanitization
|
||||
- SQL injection prevention
|
||||
- XSS protection
|
||||
- CORS configuration
|
||||
|
||||
---
|
||||
|
||||
## 📚 Additional Resources
|
||||
|
||||
- [Postman Collection](./postman-collection.json)
|
||||
- [OpenAPI Specification](./openapi.yaml)
|
||||
- [SDK Documentation](./sdk-docs.md)
|
||||
- [Integration Examples](./examples/)
|
||||
162
docs/development/APPLICATION_SECURITY.md
Normal file
162
docs/development/APPLICATION_SECURITY.md
Normal file
@@ -0,0 +1,162 @@
|
||||
# Security Guide
|
||||
|
||||
## 🔐 Security Best Practices for Medication Reminder App
|
||||
|
||||
### **Password Security**
|
||||
|
||||
#### **Password Requirements**
|
||||
|
||||
- Minimum 8 characters
|
||||
- Must contain uppercase and lowercase letters
|
||||
- Must contain at least one number
|
||||
- Must contain at least one special character
|
||||
- Cannot be common passwords (password123, admin, etc.)
|
||||
|
||||
#### **Password Hashing**
|
||||
|
||||
- Uses bcrypt with salt rounds for secure password storage
|
||||
- Passwords are never stored in plain text
|
||||
- Password verification happens through secure hash comparison
|
||||
|
||||
### **Authentication Security**
|
||||
|
||||
#### **Session Management**
|
||||
|
||||
- JWT-like token system for user sessions
|
||||
- Tokens have expiration times
|
||||
- Secure token storage and transmission
|
||||
- Automatic session cleanup on logout
|
||||
|
||||
#### **Email Verification**
|
||||
|
||||
- All new accounts require email verification
|
||||
- Verification tokens are time-limited
|
||||
- Prevents unauthorized account creation
|
||||
- Uses cryptographically secure random tokens
|
||||
|
||||
#### **OAuth Security**
|
||||
|
||||
- Supports Google and GitHub OAuth
|
||||
- Secure OAuth flow implementation
|
||||
- No password storage for OAuth users
|
||||
- Account linking prevention for security
|
||||
|
||||
### **Environment Security**
|
||||
|
||||
#### **Environment Variables**
|
||||
|
||||
- Never commit `.env` files to version control
|
||||
- Use separate environment files for different deployments
|
||||
- Rotate credentials regularly
|
||||
- Use strong, unique passwords for each environment
|
||||
|
||||
#### **Docker Security**
|
||||
|
||||
- Non-root user for application execution
|
||||
- Multi-stage builds to minimize attack surface
|
||||
- Health checks for service monitoring
|
||||
- Isolated network for services
|
||||
|
||||
### **Database Security**
|
||||
|
||||
#### **CouchDB Security**
|
||||
|
||||
- Admin authentication required
|
||||
- Database-level access control
|
||||
- SSL/TLS encryption for production
|
||||
- Regular backup and security updates
|
||||
|
||||
#### **Data Protection**
|
||||
|
||||
- User data isolation by user ID
|
||||
- Input validation and sanitization
|
||||
- Protection against injection attacks
|
||||
- Secure data deletion capabilities
|
||||
|
||||
### **Production Security Checklist**
|
||||
|
||||
#### **Before Deployment**
|
||||
|
||||
- [ ] Change default admin password
|
||||
- [ ] Configure strong CouchDB credentials
|
||||
- [ ] Set up Mailgun with proper API keys
|
||||
- [ ] Enable SSL/TLS certificates
|
||||
- [ ] Configure firewall rules
|
||||
- [ ] Set up monitoring and logging
|
||||
|
||||
#### **Regular Security Tasks**
|
||||
|
||||
- [ ] Rotate credentials monthly
|
||||
- [ ] Update dependencies regularly
|
||||
- [ ] Monitor logs for suspicious activity
|
||||
- [ ] Backup databases securely
|
||||
- [ ] Review user access permissions
|
||||
- [ ] Test disaster recovery procedures
|
||||
|
||||
### **Incident Response**
|
||||
|
||||
#### **Security Breach Protocol**
|
||||
|
||||
1. **Immediate Response**
|
||||
- Disable affected accounts
|
||||
- Change all credentials
|
||||
- Review access logs
|
||||
- Document the incident
|
||||
|
||||
2. **Investigation**
|
||||
- Identify breach source
|
||||
- Assess data exposure
|
||||
- Notify affected users
|
||||
- Implement fixes
|
||||
|
||||
3. **Recovery**
|
||||
- Restore from secure backups
|
||||
- Update security measures
|
||||
- Monitor for further issues
|
||||
- Conduct post-incident review
|
||||
|
||||
### **Compliance Considerations**
|
||||
|
||||
#### **Data Privacy**
|
||||
|
||||
- User data minimization
|
||||
- Right to data deletion
|
||||
- Transparent privacy policy
|
||||
- Secure data export capabilities
|
||||
|
||||
#### **Healthcare Compliance**
|
||||
|
||||
- HIPAA considerations for health data
|
||||
- Secure medication information handling
|
||||
- Audit trail capabilities
|
||||
- Data retention policies
|
||||
|
||||
### **Security Monitoring**
|
||||
|
||||
#### **Logging**
|
||||
|
||||
- Authentication attempts
|
||||
- Failed login monitoring
|
||||
- Admin actions tracking
|
||||
- Database access logging
|
||||
|
||||
#### **Alerting**
|
||||
|
||||
- Multiple failed login attempts
|
||||
- Admin privilege escalation
|
||||
- Unusual data access patterns
|
||||
- System health issues
|
||||
|
||||
### **Emergency Contacts**
|
||||
|
||||
#### **Security Issues**
|
||||
|
||||
- Development Team: security@your-domain.com
|
||||
- System Administrator: admin@your-domain.com
|
||||
- Emergency Response: +1-XXX-XXX-XXXX
|
||||
|
||||
#### **Third-party Services**
|
||||
|
||||
- Mailgun Support: support@mailgun.com
|
||||
- CouchDB Security: security@apache.org
|
||||
- Docker Security: security@docker.com
|
||||
246
docs/development/CODE_QUALITY.md
Normal file
246
docs/development/CODE_QUALITY.md
Normal file
@@ -0,0 +1,246 @@
|
||||
# Code Quality and Formatting Setup
|
||||
|
||||
This project includes comprehensive code quality tools and pre-commit hooks to maintain consistent code standards.
|
||||
|
||||
## Tools Configured
|
||||
|
||||
### Pre-commit Hooks
|
||||
|
||||
- **File formatting**: Trailing whitespace, end-of-file fixes, line ending normalization
|
||||
- **Security**: Private key detection, secrets scanning with detect-secrets
|
||||
- **Linting**: ESLint for TypeScript/JavaScript, Hadolint for Docker, ShellCheck for scripts
|
||||
- **Type checking**: TypeScript compilation checks
|
||||
- **Formatting**: Prettier for code formatting, Markdownlint for documentation
|
||||
|
||||
### Code Formatters
|
||||
|
||||
- **Prettier**: Handles JavaScript, TypeScript, JSON, YAML, Markdown, CSS, SCSS, HTML formatting
|
||||
- **ESLint**: TypeScript/JavaScript linting with comprehensive rules and React hooks support
|
||||
- **EditorConfig**: Consistent coding styles across editors
|
||||
|
||||
### Security Tools
|
||||
|
||||
- **detect-secrets**: Prevents secrets from being committed to the repository
|
||||
- **Private key detection**: Automatically detects and blocks private keys
|
||||
|
||||
## Setup
|
||||
|
||||
Run the setup script to install all tools and configure pre-commit hooks:
|
||||
|
||||
```bash
|
||||
./scripts/setup-pre-commit.sh
|
||||
```
|
||||
|
||||
Alternatively, install manually:
|
||||
|
||||
```bash
|
||||
# Install dependencies
|
||||
bun install
|
||||
|
||||
# Install pre-commit in Python virtual environment
|
||||
python -m venv .venv
|
||||
source .venv/bin/activate # or .venv/Scripts/activate on Windows
|
||||
pip install pre-commit detect-secrets
|
||||
|
||||
# Install pre-commit hooks
|
||||
pre-commit install
|
||||
|
||||
# Create secrets baseline (if it doesn't exist)
|
||||
detect-secrets scan --baseline .secrets.baseline
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
### Automatic (Recommended)
|
||||
|
||||
Pre-commit hooks will automatically run on every commit, ensuring:
|
||||
|
||||
- Code is properly formatted
|
||||
- Linting rules are followed
|
||||
- Type checking passes
|
||||
- No secrets are committed
|
||||
|
||||
### Manual Commands
|
||||
|
||||
```bash
|
||||
# Format all files
|
||||
bun run format
|
||||
|
||||
# Check formatting without fixing
|
||||
bun run format:check
|
||||
|
||||
# Lint TypeScript/JavaScript files
|
||||
bun run lint
|
||||
|
||||
# Lint with auto-fix
|
||||
bun run lint:fix
|
||||
|
||||
# Type checking
|
||||
bun run type-check
|
||||
|
||||
# Run pre-commit hook
|
||||
bun run pre-commit
|
||||
|
||||
# Run all pre-commit hooks manually (using virtual environment)
|
||||
/home/will/Code/meds/.venv/bin/pre-commit run --all-files
|
||||
|
||||
# Run specific hook
|
||||
/home/will/Code/meds/.venv/bin/pre-commit run prettier --all-files
|
||||
|
||||
# Update pre-commit hook versions
|
||||
/home/will/Code/meds/.venv/bin/pre-commit autoupdate
|
||||
```
|
||||
|
||||
## Configuration Files
|
||||
|
||||
- `.pre-commit-config.yaml` - Pre-commit hooks configuration with comprehensive security and quality checks
|
||||
- `.prettierrc` - Prettier formatting rules with TypeScript/React optimizations
|
||||
- `.prettierignore` - Files to ignore for Prettier formatting
|
||||
- `.editorconfig` - Editor configuration for consistent coding styles across IDEs
|
||||
- `eslint.config.cjs` - ESLint linting rules with TypeScript and React hooks support
|
||||
- `.markdownlint.json` - Markdown linting configuration for documentation quality
|
||||
- `.secrets.baseline` - Baseline for detect-secrets security scanning
|
||||
- `scripts/setup-pre-commit.sh` - Automated setup script for all tools
|
||||
- `docs/CODE_QUALITY.md` - This documentation file
|
||||
|
||||
## Pre-commit Hook Details
|
||||
|
||||
The following hooks run automatically on every commit:
|
||||
|
||||
### File Quality Hooks
|
||||
|
||||
- `trailing-whitespace` - Removes trailing whitespace
|
||||
- `end-of-file-fixer` - Ensures files end with newline
|
||||
- `check-yaml` - Validates YAML syntax
|
||||
- `check-json` - Validates JSON syntax
|
||||
- `check-toml` - Validates TOML syntax
|
||||
- `check-xml` - Validates XML syntax
|
||||
- `check-merge-conflict` - Prevents merge conflict markers
|
||||
- `check-added-large-files` - Prevents large files from being committed
|
||||
- `check-case-conflict` - Prevents case conflicts on case-insensitive filesystems
|
||||
- `check-symlinks` - Validates symlinks
|
||||
- `mixed-line-ending` - Ensures consistent line endings (LF)
|
||||
|
||||
### Security Hooks
|
||||
|
||||
- `detect-private-key` - Prevents private keys from being committed
|
||||
- `detect-secrets` - Scans for secrets using baseline comparison
|
||||
|
||||
### Code Quality Hooks
|
||||
|
||||
- `prettier` - Formats JavaScript, TypeScript, JSON, YAML, Markdown, CSS, SCSS, HTML
|
||||
- `eslint` - Lints TypeScript/JavaScript with auto-fix
|
||||
- `tsc` - TypeScript type checking
|
||||
|
||||
### Infrastructure Hooks
|
||||
|
||||
- `hadolint-docker` - Lints Dockerfile files
|
||||
- `shellcheck` - Lints shell scripts
|
||||
- `markdownlint` - Lints and formats Markdown files
|
||||
|
||||
## IDE Integration
|
||||
|
||||
### VS Code (Recommended)
|
||||
|
||||
Install these extensions for optimal integration:
|
||||
|
||||
- **Prettier - Code formatter** (`esbenp.prettier-vscode`)
|
||||
- **ESLint** (`dbaeumer.vscode-eslint`)
|
||||
- **EditorConfig for VS Code** (`editorconfig.editorconfig`)
|
||||
|
||||
### Settings for VS Code
|
||||
|
||||
Add these settings to your VS Code `settings.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"editor.formatOnSave": true,
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.fixAll.eslint": true
|
||||
},
|
||||
"eslint.validate": ["javascript", "javascriptreact", "typescript", "typescriptreact"]
|
||||
}
|
||||
```
|
||||
|
||||
### Other IDEs
|
||||
|
||||
Most modern IDEs support EditorConfig, Prettier, and ESLint through plugins:
|
||||
|
||||
- **WebStorm/IntelliJ**: Built-in support for most tools
|
||||
- **Vim/Neovim**: Use coc.nvim or native LSP with appropriate plugins
|
||||
- **Sublime Text**: Install Package Control packages for each tool
|
||||
|
||||
## Customization
|
||||
|
||||
### Prettier
|
||||
|
||||
Edit `.prettierrc` to modify formatting rules.
|
||||
|
||||
### ESLint
|
||||
|
||||
Edit `eslint.config.cjs` to add or modify linting rules.
|
||||
|
||||
### Pre-commit
|
||||
|
||||
Edit `.pre-commit-config.yaml` to add, remove, or modify hooks.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Pre-commit hooks failing
|
||||
|
||||
```bash
|
||||
# Skip hooks temporarily (not recommended)
|
||||
git commit --no-verify -m "commit message"
|
||||
|
||||
# Fix issues and try again
|
||||
bun run lint:fix
|
||||
bun run format
|
||||
git add .
|
||||
git commit -m "commit message"
|
||||
```
|
||||
|
||||
### Update hook versions
|
||||
|
||||
```bash
|
||||
/home/will/Code/meds/.venv/bin/pre-commit autoupdate
|
||||
```
|
||||
|
||||
### Clear pre-commit cache
|
||||
|
||||
```bash
|
||||
/home/will/Code/meds/.venv/bin/pre-commit clean
|
||||
```
|
||||
|
||||
### Secrets detection issues
|
||||
|
||||
```bash
|
||||
# Update secrets baseline
|
||||
/home/will/Code/meds/.venv/bin/detect-secrets scan --update .secrets.baseline
|
||||
|
||||
# Audit detected secrets
|
||||
/home/will/Code/meds/.venv/bin/detect-secrets audit .secrets.baseline
|
||||
```
|
||||
|
||||
### Python virtual environment issues
|
||||
|
||||
```bash
|
||||
# Recreate virtual environment
|
||||
rm -rf .venv
|
||||
python -m venv .venv
|
||||
source .venv/bin/activate
|
||||
pip install pre-commit detect-secrets
|
||||
/home/will/Code/meds/.venv/bin/pre-commit install
|
||||
```
|
||||
|
||||
### ESLint configuration issues
|
||||
|
||||
If you encounter TypeScript project configuration errors:
|
||||
|
||||
```bash
|
||||
# Ensure tsconfig.json is properly configured
|
||||
bun run type-check
|
||||
|
||||
# Check ESLint configuration
|
||||
npx eslint --print-config index.tsx
|
||||
```
|
||||
148
docs/development/SECURITY_CHANGES.md
Normal file
148
docs/development/SECURITY_CHANGES.md
Normal file
@@ -0,0 +1,148 @@
|
||||
# 🔐 Security Changes Summary
|
||||
|
||||
## Overview
|
||||
|
||||
We have systematically removed all hardcoded credentials from the RxMinder application and replaced them with secure defaults and environment variables.
|
||||
|
||||
## ✅ Changes Made
|
||||
|
||||
### 1. Kubernetes Configuration
|
||||
|
||||
- **`k8s/couchdb-secret.yaml`**: Converted to template with secure base64-encoded defaults
|
||||
- **`k8s/db-seed-job.yaml`**: Now uses environment variables from secrets instead of hardcoded credentials
|
||||
|
||||
### 2. Docker Configuration
|
||||
|
||||
- **`docker/Dockerfile`**: Updated default password arguments to secure values
|
||||
- **`docker/docker-compose.yaml`**: All password environment variables use secure fallbacks
|
||||
- **`docker/docker-bake.hcl`**: Updated variable defaults to secure passwords
|
||||
|
||||
### 3. Shell Scripts
|
||||
|
||||
Updated all deployment and build scripts with secure password fallbacks:
|
||||
|
||||
- `scripts/setup.sh`
|
||||
- `scripts/deploy.sh`
|
||||
- `scripts/validate-deployment.sh`
|
||||
- `scripts/buildx-helper.sh`
|
||||
- `scripts/gitea-deploy.sh`
|
||||
- `scripts/gitea-helper.sh`
|
||||
- `scripts/seed-production.js`
|
||||
- `rename-app.sh`
|
||||
|
||||
### 4. CI/CD Workflows
|
||||
|
||||
- **`.github/workflows/build-deploy.yml`**: Updated fallback passwords to secure values
|
||||
- **`.gitea/workflows/ci-cd.yml`**: Updated fallback passwords to secure values
|
||||
- **`.gitea/docker-compose.ci.yml`**: Updated test database passwords
|
||||
- **`.gitea/gitea-bake.hcl`**: Updated default password variables
|
||||
|
||||
### 5. Environment Files
|
||||
|
||||
- **`.env.example`**: Updated with secure default passwords and documentation
|
||||
- **`.env.production`**: Updated with secure default passwords
|
||||
- **`test.env`**: Updated test credentials to secure values
|
||||
|
||||
### 6. Documentation
|
||||
|
||||
- **`README.md`**: Updated default admin credentials documentation
|
||||
- **`SECURITY.md`**: Created comprehensive security guide with checklists
|
||||
- **`.gitea/README.md`**: Updated documentation
|
||||
- **`GITEA_SETUP.md`**: Updated setup instructions
|
||||
|
||||
## 🛡️ Security Improvements
|
||||
|
||||
### Before
|
||||
|
||||
- Hardcoded `admin123!` and `password` throughout configuration files
|
||||
- Weak default passwords in CI/CD systems
|
||||
- No security documentation or guidelines
|
||||
|
||||
### After
|
||||
|
||||
- All passwords use environment variables or Kubernetes secrets
|
||||
- Secure fallback passwords (`change-this-secure-password`)
|
||||
- Comprehensive security documentation and checklists
|
||||
- CI/CD systems use repository secrets with secure fallbacks
|
||||
|
||||
## 🔄 Required Actions
|
||||
|
||||
**CRITICAL**: Before production deployment, you must:
|
||||
|
||||
1. **Update Kubernetes Secrets**:
|
||||
|
||||
```bash
|
||||
# Update k8s/couchdb-secret.yaml with your own secure base64-encoded credentials
|
||||
echo -n "your-secure-password" | base64
|
||||
```
|
||||
|
||||
2. **Update Environment Variables**:
|
||||
|
||||
```bash
|
||||
# Update .env and .env.production with your secure passwords
|
||||
COUCHDB_PASSWORD=your-very-secure-password
|
||||
VITE_COUCHDB_PASSWORD=your-very-secure-password
|
||||
```
|
||||
|
||||
3. **Configure CI/CD Secrets**:
|
||||
- Set `VITE_COUCHDB_PASSWORD` in repository secrets
|
||||
- Set `GITEA_TOKEN` / `GITHUB_TOKEN` for registry authentication
|
||||
|
||||
4. **Review Security Checklist**:
|
||||
- Follow the checklist in `SECURITY.md`
|
||||
- Use strong passwords (16+ characters, mixed case, numbers, symbols)
|
||||
- Enable TLS/SSL for all external communications
|
||||
|
||||
## 📝 Files Modified
|
||||
|
||||
### Configuration Files (11)
|
||||
|
||||
- `k8s/couchdb-secret.yaml`
|
||||
- `k8s/db-seed-job.yaml`
|
||||
- `docker/Dockerfile`
|
||||
- `docker/docker-compose.yaml`
|
||||
- `docker/docker-bake.hcl`
|
||||
- `.env.example`
|
||||
- `.env.production`
|
||||
- `test.env`
|
||||
- `.github/workflows/build-deploy.yml`
|
||||
- `.gitea/workflows/ci-cd.yml`
|
||||
- `.gitea/docker-compose.ci.yml`
|
||||
- `.gitea/gitea-bake.hcl`
|
||||
|
||||
### Scripts (8)
|
||||
|
||||
- `scripts/setup.sh`
|
||||
- `scripts/deploy.sh`
|
||||
- `scripts/validate-deployment.sh`
|
||||
- `scripts/buildx-helper.sh`
|
||||
- `scripts/gitea-deploy.sh`
|
||||
- `scripts/gitea-helper.sh`
|
||||
- `scripts/seed-production.js`
|
||||
- `rename-app.sh`
|
||||
|
||||
### Documentation (5)
|
||||
|
||||
- `README.md`
|
||||
- `SECURITY.md` (created)
|
||||
- `SECURITY_CHANGES.md` (this file)
|
||||
- `.gitea/README.md`
|
||||
- `GITEA_SETUP.md`
|
||||
|
||||
## ✅ Verification
|
||||
|
||||
To verify no hardcoded credentials remain:
|
||||
|
||||
```bash
|
||||
# Check for insecure passwords (should return only secure defaults)
|
||||
grep -r "admin123\|password[^-]\|testpassword" --include="*.yaml" --include="*.yml" --include="*.sh" --include="*.env" --include="*.js" --include="*.hcl" .
|
||||
|
||||
# The only matches should be:
|
||||
# - "change-this-secure-password" (secure fallback)
|
||||
# - "test-secure-password" (secure test credentials)
|
||||
# - Test files (acceptable for testing)
|
||||
```
|
||||
|
||||
## 🎯 Result
|
||||
|
||||
RxMinder is now production-ready with secure credential management. All sensitive data is properly externalized to environment variables and Kubernetes secrets, with comprehensive documentation to guide secure deployment.
|
||||
Reference in New Issue
Block a user