Skip to content

Commit 6480715

Browse files
authored
fix(settings): strip env-supplied ApiKeys from the request before persisting (#9438)
GET /api/settings returns settings.ApiKeys as the merged env+runtime list via ApplicationConfig.ToRuntimeSettings(). The WebUI displays that list and round-trips it back on POST /api/settings unchanged. UpdateSettingsEndpoint was then doing: appConfig.ApiKeys = append(envKeys, runtimeKeys...) where runtimeKeys already contained envKeys (because the UI got them from the merged GET). Every save therefore duplicated the env keys on top of the previous merge, and also wrote the duplicates to runtime_settings.json so the duplication survived restarts and compounded with each save. This is the user-visible behaviour in #9071: the Web UI shows the keys twice / three times after consecutive saves. Before we marshal the settings to disk or call ApplyRuntimeSettings, drop any incoming key that already appears in startupConfig.ApiKeys. The file on disk now stores only the genuinely runtime-added keys; the subsequent append(envKeys, runtimeKeys...) produces one copy of each env key, as intended. Behaviour is unchanged for users who never had env keys set. Fixes #9071 Co-authored-by: SAY-5 <SAY-5@users.noreply.github.com>
1 parent f683231 commit 6480715

1 file changed

Lines changed: 21 additions & 0 deletions

File tree

core/http/endpoints/localai/settings.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,27 @@ func UpdateSettingsEndpoint(app *application.Application) echo.HandlerFunc {
110110
})
111111
}
112112

113+
// The UI reads ApiKeys from GET /api/settings, which already returns the
114+
// merged env+runtime list. When the user clicks Save, the same merged
115+
// list comes back in the POST body. Strip the env-supplied keys from
116+
// the incoming list before we persist or re-merge, otherwise each save
117+
// duplicates the env keys on top of the previous merge (#9071).
118+
if settings.ApiKeys != nil {
119+
envKeys := startupConfig.ApiKeys
120+
envSet := make(map[string]struct{}, len(envKeys))
121+
for _, k := range envKeys {
122+
envSet[k] = struct{}{}
123+
}
124+
runtimeOnly := make([]string, 0, len(*settings.ApiKeys))
125+
for _, k := range *settings.ApiKeys {
126+
if _, fromEnv := envSet[k]; fromEnv {
127+
continue
128+
}
129+
runtimeOnly = append(runtimeOnly, k)
130+
}
131+
settings.ApiKeys = &runtimeOnly
132+
}
133+
113134
settingsFile := filepath.Join(appConfig.DynamicConfigsDir, "runtime_settings.json")
114135
settingsJSON, err := json.MarshalIndent(settings, "", " ")
115136
if err != nil {

0 commit comments

Comments
 (0)