Always use "chattr +i" on backup files!
IMPORTANT:
Always use "chattr +i" on backup files to prevent accidental overwrites...
and of course, use "chmod -w" as a fallback if the chattr is not supported or permitted...
Prevent "Page Expired" errors in Laravel PEST testing with "actingAs"
If you want to test a POST route without loading a page first it will not work:
actingAs($user) ...
1test('users can logout', function () {
2 $user = User::factory()->create();
3
4 $response = $this->actingAs($user)
5 ->post(route('logout-user'));
6
7 $response->assertRedirect(route('filament.user.pages..'));
8
9 $this->assertGuest();
10});
It will return a 419 status ("Page expired"), because the "CSRF" token will not be set.
(no session is started at the post request)
You MUST initialize the CSRF token before the post call:
Start session -or - Regenerate CSRF token (starts the session as well) ...
1test('users can logout', function () {
2 ...
3 session()->start(); // OR session()->regenerateToken();
4
5 $response = $this->actingAs($user)->post(route('logout-user'));
6 ...
7});
And it still will not work, the csrf_token must be passed with the post request:
Sample code... ...
1test('users can logout', function () {
2 ...
3 $response = $this
4 ->actingAs($user)
5 ->post(route('logout-user'), [
6 '_token' => csrf_token(),
7 ]);
8 ...
9});
-OR- add an empty array to the (non jet existing) session:
Sample code... ...
1test('users can logout', function () {
2 $user = User::factory()->create();
3
4 $response = $this
5 ->actingAs($user)
6 ->session([])
7 ->post(route('logout-user'), [
8 '_token' => csrf_token(),
9 ]);
10
11 $response->assertRedirect(route('filament.user.pages..'));
12
13 $this->assertGuest();
14});
So a new session will be created and a "CSRF Token" will be generated.
Filamentphp Panel with empty path name and a custom front page
In an filament panel, which has an empty panel path, and has a custom front page the root ('/') path is named "filament.user.pages..", with two dots at the end!
panel definition ...
1class UserPanelProvider extends PanelProvider
2{
3 public function panel(Panel $panel): Panel
4 {
5 return $panel
6 ->default()
7 ->default()
8 ->id('user')
9 ->path('')
10 ...
11 }
12}
To refer to it, it must be used like:
route by name ...
1route('filament.user.pages..')
Which is a bit odd, but hey, as long as it works...
How can this be confirmed? Easy!
route list ...
1$ php artisan route:list
route list result ...
1 GET|HEAD / ......................................... filament.user.pages.. › App\Filament\User\Pages\FrontPage
Laravel livewire upload error behind nginx/cloudflare
Infrastructure:
The laravel application is server with nginx in a docker container
The nginx forwards the real ip (real_ip_header) with one of:
X-FORWARDED-FOR
X-REAL-IP
CF-CONNECTING-IP
The application is accessible to the internet trough a cloudflare tunnel
The DNS of the domain is masked by the cloudflare tunnel
The tunnel is configured to enforce https conection
The SSL certificate is automatically provided by thecloudflare tunnel
The problem:
The livewire components generating "http://..." addresses for themself
Even if the ASSET_URL is set with https, some internally generated links will fail
The browser error:
Blocked loading mixed active content 'http://scriptum.goliath.hu/livewire/upload-file?...'
The solution:
Define Trusted Proxies.
In the "bootstrap/app.php" file mark connections as "trusted".
bootstrap/app.php ...
1return Application::configure(basePath: dirname(__DIR__))
2 ...
3 ->withMiddleware(function (Middleware $middleware) {
4 $middleware->trustProxies(at: '*');
5 })
6 ...
7 })->create();
NOTE: individual proxies can be specified, but in case of real ip forwarding, that may be not enough...
Bonus:
Set APP_URL and ASSET_URL in the ".env" file to https values...
.env values ...
1APP_URL="https://scriptum.goliath.hu"
2ASSET_URL="https://scriptum.goliath.hu"
Laravel Model Local Scoping with attributes
The new "way" of using local scopes in laravel is with using attributes.
The old way:
old way ...
1// feeds on magic...
2public function scopeLike(Builder $query, string $pattern): Builder
3{
4 return $query->where('name','like',"%$pattern%");
5}
6
7// Usage:
8User::like('foo')->get();
The new way:
new way ...
1use Illuminate\Database\Eloquent\Attributes\Scope;
2
3#[Scope]
4public function like2(Builder $query, string $pattern): Builder
5{
6 return $query->where('name','like',"%$pattern%");
7}
8
9// Usage:
10User::query()->like('foo')->get();
The new version does not work with the old query method:
Error: Non-static method App\Models\User::like() cannot be called statically.
Well, of course the scope could be declared as static method, but...
then $this is not accessible,
auto injecting the Builder does not work,
TypeError: App\Models\User::like(): Argument #1 ($query) must be of type Illuminate\Database\Eloquent\Builder, string given, called on line 1.
chaining does not work,
it is bad practice to use mismatched functions for the same functionality...
The good way:
Always use the query() method, it work in both scenarios:
the way ...
1// Usage:
2User::query()->like('foo')->get();
The old way: Laravel 11 Local Scopes
The new way: Laravel 12 Local Scopes
ChatGPT is a busy bee..
Wow, in less then 12 hours, after i created the mirror repository and uploaded my side project to github, chatgpt did crawl my live site, which was only linked in the github repository :D
Well, it was linked in the main repository as well, but that has been up for days, so it monitors github pretty intensely...
It was not denied in the robots.txt, i just wonder, if it would have been banned, would it have respected the ban?
Some notes:
It did first read the robots.txt
After that the crawler cam from a different IP
It did download all html, javascript, images, css even fonts, basically what it could find
It did not try to fill any form, only did GET requests
access log ...
14.227.36.37 - - [20/Oct/2025:22:27:46 +0000] "GET /robots.txt HTTP/1.1" 200 55 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36; compatible; OAI-SearchBot/1.0; +h
2ttps://openai.com/searchbot"
320.171.207.65 - - [20/Oct/2025:22:27:47 +0000] "GET / HTTP/1.1" 200 35202 "-" "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; GPTBot/1.2; +https://openai.com/gptbot)"
420.171.207.65 - - [20/Oct/2025:22:27:49 +0000] "GET /notes/bigfoot-mcfly/prevent-page-expired-errors-in-laravel-pest-testing-with-actingas HTTP/1.1" 200 29763 "-" "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; GPTBot/1.2; +https://openai.com/gptbot)"
520.171.207.65 - - [20/Oct/2025:22:27:53 +0000] "GET /notes/bigfoot-mcfly/always-use-chattr-i-on-backup-files HTTP/1.1" 200 28572 "-" "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; GPTBot/1.2; +https://openai.com/gptbot)"
620.171.207.65 - - [20/Oct/2025:22:27:55 +0000] "GET /notes/benedek-gerzson/how-does-laravel-withoutmodelevents-work HTTP/1.1" 200 29364 "-" "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; GPTBot/1.2; +https://openai.com/gptbot)"
720.171.207.65 - - [20/Oct/2025:22:27:58 +0000] "GET /storage/avatars/01K7PGM49GYJYKJ9E16AZGTJ6J.png HTTP/1.1" 200 231773 "-" "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; GPTBot/1.2; +https://openai.com/gptbot)"
820.171.207.65 - - [20/Oct/2025:22:27:59 +0000] "GET /notes/bigfoot-mcfly/filamentphp-panel-with-empty-path-name-and-a-custom-front-page HTTP/1.1" 200 29410 "-" "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; GPTBot/1.2; +https://openai.com/gptbot)"
920.171.207.65 - - [20/Oct/2025:22:28:01 +0000] "GET /js/filament/support/support.js?v=4.1.7.0 HTTP/1.1" 200 55524 "-" "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; GPTBot/1.2; +https://openai.com/gptbot)"
1020.171.207.65 - - [20/Oct/2025:22:28:03 +0000] "GET /notes/bigfoot-mcfly/laravel-livewire-upload-error-behind-nginxcloudflare HTTP/1.1" 200 29992 "-" "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; GPTBot/1.2; +https://openai.com/gptbot)"
1120.171.207.65 - - [20/Oct/2025:22:28:05 +0000] "GET /storage/avatars/01K6W7KCNQBW9BAM2ZGVBK584E.jpg HTTP/1.1" 404 2318 "-" "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; GPTBot/1.2; +https://openai.com/gptbot)"
1220.171.207.65 - - [20/Oct/2025:22:28:06 +0000] "GET /livewire/upload-file?expires=1760438926&signature=26dd9c5dd9156ea312bf70917931d1c2dc3ea1cfead611bf5523baa7ba706a25%E2%80%9D HTTP/1.1" 405 1023 "-" "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; GPTBot/1.2; +https://openai.com/gptbot)"
1320.171.207.65 - - [20/Oct/2025:22:28:07 +0000] "GET /notes/bigfoot-mcfly/laravel-model-local-scoping-with-attributes HTTP/1.1" 200 29771 "-" "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; GPTBot/1.2; +https://openai.com/gptbot)"
1420.171.207.65 - - [20/Oct/2025:22:28:08 +0000] "GET /login HTTP/1.1" 200 6285 "-" "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; GPTBot/1.2; +https://openai.com/gptbot)"
1520.171.207.65 - - [20/Oct/2025:22:28:10 +0000] "GET /vendor/livewire/livewire.min.js?id=df3a17f2 HTTP/1.1" 200 58572 "-" "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; GPTBot/1.2; +https://openai.com/gptbot)"
1620.171.207.65 - - [20/Oct/2025:22:28:11 +0000] "GET /build/assets/app-BmsqrX6M.js HTTP/1.1" 200 1 "-" "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; GPTBot/1.2; +https://openai.com/gptbot)"
1720.171.207.65 - - [20/Oct/2025:22:28:12 +0000] "GET /build/assets/scriptum-CSnYTD7J.js HTTP/1.1" 200 168 "-" "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; GPTBot/1.2; +https://openai.com/gptbot)"
1820.171.207.65 - - [20/Oct/2025:22:28:13 +0000] "GET /users/bigfoot-mcfly HTTP/1.1" 200 34443 "-" "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; GPTBot/1.2; +https://openai.com/gptbot)"
1920.171.207.65 - - [20/Oct/2025:22:28:14 +0000] "GET /js/filament/actions/actions.js?v=4.1.7.0 HTTP/1.1" 200 439 "-" "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; GPTBot/1.2; +https://openai.com/gptbot)"
2020.171.207.65 - - [20/Oct/2025:22:28:15 +0000] "GET /livewire/upload-file?...%27 HTTP/1.1" 405 1023 "-" "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; GPTBot/1.2; +https://openai.com/gptbot)"
2120.171.207.65 - - [20/Oct/2025:22:28:17 +0000] "GET /js/filament/schemas/schemas.js?v=4.1.7.0 HTTP/1.1" 200 1279 "-" "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; GPTBot/1.2; +https://openai.com/gptbot)"
2220.171.207.65 - - [20/Oct/2025:22:28:17 +0000] "GET /register HTTP/1.1" 200 6821 "-" "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; GPTBot/1.2; +https://openai.com/gptbot)"
2320.171.207.65 - - [20/Oct/2025:22:28:19 +0000] "GET /users/benedek-gerzson HTTP/1.1" 200 29824 "-" "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; GPTBot/1.2; +https://openai.com/gptbot)"
2420.171.207.65 - - [20/Oct/2025:22:28:20 +0000] "GET /js/filament/tables/tables.js?v=4.1.7.0 HTTP/1.1" 200 2492 "-" "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; GPTBot/1.2; +https://openai.com/gptbot)"
2520.171.207.65 - - [20/Oct/2025:22:28:21 +0000] "GET /js/filament/filament/app.js?v=4.1.7.0 HTTP/1.1" 200 4450 "-" "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; GPTBot/1.2; +https://openai.com/gptbot)"
2620.171.207.65 - - [20/Oct/2025:22:28:22 +0000] "GET /storage/avatars/_guest.svg HTTP/1.1" 200 5781 "-" "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; GPTBot/1.2; +https://openai.com/gptbot)"
2720.171.207.65 - - [20/Oct/2025:22:28:24 +0000] "GET /js/filament/filament/echo.js?v=4.1.7.0 HTTP/1.1" 200 29165 "-" "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; GPTBot/1.2; +https://openai.com/gptbot)"
2820.171.207.65 - - [20/Oct/2025:22:28:25 +0000] "GET /js/filament/notifications/notifications.js?v=4.1.7.0 HTTP/1.1" 200 2764 "-" "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; GPTBot/1.2; +https://openai.com/gptbot)"
2920.171.207.65 - - [20/Oct/2025:22:28:26 +0000] "GET /build/assets/theme-C-fBfsLR.css HTTP/1.1" 200 80042 "-" "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; GPTBot/1.2; +https://openai.com/gptbot)"
3020.171.207.65 - - [20/Oct/2025:22:28:27 +0000] "GET /build/assets/app-DYP3tEh-.css HTTP/1.1" 200 35485 "-" "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; GPTBot/1.2; +https://openai.com/gptbot)"
3120.171.207.65 - - [20/Oct/2025:22:28:28 +0000] "GET /fonts/filament/filament/inter/index.css?v=4.1.7.0 HTTP/1.1" 200 633 "-" "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; GPTBot/1.2; +https://openai.com/gptbot)"
3220.171.207.65 - - [20/Oct/2025:22:28:29 +0000] "GET /vendor/livewire/livewire.min.js.map HTTP/1.1" 200 584196 "-" "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; GPTBot/1.2; +https://openai.com/gptbot)"
3320.171.207.65 - - [20/Oct/2025:22:28:31 +0000] "GET /fonts/filament/filament/inter/inter-greek-wght-normal-IRE366VL.woff2 HTTP/1.1" 200 18996 "-" "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; GPTBot/1.2; +https://openai.com/gptbot)"
3420.171.207.65 - - [20/Oct/2025:22:28:32 +0000] "GET /fonts/filament/filament/inter/inter-latin-wght-normal-NRMW37G5.woff2 HTTP/1.1" 200 48256 "-" "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; GPTBot/1.2; +https://openai.com/gptbot)"
3520.171.207.65 - - [20/Oct/2025:22:28:33 +0000] "GET /fonts/filament/filament/inter/inter-vietnamese-wght-normal-CE5GGD3W.woff2 HTTP/1.1" 200 10252 "-" "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; GPTBot/1.2; +https://openai.com/gptbot)"
3620.171.207.65 - - [20/Oct/2025:22:28:34 +0000] "GET /fonts/filament/filament/inter/inter-latin-ext-wght-normal-HA22NDSG.woff2 HTTP/1.1" 200 85068 "-" "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; GPTBot/1.2; +https://openai.com/gptbot)"
3720.171.207.65 - - [20/Oct/2025:22:28:36 +0000] "GET /fonts/filament/filament/inter/inter-greek-ext-wght-normal-EOVOK2B5.woff2 HTTP/1.1" 200 11232 "-" "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; GPTBot/1.2; +https://openai.com/gptbot)"
3820.171.207.65 - - [20/Oct/2025:22:28:37 +0000] "GET /fonts/filament/filament/inter/inter-cyrillic-ext-wght-normal-IYF56FF6.woff2 HTTP/1.1" 200 25960 "-" "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; GPTBot/1.2; +https://openai.com/gptbot)"
3920.171.207.65 - - [20/Oct/2025:22:28:38 +0000] "GET /fonts/filament/filament/inter/inter-cyrillic-wght-normal-JEOLYBOO.woff2 HTTP/1.1" 200 18748 "-" "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; GPTBot/1.2; +https://openai.com/gptbot)"
4020.171.207.65 - - [21/Oct/2025:01:17:02 +0000] "GET /favicon.ico HTTP/1.1" 200 8679 "-" "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; GPTBot/1.2; +https://openai.com/gptbot)"