Skip to content

Commit 0c519d7

Browse files
authored
Merge pull request #3 from BitsHost/ReadyForPackagist
Ready for packagist.org
2 parents 2de374e + a1c7a00 commit 0c519d7

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

60 files changed

+14849
-101
lines changed

.gitignore

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,25 @@
1+
# Dependencies
12
/vendor/
3+
/composer.lock
4+
5+
# Configuration files (contain secrets)
26
/config/db.php
37
/config/api.php
8+
/config/api.local.php
49
/.env
10+
11+
# Logs and storage
12+
/storage/
13+
/logs/
14+
*.log
15+
16+
# Testing artifacts
17+
jwt_token.txt
18+
*.token
19+
test_*.txt
20+
secrets_*.txt
21+
22+
# IDE and OS
523
.DS_Store
624
.idea/
7-
/tests/output/
8-
/composer.lock
25+
/tests/output/

.phpunit.cache/test-results

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"version":2,"defects":{"RateLimiterTest::testCleanup":7,"RequestLoggerTest::testLogStatistics":7},"times":{"RateLimiterTest::testBasicRateLimiting":0.02,"RateLimiterTest::testRequestCount":0.007,"RateLimiterTest::testRemainingRequests":0.006,"RateLimiterTest::testRateLimitReset":0.014,"RateLimiterTest::testWindowExpiration":3.017,"RateLimiterTest::testHeaders":0.007,"RateLimiterTest::testDisabledRateLimiting":0.001,"RateLimiterTest::testCustomLimits":0.009,"RateLimiterTest::testMultipleIdentifiers":0.015,"RateLimiterTest::testResetTime":0.005,"RateLimiterTest::testCleanup":1.01,"RequestLoggerTest::testBasicRequestLogging":0.013,"RequestLoggerTest::testSensitiveDataRedaction":0.006,"RequestLoggerTest::testAuthenticationLogging":0.009,"RequestLoggerTest::testRateLimitLogging":0.004,"RequestLoggerTest::testErrorLogging":0.004,"RequestLoggerTest::testQuickRequestLogging":0.006,"RequestLoggerTest::testLogStatistics":0.014,"RequestLoggerTest::testDisabledLogging":0.001,"RequestLoggerTest::testLogRotation":0.082,"RequestLoggerTest::testCleanup":0.015,"RequestLoggerTest::testLogLevels":0.021}}

CHANGELOG.md

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,119 @@
11
# Changelog
22

