protected override async Task ExchangeCodeAsync()

in src/JetBrains.Space.AspNetCore.Authentication/SpaceHandler.cs [104:142]


    protected override async Task<OAuthTokenResponse> ExchangeCodeAsync(OAuthCodeExchangeContext context)
    {
        var tokenRequestParameters = new Dictionary<string, string?>
        {
            { "client_id", Options.ClientId },
            { "redirect_uri", context.RedirectUri },
            { "client_secret", Options.ClientSecret },
            { "code", context.Code },
            { "grant_type", "authorization_code" }
        };

        // PKCE https://tools.ietf.org/html/rfc7636#section-4.5, see BuildChallengeUrl
        if (context.Properties.Items.TryGetValue(OAuthConstants.CodeVerifierKey, out var codeVerifier))
        {
            tokenRequestParameters.Add(OAuthConstants.CodeVerifierKey, codeVerifier);
            context.Properties.Items.Remove(OAuthConstants.CodeVerifierKey);
        }

#pragma warning disable 8620 // new Dictionary<string, string?> -> new FormUrlEncodedContent(tokenRequestParameters)
        var requestContent = new FormUrlEncodedContent(tokenRequestParameters);
#pragma warning restore 8620

        var requestMessage = new HttpRequestMessage(HttpMethod.Post, Options.TokenEndpoint)
            .WithClientAndSdkHeaders(SdkInfo.Version);

        requestMessage.Headers.Authorization = AuthenticationHeaderValue.Parse(
            "Basic " + Convert.ToBase64String(Encoding.UTF8.GetBytes($"{Options.ClientId}:{Options.ClientSecret}")));
        requestMessage.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
        requestMessage.Content = requestContent;
        var response = await Backchannel.SendAsync(requestMessage, Context.RequestAborted);
        if (response.IsSuccessStatusCode)
        {
            var payload = JsonDocument.Parse(await response.Content.ReadAsStringAsync());
            return OAuthTokenResponse.Success(payload);
        }

        var error = "OAuth token endpoint failure: " + await Display(response);
        return OAuthTokenResponse.Failed(new Exception(error));
    }