refactor: POST env vars as JSON array instead of KEY=value string
All checks were successful
Check / check (pull_request) Successful in 4s
All checks were successful
Check / check (pull_request) Successful in 4s
Replace the string-serialized KEY=value format with a proper JSON array
of {key, value} objects for the env var save endpoint.
Frontend changes:
- envVarEditor.submitAll() now uses fetch() with Content-Type:
application/json and X-CSRF-Token header instead of form submission
- Sends JSON array: [{"key":"FOO","value":"bar"}, ...]
- Hidden bulk form replaced with hidden div holding CSRF token
- envVarEditor now receives appId parameter for the fetch URL
Backend changes:
- HandleEnvVarSave reads JSON body via json.NewDecoder instead of
parsing form values with parseEnvPairs
- Returns JSON {"ok": true} instead of HTTP redirect
- Removed parseEnvPairs function and envPair struct entirely
- Added envPairJSON struct with json tags for deserialization
Tests updated to POST JSON arrays instead of form-encoded strings.
Closes #163
This commit is contained in:
@@ -903,9 +903,16 @@ func (h *Handlers) addKeyValueToApp(
|
||||
http.Redirect(writer, request, "/apps/"+application.ID, http.StatusSeeOther)
|
||||
}
|
||||
|
||||
// envPairJSON represents a key-value pair in the JSON request body.
|
||||
type envPairJSON struct {
|
||||
Key string `json:"key"`
|
||||
Value string `json:"value"`
|
||||
}
|
||||
|
||||
// HandleEnvVarSave handles bulk saving of all environment variables.
|
||||
// It deletes all existing env vars for the app and inserts the full
|
||||
// submitted set (monolithic list approach).
|
||||
// It reads a JSON array of {key, value} objects from the request body,
|
||||
// deletes all existing env vars for the app, and inserts the full
|
||||
// submitted set.
|
||||
func (h *Handlers) HandleEnvVarSave() http.HandlerFunc {
|
||||
return func(writer http.ResponseWriter, request *http.Request) {
|
||||
appID := chi.URLParam(request, "id")
|
||||
@@ -917,14 +924,15 @@ func (h *Handlers) HandleEnvVarSave() http.HandlerFunc {
|
||||
return
|
||||
}
|
||||
|
||||
parseErr := request.ParseForm()
|
||||
if parseErr != nil {
|
||||
var pairs []envPairJSON
|
||||
|
||||
decodeErr := json.NewDecoder(request.Body).Decode(&pairs)
|
||||
if decodeErr != nil {
|
||||
http.Error(writer, "Bad Request", http.StatusBadRequest)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
pairs := parseEnvPairs(request.FormValue("env_vars"))
|
||||
ctx := request.Context()
|
||||
|
||||
// Delete all existing env vars for this app
|
||||
@@ -944,59 +952,23 @@ func (h *Handlers) HandleEnvVarSave() http.HandlerFunc {
|
||||
for _, p := range pairs {
|
||||
envVar := models.NewEnvVar(h.db)
|
||||
envVar.AppID = application.ID
|
||||
envVar.Key = p.key
|
||||
envVar.Value = p.value
|
||||
envVar.Key = p.Key
|
||||
envVar.Value = p.Value
|
||||
|
||||
saveErr := envVar.Save(ctx)
|
||||
if saveErr != nil {
|
||||
h.log.Error(
|
||||
"failed to save env var",
|
||||
"key", p.key,
|
||||
"key", p.Key,
|
||||
"error", saveErr,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
http.Redirect(
|
||||
writer,
|
||||
request,
|
||||
"/apps/"+appID+"?success=env-updated",
|
||||
http.StatusSeeOther,
|
||||
)
|
||||
h.respondJSON(writer, request, map[string]bool{"ok": true}, http.StatusOK)
|
||||
}
|
||||
}
|
||||
|
||||
// envPair holds a parsed key-value pair from the env vars textarea.
|
||||
type envPair struct {
|
||||
key string
|
||||
value string
|
||||
}
|
||||
|
||||
// parseEnvPairs parses KEY=VALUE lines from a textarea string.
|
||||
// Blank lines and lines starting with # are skipped.
|
||||
func parseEnvPairs(text string) []envPair {
|
||||
var pairs []envPair
|
||||
|
||||
for line := range strings.SplitSeq(text, "\n") {
|
||||
line = strings.TrimSpace(line)
|
||||
if line == "" || strings.HasPrefix(line, "#") {
|
||||
continue
|
||||
}
|
||||
|
||||
key, value, ok := strings.Cut(line, "=")
|
||||
if !ok || strings.TrimSpace(key) == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
pairs = append(pairs, envPair{
|
||||
key: strings.TrimSpace(key),
|
||||
value: value,
|
||||
})
|
||||
}
|
||||
|
||||
return pairs
|
||||
}
|
||||
|
||||
// HandleLabelAdd handles adding a label.
|
||||
func (h *Handlers) HandleLabelAdd() http.HandlerFunc {
|
||||
return func(writer http.ResponseWriter, request *http.Request) {
|
||||
|
||||
Reference in New Issue
Block a user