3+
## 1.3.0 - Request Logging and Monitoring
4+
5+
### New Features
6+
- **📝 Request Logging**: Comprehensive request/response logging system
7+
- Automatic logging of all API requests and responses
8+
- Multiple log levels (debug, info, warning, error)
9+
- Sensitive data redaction (passwords, tokens, API keys)
10+
- Authentication attempt logging
11+
- Rate limit hit logging
12+
- Error logging with stack traces
13+
- Log rotation and cleanup
14+
- Configurable log retention
15+
- Statistics and analytics
16+
- Zero configuration required (works out of the box)
17+
18+
### Improvements
19+
- Enhanced security with comprehensive audit logging
20+
- Better debugging capabilities with detailed request/response logging
21+
- Performance monitoring with execution time tracking
22+
- Security monitoring with authentication and rate limit logging
23+
- Automatic sensitive data redaction in logs
24+
- Added log statistics for monitoring
25+
- Improved Router integration with automatic logging
26+
27+
### Logging Features
28+
- **Request Details**: Method, action, table, IP, user, query params, headers, body
29+
- **Response Details**: Status code, execution time, response size, body (optional)
30+
- **Authentication Logging**: Success/failure with reasons
31+
- **Rate Limit Logging**: Tracks rate limit violations
32+
- **Error Logging**: Comprehensive error details with context
33+
- **Sensitive Data Redaction**: Automatic redaction of passwords, tokens, API keys
34+
- **Log Rotation**: Automatic rotation when file exceeds size limit
35+
- **Cleanup**: Automatic removal of old log files
36+
- **Statistics**: Daily statistics (requests, errors, warnings, etc.)
37+
38+
### Configuration
39+
- Added logging section to api.example.php:
40+
- `enabled` - Enable/disable logging
41+
- `log_dir` - Log directory path
42+
- `log_level` - Minimum log level (debug, info, warning, error)
43+
- `log_headers` - Log request headers
44+
- `log_body` - Log request body
45+
- `log_query_params` - Log query parameters
46+
- `log_response_body` - Log response body (optional)
47+
- `max_body_length` - Maximum body length to log
48+
- `sensitive_keys` - Keys to redact in logs
49+
- `rotation_size` - Size threshold for log rotation
50+
- `max_files` - Maximum log files to retain
51+
52+
### Documentation
53+
- Added `docs/REQUEST_LOGGING.md` (coming soon)
54+
- Updated README with logging information
55+
- Added logging demo script
56+
- Added comprehensive test coverage
57+
58+
### Testing
59+
- Added comprehensive RequestLoggerTest with 11 test cases
60+
- Tests cover: request logging, sensitive data redaction, auth logging, rate limit logging, error logging, statistics, rotation, cleanup
61+
62+
### Migration Notes
63+
-**100% Backward Compatible** - No breaking changes
64+
- Logging is enabled by default but can be disabled in config
65+
- Logs are stored in `/logs` directory (auto-created)
66+
- Recommended: Review log settings for production use
67+
68+
---
69+
70+
## 1.2.0 - Rate Limiting and Production Security
71+
72+
### New Features
73+
- **🔒 Rate Limiting**: Built-in rate limiting to prevent API abuse
74+
- Configurable request limits (default: 100 requests per 60 seconds)
75+
- Smart identification (user, API key, or IP address)
76+
- Standard HTTP headers (X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset)
77+
- File-based storage (easily extensible to Redis/Memcached)
78+
- Automatic cleanup of old rate limit data
79+
- 429 Too Many Requests response with retry information
80+
- Per-user/IP rate limiting with sliding window algorithm
81+
- Zero configuration required (works out of the box)
82+
83+
### Improvements
84+
- Enhanced security with rate limiting layer
85+
- Added comprehensive rate limiting documentation
86+
- Added storage directory structure for rate limit data
87+
- Improved Router class with rate limit integration
88+
- Added rate limit headers to all API responses
89+
- Better protection against DoS and brute force attacks
90+
91+
### Documentation
92+
- Added `docs/RATE_LIMITING.md` with comprehensive guide
93+
- Updated README with rate limiting information
94+
- Added client implementation examples (JavaScript, Python, PHP)
95+
- Added benchmarks and performance considerations
96+
- Added troubleshooting guide
97+
98+
### Testing
99+
- Added comprehensive RateLimiterTest with 11 test cases
100+
- Tests cover: basic limiting, request counting, window expiration, headers, cleanup
101+
102+
### Configuration
103+
- Added rate_limit section to api.example.php:
104+
- `enabled` - Enable/disable rate limiting
105+
- `max_requests` - Maximum requests per window
106+
- `window_seconds` - Time window in seconds
107+
- `storage_dir` - Storage directory for rate limit data
108+
109+
### Migration Notes
110+
-**100% Backward Compatible** - No breaking changes
111+
- Rate limiting is enabled by default but can be disabled in config
112+
- Existing APIs will continue to work without modification
113+
- Recommended: Review and adjust rate limits for your use case
114+
115+
---
116+
3117
## 1.1.0 - Enhanced Query Capabilities and Bulk Operations
4118

5119
### New Features

README.md

Lines changed: 130 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,24 @@
11
# PHP CRUD API Generator
22

