Prepare Beta Version
This commit is contained in:
@ -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;
|
||||
}
|
20
src/Application/Loggers/Contracts/SystemLoggerInterface.php
Normal file
20
src/Application/Loggers/Contracts/SystemLoggerInterface.php
Normal 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;
|
||||
}
|
@ -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;
|
||||
}
|
70
src/Application/Loggers/KonekoSecurityAuditLogger.php
Normal file
70
src/Application/Loggers/KonekoSecurityAuditLogger.php
Normal 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 [];
|
||||
}
|
||||
}
|
||||
}
|
51
src/Application/Loggers/KonekoSecurityLogger.php
Normal file
51
src/Application/Loggers/KonekoSecurityLogger.php
Normal 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,
|
||||
]);
|
||||
}
|
||||
}
|
72
src/Application/Loggers/KonekoSystemLogger.php
Normal file
72
src/Application/Loggers/KonekoSystemLogger.php
Normal 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;
|
||||
}
|
||||
}
|
47
src/Application/Loggers/KonekoUserInteractionLogger.php
Normal file
47
src/Application/Loggers/KonekoUserInteractionLogger.php
Normal 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(),
|
||||
]);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user