Backend: - Cookie + OIDC + API Key authentication schemes - ApiKeyAuthenticationHandler with SHA-256 validation and 24h cache - AuthController with login/logout/profile endpoints - API Key domain model (EventFlow aggregate, events, commands) - ApiKeyReadModel and repository for key validation - Database migration 002_ApiKeys.sql - CORS configuration for frontend Frontend: - authService.ts for login/logout/profile API calls - authStore.ts (Zustand) for user context state - ProtectedRoute component for route guards - Header updated with user display and logout - GraphQL client with credentials: include 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
45 lines
1.1 KiB
C#
45 lines
1.1 KiB
C#
using Books.Api;
|
|
using Books.Api.GraphQL;
|
|
using GraphQL;
|
|
using GraphQL.Server.Ui.Altair;
|
|
using Hangfire;
|
|
|
|
// Enable legacy timestamp behavior for Npgsql 6.0+
|
|
// This allows DateTimeOffset with non-UTC offsets to be written to timestamptz columns
|
|
AppContext.SetSwitch("Npgsql.EnableLegacyTimestampBehavior", true);
|
|
|
|
var builder = WebApplication.CreateBuilder(args);
|
|
|
|
// Configure EventFlow, Hangfire, GraphQL and all services
|
|
Startup.ConfigureServices(builder.Services, builder.Configuration, builder.Environment);
|
|
|
|
var app = builder.Build();
|
|
|
|
// Configure the HTTP request pipeline
|
|
if (app.Environment.IsDevelopment())
|
|
{
|
|
app.UseHangfireDashboard();
|
|
}
|
|
|
|
app.UseHttpsRedirection();
|
|
|
|
// CORS must come before auth
|
|
app.UseCors();
|
|
|
|
// Authentication & Authorization
|
|
app.UseAuthentication();
|
|
app.UseAuthorization();
|
|
|
|
// Map controllers (for AuthController)
|
|
app.MapControllers();
|
|
|
|
// GraphQL endpoint
|
|
app.UseGraphQL<BooksSchema>("/graphql");
|
|
|
|
// GraphQL UI (development only) - use external tools like Altair, Insomnia, or GraphiQL
|
|
if (app.Environment.IsDevelopment())
|
|
{
|
|
app.UseGraphQLAltair("/graphql/ui");
|
|
}
|
|
|
|
app.Run();
|