using System.Linq;
using System.Text.Json;
using Gott.Extensions;
using Gott.Services;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Routing;
namespace Gott.Endpoints;
public static class ProfileEndpoint
{
public static void MapProfileEndpoints(this WebApplication app)
{
app.MapGet("/api/profile", HandleGet);
app.MapPut("/api/profile", HandleUpdate);
app.MapPut("/api/profile/password", HandlePasswordChange);
app.MapGet("/api/users", HandleListDirectory);
}
///
/// Minimales User-Verzeichnis für jeden eingeloggten Nutzer (z. B. um eine Session
/// einem anderen Benutzer zuzuweisen). Gibt bewusst NUR id/username/displayName zurück –
/// keine sensiblen Felder wie defaultPath/canUseCli/isAdmin (dafür gibt es /api/admin/users).
///
private static async System.Threading.Tasks.Task HandleListDirectory(HttpContext ctx, DatabaseService db)
{
var users = await db.GetUsers();
var result = users.Select(u => new
{
userId = u.UserId,
username = u.Username,
displayName = u.DisplayName
});
await ctx.Response.WriteAsJsonAsync(result);
}
private static async System.Threading.Tasks.Task HandleGet(HttpContext ctx, DatabaseService db)
{
var userId = ctx.GetUserId();
var user = await db.GetUser(userId);
if (user == null)
{
ctx.Response.StatusCode = 404;
await ctx.Response.WriteAsJsonAsync(new { error = "User not found" });
return;
}
await ctx.Response.WriteAsJsonAsync(new
{
userId = user.UserId,
username = user.Username,
displayName = user.DisplayName,
persona = user.Persona,
defaultPath = user.DefaultPath,
isAdmin = user.IsAdmin
});
}
private static async System.Threading.Tasks.Task HandleUpdate(HttpContext ctx, DatabaseService db)
{
var userId = ctx.GetUserId();
var body = await JsonSerializer.DeserializeAsync(ctx.Request.Body);
var displayName = body.TryGetProperty("displayName", out var dn) ? dn.GetString() : null;
var persona = body.TryGetProperty("persona", out var p) ? p.GetString() : null;
await db.UpdateUserProfile(userId, displayName, persona);
var user = await db.GetUser(userId);
await ctx.Response.WriteAsJsonAsync(new
{
userId = user.UserId,
username = user.Username,
displayName = user.DisplayName,
persona = user.Persona,
defaultPath = user.DefaultPath,
isAdmin = user.IsAdmin
});
}
private static async System.Threading.Tasks.Task HandlePasswordChange(HttpContext ctx, DatabaseService db, AuthService auth)
{
var userId = ctx.GetUserId();
var body = await JsonSerializer.DeserializeAsync(ctx.Request.Body);
var currentPassword = body.TryGetProperty("currentPassword", out var cp) ? cp.GetString() : null;
var newPassword = body.TryGetProperty("newPassword", out var np) ? np.GetString() : null;
if (string.IsNullOrEmpty(currentPassword) || string.IsNullOrEmpty(newPassword))
{
ctx.Response.StatusCode = 400;
await ctx.Response.WriteAsJsonAsync(new { error = "Aktuelles und neues Passwort erforderlich" });
return;
}
if (newPassword.Length < 4)
{
ctx.Response.StatusCode = 400;
await ctx.Response.WriteAsJsonAsync(new { error = "Passwort muss mindestens 4 Zeichen lang sein" });
return;
}
var user = await db.GetUser(userId);
if (user == null || !auth.VerifyPassword(currentPassword, user.PasswordHash))
{
ctx.Response.StatusCode = 403;
await ctx.Response.WriteAsJsonAsync(new { error = "Aktuelles Passwort ist falsch" });
return;
}
var newHash = auth.HashPassword(newPassword);
await db.UpdateUserPassword(userId, newHash);
await ctx.Response.WriteAsJsonAsync(new { ok = true });
}
}