feat: implement Blazor web interface for GM session management
Deploy Telegram Bot / deploy (push) Has been cancelled
Deploy Telegram Bot / deploy (push) Has been cancelled
- Created GmRelay.Web project (Blazor Server) - Created GmRelay.Shared library for domain models and rendering - Refactored GmRelay.Bot to use the Shared library - Integrated Telegram Login widget with server-side HMAC verification - Added Dashboard, Group Details, and Edit Session pages - Enabled bot notifications and in-place message updates from web actions - Updated .NET Aspire orchestration and Docker Compose configuration
This commit is contained in:
@@ -0,0 +1,92 @@
|
||||
using GmRelay.Web.Components;
|
||||
using GmRelay.Web.Services;
|
||||
using Microsoft.AspNetCore.Authentication.Cookies;
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using System.Security.Claims;
|
||||
using Telegram.Bot;
|
||||
using Npgsql;
|
||||
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
|
||||
// Add Aspire service defaults
|
||||
builder.AddServiceDefaults();
|
||||
|
||||
// Add Npgsql
|
||||
builder.AddNpgsqlDataSource("gmrelay-db");
|
||||
|
||||
// Add Services
|
||||
builder.Services.AddSingleton<TelegramAuthService>();
|
||||
builder.Services.AddSingleton<SessionService>();
|
||||
|
||||
// Add Bot Client
|
||||
builder.Services.AddSingleton<ITelegramBotClient>(sp =>
|
||||
{
|
||||
var config = sp.GetRequiredService<IConfiguration>();
|
||||
var token = config["Telegram__BotToken"] ?? config["Telegram:BotToken"]
|
||||
?? throw new InvalidOperationException("Telegram__BotToken is required.");
|
||||
return new TelegramBotClient(token);
|
||||
});
|
||||
|
||||
// Add Authentication
|
||||
builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
|
||||
.AddCookie(options =>
|
||||
{
|
||||
options.LoginPath = "/login";
|
||||
options.AccessDeniedPath = "/access-denied";
|
||||
});
|
||||
|
||||
builder.Services.AddAuthorization();
|
||||
builder.Services.AddCascadingAuthenticationState();
|
||||
|
||||
// Add services to the container.
|
||||
builder.Services.AddRazorComponents()
|
||||
.AddInteractiveServerComponents();
|
||||
|
||||
var app = builder.Build();
|
||||
|
||||
// Configure the HTTP request pipeline.
|
||||
if (!app.Environment.IsDevelopment())
|
||||
{
|
||||
app.UseExceptionHandler("/Error", createScopeForErrors: true);
|
||||
app.UseHsts();
|
||||
}
|
||||
|
||||
app.UseHttpsRedirection();
|
||||
|
||||
app.UseAuthentication();
|
||||
app.UseAuthorization();
|
||||
app.UseAntiforgery();
|
||||
|
||||
app.MapStaticAssets();
|
||||
app.MapRazorComponents<App>()
|
||||
.AddInteractiveServerRenderMode();
|
||||
|
||||
// Endpoint to handle Telegram Login callback
|
||||
app.MapGet("/auth/telegram", async (HttpContext context, TelegramAuthService authService) =>
|
||||
{
|
||||
if (authService.Verify(context.Request.Query, out var telegramId, out var name))
|
||||
{
|
||||
var claims = new List<Claim>
|
||||
{
|
||||
new Claim(ClaimTypes.NameIdentifier, telegramId.ToString()),
|
||||
new Claim(ClaimTypes.Name, name),
|
||||
new Claim("TelegramId", telegramId.ToString())
|
||||
};
|
||||
|
||||
var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
|
||||
var authProperties = new AuthenticationProperties { IsPersistent = true };
|
||||
|
||||
await context.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(claimsIdentity), authProperties);
|
||||
return Results.Redirect("/");
|
||||
}
|
||||
|
||||
return Results.Redirect("/login?error=auth_failed");
|
||||
});
|
||||
|
||||
app.MapPost("/auth/logout", async (HttpContext context) =>
|
||||
{
|
||||
await context.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
|
||||
return Results.Redirect("/");
|
||||
});
|
||||
|
||||
app.Run();
|
||||
Reference in New Issue
Block a user