diff --git a/src/components/settings_modal/admin_tabs/rates_tab.js b/src/components/settings_modal/admin_tabs/rates_tab.js
new file mode 100644
index 000000000..c602dcc8a
--- /dev/null
+++ b/src/components/settings_modal/admin_tabs/rates_tab.js
@@ -0,0 +1,20 @@
+import RateSetting from '../helpers/rate_setting.vue'
+
+import SharedComputedObject from '../helpers/shared_computed_object.js'
+
+const RatesTab = {
+ provide () {
+ return {
+ defaultDraftMode: true,
+ defaultSource: 'admin'
+ }
+ },
+ components: {
+ RateSetting,
+ },
+ computed: {
+ ...SharedComputedObject()
+ }
+}
+
+export default RatesTab
diff --git a/src/components/settings_modal/admin_tabs/rates_tab.vue b/src/components/settings_modal/admin_tabs/rates_tab.vue
new file mode 100644
index 000000000..dad5ad6e0
--- /dev/null
+++ b/src/components/settings_modal/admin_tabs/rates_tab.vue
@@ -0,0 +1,41 @@
+
+
+
+
{{ $t('admin_dash.rate_limit.account_confirmation_resend') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/settings_modal/helpers/rate_setting.js b/src/components/settings_modal/helpers/rate_setting.js
new file mode 100644
index 000000000..7425cdba3
--- /dev/null
+++ b/src/components/settings_modal/helpers/rate_setting.js
@@ -0,0 +1,53 @@
+import Checkbox from 'src/components/checkbox/checkbox.vue'
+import Setting from './setting.js'
+
+export default {
+ ...Setting,
+ data () {
+ return {
+ newValue: '',
+ }
+ },
+ components: {
+ ...Setting.components,
+ Checkbox
+ },
+ props: {
+ ...Setting.props
+ },
+ computed: {
+ ...Setting.computed,
+ isSeparate () {
+ // [[a1, b1], [a2, b2]] vs [a, b]
+ return Array.isArray(this.visibleState[0])
+ },
+ normalizedState () {
+ if (this.isSeparate) {
+ return this.visibleState.map(y => y.map(x => Number(x) || 0))
+ } else {
+ return [this.visibleState.map(x => Number(x) || 0)]
+ }
+ }
+ },
+ methods: {
+ ...Setting.methods,
+ getValue ({ event, side, index, eventType }) {
+ if (eventType === 'edit') {
+ const value = Number(event.target.value)
+ if (Number.isNaN(value)) return this.visibleState
+
+ const newVal = [...this.normalizedState.map(x => [...x])]
+ newVal[side][index] = value
+ return newVal
+ }
+
+ if (eventType === 'toggleMode') {
+ if (event === 'split') {
+ return [this.normalizedState[0], this.normalizedState[0]]
+ } else if (event === 'join') {
+ return [this.normalizedState[0]]
+ }
+ }
+ }
+ }
+}
diff --git a/src/components/settings_modal/helpers/rate_setting.vue b/src/components/settings_modal/helpers/rate_setting.vue
new file mode 100644
index 000000000..a28ed13c2
--- /dev/null
+++ b/src/components/settings_modal/helpers/rate_setting.vue
@@ -0,0 +1,117 @@
+
+
+
+
+ {{ backendDescriptionLabel + ' ' }}
+
+
+ MISSING LABEL FOR {{ path }}
+
+
+
+
+ {{ backendDescriptionDescription + ' ' }}
+
+
+
+
+
+ {{ $t('admin_dash.rate_limit.period') }}
+
+
+ {{ $t('admin_dash.rate_limit.amount') }}
+
+
+
+
+ {{ $t('admin_dash.rate_limit.unauthenticated') }}
+
+
+ {{ $t('admin_dash.rate_limit.rate_limit') }}
+
+
+ update({ event: e, index: 0, side: 0, eventType: 'edit' })"
+ >
+
+
+ update({ event: e, index: 1, side: 0, eventType: 'edit' })"
+ >
+
+
+
+
+ {{ $t('admin_dash.rate_limit.authenticated') }}
+
+
+ update({ event: e, index: 0, side: 1, eventType: 'edit' })"
+ >
+
+
+ update({ event: e, index: 1, side: 1, eventType: 'edit' })"
+ >
+
+
+
+
update({ event: event ? 'join' : 'split', eventType: 'toggleMode' })"
+ >
+ {{ $t('admin_dash.rate_limit.separate') }}
+
+
+
+
+
+
+
diff --git a/src/components/settings_modal/settings_modal_admin_content.js b/src/components/settings_modal/settings_modal_admin_content.js
index 4a05868d8..77a3d6b81 100644
--- a/src/components/settings_modal/settings_modal_admin_content.js
+++ b/src/components/settings_modal/settings_modal_admin_content.js
@@ -13,6 +13,7 @@ import RegistrationsTab from './admin_tabs/registrations_tab.vue'
import AuthTab from './admin_tabs/auth_tab.vue'
import HTTPTab from './admin_tabs/http_tab.vue'
import OtherTab from './admin_tabs/other_tab.vue'
+import RatesTab from './admin_tabs/rates_tab.vue'
import PostsTab from './admin_tabs/posts_tab.vue'
import FederationTab from './admin_tabs/federation_tab.vue'
import JobQueuesTab from './admin_tabs/job_queues_tab.vue'
@@ -34,7 +35,8 @@ import {
faCircleNodes,
faUpload,
faMessage,
- faEllipsis
+ faEllipsis,
+ faGauge
} from '@fortawesome/free-solid-svg-icons'
library.add(
@@ -52,7 +54,8 @@ library.add(
faCircleNodes,
faUpload,
faMessage,
- faEllipsis
+ faEllipsis,
+ faGauge
)
const SettingsModalAdminContent = {
@@ -73,6 +76,7 @@ const SettingsModalAdminContent = {
AuthTab,
HTTPTab,
MonitoringTab,
+ RatesTab,
OtherTab,
PostsTab
},
diff --git a/src/components/settings_modal/settings_modal_admin_content.vue b/src/components/settings_modal/settings_modal_admin_content.vue
index 80c82d84f..ef8e2793e 100644
--- a/src/components/settings_modal/settings_modal_admin_content.vue
+++ b/src/components/settings_modal/settings_modal_admin_content.vue
@@ -92,6 +92,15 @@
+
+
+
+
{
const path = [c.group, c.key]
if (c.db) {
@@ -94,16 +95,33 @@ const adminSettingsStorage = {
// Using strings for modified paths for easier searching
c.db.forEach(x => modifiedPaths.add([...path, x].join(' -> ')))
}
- const convert = (value) => {
+
+ // we need to preserve tuples on second level only, possibly third
+ // but it's not a case right now.
+ const convert = (value, preserveTuples, preserveTuplesLv2) => {
if (Array.isArray(value) && value.length > 0 && value[0].tuple) {
- return value.reduce((acc, c) => {
- return { ...acc, [c.tuple[0]]: convert(c.tuple[1]) }
- }, {})
+ if (!preserveTuples) {
+ return value.reduce((acc, c) => {
+ return { ...acc, [c.tuple[0]]: convert(c.tuple[1], preserveTuplesLv2) }
+ }, {})
+ } else {
+ return value.map(x => x.tuple)
+ }
} else {
- return value
+ if (!preserveTuples) {
+ return value
+ } else {
+ return value.tuple
+ }
}
}
- set(config, path, convert(c.value))
+ // for most stuff we want maps since those are more convenient
+ // however this doesn't allow for multiple values per same key
+ // so for those cases we want to preserve tuples as-is
+ // right now it's made exclusively for :pleroma.:rate_limit
+ // so it might not work properly elsewhere
+ const preserveTuples = path.find(x => x === ':rate_limit')
+ set(config, path, convert(c.value, false, preserveTuples))
})
console.log('CONFIG', JSON.parse(JSON.stringify(config)))
// patching http adapter config to be easier to handle