This commit is contained in:
Renan Bernordi 2026-07-24 18:54:23 -03:00
parent 3453b1efd6
commit 65ff1bd88f
7 changed files with 53 additions and 10 deletions

View file

@ -5,8 +5,15 @@ declare(strict_types=1);
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Cache;
final class BlockedDomain extends Model
{
protected $fillable = ['domain', 'reason'];
protected static function booted(): void
{
static::saved(fn () => Cache::forget('marreta.blocked_domains'));
static::deleted(fn () => Cache::forget('marreta.blocked_domains'));
}
}

View file

@ -5,8 +5,15 @@ declare(strict_types=1);
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Cache;
final class DmcaDomain extends Model
{
protected $fillable = ['host', 'message'];
protected static function booted(): void
{
static::saved(fn () => Cache::forget('marreta.dmca_domains'));
static::deleted(fn () => Cache::forget('marreta.dmca_domains'));
}
}

View file

@ -5,6 +5,7 @@ declare(strict_types=1);
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Cache;
final class DomainRule extends Model
{
@ -17,4 +18,10 @@ final class DomainRule extends Model
'is_active' => 'boolean',
];
}
protected static function booted(): void
{
static::saved(fn () => Cache::forget('marreta.domain_rules'));
static::deleted(fn () => Cache::forget('marreta.domain_rules'));
}
}

View file

@ -5,6 +5,7 @@ declare(strict_types=1);
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Cache;
final class GlobalRuleSet extends Model
{
@ -21,4 +22,10 @@ final class GlobalRuleSet extends Model
{
return self::latest('id')->first();
}
protected static function booted(): void
{
static::saved(fn () => Cache::forget('marreta.global_rules'));
static::deleted(fn () => Cache::forget('marreta.global_rules'));
}
}

View file

@ -4,6 +4,8 @@ namespace App\Models;
// use Illuminate\Contracts\Auth\MustVerifyEmail;
use Database\Factories\UserFactory;
use Filament\Models\Contracts\FilamentUser;
use Filament\Panel;
use Illuminate\Database\Eloquent\Attributes\Fillable;
use Illuminate\Database\Eloquent\Attributes\Hidden;
use Illuminate\Database\Eloquent\Factories\HasFactory;
@ -12,11 +14,16 @@ use Illuminate\Notifications\Notifiable;
#[Fillable(['name', 'email', 'password'])]
#[Hidden(['password', 'remember_token'])]
class User extends Authenticatable
class User extends Authenticatable implements FilamentUser
{
/** @use HasFactory<UserFactory> */
use HasFactory, Notifiable;
public function canAccessPanel(Panel $panel): bool
{
return true;
}
/**
* Get the attributes that should be cast.
*

View file

@ -34,14 +34,18 @@ final class FetchManager
$strategies = $this->strategyMap();
// Use domain-specific fetchStrategies if set
// Use domain-specific fetchStrategies if set (falls through to the normal cascade
// when it points at the browser but no browser endpoint is configured)
$strategyName = $rules['fetchStrategies'] ?? null;
if ($strategyName && isset($strategies[$strategyName])) {
if ($strategyName && isset($strategies[$strategyName]) && $this->strategyAvailable($strategyName)) {
return $strategies[$strategyName]->fetch($url, $rules);
}
// Cascade: cURL → Wayback → Browser
$cascade = ['fetchContent', 'fetchFromWaybackMachine', 'fetchFromSelenium'];
$cascade = array_filter(
['fetchContent', 'fetchFromWaybackMachine', 'fetchFromSelenium'],
fn (string $name): bool => $this->strategyAvailable($name),
);
$lastError = null;
foreach ($cascade as $name) {
@ -72,15 +76,12 @@ final class FetchManager
'verify' => false,
'curl' => [
CURLOPT_NOBODY => true,
CURLOPT_DNS_SERVERS => implode(',', config('marreta.dns_servers', ['8.8.8.8', '8.8.4.4'])),
],
];
$headers = [
'User-Agent' => 'Mozilla/5.0 (Linux; Android 6.0.1; Nexus 5X Build/MMB29P) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.6778.200 Mobile Safari/537.36 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)',
'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36',
'Accept' => 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
'X-Forwarded-For' => '66.249.'.rand(64, 95).'.'.rand(1, 254),
'From' => 'googlebot(at)googlebot.com',
];
try {
@ -110,6 +111,14 @@ final class FetchManager
];
}
/**
* The browser strategy requires BROWSER_WS_ENDPOINT to be configured.
*/
private function strategyAvailable(string $name): bool
{
return $name !== 'fetchFromSelenium' || config('marreta.browser.ws_endpoint') !== null;
}
/**
* Apply urlMods from domain rules to modify query parameters.
*/

View file

@ -92,8 +92,7 @@ final class MarretaDataSeeder extends Seeder
$unique[$domain] = true;
BlockedDomain::create([
'domain' => (string) $domain,
'reason' => 'Imported from legacy blocked_domains.php',
'domain' => (string) $domain
]);
}
}