Prepare Beta Version

This commit is contained in:
2025-05-29 10:05:27 -06:00
parent a7002701f5
commit ea6b04f3f4
254 changed files with 5653 additions and 6569 deletions

View File

@ -0,0 +1,16 @@
<?php
namespace Koneko\VuexyAdmin\Application\Contracts\Loggers;
use Illuminate\Http\Request;
interface SecurityLoggerInterface
{
public function logEvent(
string $type,
?Request $request = null,
?int $userId = null,
array $payload = [],
bool $isProxy = false
): void;
}

View File

@ -0,0 +1,20 @@
<?php
namespace Koneko\VuexyAdmin\Application\Contracts\Loggers;
use Illuminate\Database\Eloquent\Model;
use Koneko\VuexyAdmin\Application\Enums\SystemLog\LogTriggerType;
use Koneko\VuexyAdmin\Application\Enums\SystemLog\LogLevel;
use Koneko\VuexyAdmin\Models\SystemLog;
interface SystemLoggerInterface
{
public function log(
string|LogLevel $level,
string $message,
array $context = [],
?Model $relatedModel = null,
LogTriggerType $triggerType = LogTriggerType::System,
?int $triggerId = null
): SystemLog;
}

View File

@ -0,0 +1,16 @@
<?php
namespace Koneko\VuexyAdmin\Application\Contracts\Loggers;
use Koneko\VuexyAdmin\Application\Enums\UserInteractions\InteractionSecurityLevel;
use Koneko\VuexyAdmin\Models\UserInteraction;
interface UserInteractionLoggerInterface
{
public function record(
string $action,
array $context = [],
InteractionSecurityLevel|string $security = 'normal',
?string $livewireComponent = null
): ?UserInteraction;
}

View File

@ -0,0 +1,70 @@
<?php
declare(strict_types=1);
namespace Koneko\VuexyAdmin\Application\Loggers;
use GeoIp2\Database\Reader;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Jenssegers\Agent\Agent;
use Koneko\VuexyAdmin\Models\SecurityEvent;
class KonekoSecurityAuditLogger
{
/**
* Registra un nuevo evento de seguridad.
*/
public function logEvent(string $type, Request $request, ?int $userId = null, array $payload = [], bool $isProxy = false)
{
$agent = new Agent();
$ip = $request->ip();
$geoData = $this->getGeoData($ip);
SecurityEvent::create([
'user_id' => $userId,
'event_type' => $type,
'status' => 'new',
'ip_address' => $ip,
'user_agent' => $request->userAgent(),
'device_type' => $agent->device(),
'browser' => $agent->browser(),
'browser_version' => $agent->version($agent->browser()),
'os' => $agent->platform(),
'os_version' => $agent->version($agent->platform()),
'country' => $geoData['country'] ?? null,
'region' => $geoData['region'] ?? null,
'city' => $geoData['city'] ?? null,
'lat' => $geoData['latitude'] ?? null,
'lng' => $geoData['longitude'] ?? null,
'is_proxy' => $isProxy,
'url' => $request->fullUrl(),
'http_method' => $request->method(),
'payload' => json_encode($payload),
]);
}
/**
* Obtiene datos de geolocalización usando MaxMind GeoIP2.
*/
private function getGeoData(string $ip): array
{
try {
$reader = new Reader(public_path('vendor/geoip/GeoLite2-City.mmdb'));
$record = $reader->city($ip);
return [
'country' => $record->country->name,
'region' => $record->mostSpecificSubdivision->name,
'city' => $record->city->name,
'latitude' => $record->location->latitude,
'longitude' => $record->location->longitude,
];
} catch (\Exception $e) {
Log::warning("GeoIP falló para IP: {$ip} - {$e->getMessage()}");
return [];
}
}
}

View File

