diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 5e697737ab3..885e854a895 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -137,11 +137,16 @@ jobs: key: ${{ runner.os }}-composer-${{ hashFiles('composer.lock') }} restore-keys: ${{ runner.os }}-composer- + - name: Get current date + id: current-date + run: echo "today=$(date '+%Y%m%d')" >> "$GITHUB_OUTPUT" + - name: Cache ip2asn uses: actions/cache@v4 with: path: database/ip2asn/ - key: ip2asn + key: ip2asn-${{ steps.current-date.outputs.today }} + restore-keys: ip2asn- - run: ./build.sh diff --git a/app/Http/Controllers/UserCoverPresetsController.php b/app/Http/Controllers/UserCoverPresetsController.php index 87bdfa70122..2a8302b0cbe 100644 --- a/app/Http/Controllers/UserCoverPresetsController.php +++ b/app/Http/Controllers/UserCoverPresetsController.php @@ -82,6 +82,6 @@ public function update(string $id): Response $item->update(['active' => $params['active']]); } - return ujs_redirect(route('user-cover-presets.index').'#cover-'.$item->getKey()); + return response(null, 204); } } diff --git a/app/Http/Controllers/UsersController.php b/app/Http/Controllers/UsersController.php index 605f995b851..cd72c10642a 100644 --- a/app/Http/Controllers/UsersController.php +++ b/app/Http/Controllers/UsersController.php @@ -17,7 +17,6 @@ use App\Libraries\UserRegistration; use App\Models\Beatmap; use App\Models\BeatmapDiscussion; -use App\Models\Country; use App\Models\IpBan; use App\Models\Log; use App\Models\User; @@ -983,9 +982,8 @@ private function storeUser(array $rawParams) 'username', ], ['null_missing' => true]); $countryCode = request_country(); - $country = Country::find($countryCode); $params['user_ip'] = $ip; - $params['country_acronym'] = $country === null ? '' : $country->getKey(); + $params['country_acronym'] = $countryCode; $params['user_lang'] = \App::getLocale(); $registration = new UserRegistration($params); @@ -1009,7 +1007,11 @@ private function storeUser(array $rawParams) $user = $registration->user(); // report unknown country code but ignore non-country from cloudflare - if ($countryCode !== null && $country === null && $countryCode !== 'T1') { + if ( + $countryCode !== null + && $countryCode !== 'T1' + && app('countries')->byCode($countryCode) === null + ) { app('sentry')->getClient()->captureMessage( 'User registered from unknown country', null, diff --git a/app/Libraries/User/CountryChange.php b/app/Libraries/User/CountryChange.php index d8304baab04..f28943cc94b 100644 --- a/app/Libraries/User/CountryChange.php +++ b/app/Libraries/User/CountryChange.php @@ -9,7 +9,6 @@ use App\Exceptions\InvariantException; use App\Models\Beatmap; -use App\Models\Country; use App\Models\User; use App\Models\UserAccountHistory; @@ -18,7 +17,7 @@ class CountryChange public static function handle(User $user, string $newCountry, string $reason): void { // Assert valid country acronym - $country = Country::find($newCountry); + $country = app('countries')->byCode($newCountry); if ($country === null) { throw new InvariantException('invalid country specified'); } diff --git a/app/Models/User.php b/app/Models/User.php index 66951d35108..29297a6f14e 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -2320,11 +2320,12 @@ public function isValid() if ($this->isDirty('country_acronym')) { if (present($this->country_acronym)) { - if (($country = Country::find($this->country_acronym)) !== null) { + $country = app('countries')->byCode($this->country_acronym); + if ($country === null) { + $this->validationErrors()->add('country', '.invalid_country'); + } else { // ensure matching case $this->country_acronym = $country->getKey(); - } else { - $this->validationErrors()->add('country', '.invalid_country'); } } else { $this->country_acronym = Country::UNKNOWN; diff --git a/database/factories/CountryFactory.php b/database/factories/CountryFactory.php index e3ca111fd94..a3ac82f6c6c 100644 --- a/database/factories/CountryFactory.php +++ b/database/factories/CountryFactory.php @@ -13,6 +13,11 @@ class CountryFactory extends Factory { protected $model = Country::class; + public function configure(): static + { + return $this->afterCreating(fn () => app('countries')->resetMemoized()); + } + public function definition(): array { return [ diff --git a/resources/js/setup-turbo.ts b/resources/js/setup-turbo.ts index f6c0e566b4d..b2f7bb2eb67 100644 --- a/resources/js/setup-turbo.ts +++ b/resources/js/setup-turbo.ts @@ -3,6 +3,7 @@ import '@hotwired/turbo'; import { hideLoadingOverlay, showLoadingOverlay } from 'utils/loading-overlay'; +import { reloadPage } from 'utils/turbolinks'; Turbo.config.drive.progressBarDelay = 0; @@ -17,6 +18,11 @@ document.addEventListener('turbo:submit-start', (e) => { } }); document.addEventListener('turbo:submit-end', hideLoadingOverlay); +document.addEventListener('turbo:submit-end', (e) => { + if (e.detail.success && e.detail.formSubmission.formElement.dataset.reloadOnSuccess === '1') { + reloadPage(); + } +}); // disable turbo navigation for old webs document.addEventListener('turbo:click', (event) => { diff --git a/resources/views/layout/ujs-redirect.blade.php b/resources/views/layout/ujs-redirect.blade.php index 84052e14c6a..fe651fb8e7a 100644 --- a/resources/views/layout/ujs-redirect.blade.php +++ b/resources/views/layout/ujs-redirect.blade.php @@ -2,7 +2,6 @@ Copyright (c) ppy Pty Ltd . Licensed under the GNU Affero General Public License v3.0. See the LICENCE file in the repository root for full licence text. --}} -;(function() { - $(document).off(".ujsHideLoadingOverlay"); - window.setTimeout(() => Turbo.visit({!! json_encode($url) !!}), 0); -}).call(this); +$(document).off('.ujsHideLoadingOverlay'); +Turbo.cache.clear(); +Turbo.visit({!! json_encode($url) !!}); diff --git a/resources/views/password_reset/index.blade.php b/resources/views/password_reset/index.blade.php index d8235e796cb..e4af3c8658a 100644 --- a/resources/views/password_reset/index.blade.php +++ b/resources/views/password_reset/index.blade.php @@ -22,7 +22,6 @@

