* * @version 1.0.0 */ class Arco extends Model { protected $table = 'arcos'; protected $fillable = [ 'nombre', 'ip_address', 'ubicacion', 'activo', 'antena_1', 'antena_2', 'antena_3', 'antena_4' ]; protected $casts = [ 'activo' => 'boolean', 'created_at' => 'datetime', 'updated_at' => 'datetime' ]; protected $hidden = [ 'api_token' ]; protected static function boot() { parent::boot(); static::creating(function ($arco) { if (!$arco->api_token) { $plainToken = Str::random(64); $arco->api_token = EncryptionHelper::encryptWithCustomKey( $plainToken, self::getEncryptionKey() ); } }); } /** * Obtener la clave de encriptación personalizada para tokens de arcos */ private static function getEncryptionKey(): string { $key = config('app.arco_token_encryption_key'); if (empty($key)) { throw new \RuntimeException('ARCO_TOKEN_ENCRYPTION_KEY no está configurada en .env'); } // Si la clave está en formato base64:xxxx, decodificarla if (str_starts_with($key, 'base64:')) { return base64_decode(substr($key, 7)); } return $key; } /** * Relación con detecciones */ public function detecciones(): HasMany { return $this->hasMany(Detection::class, 'arco_id'); } /** * Scope para obtener solo arcos activos */ public function scopeActivos($query) { return $query->where('activo', true); } /** * Buscar arco por IP */ public static function buscarPorIp(string $ip): ?self { return self::where('ip_address', $ip)->first(); } /** * Buscar arco por API token (recibe token plano, busca desencriptando) */ public static function buscarPorToken(string $tokenPlano): ?self { $arcos = self::all(); foreach ($arcos as $arco) { // Desencriptar el token de la BD y comparar con el token plano recibido if (EncryptionHelper::verifyWithCustomKey($tokenPlano, $arco->api_token, self::getEncryptionKey())) { return $arco; } } return null; } /** * Regenerar token encriptado */ public function regenerarToken(): string { $plainToken = Str::random(64); $this->api_token = EncryptionHelper::encryptWithCustomKey( $plainToken, self::getEncryptionKey() ); $this->save(); return $plainToken; } /** * Obtener token desencriptado */ public function obtenerTokenDesencriptado(): ?string { return EncryptionHelper::decryptWithCustomKey($this->api_token, self::getEncryptionKey()); } }