Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
8b84cc8
all the things.
ljonesfl Nov 6, 2025
5199748
Update src/Cms/Auth/AuthManager.php
ljonesfl Nov 6, 2025
a0a0348
Update src/Cms/Auth/AuthManager.php
ljonesfl Nov 6, 2025
73eea63
Update src/Cms/Auth/AuthManager.php
ljonesfl Nov 6, 2025
f984ce4
Update tests/Cms/Cli/Commands/User/CreateCommandTest.php
ljonesfl Nov 6, 2025
bdfb232
Update resources/views/admin/layouts/admin.php
ljonesfl Nov 6, 2025
be64a81
Initial plan
Copilot Nov 6, 2025
9803c9d
Update src/Cms/Auth/Filters/AuthenticationFilter.php
ljonesfl Nov 6, 2025
050456d
Update src/Cms/Cli/Commands/Migrate/RunCommand.php
ljonesfl Nov 6, 2025
500f4f8
Fix open redirect vulnerability in login method
Copilot Nov 6, 2025
a1156fe
Update src/Cms/Cli/Commands/Maintenance/EnableCommand.php
ljonesfl Nov 6, 2025
919a209
Improve empty string check for clarity
Copilot Nov 6, 2025
c54f535
Update src/Cms/Controllers/Admin/DashboardController.php
ljonesfl Nov 6, 2025
3b5980a
Initial plan
Copilot Nov 6, 2025
f789ee8
Fix open redirect vulnerability in LoginController
Copilot Nov 6, 2025
087f6bb
Add protection against protocol-relative URLs
Copilot Nov 6, 2025
1c6126c
Merge pull request #4 from Neuron-PHP/copilot/sub-pr-1-another-one
ljonesfl Nov 6, 2025
f299a15
Merge branch 'feature/auth' into copilot/sub-pr-1
ljonesfl Nov 6, 2025
8c01387
fixed bugs
ljonesfl Nov 7, 2025
9b531ad
adds database, auth, basic admin site, blog and installer.
ljonesfl Nov 9, 2025
c5e0ae9
Merge pull request #2 from Neuron-PHP/copilot/sub-pr-1
ljonesfl Nov 9, 2025
6ad5a9f
Merge branch 'feature/auth' of github.com:Neuron-PHP/cms into feature…
ljonesfl Nov 9, 2025
936b2a9
Initial plan
Copilot Nov 9, 2025
8c2649a
Add path traversal protection to MaintenanceFilter custom view
Copilot Nov 9, 2025
4de0ad1
Improve path traversal detection to allow filenames with double dots
Copilot Nov 9, 2025
f011586
Merge pull request #5 from Neuron-PHP/copilot/sub-pr-1
ljonesfl Nov 9, 2025
03e410a
fixes for github action tests. Adds rss feed to public site.
ljonesfl Nov 9, 2025
c6e3809
Merge branch 'feature/auth' of github.com:Neuron-PHP/cms into feature…
ljonesfl Nov 9, 2025
0b9b02b
fixes for github action tests. Adds rss feed to public site.
ljonesfl Nov 9, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
"ext-json": "*",
"neuron-php/mvc": "0.8.*",
"neuron-php/cli": "0.8.*",
"ljonesfl/blahg": "0.5.*"
"neuron-php/jobs": "0.2.*",
"phpmailer/phpmailer": "^6.9"
},
"require-dev": {
"phpunit/phpunit": "9.*",
Expand All @@ -25,12 +26,20 @@
"Neuron\\": "src/"
},
"files": [
"src/Bootstrap.php"
"src/Bootstrap.php",
"src/Cms/Auth/helpers.php",
"src/Cms/Email/helpers.php",
"src/Cms/View/helpers.php"
]
},
"autoload-dev": {
"psr-4": {
"Tests\\": "tests/"
}
},
"extra": {
"neuron": {
"cli-provider": "Neuron\\Cms\\Cli\\Provider"
}
}
}
40 changes: 40 additions & 0 deletions config/auth.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Authentication Configuration
# Configuration for the Neuron CMS authentication system

auth:
# Default authentication driver
default: session

