From de1accba4ac13356f7750447f6b68ce8ecc1f67c Mon Sep 17 00:00:00 2001 From: Constantin Graf Date: Tue, 25 Jun 2024 11:48:24 +0200 Subject: [PATCH] Added ip lookup on registration, fixes ST-245 --- app/Actions/Fortify/CreateNewUser.php | 67 +++++++++++-------- app/Providers/AppServiceProvider.php | 4 ++ app/Service/IpLookup/IpLookupResponseDto.php | 23 +++++++ .../IpLookup/IpLookupServiceContract.php | 10 +++ app/Service/IpLookup/NoIpLookupService.php | 13 ++++ 5 files changed, 89 insertions(+), 28 deletions(-) create mode 100644 app/Service/IpLookup/IpLookupResponseDto.php create mode 100644 app/Service/IpLookup/IpLookupServiceContract.php create mode 100644 app/Service/IpLookup/NoIpLookupService.php diff --git a/app/Actions/Fortify/CreateNewUser.php b/app/Actions/Fortify/CreateNewUser.php index 638871a8..06a5a94e 100644 --- a/app/Actions/Fortify/CreateNewUser.php +++ b/app/Actions/Fortify/CreateNewUser.php @@ -9,6 +9,7 @@ use App\Enums\Weekday; use App\Events\NewsletterRegistered; use App\Models\Organization; use App\Models\User; +use App\Service\IpLookup\IpLookupServiceContract; use App\Service\TimezoneService; use Illuminate\Database\Eloquent\Builder; use Illuminate\Support\Facades\DB; @@ -18,6 +19,7 @@ use Illuminate\Validation\ValidationException; use Korridor\LaravelModelValidationRules\Rules\UniqueEloquent; use Laravel\Fortify\Contracts\CreatesNewUsers; use Laravel\Jetstream\Jetstream; +use Log; class CreateNewUser implements CreatesNewUsers { @@ -55,20 +57,49 @@ class CreateNewUser implements CreatesNewUsers ], ])->validate(); - $timezone = 'UTC'; - if (array_key_exists('timezone', $input) && is_string($input['timezone']) && app(TimezoneService::class)->isValid($input['timezone'])) { - $timezone = $input['timezone']; + $timezone = null; + if (array_key_exists('timezone', $input) && is_string($input['timezone'])) { + if (app(TimezoneService::class)->isValid($input['timezone'])) { + $timezone = $input['timezone']; + } else { + Log::debug('Invalid timezone', ['timezone' => $input['timezone']]); + } } - $user = DB::transaction(function () use ($input, $timezone) { + $ipLookupResponse = app(IpLookupServiceContract::class)->lookup(request()->ip()); + + $startOfWeek = Weekday::Monday; + $currency = null; + if ($ipLookupResponse !== null) { + $startOfWeek = $ipLookupResponse->startOfWeek ?? Weekday::Monday; + if ($timezone === null) { + $timezone = $ipLookupResponse->timezone; + } + $currency = $ipLookupResponse->currency; + } + + $user = DB::transaction(function () use ($input, $timezone, $startOfWeek, $currency) { return tap(User::create([ 'name' => $input['name'], 'email' => $input['email'], 'password' => Hash::make($input['password']), - 'timezone' => $timezone, - 'week_start' => Weekday::Monday, - ]), function (User $user) { - $this->createTeam($user); + 'timezone' => $timezone ?? 'UTC', + 'week_start' => $startOfWeek, + ]), function (User $user) use ($currency): void { + $organization = new Organization(); + $organization->name = explode(' ', $user->name, 2)[0]."'s Organization"; + $organization->personal_team = true; + $organization->currency = $currency ?? 'EUR'; + $organization->owner()->associate($user); + $organization->save(); + + $organization->users()->attach( + $user, [ + 'role' => Role::Owner->value, + ] + ); + + $user->ownedTeams()->save($organization); }); }); @@ -79,24 +110,4 @@ class CreateNewUser implements CreatesNewUsers return $user; } - - /** - * Create a personal team for the user. - */ - protected function createTeam(User $user): void - { - $organization = new Organization(); - $organization->name = explode(' ', $user->name, 2)[0]."'s Organization"; - $organization->personal_team = true; - $organization->owner()->associate($user); - $organization->save(); - - $organization->users()->attach( - $user, [ - 'role' => Role::Owner->value, - ] - ); - - $user->ownedTeams()->save($organization); - } } diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index 05fc5dfd..5dbf207c 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -13,6 +13,8 @@ use App\Models\Tag; use App\Models\Task; use App\Models\TimeEntry; use App\Models\User; +use App\Service\IpLookup\IpLookupServiceContract; +use App\Service\IpLookup\NoIpLookupService; use App\Service\PermissionStore; use Dedoc\Scramble\Scramble; use Dedoc\Scramble\Support\Generator\OpenApi; @@ -85,6 +87,8 @@ class AppServiceProvider extends ServiceProvider return new PermissionStore(); }); + $this->app->bind(IpLookupServiceContract::class, NoIpLookupService::class); + Route::model('member', Member::class); Route::model('invitation', OrganizationInvitation::class); } diff --git a/app/Service/IpLookup/IpLookupResponseDto.php b/app/Service/IpLookup/IpLookupResponseDto.php new file mode 100644 index 00000000..055b182a --- /dev/null +++ b/app/Service/IpLookup/IpLookupResponseDto.php @@ -0,0 +1,23 @@ +timezone = $timezone; + $this->startOfWeek = $startOfWeek; + $this->currency = $currency; + } +} diff --git a/app/Service/IpLookup/IpLookupServiceContract.php b/app/Service/IpLookup/IpLookupServiceContract.php new file mode 100644 index 00000000..b441cb54 --- /dev/null +++ b/app/Service/IpLookup/IpLookupServiceContract.php @@ -0,0 +1,10 @@ +