Scene/source builder with image overlays, reuse dialog, and SQLite layout persistence
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
using System.Diagnostics;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
@@ -46,6 +47,49 @@ public class YouTubeAuthService
|
||||
return $"{AuthorizationEndpoint}?{encoded}";
|
||||
}
|
||||
|
||||
public async Task<YouTubeChannel?> AuthenticateAsync()
|
||||
{
|
||||
const int port = 8765;
|
||||
var redirectUri = $"http://localhost:{port}/oauth2/callback";
|
||||
|
||||
if (string.IsNullOrWhiteSpace(_clientId) || string.IsNullOrWhiteSpace(_clientSecret))
|
||||
return null;
|
||||
|
||||
using var listener = new HttpListener();
|
||||
listener.Prefixes.Add($"{redirectUri}/");
|
||||
listener.Start();
|
||||
|
||||
Process.Start(new ProcessStartInfo(GetAuthorizationUrl(redirectUri)) { UseShellExecute = true });
|
||||
|
||||
HttpListenerContext context;
|
||||
try
|
||||
{
|
||||
using var cts = new CancellationTokenSource(TimeSpan.FromMinutes(5));
|
||||
context = await listener.GetContextAsync().WaitAsync(cts.Token);
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var code = context.Request.QueryString["code"];
|
||||
var error = context.Request.QueryString["error"];
|
||||
|
||||
var html = error != null
|
||||
? "<html><body style=\"font-family:sans-serif\"><h2>Sign-in failed</h2><p>You can close this window and return to ytLlive.</p></body></html>"
|
||||
: "<html><body style=\"font-family:sans-serif\"><h2>Sign-in successful!</h2><p>You can close this window and return to ytLlive.</p></body></html>";
|
||||
var buffer = Encoding.UTF8.GetBytes(html);
|
||||
context.Response.ContentType = "text/html; charset=utf-8";
|
||||
context.Response.ContentLength64 = buffer.Length;
|
||||
await context.Response.OutputStream.WriteAsync(buffer);
|
||||
context.Response.Close();
|
||||
|
||||
if (error != null || string.IsNullOrEmpty(code))
|
||||
return null;
|
||||
|
||||
return await ExchangeCodeForToken(code, redirectUri);
|
||||
}
|
||||
|
||||
public async Task<YouTubeChannel?> ExchangeCodeForToken(string code, string redirectUri)
|
||||
{
|
||||
var body = new FormUrlEncodedContent(new Dictionary<string, string>
|
||||
|
||||
Reference in New Issue
Block a user