Skip to content

Commit

Permalink
Merge pull request #59 from daniel-de-wit/fix/guard-login-with-email-…
Browse files Browse the repository at this point in the history
…verification

Guard login with email verification check
  • Loading branch information
wimski authored Jun 21, 2021
2 parents f7374a5 + fc14105 commit 755e68f
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 1 deletion.
5 changes: 5 additions & 0 deletions src/GraphQL/Mutations/Login.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use DanielDeWit\LighthouseSanctum\Traits\CreatesUserProvider;
use Exception;
use Illuminate\Auth\AuthManager;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Contracts\Config\Repository as Config;
use Laravel\Sanctum\Contracts\HasApiTokens;
use Nuwave\Lighthouse\Exceptions\AuthenticationException;
Expand Down Expand Up @@ -44,6 +45,10 @@ public function __invoke($_, array $args): array
throw new AuthenticationException('The provided credentials are incorrect.');
}

if ($user instanceof MustVerifyEmail && ! $user->hasVerifiedEmail()) {
throw new AuthenticationException('Your email address is not verified.');
}

if (! $user instanceof HasApiTokens) {
throw new HasApiTokensException($user);
}
Expand Down
26 changes: 26 additions & 0 deletions tests/Integration/GraphQL/Mutations/LoginTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use DanielDeWit\LighthouseSanctum\Tests\Integration\AbstractIntegrationTest;
use DanielDeWit\LighthouseSanctum\Tests\stubs\Users\UserHasApiTokens;
use DanielDeWit\LighthouseSanctum\Tests\stubs\Users\UserMustVerifyEmail;
use Illuminate\Support\Facades\Hash;

class LoginTest extends AbstractIntegrationTest
Expand Down Expand Up @@ -77,6 +78,31 @@ public function it_returns_an_error_if_the_password_is_incorrect(): void
')->assertGraphQLErrorMessage('The provided credentials are incorrect.');
}

/**
* @test
*/
public function it_returns_an_error_if_the_email_is_not_verified(): void
{
$this->app['config']->set('auth.providers.users.model', UserMustVerifyEmail::class);

UserMustVerifyEmail::factory()->create([
'email' => '[email protected]',
'password' => Hash::make('supersecret'),
'email_verified_at' => null,
]);

$this->graphQL(/** @lang GraphQL */'
mutation {
login(input: {
email: "[email protected]",
password: "supersecret"
}) {
token
}
}
')->assertGraphQLErrorMessage('Your email address is not verified.');
}

/**
* @test
*/
Expand Down
38 changes: 37 additions & 1 deletion tests/Unit/GraphQL/Mutations/LoginTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,15 @@
use DanielDeWit\LighthouseSanctum\Exceptions\HasApiTokensException;
use DanielDeWit\LighthouseSanctum\GraphQL\Mutations\Login;
use DanielDeWit\LighthouseSanctum\Tests\stubs\Users\UserHasApiTokens;
use DanielDeWit\LighthouseSanctum\Tests\stubs\Users\UserMustVerifyEmail;
use DanielDeWit\LighthouseSanctum\Tests\Traits\MocksUserProvider;
use DanielDeWit\LighthouseSanctum\Tests\Unit\AbstractUnitTest;
use Illuminate\Auth\AuthenticationException;
use Illuminate\Contracts\Auth\UserProvider;
use Illuminate\Foundation\Auth\User;
use Laravel\Sanctum\NewAccessToken;
use Mockery;
use Mockery\MockInterface;
use Nuwave\Lighthouse\Exceptions\AuthenticationException;
use RuntimeException;

class LoginTest extends AbstractUnitTest
Expand Down Expand Up @@ -173,6 +174,41 @@ public function it_throws_an_exception_if_the_user_does_not_have_the_has_api_tok
]);
}

/**
* @test
*/
public function it_throws_an_exception_if_the_users_email_is_not_verified(): void
{
static::expectException(AuthenticationException::class);
static::expectExceptionMessage('Your email address is not verified.');

/** @var UserMustVerifyEmail|MockInterface $user */
$user = Mockery::mock(UserMustVerifyEmail::class)
->shouldReceive('hasVerifiedEmail')
->andReturnFalse()
->getMock();

$userProvider = $this->mockUserProvider($user);
$userProvider
->shouldReceive('validateCredentials')
->with($user, [
'email' => '[email protected]',
'password' => 'supersecret',
])
->andReturnTrue()
->getMock();

$mutation = new Login(
$this->mockAuthManager($userProvider),
$this->mockConfig(),
);

$mutation(null, [
'email' => '[email protected]',
'password' => 'supersecret',
]);
}

/**
* @return UserProvider|MockInterface
*/
Expand Down

0 comments on commit 755e68f

Please sign in to comment.