extract oauth client as plugin
This commit is contained in:
parent
1e85794256
commit
aeb8a0800c
|
|
@ -15,7 +15,6 @@ use Cache;
|
|||
use Carbon\Carbon;
|
||||
use Illuminate\Contracts\Events\Dispatcher;
|
||||
use Illuminate\Http\Request;
|
||||
use Laravel\Socialite\Facades\Socialite;
|
||||
use Mail;
|
||||
use Session;
|
||||
use URL;
|
||||
|
|
@ -393,47 +392,4 @@ class AuthController extends Controller
|
|||
{
|
||||
return json(['token' => Auth::guard('jwt')->refresh()]);
|
||||
}
|
||||
|
||||
public function oauthLogin($driver)
|
||||
{
|
||||
return Socialite::driver($driver)->redirect();
|
||||
}
|
||||
|
||||
public function oauthCallback(Dispatcher $dispatcher, Filter $filter, $driver)
|
||||
{
|
||||
$remoteUser = Socialite::driver($driver)->user();
|
||||
|
||||
$email = $remoteUser->email;
|
||||
if (empty($email)) {
|
||||
abort(500, 'Unsupported OAuth Server which does not provide email.');
|
||||
}
|
||||
|
||||
$user = User::where('email', $email)->first();
|
||||
if (!$user) {
|
||||
$whip = new Whip();
|
||||
$ip = $whip->getValidIpAddress();
|
||||
$ip = $filter->apply('client_ip', $ip);
|
||||
|
||||
$user = new User();
|
||||
$user->email = $email;
|
||||
$user->nickname = $remoteUser->nickname ?? $remoteUser->name ?? $email;
|
||||
$user->score = option('user_initial_score');
|
||||
$user->avatar = 0;
|
||||
$user->password = '';
|
||||
$user->ip = $ip;
|
||||
$user->permission = User::NORMAL;
|
||||
$user->register_at = Carbon::now();
|
||||
$user->last_sign_at = Carbon::now()->subDay();
|
||||
$user->verified = true;
|
||||
|
||||
$user->save();
|
||||
$dispatcher->dispatch('auth.registration.completed', [$user]);
|
||||
}
|
||||
|
||||
$dispatcher->dispatch('auth.login.ready', [$user]);
|
||||
Auth::login($user);
|
||||
$dispatcher->dispatch('auth.login.succeeded', [$user]);
|
||||
|
||||
return redirect('/user');
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,9 +14,6 @@ class AppServiceProvider extends ServiceProvider
|
|||
$this->app->singleton(Services\Option::class);
|
||||
$this->app->alias(Services\Option::class, 'options');
|
||||
$this->app->singleton(Services\Webpack::class);
|
||||
$this->app->singleton('oauth.providers', function () {
|
||||
return new \Illuminate\Support\Collection();
|
||||
});
|
||||
}
|
||||
|
||||
public function boot(Request $request)
|
||||
|
|
|
|||
|
|
@ -75,9 +75,5 @@ class ViewServiceProvider extends ServiceProvider
|
|||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
});
|
||||
|
||||
View::composer('auth.oauth', function ($view) {
|
||||
$view->with('providers', resolve('oauth.providers'));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,7 +31,6 @@
|
|||
"nesbot/carbon": "^2.0",
|
||||
"nunomaduro/collision": "^4.1",
|
||||
"rcrowe/twigbridge": "^0.11.3",
|
||||
"socialiteproviders/manager": "^3.5",
|
||||
"spatie/laravel-translation-loader": "^2.6",
|
||||
"symfony/process": "^5.0",
|
||||
"symfony/yaml": "^5.0",
|
||||
|
|
|
|||
231
composer.lock
generated
231
composer.lock
generated
|
|
@ -4,7 +4,7 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "69f751f6f450fda951eb714d895e7981",
|
||||
"content-hash": "7a2599e2e1372d9c5ff7de7e1b75d5e2",
|
||||
"packages": [
|
||||
{
|
||||
"name": "blessing/filter",
|
||||
|
|
@ -1019,16 +1019,16 @@
|
|||
},
|
||||
{
|
||||
"name": "facade/ignition",
|
||||
"version": "2.0.5",
|
||||
"version": "2.0.6",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/facade/ignition.git",
|
||||
"reference": "38e1b180544bfefebe37e0f65980792ea78a534a"
|
||||
"reference": "5261c488a1e8a7c3ebdf6a4037c34f5ddeb33922"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/facade/ignition/zipball/38e1b180544bfefebe37e0f65980792ea78a534a",
|
||||
"reference": "38e1b180544bfefebe37e0f65980792ea78a534a",
|
||||
"url": "https://api.github.com/repos/facade/ignition/zipball/5261c488a1e8a7c3ebdf6a4037c34f5ddeb33922",
|
||||
"reference": "5261c488a1e8a7c3ebdf6a4037c34f5ddeb33922",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -1086,7 +1086,7 @@
|
|||
"laravel",
|
||||
"page"
|
||||
],
|
||||
"time": "2020-05-28T22:49:07+00:00"
|
||||
"time": "2020-06-01T09:04:48+00:00"
|
||||
},
|
||||
{
|
||||
"name": "facade/ignition-contracts",
|
||||
|
|
@ -1708,16 +1708,16 @@
|
|||
},
|
||||
{
|
||||
"name": "laravel/framework",
|
||||
"version": "v7.13.0",
|
||||
"version": "v7.14.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/laravel/framework.git",
|
||||
"reference": "6fa69bfbd57744a5bbec5538ce483919b3fd625f"
|
||||
"reference": "469b7719a8dca40841a74f59f2e9f30f01d3a106"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/laravel/framework/zipball/6fa69bfbd57744a5bbec5538ce483919b3fd625f",
|
||||
"reference": "6fa69bfbd57744a5bbec5538ce483919b3fd625f",
|
||||
"url": "https://api.github.com/repos/laravel/framework/zipball/469b7719a8dca40841a74f59f2e9f30f01d3a106",
|
||||
"reference": "469b7719a8dca40841a74f59f2e9f30f01d3a106",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -1728,7 +1728,7 @@
|
|||
"ext-mbstring": "*",
|
||||
"ext-openssl": "*",
|
||||
"league/commonmark": "^1.3",
|
||||
"league/flysystem": "^1.0.8",
|
||||
"league/flysystem": "^1.0.34",
|
||||
"monolog/monolog": "^2.0",
|
||||
"nesbot/carbon": "^2.17",
|
||||
"opis/closure": "^3.1",
|
||||
|
|
@ -1754,6 +1754,9 @@
|
|||
"conflict": {
|
||||
"tightenco/collect": "<5.5.33"
|
||||
},
|
||||
"provide": {
|
||||
"psr/container-implementation": "1.0"
|
||||
},
|
||||
"replace": {
|
||||
"illuminate/auth": "self.version",
|
||||
"illuminate/broadcasting": "self.version",
|
||||
|
|
@ -1857,7 +1860,7 @@
|
|||
"framework",
|
||||
"laravel"
|
||||
],
|
||||
"time": "2020-05-26T14:32:43+00:00"
|
||||
"time": "2020-06-02T22:34:18+00:00"
|
||||
},
|
||||
{
|
||||
"name": "laravel/passport",
|
||||
|
|
@ -1932,70 +1935,6 @@
|
|||
],
|
||||
"time": "2020-05-05T14:25:53+00:00"
|
||||
},
|
||||
{
|
||||
"name": "laravel/socialite",
|
||||
"version": "v4.3.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/laravel/socialite.git",
|
||||
"reference": "4bd66ee416fea04398dee5b8c32d65719a075db4"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/laravel/socialite/zipball/4bd66ee416fea04398dee5b8c32d65719a075db4",
|
||||
"reference": "4bd66ee416fea04398dee5b8c32d65719a075db4",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-json": "*",
|
||||
"guzzlehttp/guzzle": "~6.0",
|
||||
"illuminate/http": "~5.7.0|~5.8.0|^6.0|^7.0",
|
||||
"illuminate/support": "~5.7.0|~5.8.0|^6.0|^7.0",
|
||||
"league/oauth1-client": "~1.0",
|
||||
"php": "^7.1.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"illuminate/contracts": "~5.7.0|~5.8.0|^6.0|^7.0",
|
||||
"mockery/mockery": "^1.0",
|
||||
"phpunit/phpunit": "^7.0|^8.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "4.x-dev"
|
||||
},
|
||||
"laravel": {
|
||||
"providers": [
|
||||
"Laravel\\Socialite\\SocialiteServiceProvider"
|
||||
],
|
||||
"aliases": {
|
||||
"Socialite": "Laravel\\Socialite\\Facades\\Socialite"
|
||||
}
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Laravel\\Socialite\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Taylor Otwell",
|
||||
"email": "taylor@laravel.com"
|
||||
}
|
||||
],
|
||||
"description": "Laravel wrapper around OAuth 1 & OAuth 2 libraries.",
|
||||
"homepage": "https://laravel.com",
|
||||
"keywords": [
|
||||
"laravel",
|
||||
"oauth"
|
||||
],
|
||||
"time": "2020-02-04T15:30:01+00:00"
|
||||
},
|
||||
{
|
||||
"name": "lcobucci/jwt",
|
||||
"version": "3.3.2",
|
||||
|
|
@ -2301,69 +2240,6 @@
|
|||
],
|
||||
"time": "2020-05-18T15:13:39+00:00"
|
||||
},
|
||||
{
|
||||
"name": "league/oauth1-client",
|
||||
"version": "1.7.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/thephpleague/oauth1-client.git",
|
||||
"reference": "fca5f160650cb74d23fc11aa570dd61f86dcf647"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/thephpleague/oauth1-client/zipball/fca5f160650cb74d23fc11aa570dd61f86dcf647",
|
||||
"reference": "fca5f160650cb74d23fc11aa570dd61f86dcf647",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"guzzlehttp/guzzle": "^6.0",
|
||||
"php": ">=5.5.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"mockery/mockery": "^0.9",
|
||||
"phpunit/phpunit": "^4.0",
|
||||
"squizlabs/php_codesniffer": "^2.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.0-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"League\\OAuth1\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Ben Corlett",
|
||||
"email": "bencorlett@me.com",
|
||||
"homepage": "http://www.webcomm.com.au",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"description": "OAuth 1.0 Client Library",
|
||||
"keywords": [
|
||||
"Authentication",
|
||||
"SSO",
|
||||
"authorization",
|
||||
"bitbucket",
|
||||
"identity",
|
||||
"idp",
|
||||
"oauth",
|
||||
"oauth1",
|
||||
"single sign on",
|
||||
"trello",
|
||||
"tumblr",
|
||||
"twitter"
|
||||
],
|
||||
"time": "2016-08-17T00:36:58+00:00"
|
||||
},
|
||||
{
|
||||
"name": "league/oauth2-server",
|
||||
"version": "8.1.0",
|
||||
|
|
@ -2875,16 +2751,16 @@
|
|||
},
|
||||
{
|
||||
"name": "opis/closure",
|
||||
"version": "3.5.3",
|
||||
"version": "3.5.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/opis/closure.git",
|
||||
"reference": "cac47092144043d5d676e2e7cf8d0d2f83fc89ca"
|
||||
"reference": "1d0deef692f66dae5d70663caee2867d0971306b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/opis/closure/zipball/cac47092144043d5d676e2e7cf8d0d2f83fc89ca",
|
||||
"reference": "cac47092144043d5d676e2e7cf8d0d2f83fc89ca",
|
||||
"url": "https://api.github.com/repos/opis/closure/zipball/1d0deef692f66dae5d70663caee2867d0971306b",
|
||||
"reference": "1d0deef692f66dae5d70663caee2867d0971306b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -2932,7 +2808,7 @@
|
|||
"serialization",
|
||||
"serialize"
|
||||
],
|
||||
"time": "2020-05-25T09:32:45+00:00"
|
||||
"time": "2020-06-07T11:41:29+00:00"
|
||||
},
|
||||
{
|
||||
"name": "paragonie/random_compat",
|
||||
|
|
@ -3791,63 +3667,6 @@
|
|||
],
|
||||
"time": "2020-03-02T05:59:21+00:00"
|
||||
},
|
||||
{
|
||||
"name": "socialiteproviders/manager",
|
||||
"version": "v3.5",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/SocialiteProviders/Manager.git",
|
||||
"reference": "7a5872d9e4b22bb26ecd0c69ea9ddbaad8c0f570"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/SocialiteProviders/Manager/zipball/7a5872d9e4b22bb26ecd0c69ea9ddbaad8c0f570",
|
||||
"reference": "7a5872d9e4b22bb26ecd0c69ea9ddbaad8c0f570",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"illuminate/support": "~5.4|~5.7.0|~5.8.0|^6.0|^7.0",
|
||||
"laravel/socialite": "~3.0|~4.0",
|
||||
"php": "^5.6 || ^7.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"mockery/mockery": "^0.9.4",
|
||||
"phpunit/phpunit": "^5.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"laravel": {
|
||||
"providers": [
|
||||
"SocialiteProviders\\Manager\\ServiceProvider"
|
||||
]
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"SocialiteProviders\\Manager\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Andy Wendt",
|
||||
"email": "andy@awendt.com"
|
||||
},
|
||||
{
|
||||
"name": "Anton Komarev",
|
||||
"email": "a.komarev@cybercog.su"
|
||||
},
|
||||
{
|
||||
"name": "Miguel Piedrafita",
|
||||
"email": "soy@miguelpiedrafita.com"
|
||||
}
|
||||
],
|
||||
"description": "Easily add new or override built-in providers in Laravel Socialite.",
|
||||
"time": "2020-03-08T16:54:44+00:00"
|
||||
},
|
||||
{
|
||||
"name": "spatie/laravel-translation-loader",
|
||||
"version": "2.6.1",
|
||||
|
|
@ -7216,16 +7035,16 @@
|
|||
},
|
||||
{
|
||||
"name": "nikic/php-parser",
|
||||
"version": "v4.4.0",
|
||||
"version": "v4.5.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/nikic/PHP-Parser.git",
|
||||
"reference": "bd43ec7152eaaab3bd8c6d0aa95ceeb1df8ee120"
|
||||
"reference": "53c2753d756f5adb586dca79c2ec0e2654dd9463"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/bd43ec7152eaaab3bd8c6d0aa95ceeb1df8ee120",
|
||||
"reference": "bd43ec7152eaaab3bd8c6d0aa95ceeb1df8ee120",
|
||||
"url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/53c2753d756f5adb586dca79c2ec0e2654dd9463",
|
||||
"reference": "53c2753d756f5adb586dca79c2ec0e2654dd9463",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -7264,7 +7083,7 @@
|
|||
"parser",
|
||||
"php"
|
||||
],
|
||||
"time": "2020-04-10T16:34:50+00:00"
|
||||
"time": "2020-06-03T07:24:19+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phar-io/manifest",
|
||||
|
|
|
|||
|
|
@ -1,11 +0,0 @@
|
|||
{% if providers|length > 0 %}
|
||||
<div class="mb-3 text-center">
|
||||
<div class="mb-1">- {{ trans('general.more') }} -</div>
|
||||
{% for name, provider in providers %}
|
||||
<a href="{{ url("/auth/login/#{name}") }}" class="btn btn-block bg-light border-secondary">
|
||||
<i class="fab fa-{{ provider.icon }}"></i>
|
||||
{{ provider.displayName }}
|
||||
</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
|
@ -28,9 +28,6 @@ Route::prefix('auth')->name('auth.')->group(function () {
|
|||
|
||||
Route::get('reset/{uid}', 'AuthController@reset')->name('reset');
|
||||
Route::post('reset/{uid}', 'AuthController@handleReset')->name('reset');
|
||||
|
||||
Route::get('login/{driver}', 'AuthController@oauthLogin');
|
||||
Route::get('login/{driver}/callback', 'AuthController@oauthCallback');
|
||||
});
|
||||
|
||||
Route::post('logout', 'AuthController@logout')->name('logout')->middleware('authorize');
|
||||
|
|
|
|||
|
|
@ -15,8 +15,6 @@ use Illuminate\Foundation\Testing\DatabaseTransactions;
|
|||
use Illuminate\Support\Facades\Mail;
|
||||
use Illuminate\Support\Facades\URL;
|
||||
use Illuminate\Support\Str;
|
||||
use Laravel\Socialite\AbstractUser;
|
||||
use Laravel\Socialite\Facades\Socialite;
|
||||
use Tests\Fakes\Filter;
|
||||
use Vectorface\Whip\Whip;
|
||||
|
||||
|
|
@ -814,120 +812,4 @@ class AuthControllerTest extends TestCase
|
|||
])->decodeResponseJson('token');
|
||||
$this->assertTrue(is_string($token));
|
||||
}
|
||||
|
||||
public function testOauthLogin()
|
||||
{
|
||||
Socialite::shouldReceive('driver')
|
||||
->with('github')
|
||||
->once()
|
||||
->andReturn(new class() {
|
||||
public function redirect()
|
||||
{
|
||||
return redirect('/');
|
||||
}
|
||||
});
|
||||
|
||||
$this->get('/auth/login/github')->assertRedirect();
|
||||
}
|
||||
|
||||
public function testOauthCallback()
|
||||
{
|
||||
Event::fake();
|
||||
$filter = Filter::fake();
|
||||
$whip = new Whip();
|
||||
$ip = $whip->getValidIpAddress();
|
||||
|
||||
Socialite::shouldReceive('driver')
|
||||
->with('github')
|
||||
->times(3)
|
||||
->andReturn(
|
||||
new class() {
|
||||
public function user()
|
||||
{
|
||||
return new class() extends AbstractUser {
|
||||
};
|
||||
}
|
||||
},
|
||||
new class() {
|
||||
public function user()
|
||||
{
|
||||
return new class() extends AbstractUser {
|
||||
public $email = 'a@b.c';
|
||||
|
||||
public $nickname = 'abc';
|
||||
};
|
||||
}
|
||||
},
|
||||
new class() {
|
||||
public function user()
|
||||
{
|
||||
return new class() extends AbstractUser {
|
||||
public $email = 'a@b.c';
|
||||
|
||||
public $nickname = 'abc';
|
||||
};
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
$this->get('/auth/login/github/callback')
|
||||
->assertStatus(500)
|
||||
->assertSee('Unsupported');
|
||||
|
||||
$this->get('/auth/login/github/callback')->assertRedirect('/user');
|
||||
$filter->assertApplied('client_ip', function ($value) use ($ip) {
|
||||
$this->assertEquals($ip, $value);
|
||||
|
||||
return true;
|
||||
});
|
||||
$this->assertDatabaseHas('users', [
|
||||
'email' => 'a@b.c',
|
||||
'nickname' => 'abc',
|
||||
'score' => option('user_initial_score'),
|
||||
'avatar' => 0,
|
||||
'ip' => $ip,
|
||||
'permission' => User::NORMAL,
|
||||
'verified' => true,
|
||||
]);
|
||||
$this->assertAuthenticated();
|
||||
Event::assertDispatched('auth.registration.completed', function ($event, $payload) {
|
||||
[$user] = $payload;
|
||||
$this->assertEquals('a@b.c', $user->email);
|
||||
$this->assertEquals(1, $user->uid);
|
||||
|
||||
return true;
|
||||
});
|
||||
Event::assertDispatched('auth.login.ready', function ($event, $payload) {
|
||||
[$user] = $payload;
|
||||
$this->assertEquals('a@b.c', $user->email);
|
||||
|
||||
return true;
|
||||
});
|
||||
Event::assertDispatched('auth.login.succeeded', function ($event, $payload) {
|
||||
[$user] = $payload;
|
||||
$this->assertEquals('a@b.c', $user->email);
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
auth()->logout();
|
||||
$this->assertGuest();
|
||||
Event::fake();
|
||||
|
||||
$this->get('/auth/login/github/callback')->assertRedirect('/user');
|
||||
$this->assertAuthenticated();
|
||||
Event::assertNotDispatched('auth.registration.completed');
|
||||
Event::assertDispatched('auth.login.ready', function ($event, $payload) {
|
||||
[$user] = $payload;
|
||||
$this->assertEquals('a@b.c', $user->email);
|
||||
|
||||
return true;
|
||||
});
|
||||
Event::assertDispatched('auth.login.succeeded', function ($event, $payload) {
|
||||
[$user] = $payload;
|
||||
$this->assertEquals('a@b.c', $user->email);
|
||||
|
||||
return true;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user