using System.Threading.Tasks; using eprintServer.Entities; using System.Text.Json; using eprintServer.Enums; using eprintServer.Models; using System; namespace eprintServer.Services; public class LinkedInOAuthService : BaseOAuthService { private readonly OAuthSettingsService _settingsService; private readonly IHttpClientFactory _httpClientFactory; public LinkedInOAuthService(OAuthSettingsService settingsService, UserService userService, TokenService tokenService, IHttpClientFactory httpClientFactory) : base(userService, tokenService) { _settingsService = settingsService; _httpClientFactory = httpClientFactory; } public async Task<(User? user, string? token, string? error)> HandleLoginCallbackAsync(string code) { var settings = await _settingsService.GetOrCreateSettingsAsync(); var client = _httpClientFactory.CreateClient(); // 1. Token Exchange var request = new HttpRequestMessage(HttpMethod.Post, "https://www.linkedin.com/oauth/v2/accessToken"); request.Content = new FormUrlEncodedContent(new Dictionary { ["grant_type"] = "authorization_code", ["code"] = code, ["client_id"] = settings.LinkedInClientId!, ["client_secret"] = settings.LinkedInClientSecret!, ["redirect_uri"] = "https://server.etbaaonline.com/api/v1/oauth/linkedin/callback" }); var response = await client.SendAsync(request); var tokenData = await response.Content.ReadFromJsonAsync(); var accessToken = tokenData.GetProperty("access_token").GetString(); // 2. User Info (OpenID Connect) client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", accessToken); var profileResponse = await client.GetAsync("https://api.linkedin.com/v2/userinfo"); var liUser = await profileResponse.Content.ReadFromJsonAsync(); var externalUser = new ExternalUserData { Email = liUser.GetProperty("email").GetString()!, Name = liUser.GetProperty("name").GetString()!, ProviderUserId = liUser.GetProperty("sub").GetString() }; return await SignInUserAsync(externalUser, Provider.LINKEDIN); } }