Merge pull request #36 from trypostit/fix/linkedin-page-scopes

fix(linkedin-page): persist OAuth scopes through the page-picker flow
This commit is contained in:
Paulo Castellano 2026-05-14 11:49:20 -03:00 committed by GitHub
commit 368176cccb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 39 additions and 0 deletions

View file

@ -103,6 +103,7 @@ public function callback(Request $request): View|RedirectResponse
'token' => $socialUser->token,
'refresh_token' => $socialUser->refreshToken,
'expires_in' => $socialUser->expiresIn,
'approved_scopes' => $socialUser->approvedScopes ?? [],
'organizations' => $organizations,
'reconnect_id' => session('linkedin_page_reconnect_id'),
],
@ -182,6 +183,8 @@ public function select(Request $request): View
'access_token' => $pendingData['token'],
'refresh_token' => $pendingData['refresh_token'],
'token_expires_at' => $pendingData['expires_in'] ? now()->addSeconds($pendingData['expires_in']) : null,
// LinkedIn returns scope CSV-joined but Socialite splits on space, so re-split here.
'scopes' => explode(',', implode(',', $pendingData['approved_scopes'] ?? [])),
'meta' => [
'organization_id' => $request->organization_id,
'admin_user_id' => $pendingData['user_id'],
@ -211,6 +214,8 @@ public function select(Request $request): View
'access_token' => $pendingData['token'],
'refresh_token' => $pendingData['refresh_token'],
'token_expires_at' => $pendingData['expires_in'] ? now()->addSeconds($pendingData['expires_in']) : null,
// LinkedIn returns scope CSV-joined but Socialite splits on space, so re-split here.
'scopes' => explode(',', implode(',', $pendingData['approved_scopes'] ?? [])),
'status' => Status::Connected,
'error_message' => null,
'disconnected_at' => null,

View file

@ -166,6 +166,40 @@
]);
});
test('linkedin page select splits comma-separated approvedScopes before saving', function () {
session([
'linkedin_page_pending' => [
'workspace_id' => $this->workspace->id,
'user_id' => 'user123',
'name' => 'John Doe',
'avatar' => null,
'token' => 'test-access-token',
'refresh_token' => 'test-refresh-token',
'expires_in' => 5184000,
// Simulates what Socialite returns for LinkedIn (CSV-joined into
// a single array element because the provider splits on space).
'approved_scopes' => ['email,openid,profile,w_organization_social,r_organization_social,rw_organization_admin,w_member_social'],
'organizations' => [
['id' => 999888, 'name' => 'Scope Company', 'vanity_name' => 'scopeco', 'logo' => null],
],
],
]);
$this->actingAs($this->user)->post(route('app.social.linkedin-page.select'), [
'organization_id' => 999888,
'organization_name' => 'Scope Company',
'organization_vanity_name' => 'scopeco',
'organization_logo' => null,
]);
$account = SocialAccount::where('platform_user_id', 999888)->first();
expect($account->scopes)->toEqualCanonicalizing([
'email', 'openid', 'profile',
'w_organization_social', 'r_organization_social',
'rw_organization_admin', 'w_member_social',
]);
});
test('linkedin page select fails with expired session', function () {
// No session data