- + + +

@csrf diff --git a/tests/TestCase.php b/tests/TestCase.php index 9a95cea322a..5dbb8b506ad 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -152,24 +152,22 @@ protected function tearDown(): void /** * Act as a User with OAuth scope permissions. */ - protected function actAsScopedUser(?User $user, ?array $scopes = ['*'], ?Client $client = null): void + protected function actAsScopedUser(?User $user, ?array $scopes = ['*'], ?Client $client = null): static { - $this->actingWithToken($this->createToken( + return $this->actingWithToken($this->createToken( $user, $scopes, $client ?? Client::factory()->create(), )); } - protected function actAsUser(?User $user, bool $verified = false, $driver = null) + protected function actAsUser(?User $user, bool $verified = false, $driver = null): static { - if ($user === null) { - return; + if ($user !== null) { + $this->be($user, $driver)->withSession(['verified' => $verified]); } - $this->be($user, $driver); - - $this->withSession(['verified' => $verified]); + return $this; } /** @@ -179,7 +177,7 @@ protected function actAsUser(?User $user, bool $verified = false, $driver = null * @param string $driver Auth driver to use. * @return void */ - protected function actAsUserWithToken(Token $token, $driver = null) + protected function actAsUserWithToken(Token $token, $driver = null): static { $guard = app('auth')->guard($driver); $user = $token->getResourceOwner(); @@ -196,24 +194,19 @@ protected function actAsUserWithToken(Token $token, $driver = null) request()->attributes->set(AuthApi::REQUEST_OAUTH_TOKEN_KEY, $token); app('auth')->shouldUse($driver); - } - - protected function actingAsVerified($user) - { - $this->actAsUser($user, true); return $this; } - protected function actingWithToken($token) + protected function actingAsVerified($user): static { - $this->actAsUserWithToken($token); - - $encodedToken = EncodeToken::encodeAccessToken($token); + return $this->actAsUser($user, true); + } - return $this->withHeaders([ - 'Authorization' => "Bearer {$encodedToken}", - ]); + protected function actingWithToken($token): static + { + return $this->actAsUserWithToken($token) + ->withToken(EncodeToken::encodeAccessToken($token)); } protected function assertEqualsUpToOneSecond(CarbonInterface $expected, CarbonInterface $actual): void