diff --git a/lib/Service/OpenAiSettingsService.php b/lib/Service/OpenAiSettingsService.php
index 415427fd..833023c8 100644
--- a/lib/Service/OpenAiSettingsService.php
+++ b/lib/Service/OpenAiSettingsService.php
@@ -219,7 +219,7 @@ public function getQuotas(): array {
// Make sure all quota types are set in the json encoded app value (in case new quota types are added in the future)
if (count($quotas) !== count(Application::DEFAULT_QUOTAS)) {
foreach (Application::DEFAULT_QUOTAS as $quotaType => $_) {
- if (!isset($quotas[$quotaType])) {
+ if (!isset($quotas[$quotaType]) || !is_int($quotas[$quotaType]) || $quotas[$quotaType] < 0) {
$quotas[$quotaType] = Application::DEFAULT_QUOTAS[$quotaType];
}
}
diff --git a/src/components/AdminSettings.vue b/src/components/AdminSettings.vue
index 659f9c50..fba69594 100644
--- a/src/components/AdminSettings.vue
+++ b/src/components/AdminSettings.vue
@@ -296,6 +296,36 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ t('integration_openai', 'Use "{newParam}" parameter instead of the deprecated "{deprecatedParam}"', { newParam: 'max_completion_tokens', deprecatedParam: 'max_tokens' }) }}
+
+
@@ -352,11 +382,13 @@
-
- {{ t('integration_openai', 'Use authentication for image retrieval request') }}
-
+
+
+ {{ t('integration_openai', 'Use authentication for image retrieval request') }}
+
+
@@ -482,9 +514,13 @@
-
+
{{ t('integration_openai', 'Usage quotas per time period') }}
-
+
+
+ {{ t('integration_openai', 'A per-user quota for each quota type can be set. If the user has not provided their own API key, this quota will be enforced.') }}
+ {{ t('integration_openai', '"0" means unlimited usage for a particular quota type.') }}
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{ t('integration_openai', 'Use "{newParam}" parameter instead of the deprecated "{deprecatedParam}"', { newParam: 'max_completion_tokens', deprecatedParam: 'max_tokens' }) }}
-
@@ -831,6 +839,8 @@ export default {
}
}, 2000),
onInput: debounce(async function() {
+ // sanitize quotas
+ this.state.quotas = this.state.quotas.map(e => parseInt(e)).map(e => isNaN(e) || e < 0 ? 0 : e)
const values = {
service_name: this.state.service_name,
request_timeout: parseInt(this.state.request_timeout),