From 540cda102f7922ad49eae200599977d696746e80 Mon Sep 17 00:00:00 2001 From: Tim Krampitz Date: Sat, 22 Aug 2026 19:05:53 +0200 Subject: [PATCH] Support Android emulator API access Enable CORS in all environments and disable HTTPS redirect in dev. Seed the database after migrations. Make the API base URL configurable, defaulting to the Android emulator host, and use per-config Android manifests. --- SlipItIn.Server/Data/DbSeeder.cs | 89 +++++++++++++++++++ SlipItIn.Server/Program.cs | 13 ++- .../Android/AndroidManifest.Debug.xml | 11 +++ .../Android/AndroidManifest.Release.xml | 11 +++ .../Platforms/Android/AndroidManifest.xml | 6 -- SlipItIn/Services/AppConfigurationService.cs | 15 +++- SlipItIn/SlipItIn.csproj | 8 ++ 7 files changed, 142 insertions(+), 11 deletions(-) create mode 100644 SlipItIn.Server/Data/DbSeeder.cs create mode 100644 SlipItIn/Platforms/Android/AndroidManifest.Debug.xml create mode 100644 SlipItIn/Platforms/Android/AndroidManifest.Release.xml delete mode 100644 SlipItIn/Platforms/Android/AndroidManifest.xml diff --git a/SlipItIn.Server/Data/DbSeeder.cs b/SlipItIn.Server/Data/DbSeeder.cs new file mode 100644 index 0000000..dc2e38c --- /dev/null +++ b/SlipItIn.Server/Data/DbSeeder.cs @@ -0,0 +1,89 @@ +using Microsoft.EntityFrameworkCore; +using SlipItIn.Shared.Models; + +namespace SlipItIn.Server.Data; + +/// +/// Befüllt die Datenbank mit Testdaten (2 Testuser, einige Dutzend Phrasen), +/// wenn sie leer ist. Dient der Erleichterung manueller Tests. +/// +public static class DbSeeder +{ + public static async Task SeedAsync(SlipItInDbContext context) + { + // Nur seeden, wenn die Datenbank leer ist + if (await context.Users.AnyAsync() || await context.Phrases.AnyAsync()) + return; + + var alice = new User + { + Username = "alice", + Email = "alice@test.local", + PasswordHash = BCrypt.Net.BCrypt.HashPassword("Test123!") + }; + + var bob = new User + { + Username = "bob", + Email = "bob@test.local", + PasswordHash = BCrypt.Net.BCrypt.HashPassword("Test123!") + }; + + context.Users.AddRange(alice, bob); + await context.SaveChangesAsync(); + + var phrases = new[] + { + "Das hat mir meine Oma schon immer gesagt.", + "Ich hab da mal eine Doku gesehen.", + "Das ist wie damals in der Grundschule.", + "Das muss man sich mal auf der Zunge zergehen lassen.", + "Da kommt mir direkt ein Lied in den Sinn.", + "Das ist wie beim Autofahren: Bremsen kann man immer noch.", + "Ich habe das Gefühl, wir reden aneinander vorbei.", + "Das würde ich an deiner Stelle nochmal überdenken.", + "Ich glaube, da steckt mehr dahinter.", + "Also ich finde, das riecht verdächtig nach Montag.", + "Das schmeckt nach mehr.", + "Da ist der Wurm drin.", + "Das hat hand und Fuß.", + "Das ist ein zweischneidiges Schwert.", + "Da liegt der Hase im Pfeffer.", + "Das ist wie ein guter Wein – wird mit den Jahren besser.", + "Ich würde sagen: Glück im Unglück.", + "Das ist schon fast eine Wissenschaft für sich.", + "Man muss das Kind beim Namen nennen.", + "Das ist wie Weihnachten und Geburtstag zusammen.", + "Da geht mir das Herz auf.", + "Ich würde das jetzt nicht überbewerten.", + "Das kommt mir spanisch vor.", + "Das ist das Beste seit geschnittenem Brot.", + "Da bleibt kein Auge trocken.", + "Das ist wie Nägel mit Köpfen machen.", + "Ich habe da so eine Vermutung.", + "Das ist wie ein roter Faden.", + "Da platzt mir gleich der Kragen.", + "Ich bin da ganz bei dir.", + "Das muss man erstmal sacken lassen.", + "Das ist wie ein offenes Buch.", + "Da würde ich nicht drauf wetten.", + "Das ist wie eine Achterbahn der Gefühle.", + "Ich hab da ein ganz mieses Gefühl bei.", + "Das ist wie ein Dorn im Auge." + }; + + var random = new Random(42); + var creators = new[] { alice, bob }; + + foreach (var text in phrases) + { + context.Phrases.Add(new Phrase + { + Text = text, + CreatorId = creators[random.Next(creators.Length)].Id + }); + } + + await context.SaveChangesAsync(); + } +} diff --git a/SlipItIn.Server/Program.cs b/SlipItIn.Server/Program.cs index 55a9cc0..fa5f097 100644 --- a/SlipItIn.Server/Program.cs +++ b/SlipItIn.Server/Program.cs @@ -98,21 +98,28 @@ var app = builder.Build(); // Aspire Default Endpoints (Health Checks) app.MapDefaultEndpoints(); -// Migrations anwenden +// Migrations anwenden und Testdaten seeden (nur wenn die Datenbank leer ist) using (var scope = app.Services.CreateScope()) { var db = scope.ServiceProvider.GetRequiredService(); db.Database.Migrate(); + await DbSeeder.SeedAsync(db); } // Configure the HTTP request pipeline. if (app.Environment.IsDevelopment()) { app.MapOpenApi(); - app.UseCors("AllowAll"); } -app.UseHttpsRedirection(); +app.UseCors("AllowAll"); + +// Beim Emulator/geräteübergreifenden Zugriff würde die HTTPS-Umleitung +// den Client auf eine nicht vertrauenswürdige Dev-Zertifikats-URL schicken. +if (!app.Environment.IsDevelopment()) +{ + app.UseHttpsRedirection(); +} app.UseAuthentication(); app.UseAuthorization(); diff --git a/SlipItIn/Platforms/Android/AndroidManifest.Debug.xml b/SlipItIn/Platforms/Android/AndroidManifest.Debug.xml new file mode 100644 index 0000000..9bb68cf --- /dev/null +++ b/SlipItIn/Platforms/Android/AndroidManifest.Debug.xml @@ -0,0 +1,11 @@ + + + + + + \ No newline at end of file diff --git a/SlipItIn/Platforms/Android/AndroidManifest.Release.xml b/SlipItIn/Platforms/Android/AndroidManifest.Release.xml new file mode 100644 index 0000000..2b26593 --- /dev/null +++ b/SlipItIn/Platforms/Android/AndroidManifest.Release.xml @@ -0,0 +1,11 @@ + + + + + + + \ No newline at end of file diff --git a/SlipItIn/Platforms/Android/AndroidManifest.xml b/SlipItIn/Platforms/Android/AndroidManifest.xml deleted file mode 100644 index 60ca4c2..0000000 --- a/SlipItIn/Platforms/Android/AndroidManifest.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/SlipItIn/Services/AppConfigurationService.cs b/SlipItIn/Services/AppConfigurationService.cs index 8a57d94..eea0248 100644 --- a/SlipItIn/Services/AppConfigurationService.cs +++ b/SlipItIn/Services/AppConfigurationService.cs @@ -4,9 +4,20 @@ namespace SlipItIn.Services; public class AppConfigurationService : IAppConfigurationService { + private const string ApiBaseUrlPreferenceKey = "api_base_url"; private const string DefaultApiBaseUrl = "https://localhost:7274"; + private const string AndroidEmulatorApiBaseUrl = "http://10.0.2.2:5234"; - public string ApiBaseUrl => DefaultApiBaseUrl; + public string ApiBaseUrl => Preferences.Default + .Get(ApiBaseUrlPreferenceKey, GetPlatformDefaultApiBaseUrl()) + .TrimEnd('/'); - public string HubUrl => $"{DefaultApiBaseUrl.TrimEnd('/')}/hubs/game"; + public string HubUrl => $"{ApiBaseUrl}/hubs/game"; + + private static string GetPlatformDefaultApiBaseUrl() + { + return DeviceInfo.Platform == DevicePlatform.Android + ? AndroidEmulatorApiBaseUrl + : DefaultApiBaseUrl; + } } diff --git a/SlipItIn/SlipItIn.csproj b/SlipItIn/SlipItIn.csproj index 81b956c..27c5b59 100644 --- a/SlipItIn/SlipItIn.csproj +++ b/SlipItIn/SlipItIn.csproj @@ -124,4 +124,12 @@ + + Platforms\Android\AndroidManifest.Debug.xml + + + + Platforms\Android\AndroidManifest.Release.xml + +