# Session configuration
session:
lifetime: 120 # Session lifetime in minutes (2 hours)
expire_on_close: false
cookie_name: neuron_session
cookie_httponly: true
cookie_secure: true # Set to true for HTTPS only
cookie_samesite: Lax # Lax, Strict, or None

# Remember me configuration
remember:
enabled: true
lifetime: 43200 # 30 days in minutes

# Password configuration
passwords:
min_length: 8
require_uppercase: true
require_lowercase: true
require_numbers: true
require_special_chars: false
hash_algorithm: argon2id # argon2id or bcrypt

# Login throttling (brute force protection)
throttle:
enabled: true
max_attempts: 5 # Max failed attempts before lockout
lockout_duration: 15 # Lockout duration in minutes

# User storage
storage:
type: file # file or database (future)
path: storage/users # Path for file-based storage
28 changes: 28 additions & 0 deletions debug-maintenance.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

require_once __DIR__ . '/vendor/autoload.php';

use Neuron\Cms\Maintenance\MaintenanceManager;

$basePath = getcwd();
$manager = new MaintenanceManager($basePath);

echo "Maintenance Status Check\n";
echo "========================\n\n";

echo "Base Path: $basePath\n";
echo "Maintenance File: " . $basePath . "/.maintenance.json\n";
echo "File Exists: " . (file_exists($basePath . '/.maintenance.json') ? 'Yes' : 'No') . "\n\n";

if (file_exists($basePath . '/.maintenance.json')) {
echo "File Contents:\n";
echo file_get_contents($basePath . '/.maintenance.json') . "\n\n";
}

echo "Is Enabled: " . ($manager->isEnabled() ? 'Yes' : 'No') . "\n";
echo "Message: " . $manager->getMessage() . "\n";
echo "Retry After: " . $manager->getRetryAfter() . "\n\n";

$status = $manager->getStatus();
echo "Full Status:\n";
print_r($status);
Comment on lines +1 to +28
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Debug script should not be in version control or deployed to production.

This debug script exposes maintenance configuration details and file paths, which could provide attackers with information about the application structure. It has no authentication or authorization checks.

Options:

  1. Remove from version control - Add to .gitignore and delete:

    echo "debug-maintenance.php" >> .gitignore
    git rm debug-maintenance.php
    
  2. Move to a development-only location - Place in a dev/ or scripts/ directory that's excluded from production deployments

  3. Add authentication - If this must be accessible, add authentication:

    <?php
    // Only allow in development or with valid auth
    if( getenv('APP_ENV') === 'production' ) {
        http_response_code(404);
        exit('Not found');
    }

Recommendation: Remove from version control as it's a temporary debugging tool.

🤖 Prompt for AI Agents
In debug-maintenance.php around lines 1 to 28, this debug script exposes
internal maintenance configuration and file paths without any authentication and
should not be in version control or deployed to production; remove the file from
the repo and add it to .gitignore (or move it to a dev-only scripts/ or dev/
directory that is excluded from production deployments), or if it must remain in
the tree wrap it with strict environment gating so it only runs in
non-production environments (e.g., bail out when APP_ENV=production) and add
authentication/authorization checks before printing any sensitive info.

202 changes: 172 additions & 30 deletions examples/config/routes.yaml
Original file line number Diff line number Diff line change
@@ -1,32 +1,174 @@
# CMS Routes Configuration
# Admin routes with authentication

routes:
login:
# Authentication routes
- method: GET
route: /login
controller: Neuron\Cms\Controllers\Auth\LoginController@showLoginForm

- method: POST
route: /login
method: POST
controller: App\Controllers\AuthController@login
request: login

test:
route: /test
method: POST
controller: Mvc\TestController@test
request: test

put:
route: /test_put
method: PUT
controller: Mvc\TestController@test

delete:
route: /test_delete
method: DELETE
controller: Mvc\TestController@test

no_request:
route: /no_request
method: GET
controller: Mvc\TestController@no_request

bad_request:
route: /bad_request
method: GET
controller: Mvc\TestController@bad_request
controller: Neuron\Cms\Controllers\Auth\LoginController@login

- method: POST
route: /logout
controller: Neuron\Cms\Controllers\Auth\LoginController@logout
filter: auth

