fix: accept deprecated timezones during registration

This commit is contained in:
Paulo Castellano 2026-03-29 17:26:27 -03:00
parent 5c26d58ad5
commit 84911dcb34
5 changed files with 113 additions and 2 deletions

View file

@ -6,6 +6,7 @@
use App\Enums\User\Setup;
use App\Http\Controllers\Controller;
use App\Rules\Timezone;
use App\Models\Language;
use App\Models\User;
use App\Models\Workspace;
@ -40,7 +41,7 @@ public function store(Request $request): RedirectResponse
'name' => ['required', 'string', 'max:255'],
'email' => ['required', 'string', 'lowercase', 'email', 'max:255', 'unique:'.User::class],
'password' => ['required', Rules\Password::defaults()],
'timezone' => ['nullable', 'string', 'timezone'],
'timezone' => ['nullable', 'string', new Timezone],
]);
// Check if registering via invite link (redirect contains /invites/)

View file

@ -2,6 +2,7 @@
namespace App\Http\Requests;
use App\Rules\Timezone;
use Illuminate\Foundation\Http\FormRequest;
class UpdateWorkspaceRequest extends FormRequest
@ -15,7 +16,7 @@ public function rules(): array
{
return [
'name' => ['required', 'string', 'max:255'],
'timezone' => ['required', 'string', 'timezone:all'],
'timezone' => ['required', 'string', new Timezone],
];
}

23
app/Rules/Timezone.php Normal file
View file

@ -0,0 +1,23 @@
<?php
declare(strict_types=1);
namespace App\Rules;
use Closure;
use Illuminate\Contracts\Validation\ValidationRule;
class Timezone implements ValidationRule
{
/**
* @param \Closure(string, ?string=): \Illuminate\Translation\PotentiallyTranslatedString $fail
*/
public function validate(string $attribute, mixed $value, Closure $fail): void
{
try {
new \DateTimeZone($value);
} catch (\Exception) {
$fail('The :attribute must be a valid timezone.');
}
}
}

View file

@ -61,6 +61,46 @@
expect($user->email_verified_at)->toBeNull();
});
test('new users can register with deprecated timezone Asia/Calcutta', function () {
$this->post(route('register.store'), [
'name' => 'Test User',
'email' => 'test@example.com',
'password' => 'Password123!',
'timezone' => 'Asia/Calcutta',
]);
$user = User::where('email', 'test@example.com')->first();
expect($user)->not->toBeNull();
expect($user->workspaces->first()->timezone)->toBe('Asia/Calcutta');
});
test('new users can register with deprecated timezone US/Eastern', function () {
$this->post(route('register.store'), [
'name' => 'Test User',
'email' => 'test@example.com',
'password' => 'Password123!',
'timezone' => 'US/Eastern',
]);
$user = User::where('email', 'test@example.com')->first();
expect($user)->not->toBeNull();
expect($user->workspaces->first()->timezone)->toBe('US/Eastern');
});
test('new users cannot register with invalid timezone', function () {
$response = $this->post(route('register.store'), [
'name' => 'Test User',
'email' => 'test@example.com',
'password' => 'Password123!',
'timezone' => 'Invalid/Timezone',
]);
$response->assertSessionHasErrors('timezone');
expect(User::where('email', 'test@example.com')->exists())->toBeFalse();
});
test('new users registering via invite have verified email automatically', function () {
$this->post(route('register.store'), [
'name' => 'Test User',

View file

@ -0,0 +1,46 @@
<?php
use App\Rules\Timezone;
use Illuminate\Support\Facades\Validator;
test('accepts valid timezone', function () {
$validator = Validator::make(['tz' => 'America/Sao_Paulo'], ['tz' => new Timezone]);
expect($validator->passes())->toBeTrue();
});
test('accepts UTC', function () {
$validator = Validator::make(['tz' => 'UTC'], ['tz' => new Timezone]);
expect($validator->passes())->toBeTrue();
});
test('accepts deprecated timezone Asia/Calcutta', function () {
$validator = Validator::make(['tz' => 'Asia/Calcutta'], ['tz' => new Timezone]);
expect($validator->passes())->toBeTrue();
});
test('accepts deprecated timezone US/Eastern', function () {
$validator = Validator::make(['tz' => 'US/Eastern'], ['tz' => new Timezone]);
expect($validator->passes())->toBeTrue();
});
test('rejects invalid timezone', function () {
$validator = Validator::make(['tz' => 'Invalid/Timezone'], ['tz' => new Timezone]);
expect($validator->passes())->toBeFalse();
});
test('rejects random string', function () {
$validator = Validator::make(['tz' => 'blabla'], ['tz' => new Timezone]);
expect($validator->passes())->toBeFalse();
});
test('accepts Europe/London', function () {
$validator = Validator::make(['tz' => 'Europe/London'], ['tz' => new Timezone]);
expect($validator->passes())->toBeTrue();
});