Added ip lookup on registration, fixes ST-245

This commit is contained in:
Constantin Graf
2024-06-25 11:48:24 +02:00
committed by Gregor Vostrak
parent 364168debd
commit de1accba4a
5 changed files with 89 additions and 28 deletions

View File

@@ -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,39 +57,39 @@ class CreateNewUser implements CreatesNewUsers
],
])->validate();
$timezone = 'UTC';
if (array_key_exists('timezone', $input) && is_string($input['timezone']) && app(TimezoneService::class)->isValid($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);
});
});
$newsletterConsent = isset($input['newsletter_consent']) && (bool) $input['newsletter_consent'];
if ($newsletterConsent) {
NewsletterRegistered::dispatch($input['name'], $input['email'], $user->getKey());
}
return $user;
}
/**
* Create a personal team for the user.
*/
protected function createTeam(User $user): void
{
'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();
@@ -98,5 +100,14 @@ class CreateNewUser implements CreatesNewUsers
);
$user->ownedTeams()->save($organization);
});
});
$newsletterConsent = isset($input['newsletter_consent']) && (bool) $input['newsletter_consent'];
if ($newsletterConsent) {
NewsletterRegistered::dispatch($input['name'], $input['email'], $user->getKey());
}
return $user;
}
}

View File

@@ -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);
}

View File

@@ -0,0 +1,23 @@
<?php
declare(strict_types=1);
namespace App\Service\IpLookup;
use App\Enums\Weekday;
class IpLookupResponseDto
{
public ?string $timezone;
public ?Weekday $startOfWeek;
public ?string $currency;
public function __construct(?string $timezone, ?Weekday $startOfWeek, ?string $currency)
{
$this->timezone = $timezone;
$this->startOfWeek = $startOfWeek;
$this->currency = $currency;
}
}

View File

@@ -0,0 +1,10 @@
<?php
declare(strict_types=1);
namespace App\Service\IpLookup;
interface IpLookupServiceContract
{
public function lookup(string $ip): ?IpLookupResponseDto;
}

View File

@@ -0,0 +1,13 @@
<?php
declare(strict_types=1);
namespace App\Service\IpLookup;
class NoIpLookupService implements IpLookupServiceContract
{
public function lookup(string $ip): ?IpLookupResponseDto
{
return null;
}
}