Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
a1d347b
commit c29d5bd
Showing
13 changed files
with
308 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace DanielDeWit\LighthouseSanctum\Contracts\Services; | ||
|
||
interface ResetPasswordServiceInterface | ||
{ | ||
public function setResetPasswordUrl(string $url): void; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
<?php | ||
|
||
namespace DanielDeWit\LighthouseSanctum\Enums; | ||
|
||
use BenSampo\Enum\Enum; | ||
|
||
/** | ||
* @method static static EMAIL_SENT() | ||
*/ | ||
final class ForgotPasswordStatus extends Enum | ||
{ | ||
public const EMAIL_SENT = 'EMAIL_SENT'; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace DanielDeWit\LighthouseSanctum\GraphQL\Mutations; | ||
|
||
use DanielDeWit\LighthouseSanctum\Contracts\Services\ResetPasswordServiceInterface; | ||
use DanielDeWit\LighthouseSanctum\Enums\ForgotPasswordStatus; | ||
use Exception; | ||
use GraphQL\Type\Definition\ResolveInfo; | ||
use Illuminate\Contracts\Auth\PasswordBroker; | ||
use Illuminate\Contracts\Translation\Translator; | ||
use Nuwave\Lighthouse\Support\Contracts\GraphQLContext; | ||
|
||
class ForgotPassword | ||
{ | ||
protected PasswordBroker $passwordBroker; | ||
protected ResetPasswordServiceInterface $resetPasswordService; | ||
protected Translator $translator; | ||
|
||
public function __construct( | ||
PasswordBroker $passwordBroker, | ||
ResetPasswordServiceInterface $resetPasswordService, | ||
Translator $translator | ||
) { | ||
$this->passwordBroker = $passwordBroker; | ||
$this->resetPasswordService = $resetPasswordService; | ||
$this->translator = $translator; | ||
} | ||
|
||
/** | ||
* @param mixed $_ | ||
* @param array<string, mixed> $args | ||
* @param GraphQLContext|null $context | ||
* @param ResolveInfo $resolveInfo | ||
* @return array<string, ForgotPasswordStatus|array|string|null> | ||
* @throws Exception | ||
*/ | ||
public function __invoke($_, array $args, GraphQLContext $context = null, ResolveInfo $resolveInfo): array | ||
{ | ||
if ($args['reset_password_url']) { | ||
$this->resetPasswordService->setResetPasswordUrl($args['reset_password_url']['url']); | ||
} | ||
|
||
$this->passwordBroker->sendResetLink([ | ||
'email' => $args['email'], | ||
]); | ||
|
||
return [ | ||
'status' => ForgotPasswordStatus::EMAIL_SENT(), | ||
'message' => $this->translator->get('An email has been sent'), | ||
]; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace DanielDeWit\LighthouseSanctum\Services; | ||
|
||
use DanielDeWit\LighthouseSanctum\Contracts\Services\ResetPasswordServiceInterface; | ||
use Illuminate\Auth\Notifications\ResetPassword as ResetPasswordNotification; | ||
use Illuminate\Contracts\Auth\CanResetPassword; | ||
|
||
class ResetPasswordService implements ResetPasswordServiceInterface | ||
{ | ||
public function setResetPasswordUrl(string $url): void | ||
{ | ||
ResetPasswordNotification::createUrlUsing(function (CanResetPassword $notifiable, string $token) use ($url) { | ||
return str_replace([ | ||
'__EMAIL__', | ||
'__TOKEN__', | ||
], [ | ||
$notifiable->getEmailForPasswordReset(), | ||
$token, | ||
], $url); | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
79 changes: 79 additions & 0 deletions
79
tests/Integration/GraphQL/Mutations/ForgotPasswordTest.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace DanielDeWit\LighthouseSanctum\Tests\Integration\GraphQL\Mutations; | ||
|
||
use DanielDeWit\LighthouseSanctum\Contracts\Services\ResetPasswordServiceInterface; | ||
use DanielDeWit\LighthouseSanctum\GraphQL\Mutations\ForgotPassword; | ||
use DanielDeWit\LighthouseSanctum\Tests\Integration\AbstractIntegrationTest; | ||
use DanielDeWit\LighthouseSanctum\Tests\stubs\Users\UserCanResetPassword; | ||
use Illuminate\Auth\Notifications\ResetPassword; | ||
use Illuminate\Auth\Notifications\ResetPassword as ResetPasswordNotification; | ||
use Illuminate\Contracts\Auth\PasswordBroker; | ||
use Illuminate\Contracts\Translation\Translator; | ||
use Illuminate\Support\Facades\Notification; | ||
use Laravel\Sanctum\Sanctum; | ||
|
||
class ForgotPasswordTest extends AbstractIntegrationTest | ||
{ | ||
protected ForgotPassword $mutation; | ||
|
||
protected function setUp(): void | ||
{ | ||
parent::setUp(); | ||
|
||
$this->app['config']->set('auth.providers', [ | ||
'users' => [ | ||
'driver' => 'eloquent', | ||
'model' => UserCanResetPassword::class, | ||
], | ||
]); | ||
|
||
$this->mutation = new ForgotPassword( | ||
$this->app->make(PasswordBroker::class), | ||
$this->app->make(ResetPasswordServiceInterface::class), | ||
$this->app->make(Translator::class), | ||
); | ||
} | ||
|
||
/** | ||
* @test | ||
*/ | ||
public function it_sends_a_reset_password_notification(): void | ||
{ | ||
Notification::fake(); | ||
|
||
/** @var UserCanResetPassword $user */ | ||
$user = UserCanResetPassword::factory()->create([ | ||
'email' => 'john.doe@gmail.com', | ||
]); | ||
|
||
$user->notify(new ResetPasswordNotification('bla')); | ||
|
||
Sanctum::actingAs($user); | ||
|
||
$this->graphQL(/** @lang GraphQL */ ' | ||
mutation { | ||
forgotPassword(input: { | ||
email: "john.doe@gmail.com" | ||
reset_password_url: { | ||
url: "https://my-front-end.com/reset-password?email=__EMAIL__&token=__TOKEN__" | ||
} | ||
}) { | ||
status | ||
message | ||
} | ||
} | ||
')->assertJson([ | ||
'data' => [ | ||
'forgotPassword' => [ | ||
'status' => 'EMAIL_SENT', | ||
'message' => 'An email has been sent', | ||
], | ||
], | ||
]); | ||
|
||
Notification::assertSentTo($user, ResetPassword::class); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace DanielDeWit\LighthouseSanctum\Tests\Integration\Services; | ||
|
||
use DanielDeWit\LighthouseSanctum\Services\ResetPasswordService; | ||
use DanielDeWit\LighthouseSanctum\Tests\Integration\AbstractIntegrationTest; | ||
use DanielDeWit\LighthouseSanctum\Tests\stubs\Users\UserMustVerifyEmail; | ||
use Illuminate\Auth\Notifications\ResetPassword; | ||
|
||
class ResetPasswordServiceTest extends AbstractIntegrationTest | ||
{ | ||
protected ResetPasswordService $service; | ||
|
||
protected function setUp(): void | ||
{ | ||
parent::setUp(); | ||
|
||
$this->service = new ResetPasswordService(); | ||
} | ||
|
||
/** | ||
* @test | ||
*/ | ||
public function it_sets_the_reset_password_url(): void | ||
{ | ||
/** @var UserMustVerifyEmail $user */ | ||
$user = UserMustVerifyEmail::factory()->create([ | ||
'email' => 'user@example.com', | ||
]); | ||
|
||
$token = 'token123'; | ||
|
||
$this->service->setResetPasswordUrl('https://mysite.com/reset-password/__EMAIL__/__TOKEN__'); | ||
|
||
$url = call_user_func(ResetPassword::$createUrlCallback, $user, $token); | ||
|
||
static::assertSame('https://mysite.com/reset-password/user@example.com/token123', $url); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace DanielDeWit\LighthouseSanctum\Tests\stubs\Users; | ||
|
||
use Illuminate\Database\Eloquent\Factories\Factory; | ||
use Illuminate\Notifications\Notifiable; | ||
|
||
class UserCanResetPassword extends UserHasApiTokens | ||
{ | ||
use Notifiable; | ||
|
||
protected static function newFactory(): Factory | ||
{ | ||
return new UserCanResetPasswordFactory(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace DanielDeWit\LighthouseSanctum\Tests\stubs\Users; | ||
|
||
use Orchestra\Testbench\Factories\UserFactory; | ||
|
||
class UserCanResetPasswordFactory extends UserFactory | ||
{ | ||
protected $model = UserCanResetPassword::class; | ||
} |