class SocialAuthService
{
+ /**
+ * The core socialite library used.
+ * @var Socialite
+ */
protected $socialite;
- protected $socialAccount;
- protected $validSocialDrivers = ['google', 'github', 'facebook', 'slack', 'twitter', 'azure', 'okta', 'gitlab', 'twitch', 'discord'];
+ /**
+ * The default built-in social drivers we support.
+ * @var string[]
+ */
+ protected $validSocialDrivers = [
+ 'google',
+ 'github',
+ 'facebook',
+ 'slack',
+ 'twitter',
+ 'azure',
+ 'okta',
+ 'gitlab',
+ 'twitch',
+ 'discord'
+ ];
+
+ /**
+ * Callbacks to run when configuring a social driver
+ * for an initial redirect action.
+ * Array is keyed by social driver name.
+ * Callbacks are passed an instance of the driver.
+ * @var array<string, callable>
+ */
+ protected $configureForRedirectCallbacks = [];
/**
* SocialAuthService constructor.
public function startLogIn(string $socialDriver): RedirectResponse
{
$driver = $this->validateDriver($socialDriver);
- return $this->getSocialDriver($driver)->redirect();
+ return $this->getDriverForRedirect($driver)->redirect();
}
/**
public function startRegister(string $socialDriver): RedirectResponse
{
$driver = $this->validateDriver($socialDriver);
- return $this->getSocialDriver($driver)->redirect();
+ return $this->getDriverForRedirect($driver)->redirect();
}
/**
/**
* Provide redirect options per service for the Laravel Socialite driver
*/
- public function getSocialDriver(string $driverName): Provider
+ protected function getDriverForRedirect(string $driverName): Provider
{
$driver = $this->socialite->driver($driverName);
$driver->with(['resource' => 'https://graph.windows.net']);
}
+ if (isset($this->configureForRedirectCallbacks[$driverName])) {
+ $this->configureForRedirectCallbacks[$driverName]($driver);
+ }
+
return $driver;
}
* within the `Config/services.php` file.
* Handler should be a Class@method handler to the SocialiteWasCalled event.
*/
- public function addSocialDriver(string $driverName, array $config, string $socialiteHandler)
- {
+ public function addSocialDriver(
+ string $driverName,
+ array $config,
+ string $socialiteHandler,
+ callable $configureForRedirect = null
+ ) {
$this->validSocialDrivers[] = $driverName;
config()->set('services.' . $driverName, $config);
config()->set('services.' . $driverName . '.redirect', url('/login/service/' . $driverName . '/callback'));
config()->set('services.' . $driverName . '.name', $config['name'] ?? $driverName);
Event::listen(SocialiteWasCalled::class, $socialiteHandler);
+ if (!is_null($configureForRedirect)) {
+ $this->configureForRedirectCallbacks[$driverName] = $configureForRedirect;
+ }
}
}
/**
* @see SocialAuthService::addSocialDriver
*/
- public function addSocialDriver(string $driverName, array $config, string $socialiteHandler)
+ public function addSocialDriver(string $driverName, array $config, string $socialiteHandler, callable $configureForRedirect = null)
{
$socialAuthService = app()->make(SocialAuthService::class);
- $socialAuthService->addSocialDriver($driverName, $config, $socialiteHandler);
+ $socialAuthService->addSocialDriver($driverName, $config, $socialiteHandler, $configureForRedirect);
}
}
\ No newline at end of file
'name' => 'Reddit',
], '\SocialiteProviders\Reddit\RedditExtendSocialite@handle');
});
+```
+
+In some cases you may need to customize the driver before it performs a redirect.
+This can be done by providing a callback as a fourth parameter like so:
+
+```php
+Theme::addSocialDriver('reddit', [
+ 'client_id' => 'abc123',
+ 'client_secret' => 'def456789',
+ 'name' => 'Reddit',
+], '\SocialiteProviders\Reddit\RedditExtendSocialite@handle', function($driver) {
+ $driver->with(['prompt' => 'select_account']);
+ $driver->scopes(['open_id']);
+});
```
\ No newline at end of file
<?php namespace Tests;
-use BookStack\Auth\Access\SocialAuthService;
use BookStack\Auth\User;
use BookStack\Entities\Models\Page;
use BookStack\Entities\Tools\PageContent;
$this->setSettings(['registration-enabled' => 'true']);
$user = factory(User::class)->make();
- $this->post('/register', ['email' => $user->email, 'name' => $user->name, 'password' => 'password']);
+ $this->post('/register', ['email' => $user->email, 'name' => $user->name, 'password' => 'password']);
$this->assertCount(2, $args);
$this->assertEquals('standard', $args[0]);
$loginResp->assertSee('Super Cat Name');
}
+
+ public function test_add_social_driver_allows_a_configure_for_redirect_callback_to_be_passed()
+ {
+ Theme::addSocialDriver(
+ 'discord',
+ [
+ 'client_id' => 'abc123',
+ 'client_secret' => 'def456',
+ 'name' => 'Super Cat Name',
+ ],
+ 'SocialiteProviders\Discord\DiscordExtendSocialite@handle',
+ function ($driver) {
+ $driver->with(['donkey' => 'donut']);
+ }
+ );
+
+ $loginResp = $this->get('/login/service/discord');
+ $redirect = $loginResp->headers->get('location');
+ $this->assertStringContainsString('donkey=donut', $redirect);
+ }
+
+
protected function usingThemeFolder(callable $callback)
{
// Create a folder and configure a theme