mirror of
https://github.com/CJackHwang/ds2api.git
synced 2026-05-12 20:27:43 +08:00
feat(admin): remember Vercel sync credentials
This commit is contained in:
@@ -15,5 +15,6 @@ type Handler struct {
|
||||
|
||||
var writeJSON = adminshared.WriteJSON
|
||||
var intFrom = adminshared.IntFrom
|
||||
var maskSecretPreview = adminshared.MaskSecretPreview
|
||||
|
||||
func nilIfEmpty(s string) any { return adminshared.NilIfEmpty(s) }
|
||||
|
||||
@@ -61,9 +61,34 @@ func (h *Handler) verify(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
func (h *Handler) getVercelConfig(w http.ResponseWriter, _ *http.Request) {
|
||||
saved := h.Store.Snapshot().Vercel
|
||||
token, tokenSource := firstConfiguredValue(
|
||||
[2]string{"env", os.Getenv("VERCEL_TOKEN")},
|
||||
[2]string{"config", saved.Token},
|
||||
)
|
||||
projectID, _ := firstConfiguredValue(
|
||||
[2]string{"env", os.Getenv("VERCEL_PROJECT_ID")},
|
||||
[2]string{"config", saved.ProjectID},
|
||||
)
|
||||
teamID, _ := firstConfiguredValue(
|
||||
[2]string{"env", os.Getenv("VERCEL_TEAM_ID")},
|
||||
[2]string{"config", saved.TeamID},
|
||||
)
|
||||
writeJSON(w, http.StatusOK, map[string]any{
|
||||
"has_token": strings.TrimSpace(os.Getenv("VERCEL_TOKEN")) != "",
|
||||
"project_id": strings.TrimSpace(os.Getenv("VERCEL_PROJECT_ID")),
|
||||
"team_id": nilIfEmpty(strings.TrimSpace(os.Getenv("VERCEL_TEAM_ID"))),
|
||||
"has_token": token != "",
|
||||
"token_preview": maskSecretPreview(token),
|
||||
"token_source": nilIfEmpty(tokenSource),
|
||||
"project_id": projectID,
|
||||
"team_id": nilIfEmpty(teamID),
|
||||
})
|
||||
}
|
||||
|
||||
func firstConfiguredValue(values ...[2]string) (string, string) {
|
||||
for _, pair := range values {
|
||||
value := strings.TrimSpace(pair[1])
|
||||
if value != "" {
|
||||
return value, strings.TrimSpace(pair[0])
|
||||
}
|
||||
}
|
||||
return "", ""
|
||||
}
|
||||
|
||||
38
internal/httpapi/admin/auth/handler_auth_test.go
Normal file
38
internal/httpapi/admin/auth/handler_auth_test.go
Normal file
@@ -0,0 +1,38 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"ds2api/internal/config"
|
||||
)
|
||||
|
||||
func TestGetVercelConfigFallsBackToSavedConfig(t *testing.T) {
|
||||
t.Setenv("DS2API_CONFIG_JSON", `{"keys":["k1"],"vercel":{"token":"saved-token","project_id":"saved-project","team_id":"saved-team"}}`)
|
||||
t.Setenv("VERCEL_TOKEN", "")
|
||||
t.Setenv("VERCEL_PROJECT_ID", "")
|
||||
t.Setenv("VERCEL_TEAM_ID", "")
|
||||
h := &Handler{Store: config.LoadStore()}
|
||||
|
||||
rec := httptest.NewRecorder()
|
||||
h.getVercelConfig(rec, httptest.NewRequest(http.MethodGet, "/admin/vercel/config", nil))
|
||||
|
||||
if rec.Code != http.StatusOK {
|
||||
t.Fatalf("expected 200, got %d: %s", rec.Code, rec.Body.String())
|
||||
}
|
||||
var payload map[string]any
|
||||
if err := json.Unmarshal(rec.Body.Bytes(), &payload); err != nil {
|
||||
t.Fatalf("decode response: %v", err)
|
||||
}
|
||||
if payload["has_token"] != true {
|
||||
t.Fatalf("expected saved token to be detected: %#v", payload)
|
||||
}
|
||||
if payload["token_source"] != "config" || payload["project_id"] != "saved-project" || payload["team_id"] != "saved-team" {
|
||||
t.Fatalf("unexpected preconfig payload: %#v", payload)
|
||||
}
|
||||
if payload["token_preview"] == "saved-token" {
|
||||
t.Fatal("token preview leaked the full token")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user