diff --git a/CHANGELOG.md b/CHANGELOG.md index 19b3e47a..d8c1f43f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,11 +9,13 @@ Write each change in both `### English` and `### 中文` under `## Unreleased`. - Replace native Logs and Models filter dropdowns with compact HeroUI Select controls that match the 32px toolbar - Add named client API keys with optional provider allowlists, and show the console administrator key on System +- Store an empty client-key provider allowlist as `[]` instead of JSON `null` ### 中文 - Logs 和模型页的筛选下拉改用紧凑 HeroUI Select,高度对齐 32px 工具栏 - 新增可限制供应商的客户端 API 密钥,并在系统页显示控制台管理员密钥 +- 客户端密钥未限制供应商时写入 `[]`,不再存成 JSON `null` ## 0.2.20 - 2026-08-29 diff --git a/internal/accounts/api_keys.go b/internal/accounts/api_keys.go index 86485a54..940703a1 100644 --- a/internal/accounts/api_keys.go +++ b/internal/accounts/api_keys.go @@ -57,7 +57,7 @@ func APIKeyPrefix(secret string) string { func NormalizeAPIKeyProviders(ids []string) ([]string, error) { if len(ids) == 0 { - return nil, nil + return []string{}, nil } seen := map[string]struct{}{} out := make([]string, 0, len(ids)) diff --git a/internal/accounts/store_test.go b/internal/accounts/store_test.go index 8bfa091e..279b9230 100644 --- a/internal/accounts/store_test.go +++ b/internal/accounts/store_test.go @@ -185,6 +185,24 @@ func TestStoreCreatesNamedAPIKeys(t *testing.T) { } defer store.Close() + all, err := store.CreateAPIKey(ctx, CreateAPIKey{Name: "All", Enabled: true}) + if err != nil { + t.Fatal(err) + } + if all.Providers == nil || len(all.Providers) != 0 { + t.Fatalf("empty allowlist providers = %#v", all.Providers) + } + listedAll, err := store.ListAPIKeys(ctx) + if err != nil { + t.Fatal(err) + } + if len(listedAll) != 1 || listedAll[0].Providers == nil { + t.Fatalf("listed empty allowlist = %+v", listedAll) + } + if err := store.DeleteAPIKey(ctx, all.ID); err != nil { + t.Fatal(err) + } + created, err := store.CreateAPIKey(ctx, CreateAPIKey{Name: "CI", Providers: []string{"qoder"}, Enabled: true}) if err != nil { t.Fatal(err)