📄 src/Api/TikTokAuth/TikTokBackchannelHandler.cs
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.WebUtilities;

namespace Slopper.Api.TikTokAuth;

internal sealed class TikTokBackchannelHandler() : DelegatingHandler(new HttpClientHandler())
{
    protected override async Task<HttpResponseMessage> SendAsync(
        HttpRequestMessage request,
        CancellationToken cancellationToken
    )
    {
        if (request.Content?.Headers.ContentType?.MediaType is "application/x-www-form-urlencoded")
        {
            var body = await request.Content.ReadAsStringAsync(cancellationToken);
            var form = QueryHelpers.ParseQuery(body);
            if (form.Remove("client_id", out var clientId))
            {
                form["client_key"] = clientId;
                request.Content = new FormUrlEncodedContent(
                    form.SelectMany(kvp => kvp.Value.Select(v => new KeyValuePair<string, string>(kvp.Key, v ?? "")))
                );
            }
        }
        return await base.SendAsync(request, cancellationToken);
    }
}