mirror of
https://codeberg.org/PostERG/xamxam.git
synced 2026-05-06 11:09:18 +02:00
refactor: reorganize to standard PHP structure
- Moved /lib → /src (PHP source code)
- Moved /includes → /public/includes (main site templates)
- Admin section remains self-contained in /public/admin with its own /inc
- Updated all require/include paths across codebase
- Updated config/bootstrap.php, justfile, tests, docs
- All tests passing ✅
Structure now follows PHP best practices:
/config - Configuration files
/database - SQLite database + schema
/docs - Documentation (intact)
/nginx - Server config (intact)
/public - Web-accessible files (entry point)
/admin - Self-contained admin interface
/assets - CSS, fonts, icons
/includes - Main site templates (header/footer)
/scripts - Deployment scripts (intact)
/src - PHP source classes (Database, AdminAuth, RateLimit)
/tests - Test suites
This commit is contained in:
@@ -25,7 +25,7 @@ This deploys all files to `/var/www/posterg/`:
|
||||
- `includes/` → `/var/www/posterg/includes/`
|
||||
- `config/` → `/var/www/posterg/config/`
|
||||
- `database/` → `/var/www/posterg/database/`
|
||||
- `lib/` → `/var/www/posterg/lib/`
|
||||
- `src/` → `/var/www/posterg/lib/`
|
||||
|
||||
### 3. Update Nginx Configuration
|
||||
|
||||
|
||||
@@ -130,7 +130,7 @@ just fixtures
|
||||
### Create a New Page
|
||||
|
||||
1. Create `newpage.php` in root
|
||||
2. Add `require_once __DIR__ . '/lib/Database.php';`
|
||||
2. Add `require_once __DIR__ . '/src/Database.php';`
|
||||
3. Include header: `include 'inc/header.php';`
|
||||
4. Add your content
|
||||
5. Include footer: `include 'inc/footer.php';`
|
||||
@@ -138,7 +138,7 @@ just fixtures
|
||||
Example:
|
||||
```php
|
||||
<?php
|
||||
require_once __DIR__ . '/lib/Database.php';
|
||||
require_once __DIR__ . '/src/Database.php';
|
||||
include 'inc/header.php';
|
||||
?>
|
||||
|
||||
@@ -154,7 +154,7 @@ include 'inc/header.php';
|
||||
|
||||
### Add a Database Function
|
||||
|
||||
1. Edit `lib/Database.php`
|
||||
1. Edit `src/Database.php`
|
||||
2. Add your method to the `Database` class
|
||||
3. Write a test in `tests/Unit/DatabaseTest.php`
|
||||
4. Run tests: `just test-unit`
|
||||
@@ -215,7 +215,7 @@ See `tests/README.md` for complete testing guide.
|
||||
**Quick example:**
|
||||
```php
|
||||
<?php
|
||||
require_once __DIR__ . '/../../lib/Database.php';
|
||||
require_once __DIR__ . '/../../src/Database.php';
|
||||
|
||||
echo "My Test\n";
|
||||
echo "=======\n\n";
|
||||
@@ -243,7 +243,7 @@ just deploy
|
||||
This deploys:
|
||||
- Public site (root PHP files)
|
||||
- Admin panel (`admin/`)
|
||||
- Shared libraries (`lib/`)
|
||||
- Shared libraries (`src/`)
|
||||
|
||||
**Note:** `vendor/` is automatically excluded from deployment.
|
||||
|
||||
|
||||
@@ -66,7 +66,7 @@ git commit -m "Pre-migration checkpoint"
|
||||
This will:
|
||||
- Move `apps/public/*` to root
|
||||
- Move `apps/admin/` to `admin/`
|
||||
- Rename `shared/` to `lib/`
|
||||
- Rename `shared/` to `src/`
|
||||
- Update all `require` paths automatically
|
||||
- Remove `apps/` directory
|
||||
- Update `.gitignore`
|
||||
@@ -149,9 +149,9 @@ just deploy-admin
|
||||
| `apps/public/assets/` | `assets/` |
|
||||
| `apps/public/inc/` | `inc/` |
|
||||
| `apps/admin/` | `admin/` |
|
||||
| `shared/Database.php` | `lib/Database.php` |
|
||||
| `shared/config.php` | `lib/config.php` |
|
||||
| `shared/cache/` | `lib/cache/` |
|
||||
| `shared/Database.php` | `src/Database.php` |
|
||||
| `shared/config.php` | `src/config.php` |
|
||||
| `shared/cache/` | `src/cache/` |
|
||||
|
||||
### Path Updates
|
||||
|
||||
|
||||
@@ -96,9 +96,9 @@ echo "vendor/" >> .gitignore
|
||||
| `apps/public/inc/header.php` | `inc/header.php` |
|
||||
| `apps/public/assets/posterg.css` | `assets/posterg.css` |
|
||||
| `apps/admin/index.php` | `admin/index.php` |
|
||||
| `shared/Database.php` | `lib/Database.php` |
|
||||
| `shared/config.php` | `lib/config.php` |
|
||||
| `shared/cache/` | `lib/cache/` |
|
||||
| `shared/Database.php` | `src/Database.php` |
|
||||
| `shared/config.php` | `src/config.php` |
|
||||
| `shared/cache/` | `src/cache/` |
|
||||
|
||||
## Deployment Changes
|
||||
|
||||
|
||||
@@ -138,7 +138,7 @@ and serve files through a dedicated PHP endpoint that validates access rights.
|
||||
|
||||
### 5. Rate Limiter Vulnerable to IP Spoofing
|
||||
|
||||
**File:** `lib/RateLimit.php` — method `getClientIdentifier()`
|
||||
**File:** `src/RateLimit.php` — method `getClientIdentifier()`
|
||||
|
||||
```php
|
||||
if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
|
||||
@@ -373,7 +373,7 @@ define('DATABASE_PATH', APP_ROOT . '/database/test.db');
|
||||
```
|
||||
|
||||
This constant is never used anywhere. `Database.php` uses `getDatabasePath()` from
|
||||
`lib/config.php`. The duplicate creates confusion about which configuration is
|
||||
`src/config.php`. The duplicate creates confusion about which configuration is
|
||||
authoritative and could lead to future bugs if someone uses the wrong one.
|
||||
|
||||
**Fix:** Remove the `DATABASE_PATH` define from `bootstrap.php`.
|
||||
|
||||
@@ -111,7 +111,7 @@ include APP_ROOT . '/includes/header.php';
|
||||
|---------|-------------|----------------------------|
|
||||
| Purpose | Reusable library | Single website |
|
||||
| Structure | Complex (PSR-4, namespaces) | Simple (includes, classes) |
|
||||
| Directories | `src/`, `resources/`, `var/`, `bin/` | `public/`, `includes/`, `lib/` |
|
||||
| Directories | `src/`, `resources/`, `var/`, `bin/` | `public/`, `includes/`, `src/` |
|
||||
| Autoloading | PSR-4 namespaces | Simple require statements |
|
||||
| Config | Complex bootstrap with many constants | Minimal bootstrap |
|
||||
| Caching | `var/cache/` with framework | Simple file-based if needed |
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
| 1 | No HTTPS — admin credentials exposed in transit | 🔴 CRITICAL | **TLS is terminated upstream by the reverse proxy** (outside nginx). nginx.conf does not need to handle TLS directly. |
|
||||
| 3 | Uploaded files stored inside the webroot | 🟠 HIGH | Storage moved to `STORAGE_ROOT` (`/var/www/posterg/storage/`), defined in `config/bootstrap.php`. `formulaire.php` updated. |
|
||||
| 4 | File path mismatch — media files broken and insecure | 🟠 HIGH | DB paths are now storage-relative (`theses/YEAR/ID/file`, `covers/file`). New controller `public/media.php` serves files safely. `memoire.php` and `search.php` updated to use `/media.php?path=…`. Cover recording in `formulaire.php` fixed (was never inserted into DB). |
|
||||
| 5 | Rate limiter bypassed by IP spoofing (`X-Forwarded-For`) | 🟠 HIGH | `lib/RateLimit.php` `getClientIdentifier()` now uses `REMOTE_ADDR` only. |
|
||||
| 5 | Rate limiter bypassed by IP spoofing (`X-Forwarded-For`) | 🟠 HIGH | `src/RateLimit.php` `getClientIdentifier()` now uses `REMOTE_ADDR` only. |
|
||||
| 6 | `.htaccess` security rules silently ignored by nginx | 🟠 HIGH | All rules ported to `nginx/posterg.conf` (CSP to `/admin/` block, `.log` denial, `autoindex off`). See `nginx/HTACCESS_TO_NGINX.md`. |
|
||||
| 13 | Deprecated `X-XSS-Protection` header | 🔵 LOW | **Removed** from `nginx/posterg.conf`; see `nginx/SECURITY_HEADERS.md` for rationale. |
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
|
||||
| # | Issue | Severity | Resolution |
|
||||
|---|-------|----------|------------|
|
||||
| 2 | No PHP-level authentication in admin panel | 🔴 CRITICAL | `lib/AdminAuth.php` implements a session guard with `password_verify` + `session_regenerate_id`. All admin PHP files now call `AdminAuth::requireLogin()` instead of bare `session_start()`. Credentials stored in gitignored `config/admin_credentials.php` (define `ADMIN_PASSWORD_HASH`). No-op when constant is absent (dev / cli-server). Also resolves item #8 (session cookie hardening via `session_set_cookie_params` before `session_start`). See `nginx/PHP_AUTH_LAYER.md`. |
|
||||
| 2 | No PHP-level authentication in admin panel | 🔴 CRITICAL | `src/AdminAuth.php` implements a session guard with `password_verify` + `session_regenerate_id`. All admin PHP files now call `AdminAuth::requireLogin()` instead of bare `session_start()`. Credentials stored in gitignored `config/admin_credentials.php` (define `ADMIN_PASSWORD_HASH`). No-op when constant is absent (dev / cli-server). Also resolves item #8 (session cookie hardening via `session_set_cookie_params` before `session_start`). See `nginx/PHP_AUTH_LAYER.md`. |
|
||||
| 8 | Session cookies not hardened (`Secure`, `HttpOnly`, `SameSite` missing) | 🟡 MEDIUM | **Resolved as part of item #2.** `AdminAuth::startSession()` sets `HttpOnly=true`, `SameSite=Strict`, `Secure=true` (off on cli-server), `Path=/admin`, `Lifetime=0` before every `session_start()`. |
|
||||
|
||||
---
|
||||
|
||||
Reference in New Issue
Block a user