# Admin Dashboard
- method: GET
route: /admin
controller: Neuron\Cms\Controllers\Admin\DashboardController@index
filter: auth

- method: GET
route: /admin/dashboard
controller: Neuron\Cms\Controllers\Admin\DashboardController@index
filter: auth

# User Management
- method: GET
route: /admin/users
controller: Neuron\Cms\Controllers\Admin\UserController@index
filter: auth

- method: GET
route: /admin/users/create
controller: Neuron\Cms\Controllers\Admin\UserController@create
filter: auth

- method: POST
route: /admin/users
controller: Neuron\Cms\Controllers\Admin\UserController@store
filter: auth

- method: GET
route: /admin/users/:id/edit
controller: Neuron\Cms\Controllers\Admin\UserController@edit
filter: auth

- method: PUT
route: /admin/users/:id
controller: Neuron\Cms\Controllers\Admin\UserController@update
filter: auth

- method: DELETE
route: /admin/users/:id
controller: Neuron\Cms\Controllers\Admin\UserController@destroy
filter: auth

# Profile Management
- method: GET
route: /admin/profile
controller: Neuron\Cms\Controllers\Admin\ProfileController@edit
filter: auth

- method: PUT
route: /admin/profile
controller: Neuron\Cms\Controllers\Admin\ProfileController@update
filter: auth

# Settings
- method: GET
route: /admin/settings
controller: Neuron\Cms\Controllers\Admin\SettingsController@index
filter: auth

- method: PUT
route: /admin/settings
controller: Neuron\Cms\Controllers\Admin\SettingsController@update
filter: auth

# Blog Post Management
- method: GET
route: /admin/posts
controller: Neuron\Cms\Controllers\Admin\PostController@index
filter: auth

- method: GET
route: /admin/posts/create
controller: Neuron\Cms\Controllers\Admin\PostController@create
filter: auth

- method: POST
route: /admin/posts
controller: Neuron\Cms\Controllers\Admin\PostController@store
filter: auth

- method: GET
route: /admin/posts/:id/edit
controller: Neuron\Cms\Controllers\Admin\PostController@edit
filter: auth

- method: PUT
route: /admin/posts/:id
controller: Neuron\Cms\Controllers\Admin\PostController@update
filter: auth

- method: DELETE
route: /admin/posts/:id
controller: Neuron\Cms\Controllers\Admin\PostController@destroy
filter: auth

# Blog Category Management
- method: GET
route: /admin/categories
controller: Neuron\Cms\Controllers\Admin\CategoryController@index
filter: auth

- method: GET
route: /admin/categories/create
controller: Neuron\Cms\Controllers\Admin\CategoryController@create
filter: auth

- method: POST
route: /admin/categories
controller: Neuron\Cms\Controllers\Admin\CategoryController@store
filter: auth

- method: GET
route: /admin/categories/:id/edit
controller: Neuron\Cms\Controllers\Admin\CategoryController@edit
filter: auth

- method: PUT
route: /admin/categories/:id
controller: Neuron\Cms\Controllers\Admin\CategoryController@update
filter: auth

- method: DELETE
route: /admin/categories/:id
controller: Neuron\Cms\Controllers\Admin\CategoryController@destroy
filter: auth

# Blog Tag Management
- method: GET
route: /admin/tags
controller: Neuron\Cms\Controllers\Admin\TagController@index
filter: auth

- method: GET
route: /admin/tags/create
controller: Neuron\Cms\Controllers\Admin\TagController@create
filter: auth

- method: POST
route: /admin/tags
controller: Neuron\Cms\Controllers\Admin\TagController@store
filter: auth

- method: GET
route: /admin/tags/:id/edit
controller: Neuron\Cms\Controllers\Admin\TagController@edit
filter: auth

- method: PUT
route: /admin/tags/:id
controller: Neuron\Cms\Controllers\Admin\TagController@update
filter: auth

- method: DELETE
route: /admin/tags/:id
controller: Neuron\Cms\Controllers\Admin\TagController@destroy
filter: auth
Empty file added examples/db/migrate/.gitkeep
Empty file.
Empty file added examples/db/seed/.gitkeep
Empty file.
Loading