3+
[![Latest Stable Version](https://poser.pugx.org/bitshost/php-crud-api-generator/v/stable)](https://packagist.org/packages/bitshost/php-crud-api-generator)
4+
[![Total Downloads](https://poser.pugx.org/bitshost/php-crud-api-generator/downloads)](https://packagist.org/packages/bitshost/php-crud-api-generator)
5+
[![License](https://poser.pugx.org/bitshost/php-crud-api-generator/license)](https://packagist.org/packages/bitshost/php-crud-api-generator)
6+
[![PHP Version](https://img.shields.io/badge/php-%3E%3D8.0-blue.svg)](https://php.net)
7+
38
Expose your MySQL/MariaDB database as a secure, flexible, and instant REST-like API.
49
Features optional authentication (API key, Basic Auth, JWT, OAuth-ready),
510
OpenAPI (Swagger) docs, and zero code generation.
611

712
---
813

9-
## 🚀 ## 🚀 Features
14+
## 🚀 Features
1015

1116
- Auto-discovers tables and columns
1217
- Full CRUD endpoints for any table
1318
- **Bulk operations** - Create or delete multiple records efficiently
1419
- Configurable authentication (API Key, Basic Auth, JWT, or none)
20+
- **Rate limiting** - Prevent API abuse with configurable request limits
21+
- **Request logging** - Comprehensive logging for debugging and monitoring
1522
- **Advanced query features:**
1623
- **Field selection** - Choose specific columns to return
1724
- **Advanced filtering** - Support for multiple comparison operators (eq, neq, gt, gte, lt, lte, like, in, notin, null, notnull)
@@ -25,6 +32,8 @@ OpenAPI (Swagger) docs, and zero code generation.
2532
- PHPUnit tests and extensible architecture
2633

2734
📖 **[See detailed enhancement documentation →](ENHANCEMENTS.md)**
35+
📖 **[Rate Limiting Documentation →](docs/RATE_LIMITING.md)**
36+
📖 **[Request Logging Documentation →](docs/REQUEST_LOGGING.md)**
2837

2938
---
3039

@@ -68,14 +77,55 @@ return [
6877
'jwt_secret' => 'YourSuperSecretKey',
6978
'jwt_issuer' => 'yourdomain.com',
7079
'jwt_audience' => 'yourdomain.com',
71-
'oauth_providers' => [
72-
// 'google' => ['client_id' => '', 'client_secret' => '', ...]
73-
]
80+
81+
// Rate limiting (recommended for production)
82+
'rate_limit' => [
83+
'enabled' => true,
84+
'max_requests' => 100, // 100 requests
85+
'window_seconds' => 60, // per 60 seconds (1 minute)
86+
],
87+
88+
// Request logging (recommended for production)
89+
'logging' => [
90+
'enabled' => true,
91+
'log_dir' => __DIR__ . '/../logs',
92+
'log_level' => 'info', // debug, info, warning, error
93+
],
7494
];
7595
```
7696

7797
---
7898

99+
## 🔒 Security Setup (Production)
100+
101+
⚠️ **IMPORTANT:** This framework ships with **example credentials for development**.
102+
You **MUST** change these before deploying to production!
103+
104+
### Quick Security Setup:
105+
106+
```bash
107+
# 1. Generate secure secrets (JWT secret + API keys)
108+
php scripts/generate_secrets.php
109+
110+
# 2. Update config/api.php with generated secrets
111+
112+
# 3. Create admin user in database
113+
php scripts/create_user.php admin admin@yoursite.com YourSecurePassword123! admin
114+
```
115+
116+
### What to Change:
117+
118+
- [ ] `jwt_secret` - Generate with: `php scripts/generate_jwt_secret.php`
119+
- [ ] `api_keys` - Use long random strings (64+ characters)
120+
- [ ] Default admin password in `sql/create_api_users.sql`
121+
- [ ] Database credentials in `config/db.php`
122+
123+
📖 **Full security guide:** [docs/AUTHENTICATION.md](docs/AUTHENTICATION.md)
124+
125+
---
126+
127+
---
128+
79129
## 🔐 Authentication Modes
80130

81131
- **No auth:** `'auth_enabled' => false`
@@ -344,11 +394,18 @@ get:
344394
## 🛡️ Security Notes
345395
346396
- **Enable authentication for any public deployment!**
397+
- **Enable rate limiting in production** to prevent abuse
398+
- **Enable request logging** for security auditing and debugging
347399
- Never commit real credentials—use `.gitignore` and example configs.
348400
- Restrict DB user privileges.
349401
- **Input validation**: All user inputs (table names, column names, IDs, filters) are validated to prevent SQL injection and invalid queries.
350402
- **Parameterized queries**: All database queries use prepared statements with bound parameters.
351403
- **RBAC enforcement**: Role-based access control is enforced at the routing level before any database operations.
404+
- **Rate limiting**: Configurable request limits prevent API abuse and DoS attacks.
405+
- **Sensitive data redaction**: Passwords, tokens, and API keys are automatically redacted from logs.
406+
407+
📖 **[Rate Limiting Documentation →](docs/RATE_LIMITING.md)**
408+
📖 **[Request Logging Documentation →](docs/REQUEST_LOGGING.md)**
352409

353410
---
354411

@@ -360,9 +417,77 @@ get:
360417

361418
---
362419

420+
### 🔗 Working with Related Data (Client-Side Joins)
421+
422+
Your API provides all the data you need - it's up to the client to decide how to combine it. This approach gives you maximum flexibility and control.
423+
424+
**Current approach:** Fetch related data in separate requests and combine on the client side.
425+
426+
#### Quick Example: Get User with Posts
427+
428+
```javascript
429+
// 1. Fetch user
430+
const user = await fetch('/api.php?action=read&table=users&id=123')
431+
.then(r => r.json());
432+
433+
// 2. Fetch user's posts
434+
const posts = await fetch('/api.php?action=list&table=posts&filter=user_id:123')
435+
.then(r => r.json());
436+
437+
// 3. Combine however you want
438+
const userData = {
439+
...user,
440+
posts: posts.data
441+
};
442+
```
443+
444+
#### Optimization: Use IN Operator for Batch Fetching
445+
446+
```javascript
447+
// Get multiple related records in one request
448+
const postIds = '1|2|3|4|5'; // IDs from previous query
449+
const comments = await fetch(
450+
`/api.php?action=list&table=comments&filter=post_id:in:${postIds}`
451+
).then(r => r.json());
452+
453+
// Group by post_id on client
454+
const commentsByPost = comments.data.reduce((acc, comment) => {
455+
acc[comment.post_id] = acc[comment.post_id] || [];
456+
acc[comment.post_id].push(comment);
457+
return acc;
458+
}, {});
459+
```
460+
461+
#### Parallel Fetching for Performance
462+
463+
```javascript
464+
// Fetch multiple resources simultaneously
465+
const [user, posts, comments] = await Promise.all([
466+
fetch('/api.php?action=read&table=users&id=123').then(r => r.json()),
467+
fetch('/api.php?action=list&table=posts&filter=user_id:123').then(r => r.json()),
468+
fetch('/api.php?action=list&table=comments&filter=user_id:123').then(r => r.json())
469+
]);
470+
471+
// All requests happen at once - much faster!
472+
```
473+
474+
📖 **[See complete client-side join examples →](docs/CLIENT_SIDE_JOINS.md)**
475+
476+
**Why this approach?**
477+
- ✅ Client decides what data to fetch and when
478+
- ✅ Easy to optimize with caching and parallel requests
479+
- ✅ Different clients can have different data needs
480+
- ✅ Standard REST API practice
481+
- ✅ No server-side complexity for joins
482+
483+
**Future:** Auto-join/expand features may be added based on user demand.
484+
485+
---
486+
363487
## 🗺️ Roadmap
364488

365-
- Relations / Linked Data (auto-join, populate, or expand related records)
489+
- **Client-side joins** ✅ (Current - simple and flexible!)
490+
- Relations / Linked Data (auto-join, populate, or expand related records) - *Future, based on demand*
366491
- API Versioning (when needed)
367492
- OAuth/SSO (if targeting SaaS/public)
368493
- More DB support (Postgres, SQLite, etc.)

composer.json

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
{
22
"name": "bitshost/php-crud-api-generator",
3-
"description": "Automatic, configurable CRUD API generator for MySQL/MariaDB in PHP (with optional authentication)",
4-
"type": "project",
3+
"description": "Instant REST API for MySQL/MariaDB with JWT auth, rate limiting, monitoring, and zero code generation",
4+
"type": "library",
55
"license": "MIT",
6+
"keywords": ["api", "rest", "crud", "mysql", "jwt", "authentication", "rate-limiting", "monitoring", "swagger", "openapi"],
7+
"homepage": "https://github.com/BitsHost/php-crud-api-generator",
68
"minimum-stability": "stable",
7-
"authors": [
9+
"authors": [
810
{
911
"name": "Adrian D",
1012
"email": "contact@delvirai.net",
@@ -23,5 +25,9 @@
2325
},
2426
"require-dev": {
2527
"phpunit/phpunit": "^10.0"
28+
},
29+
"support": {
30+
"issues": "https://github.com/BitsHost/php-crud-api-generator/issues",
31+
"source": "https://github.com/BitsHost/php-crud-api-generator"
2632
}
2733
}

0 commit comments

Comments
 (0)