Add comprehensive security audit (86 findings across 10 areas)

Secure dev auth with signed tokens, add email support for --user
Simplify breakpoint variables, suppress Sass deprecation warnings

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
root
2025-12-19 01:14:31 +00:00
parent ee87bc6297
commit f67c88a4f1
10 changed files with 270 additions and 35 deletions

View File

@@ -15,6 +15,8 @@ use App\RSpade\Core\Ajax\Exceptions\AjaxFormErrorException;
use App\RSpade\Core\Ajax\Exceptions\AjaxFatalErrorException;
use App\RSpade\Core\Session\Session;
use App\RSpade\Core\Debug\Debugger;
use App\RSpade\Core\Models\Login_User_Model;
use App\RSpade\Core\Models\Site_Model;
/**
* RSX Ajax Command
@@ -32,10 +34,11 @@ use App\RSpade\Core\Debug\Debugger;
* USAGE EXAMPLES:
* php artisan rsx:ajax Controller action # Basic call
* php artisan rsx:ajax Controller action --args='{"id":1}' # With params
* php artisan rsx:ajax Controller action --site-id=1 # With site context
* php artisan rsx:ajax Controller action --user-id=1 --site-id=1 # Full context
* php artisan rsx:ajax Controller action --site=1 # With site context
* php artisan rsx:ajax Controller action --user=1 --site=1 # Full context
* php artisan rsx:ajax Controller action --user=admin@test.com # User by email
* php artisan rsx:ajax Controller action --debug # HTTP-like response
* php artisan rsx:ajax Controller action --verbose --site-id=1 # Show context
* php artisan rsx:ajax Controller action --verbose --site=1 # Show context
*
* OUTPUT FORMAT:
* Default: {"records":[...], "total":10}
@@ -62,8 +65,8 @@ class Ajax_Debug_Command extends Command
{controller : The RSX controller name}
{action : The action/method name}
{--args= : JSON-encoded arguments to pass to the action}
{--user-id= : Set user ID for session context}
{--site-id= : Set site ID for session context}
{--user= : Set user ID or email for session context}
{--site= : Set site ID for session context}
{--debug : Wrap output in HTTP-like response format (success, _ajax_return_value, console_debug)}
{--show-context : Show request context before JSON output}';
@@ -96,11 +99,29 @@ class Ajax_Debug_Command extends Command
}
// Get options
$user_id = $this->option('user-id');
$site_id = $this->option('site-id');
$user_input = $this->option('user');
$site_input = $this->option('site');
$debug_mode = $this->option('debug');
$show_context = $this->option('show-context');
// Validate and resolve user
$user_id = null;
if ($user_input !== null) {
$user_id = $this->resolve_user($user_input);
if ($user_id === null) {
return 1; // Error already displayed
}
}
// Validate site
$site_id = null;
if ($site_input !== null) {
$site_id = $this->resolve_site($site_input);
if ($site_id === null) {
return 1; // Error already displayed
}
}
// Rotate logs before test
Debugger::logrotate();
@@ -205,4 +226,66 @@ class Ajax_Debug_Command extends Command
$this->output_json($error);
}
/**
* Resolve user identifier to user ID
*
* Accepts either a numeric user ID or an email address.
* Validates that the user exists in the database.
*
* @param string $user_input User ID or email address
* @return int|null User ID or null if not found (error already displayed)
*/
protected function resolve_user(string $user_input): ?int
{
// Check if input is an email address
if (str_contains($user_input, '@')) {
$login_user = Login_User_Model::find_by_email($user_input);
if (!$login_user) {
$this->output_json_error("User not found: {$user_input}", 'user_not_found');
return null;
}
return $login_user->id;
}
// Input is a user ID - validate it exists
if (!ctype_digit($user_input)) {
$this->output_json_error("Invalid user identifier: {$user_input} (must be numeric ID or email address)", 'invalid_user');
return null;
}
$user_id = (int) $user_input;
$login_user = Login_User_Model::find($user_id);
if (!$login_user) {
$this->output_json_error("User ID not found: {$user_id}", 'user_not_found');
return null;
}
return $user_id;
}
/**
* Resolve site identifier to site ID
*
* Validates that the site exists in the database.
*
* @param string $site_input Site ID
* @return int|null Site ID or null if not found (error already displayed)
*/
protected function resolve_site(string $site_input): ?int
{
if (!ctype_digit($site_input)) {
$this->output_json_error("Invalid site identifier: {$site_input} (must be numeric ID)", 'invalid_site');
return null;
}
$site_id = (int) $site_input;
$site = Site_Model::find($site_id);
if (!$site) {
$this->output_json_error("Site ID not found: {$site_id}", 'site_not_found');
return null;
}
return $site_id;
}
}