@ -0,0 +1,51 @@
<?php
namespace Koneko\VuexyAdmin\Application\Loggers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Jenssegers\Agent\Agent;
use Koneko\VuexyAdmin\Support\Enums\SecurityEvents\SecurityEventStatus;
use Koneko\VuexyAdmin\Support\Enums\SecurityEvents\SecurityEventType;
use Koneko\VuexyAdmin\Application\Bootstrap\Registry\KonekoModuleRegistry;
use Koneko\VuexyAdmin\Models\SecurityEvent;
use Koneko\VuexyAdmin\Support\Geo\GeoLocationResolver;
class KonekoSecurityLogger
{
public static function log(
SecurityEventType|string $type,
?Request $request = null,
?int $userId = null,
array $payload = [],
bool $isProxy = false
): ?SecurityEvent {
$request ??= request();
$agent = new Agent(null, $request->userAgent());
$geo = GeoLocationResolver::resolve($request->ip());
return SecurityEvent::create([
'module' => KonekoModuleRegistry::current()->componentNamespace ?? 'unknown',
'user_id' => $userId ?? Auth::id(),
'event_type' => (string) $type,
'status' => SecurityEventStatus::NEW,
'ip_address' => $request->ip(),
'user_agent' => $request->userAgent(),
'device_type' => $agent->device() ?: ($geo['device_type'] ?? null),
'browser' => $agent->browser() ?: ($geo['browser'] ?? null),
'browser_version' => $agent->version($agent->browser()) ?: ($geo['browser_version'] ?? null),
'os' => $agent->platform() ?: ($geo['os'] ?? null),
'os_version' => $agent->version($agent->platform()) ?: ($geo['os_version'] ?? null),
'country' => $geo['country'] ?? null,
'region' => $geo['region'] ?? null,
'city' => $geo['city'] ?? null,
'lat' => $geo['lat'] ?? null,
'lng' => $geo['lng'] ?? null,
'is_proxy' => $isProxy,
'url' => $request->fullUrl(),
'http_method' => $request->method(),
'payload' => $payload,
]);
}
}

View File

@ -0,0 +1,72 @@
<?php
namespace Koneko\VuexyAdmin\Application\Loggers;
use Illuminate\Database\Eloquent\Model;
use Koneko\VuexyAdmin\Application\Bootstrap\Registry\KonekoModuleRegistry;
use Koneko\VuexyAdmin\Models\SystemLog;
use Koneko\VuexyAdmin\Support\Enums\SystemLog\LogLevel;
use Koneko\VuexyAdmin\Support\Enums\SystemLog\LogTriggerType;
use Illuminate\Support\Facades\Auth;
/**
* ✨ Logger de sistema contextual para el ecosistema Koneko
*/
class KonekoSystemLogger
{
protected string $component;
public function __construct(?string $component = null)
{
$this->component = $component ?? KonekoModuleRegistry::current()->componentNamespace ?? 'core';
}
public function log(
LogLevel|string $level,
string $message,
array $context = [],
LogTriggerType|string $triggerType = LogTriggerType::System,
?int $triggerId = null,
?Model $relatedModel = null
): SystemLog {
return SystemLog::create([
'module' => $this->component,
'user_id' => Auth::id(),
'level' => $level instanceof LogLevel ? $level->value : $level,
'message' => $message,
'context' => $context,
'trigger_type' => $triggerType instanceof LogTriggerType ? $triggerType->value : $triggerType,
'trigger_id' => $triggerId,
'loggable_id' => $relatedModel?->getKey(),
'loggable_type'=> $relatedModel?->getMorphClass(),
]);
}
public function info(string $message, array $context = []): SystemLog
{
return $this->log(LogLevel::Info, $message, $context);
}
public function warning(string $message, array $context = []): SystemLog
{
return $this->log(LogLevel::Warning, $message, $context);
}
public function error(string $message, array $context = []): SystemLog
{
return $this->log(LogLevel::Error, $message, $context);
}
public function debug(string $message, array $context = []): SystemLog
{
return $this->log(LogLevel::Debug, $message, $context);
}
public function withTrigger(LogTriggerType|string $type, ?int $id = null): static
{
$clone = clone $this;
$clone->triggerType = $type;
$clone->triggerId = $id;
return $clone;
}
}

View File

@ -0,0 +1,47 @@
<?php
declare(strict_types=1);
namespace Koneko\VuexyAdmin\Application\Loggers;
use Illuminate\Support\Facades\Request;
use Illuminate\Support\Facades\Auth;
use Koneko\VuexyAdmin\Application\Bootstrap\Registry\KonekoModuleRegistry;
use Koneko\VuexyAdmin\Models\UserInteraction;
use Koneko\VuexyAdmin\Models\User;
use Koneko\VuexyAdmin\Support\Enums\UserInteractions\InteractionSecurityLevel;
/**
* 📋 Logger de interacciones de usuario con nivel de seguridad.
*/
class KonekoUserInteractionLogger
{
public static function record(
string $action,
array $context = [],
InteractionSecurityLevel|string $security = 'normal',
?string $livewireComponent = null,
?int $userId = null
): ?UserInteraction {
$userId = $userId ?? Auth::id();
if (!$userId) {
return null;
}
/** @var User $user */
$user = Auth::user();
return UserInteraction::create([
'module' => KonekoModuleRegistry::current()->componentNamespace ?? 'core',
'user_id' => $userId,
'action' => $action,
'livewire_component'=> $livewireComponent,
'security_level' => is_string($security) ? InteractionSecurityLevel::from($security) : $security,
'ip_address' => Request::ip(),
'user_agent' => Request::userAgent(),
'context' => $context,
'user_flags' => $user->flags_array ?? [],
'user_roles' => $user->getRoleNames()->toArray(),
]);
}
}