feat: first-run claim wizard (no default admin, claim code from the backend log); owner list shows account and passkey; container install first [CI]
ci/woodpecker/push/main-amd64-build Pipeline was successful

This commit is contained in:
justme committed 2026-10-08 06:47:10 +08:00
1 parent 2ae63653c4
commit f22fdf8b68
31 files changed
+799 -49

No files matched your search

@@ -1,3 +1,4 @@
using System.Net;
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json.Nodes;
@@ -25,6 +26,9 @@ public class BackendFixture : IAsyncLifetime
public const string AdminUser = "admin";
public const string AdminPassword = "correct horse battery";
/// <summary>首次认领码:和线上一样,第一个管理员通过 <c>/api/admin/auth/setup</c> 创建,不再用配置里的默认账户。</summary>
public const string ClaimCode = "TEST-CLAIM-CODE-0001";
private readonly List<AgentSimulator> _agents = [];
private string _adminToken = "";
private int _counter;
@@ -256,8 +260,7 @@ public class BackendFixture : IAsyncLifetime
options.SecureCookies = false;
options.WindowGrace = TimeSpan.Zero;
options.AnalysisPollInterval = TimeSpan.FromMilliseconds(100);
options.InitialAdminUser = AdminUser;
options.InitialAdminPassword = AdminPassword;
options.ClaimCode = ClaimCode;
options.LoginAttemptsPerMinute = LoginAttemptsPerMinute;
options.RequireOwner = false; // 大部分测试不建立信任根;属主必选的测试自己打开(OwnerTests)
options.GeoLookupUrl = string.Empty; // 测试里不访问外部服务
@@ -282,8 +285,8 @@ public class BackendFixture : IAsyncLifetime
{
using HttpClient session = NewClient();
using HttpResponseMessage login = await session.PostAsync(
"/api/admin/auth/login", Json(new JsonObject { ["username"] = AdminUser, ["password"] = AdminPassword, ["return_session"] = true }));
login.EnsureSuccessStatusCode();
"/api/admin/auth/setup", Json(new JsonObject { ["claim_code"] = ClaimCode, ["username"] = AdminUser, ["password"] = AdminPassword, ["return_session"] = true }));
Assert.Equal(HttpStatusCode.Created, login.StatusCode);
session.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", JsonNode.Parse(await login.Content.ReadAsStringAsync())!["session_token"]!.GetValue<string>());
string origin = BaseAddress.GetLeftPart(UriPartial.Authority);