Merge branch 'main' into chore/rename-channels-tab
This commit is contained in:
commit
8dad00d4df
6 changed files with 65 additions and 23 deletions
|
|
@ -102,7 +102,10 @@ SPACES_BUCKET=
|
|||
LINKEDIN_CLIENT_ID=
|
||||
LINKEDIN_CLIENT_SECRET=
|
||||
LINKEDIN_CLIENT_REDIRECT="${APP_URL}/accounts/linkedin/callback"
|
||||
# LINKEDIN_SCOPES="openid,profile,email,w_member_social"
|
||||
LINKEDIN_PAGE_CLIENT_REDIRECT="${APP_URL}/accounts/linkedin-page/callback"
|
||||
LINKEDIN_PAGE_CLIENT_REDIRECT="${APP_URL}/accounts/linkedin-page/callback"
|
||||
# LINKEDIN_PAGE_SCOPES="openid,profile,email,w_organization_social,r_organization_social,rw_organization_admin,w_member_social"
|
||||
|
||||
# X / Twitter (https://developer.twitter.com)
|
||||
X_CLIENT_ID=
|
||||
|
|
|
|||
|
|
@ -22,14 +22,6 @@ class LinkedInController extends SocialController
|
|||
|
||||
protected SocialPlatform $platform = SocialPlatform::LinkedIn;
|
||||
|
||||
protected array $scopes = [
|
||||
'openid',
|
||||
'profile',
|
||||
'email',
|
||||
'r_basicprofile',
|
||||
'w_member_social',
|
||||
];
|
||||
|
||||
public function connect(Request $request): Response|RedirectResponse
|
||||
{
|
||||
$this->ensurePlatformEnabled();
|
||||
|
|
@ -42,7 +34,7 @@ public function connect(Request $request): Response|RedirectResponse
|
|||
|
||||
$this->authorize('manageAccounts', $workspace);
|
||||
|
||||
return $this->redirectToProvider($request, $this->driver, $this->scopes);
|
||||
return $this->redirectToProvider($request, $this->driver, config('trypost.platforms.linkedin.scopes'));
|
||||
}
|
||||
|
||||
public function callback(Request $request): View
|
||||
|
|
|
|||
|
|
@ -24,16 +24,6 @@ class LinkedInPageController extends SocialController
|
|||
|
||||
protected SocialPlatform $platform = SocialPlatform::LinkedInPage;
|
||||
|
||||
protected array $scopes = [
|
||||
'openid',
|
||||
'profile',
|
||||
'email',
|
||||
'w_organization_social',
|
||||
'r_organization_social',
|
||||
'rw_organization_admin',
|
||||
'w_member_social',
|
||||
];
|
||||
|
||||
public function connect(Request $request): SymfonyResponse|RedirectResponse
|
||||
{
|
||||
$this->ensurePlatformEnabled();
|
||||
|
|
@ -55,7 +45,7 @@ public function connect(Request $request): SymfonyResponse|RedirectResponse
|
|||
|
||||
return Inertia::location(
|
||||
Socialite::driver($this->driver)
|
||||
->scopes($this->scopes)
|
||||
->scopes(config('trypost.platforms.linkedin-page.scopes'))
|
||||
->with([
|
||||
'redirect_uri' => config('services.linkedin-openid.redirect_page'),
|
||||
])
|
||||
|
|
@ -80,7 +70,7 @@ public function callback(Request $request): View|RedirectResponse
|
|||
|
||||
try {
|
||||
$socialUser = Socialite::driver($this->driver)
|
||||
->scopes($this->scopes)
|
||||
->scopes(config('trypost.platforms.linkedin-page.scopes'))
|
||||
->with([
|
||||
'redirect_uri' => config('services.linkedin-openid.redirect_page'),
|
||||
])
|
||||
|
|
|
|||
|
|
@ -80,10 +80,14 @@
|
|||
'api' => env('LINKEDIN_API', 'https://api.linkedin.com'),
|
||||
// OAuth host is different from the data API (api.linkedin.com).
|
||||
'oauth_api' => env('LINKEDIN_OAUTH_API', 'https://www.linkedin.com'),
|
||||
// Scopes for LinkedIn authentication
|
||||
'scopes' => array_values(array_filter(array_map('trim', explode(',', (string) env('LINKEDIN_SCOPES', 'openid,profile,email,w_member_social'))))),
|
||||
],
|
||||
'linkedin-page' => [
|
||||
'enabled' => env('LINKEDIN_PAGE_ENABLED', true),
|
||||
'api' => env('LINKEDIN_PAGE_API', 'https://api.linkedin.com'),
|
||||
// Scopes for LinkedIn Page authentication
|
||||
'scopes' => array_values(array_filter(array_map('trim', explode(',', (string) env('LINKEDIN_PAGE_SCOPES', 'openid,profile,email,w_organization_social,r_organization_social,rw_organization_admin,w_member_social'))))),
|
||||
],
|
||||
'x' => [
|
||||
'enabled' => env('X_ENABLED', true),
|
||||
|
|
|
|||
|
|
@ -89,7 +89,9 @@ R2_URL=
|
|||
LINKEDIN_CLIENT_ID=
|
||||
LINKEDIN_CLIENT_SECRET=
|
||||
LINKEDIN_CLIENT_REDIRECT="${APP_URL}/accounts/linkedin/callback"
|
||||
# LINKEDIN_SCOPES="openid,profile,email,w_member_social"
|
||||
LINKEDIN_PAGE_CLIENT_REDIRECT="${APP_URL}/accounts/linkedin-page/callback"
|
||||
# LINKEDIN_PAGE_SCOPES="openid,profile,email,w_organization_social,r_organization_social,rw_organization_admin,w_member_social"
|
||||
|
||||
X_CLIENT_ID=
|
||||
X_CLIENT_SECRET=
|
||||
|
|
|
|||
|
|
@ -39,6 +39,57 @@
|
|||
expect(session('social_connect_workspace'))->toBe($this->workspace->id);
|
||||
});
|
||||
|
||||
/**
|
||||
* Mock the LinkedIn Socialite driver, hit /connect, and return the scopes
|
||||
* the controller requested.
|
||||
*
|
||||
* @return array<int, string>
|
||||
*/
|
||||
$captureConnectScopes = function (object $test): array {
|
||||
$captured = [];
|
||||
|
||||
$driverMock = Mockery::mock();
|
||||
$driverMock->shouldReceive('scopes')
|
||||
->withArgs(function (array $scopes) use (&$captured) {
|
||||
$captured = $scopes;
|
||||
|
||||
return true;
|
||||
})
|
||||
->andReturnSelf();
|
||||
$driverMock->shouldReceive('redirect')->andReturn(Mockery::mock([
|
||||
'getTargetUrl' => 'https://www.linkedin.com/oauth/v2/authorization?test=1',
|
||||
]));
|
||||
|
||||
Socialite::shouldReceive('driver')
|
||||
->with('linkedin')
|
||||
->andReturn($driverMock);
|
||||
|
||||
$test->actingAs($test->user)
|
||||
->withHeader('X-Inertia', 'true')
|
||||
->get(route('app.social.linkedin.connect'));
|
||||
|
||||
return $captured;
|
||||
};
|
||||
|
||||
test('linkedin connect requests the default scope set', function () use ($captureConnectScopes) {
|
||||
config(['trypost.platforms.linkedin.scopes' => ['openid', 'profile', 'email', 'w_member_social']]);
|
||||
|
||||
expect($captureConnectScopes($this))->toEqualCanonicalizing([
|
||||
'openid', 'profile', 'email', 'w_member_social',
|
||||
]);
|
||||
});
|
||||
|
||||
test('linkedin connect requests the scopes configured via LINKEDIN_SCOPES', function () use ($captureConnectScopes) {
|
||||
// Operators whose LinkedIn app has legacy/enterprise products approved
|
||||
// override the default set via LINKEDIN_SCOPES (exploded into the config
|
||||
// array), e.g. re-adding r_basicprofile to restore the vanityName lookup.
|
||||
config(['trypost.platforms.linkedin.scopes' => ['openid', 'profile', 'email', 'w_member_social', 'r_basicprofile']]);
|
||||
|
||||
expect($captureConnectScopes($this))->toEqualCanonicalizing([
|
||||
'openid', 'profile', 'email', 'w_member_social', 'r_basicprofile',
|
||||
]);
|
||||
});
|
||||
|
||||
test('linkedin oauth callback creates account', function () {
|
||||
session([
|
||||
'social_connect_workspace' => $this->workspace->id,
|
||||
|
|
@ -99,7 +150,7 @@
|
|||
// splits on space (the OAuth 2.0 default), so approvedScopes lands as
|
||||
// a single-element array with the whole CSV inside. The save path
|
||||
// must normalize back to individual tokens.
|
||||
$socialiteUser->approvedScopes = ['email,openid,profile,r_basicprofile,w_member_social'];
|
||||
$socialiteUser->approvedScopes = ['email,openid,profile,w_member_social'];
|
||||
|
||||
Socialite::shouldReceive('driver')
|
||||
->with('linkedin')
|
||||
|
|
@ -116,7 +167,7 @@
|
|||
|
||||
$account = SocialAccount::where('platform_user_id', 'abc123xyz')->first();
|
||||
expect($account->scopes)->toEqualCanonicalizing([
|
||||
'email', 'openid', 'profile', 'r_basicprofile', 'w_member_social',
|
||||
'email', 'openid', 'profile', 'w_member_social',
|
||||
]);
|
||||
});
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue