You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix: use valid LinkedIn API endpoint and update version to 202506
Replaced non-existent q=hashtag endpoint with q=author query that
fetches authenticated user's posts and filters client-side for
hashtag matches. Added ResolveMemberUrn() with caching. Updated
LinkedIn-Version header from 202401 to 202506 to fix 426 error.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copy file name to clipboardExpand all lines: .ai-team/agents/sombra/history.md
+2Lines changed: 2 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -24,6 +24,8 @@
24
24
-**LinkedIn OAuth flow:** Admin-initiated OAuth is implemented via minimal API endpoints (`/api/linkedin/authorize` and `/api/linkedin/callback`) in Service_LinkedInOAuth.cs, mapped in Program.cs via `app.MapLinkedInOAuthEndpoints()`. The flow uses LinkedIn's 3-legged OAuth 2.0 with scopes `openid`, `profile`, `w_member_social`, and `r_organization_social`. Access tokens expire in 60 days. Tokens are stored encrypted in LinkedInConfiguration via IConfigureTagzApp. State parameter is persisted in AuthenticationProperties for CSRF protection. The admin UI shows an "Authorize with LinkedIn" button that redirects to the authorize endpoint, which then redirects to LinkedIn, which redirects back to the callback endpoint where tokens are exchanged and stored.
25
25
-**Blazor.Client WebAssembly constraints:** Microsoft.AspNetCore.WebUtilities.QueryHelpers is NOT available in Blazor WebAssembly projects. Use simple string parsing with `query.Contains()` and `Uri.UnescapeDataString()` for query string handling in client-side Blazor components.
26
26
-**OAuth security patterns:** Callback URLs must use HTTPS and match exactly what's registered in the LinkedIn Developer App. The app uses X-Forwarded-Proto and X-Forwarded-Host headers to correctly construct callback URLs when behind proxies/containers. State parameter is generated as GUID and stored in AuthenticationProperties, then validated on callback to prevent CSRF attacks.
27
+
-**LinkedIn API reality check:**`GET /rest/posts?q=hashtag&hashtag={tag}` does NOT exist. The `q=hashtag` finder is not a valid query parameter. With `w_member_social` scope, the realistic approach is `GET /rest/posts?q=author&author={memberUrn}` to fetch the authenticated member's own posts, then filter client-side for hashtag matches. The member URN is obtained from `GET /v2/userinfo` (`sub` field → `urn:li:person:{sub}`).
28
+
-**LinkedIn member URN resolution:** Call `/v2/userinfo` once at StartAsync (and lazily on first use if that failed). Cache the URN in `_memberUrn` field. No version header needed on the `/v2/userinfo` endpoint — it's a standard OAuth2 endpoint.
27
29
28
30
## Team Updates
29
31
- 📌 **2026-02-18**: LinkedIn provider plan decided by Mercy — architecture approved for implementation. 10 work items across 4 phases (scaffolding, core provider, integration, testing/docs). Estimated 2-3 days for implementation, 1 day for tests/docs.
0 commit comments