Merge branch 'feature/ability-to-remove-settings-from-db' into 'develop'
Ability to remove settings from db See merge request pleroma/admin-fe!77
This commit is contained in:
commit
267d59a6d4
39 changed files with 635 additions and 489 deletions
|
@ -65,7 +65,6 @@
|
|||
"vue-i18n": "^8.9.0",
|
||||
"vue-router": "3.0.2",
|
||||
"vue-splitpane": "1.0.2",
|
||||
"vue2-ace-editor": "^0.0.13",
|
||||
"vuedraggable": "^2.16.0",
|
||||
"vuex": "3.0.1",
|
||||
"xlsx": "^0.11.16"
|
||||
|
|
|
@ -40,16 +40,4 @@ export async function removeSettings(configs, authHost, token) {
|
|||
})
|
||||
}
|
||||
|
||||
export async function uploadMedia(file, authHost, token) {
|
||||
const formData = new FormData()
|
||||
formData.append('file', file)
|
||||
return await request({
|
||||
baseURL: baseName(authHost),
|
||||
url: `/api/v1/media`,
|
||||
method: 'post',
|
||||
headers: authHeaders(token),
|
||||
data: formData
|
||||
})
|
||||
}
|
||||
|
||||
const authHeaders = (token) => token ? { 'Authorization': `Bearer ${getToken()}` } : {}
|
||||
|
|
|
@ -339,12 +339,10 @@ export default {
|
|||
mediaProxy: 'Media Proxy',
|
||||
metadata: 'Metadata',
|
||||
gopher: 'Gopher',
|
||||
endpoint: 'Endpoint',
|
||||
jobQueue: 'Job queue',
|
||||
webPush: 'Web push encryption',
|
||||
esshd: 'BBS / SSH access',
|
||||
rateLimiters: 'Rate limiters',
|
||||
database: 'Database',
|
||||
other: 'Other',
|
||||
relays: 'Relays',
|
||||
follow: 'Follow',
|
||||
|
@ -383,6 +381,7 @@ export default {
|
|||
file: 'File',
|
||||
update: 'Update',
|
||||
remove: 'Remove',
|
||||
removeFromDB: 'Remove setting from the DB',
|
||||
selectLocalPack: 'Select the local pack to copy to',
|
||||
localPack: 'Local pack',
|
||||
specifyShortcode: 'Specify a custom shortcode',
|
||||
|
@ -405,7 +404,8 @@ export default {
|
|||
nowNewPacksToImport: 'No new packs to import',
|
||||
successfullyUpdated: 'Successfully updated',
|
||||
metadatLowerCase: 'metadata',
|
||||
files: 'files'
|
||||
files: 'files',
|
||||
successfullyRemoved: 'Setting removed successfully!'
|
||||
},
|
||||
invites: {
|
||||
inviteTokens: 'Invite tokens',
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import _ from 'lodash'
|
||||
|
||||
export const checkPartialUpdate = (settings, updatedSettings, description) => {
|
||||
return Object.keys(updatedSettings).reduce((acc, group) => {
|
||||
acc[group] = Object.keys(updatedSettings[group]).reduce((acc, key) => {
|
||||
|
@ -20,12 +22,22 @@ export const checkPartialUpdate = (settings, updatedSettings, description) => {
|
|||
}, {})
|
||||
}
|
||||
|
||||
const getCurrentValue = (object, keys) => {
|
||||
if (keys.length === 0) {
|
||||
return object
|
||||
const getCurrentValue = (type, value, path) => {
|
||||
if (type === 'state') {
|
||||
return _.get(value, path)
|
||||
} else {
|
||||
const [firstSettingName, ...restKeys] = path
|
||||
const firstSegment = value[firstSettingName]
|
||||
if (restKeys.length === 0 || !firstSegment) {
|
||||
return firstSegment || false
|
||||
} else {
|
||||
const secondSegment = (value, keys) => {
|
||||
const [element, ...rest] = keys
|
||||
return keys.length === 0 ? value : secondSegment(value[1][element], rest)
|
||||
}
|
||||
return secondSegment(firstSegment, restKeys)
|
||||
}
|
||||
}
|
||||
const [currentKey, ...restKeys] = keys
|
||||
return getCurrentValue(object[currentKey], restKeys)
|
||||
}
|
||||
|
||||
const getValueWithoutKey = (key, [type, value]) => {
|
||||
|
@ -136,24 +148,26 @@ export const processNested = (valueForState, valueForUpdatedSettings, group, par
|
|||
const [{ key, type }, ...otherParents] = parents
|
||||
const path = [group, parentKey, ...parents.reverse().map(parent => parent.key).slice(0, -1)]
|
||||
|
||||
let updatedValueForState = valueExists(settings, path)
|
||||
? { ...getCurrentValue(settings[group][parentKey], parents.map(el => el.key).slice(0, -1)),
|
||||
let updatedValueForState = valueExists('state', settings, path)
|
||||
? { ...getCurrentValue('state', settings[group][parentKey], parents.map(el => el.key).slice(0, -1)),
|
||||
...{ [key]: valueForState }}
|
||||
: { [key]: valueForState }
|
||||
let updatedValueForUpdatedSettings = valueExists(updatedSettings, path)
|
||||
? { ...getCurrentValue(updatedSettings[group][parentKey], parents.map(el => el.key).slice(0, -1))[1],
|
||||
let updatedValueForUpdatedSettings = valueExists('updatedSettings', updatedSettings, path)
|
||||
? { ...getCurrentValue('updatedSettings', updatedSettings[group][parentKey], parents.map(el => el.key).slice(0, -1))[1],
|
||||
...{ [key]: [type, valueForUpdatedSettings] }}
|
||||
: { [key]: [type, valueForUpdatedSettings] }
|
||||
|
||||
if (group === ':mime' && parents[0].key === ':types') {
|
||||
updatedValueForState = { ...settings[group][parents[0].key].value, ...updatedValueForState }
|
||||
updatedValueForUpdatedSettings = {
|
||||
...Object.keys(settings[group][parents[0].key].value)
|
||||
updatedValueForState = settings[group][parents[0].key]
|
||||
? { ...settings[group][parents[0].key].value, ...updatedValueForState }
|
||||
: updatedValueForState
|
||||
updatedValueForUpdatedSettings = settings[group][parents[0].key]
|
||||
? { ...Object.keys(settings[group][parents[0].key].value)
|
||||
.reduce((acc, el) => {
|
||||
return { ...acc, [el]: [type, settings[group][parents[0].key].value[el]] }
|
||||
}, {}),
|
||||
...updatedValueForUpdatedSettings
|
||||
}
|
||||
...updatedValueForUpdatedSettings }
|
||||
: updatedValueForUpdatedSettings
|
||||
}
|
||||
|
||||
return otherParents.length === 1
|
||||
|
@ -161,12 +175,25 @@ export const processNested = (valueForState, valueForUpdatedSettings, group, par
|
|||
: processNested(updatedValueForState, updatedValueForUpdatedSettings, group, parentKey, otherParents, settings, updatedSettings)
|
||||
}
|
||||
|
||||
const valueExists = (value, path) => {
|
||||
if (path.length === 0) {
|
||||
return true
|
||||
const valueExists = (type, value, path) => {
|
||||
if (type === 'state') {
|
||||
return _.get(value, path)
|
||||
} else {
|
||||
const [group, key, firstSettingName, ...restKeys] = path
|
||||
const firstSegment = _.get(value, [group, key, firstSettingName])
|
||||
if (restKeys.length === 0 || !firstSegment) {
|
||||
return firstSegment || false
|
||||
} else {
|
||||
const secondSegment = (value, keys) => {
|
||||
if (keys.length === 0) {
|
||||
return true
|
||||
}
|
||||
const [element, ...rest] = keys
|
||||
return value[1][element] ? secondSegment(value[1][element], rest) : false
|
||||
}
|
||||
return secondSegment(firstSegment, restKeys)
|
||||
}
|
||||
}
|
||||
const [element, ...rest] = path
|
||||
return value[element] ? valueExists(value[element], rest) : false
|
||||
}
|
||||
|
||||
export const valueHasTuples = (key, value) => {
|
||||
|
@ -218,8 +245,6 @@ const wrapValues = (settings, currentState) => {
|
|||
} else if (setting === ':ip') {
|
||||
const ip = value.split('.').map(s => parseInt(s, 10))
|
||||
return { 'tuple': [setting, { 'tuple': ip }] }
|
||||
} else if (setting === ':ssl_options') {
|
||||
return { 'tuple': [setting, wrapValues(value, currentState)] }
|
||||
} else if (setting === ':args') {
|
||||
const index = value.findIndex(el => el === 'implode')
|
||||
const updatedArray = value.slice()
|
||||
|
|
|
@ -1,32 +1,25 @@
|
|||
import { fetchDescription, fetchSettings, removeSettings, updateSettings, uploadMedia } from '@/api/settings'
|
||||
import { fetchDescription, fetchSettings, removeSettings, updateSettings } from '@/api/settings'
|
||||
import { checkPartialUpdate, parseNonTuples, parseTuples, valueHasTuples, wrapUpdatedSettings } from './normalizers'
|
||||
import _ from 'lodash'
|
||||
|
||||
const settings = {
|
||||
state: {
|
||||
description: [],
|
||||
settings: {
|
||||
':auto_linker': {},
|
||||
':cors_plug': {},
|
||||
':esshd': {},
|
||||
':http_signatures': {},
|
||||
':logger': {},
|
||||
':mime': {},
|
||||
':phoenix': {},
|
||||
':pleroma': {},
|
||||
':prometheus': {},
|
||||
':quack': {},
|
||||
':tesla': {},
|
||||
':ueberauth': {},
|
||||
':web_push_encryption': {}
|
||||
},
|
||||
settings: {},
|
||||
updatedSettings: {},
|
||||
ignoredIfNotEnabled: ['enabled', 'handler', 'password_authenticator', 'port', 'priv_dir'],
|
||||
db: {},
|
||||
loading: true
|
||||
},
|
||||
mutations: {
|
||||
CLEAR_UPDATED_SETTINGS: (state) => {
|
||||
state.updatedSettings = {}
|
||||
},
|
||||
REMOVE_SETTING_FROM_UPDATED: (state, { group, key, subkeys }) => {
|
||||
if (_.get(state.updatedSettings, [group, key, subkeys[0]])) {
|
||||
const { [subkeys[0]]: value, ...updatedSettings } = state.updatedSettings[group][key]
|
||||
state.updatedSettings = updatedSettings
|
||||
}
|
||||
},
|
||||
SET_DESCRIPTION: (state, data) => {
|
||||
state.description = data
|
||||
},
|
||||
|
@ -38,10 +31,19 @@ const settings = {
|
|||
const parsedValue = valueHasTuples(key, value)
|
||||
? { value: parseNonTuples(key, value) }
|
||||
: parseTuples(value, key)
|
||||
acc[group][key] = { ...acc[group][key], ...parsedValue }
|
||||
acc[group] = acc[group] ? { ...acc[group], [key]: parsedValue } : { [key]: parsedValue }
|
||||
return acc
|
||||
}, state.settings)
|
||||
}, {})
|
||||
|
||||
const newDbSettings = data.reduce((acc, { group, key, db }) => {
|
||||
if (db) {
|
||||
acc[group] = acc[group] ? { ...acc[group], [key]: db } : { [key]: db }
|
||||
}
|
||||
return acc
|
||||
}, {})
|
||||
|
||||
state.settings = newSettings
|
||||
state.db = newDbSettings
|
||||
},
|
||||
UPDATE_SETTINGS: (state, { group, key, input, value, type }) => {
|
||||
const updatedSetting = !state.updatedSettings[group] || (key === 'Pleroma.Emails.Mailer' && input === ':adapter')
|
||||
|
@ -66,8 +68,12 @@ const settings = {
|
|||
commit('SET_SETTINGS', response.data.configs)
|
||||
commit('SET_LOADING', false)
|
||||
},
|
||||
async RemoveSetting({ getters }, configs) {
|
||||
async RemoveSetting({ commit, getters }, configs) {
|
||||
await removeSettings(configs, getters.authHost, getters.token)
|
||||
const response = await fetchSettings(getters.authHost, getters.token)
|
||||
const { group, key, subkeys } = configs[0]
|
||||
commit('SET_SETTINGS', response.data.configs)
|
||||
commit('REMOVE_SETTING_FROM_UPDATED', { group, key, subkeys: subkeys || [] })
|
||||
},
|
||||
async SubmitChanges({ getters, commit, state }) {
|
||||
const updatedData = checkPartialUpdate(state.settings, state.updatedSettings, state.description)
|
||||
|
@ -75,7 +81,8 @@ const settings = {
|
|||
return [...acc, ...wrapUpdatedSettings(group, updatedData[group], state.settings)]
|
||||
}, [])
|
||||
|
||||
const response = await updateSettings(configs, getters.authHost, getters.token)
|
||||
await updateSettings(configs, getters.authHost, getters.token)
|
||||
const response = await fetchSettings(getters.authHost, getters.token)
|
||||
commit('SET_SETTINGS', response.data.configs)
|
||||
commit('CLEAR_UPDATED_SETTINGS')
|
||||
},
|
||||
|
@ -84,24 +91,14 @@ const settings = {
|
|||
? commit('UPDATE_SETTINGS', { group, key, input, value, type })
|
||||
: commit('UPDATE_SETTINGS', { group, key: input, input: '_value', value, type })
|
||||
},
|
||||
UpdateState({ commit, dispatch, state }, { group, key, input, value }) {
|
||||
async UpdateState({ commit, getters, state }, { group, key, input, value }) {
|
||||
if (key === 'Pleroma.Emails.Mailer' && input === ':adapter') {
|
||||
const subkeys = Object.keys(state.settings[group][key]).filter(el => el !== ':adapter')
|
||||
const emailsValue = subkeys.map(el => {
|
||||
return { 'tuple': [el, state.settings[group][key][el]] }
|
||||
})
|
||||
dispatch('RemoveSetting', [{ group, key, value: emailsValue, delete: true, subkeys }])
|
||||
await removeSettings([{ group, key, delete: true, subkeys }], getters.authHost, getters.token)
|
||||
}
|
||||
key
|
||||
? commit('UPDATE_STATE', { group, key, input, value })
|
||||
: commit('UPDATE_STATE', { group, key: input, input: 'value', value })
|
||||
},
|
||||
async UploadMedia({ dispatch, getters, state }, { file, tab, inputName, childName }) {
|
||||
const response = await uploadMedia(file, getters.authHost, getters.token)
|
||||
const updatedValue = childName
|
||||
? { ...state.settings[tab][inputName], ...{ [childName]: response.data.url }}
|
||||
: response.data.url
|
||||
dispatch('UpdateSettings', { tab, data: { [inputName]: updatedValue }})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
import { mapGetters } from 'vuex'
|
||||
import i18n from '@/lang'
|
||||
import Setting from './Setting'
|
||||
import _ from 'lodash'
|
||||
|
||||
export default {
|
||||
name: 'ActivityPub',
|
||||
|
@ -29,13 +30,13 @@ export default {
|
|||
return this.settings.description.find(setting => setting.key === ':activitypub')
|
||||
},
|
||||
activitypubData() {
|
||||
return this.settings.settings[':pleroma'][':activitypub']
|
||||
return _.get(this.settings.settings, [':pleroma', ':activitypub']) || {}
|
||||
},
|
||||
isMobile() {
|
||||
return this.$store.state.app.device === 'mobile'
|
||||
},
|
||||
labelWidth() {
|
||||
return this.isMobile ? '100px' : '240px'
|
||||
return this.isMobile ? '100px' : '280px'
|
||||
},
|
||||
loading() {
|
||||
return this.$store.state.settings.loading
|
||||
|
@ -44,7 +45,7 @@ export default {
|
|||
return this.settings.description.find(setting => setting.key === ':user')
|
||||
},
|
||||
userData() {
|
||||
return this.settings.settings[':pleroma'][':user']
|
||||
return _.get(this.settings.settings, [':pleroma', ':user']) || {}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
import { mapGetters } from 'vuex'
|
||||
import i18n from '@/lang'
|
||||
import Setting from './Setting'
|
||||
import _ from 'lodash'
|
||||
|
||||
export default {
|
||||
name: 'Authentication',
|
||||
|
@ -37,19 +38,19 @@ export default {
|
|||
return this.settings.description.find(setting => setting.key === ':auth')
|
||||
},
|
||||
authData() {
|
||||
return this.settings.settings[':pleroma'][':auth']
|
||||
return _.get(this.settings.settings, [':pleroma', ':auth']) || {}
|
||||
},
|
||||
isMobile() {
|
||||
return this.$store.state.app.device === 'mobile'
|
||||
},
|
||||
labelWidth() {
|
||||
return this.isMobile ? '100px' : '240px'
|
||||
return this.isMobile ? '100px' : '280px'
|
||||
},
|
||||
ldap() {
|
||||
return this.settings.description.find(setting => setting.key === ':ldap')
|
||||
},
|
||||
ldapData() {
|
||||
return this.settings.settings[':pleroma'][':ldap']
|
||||
return _.get(this.settings.settings, [':pleroma', ':ldap']) || {}
|
||||
},
|
||||
loading() {
|
||||
return this.settings.loading
|
||||
|
@ -58,13 +59,13 @@ export default {
|
|||
return this.settings.description.find(setting => setting.key === ':oauth2')
|
||||
},
|
||||
oauth2Data() {
|
||||
return this.settings.settings[':pleroma'][':oauth2']
|
||||
return _.get(this.settings.settings, [':pleroma', ':oauth2']) || {}
|
||||
},
|
||||
pleromaAuthenticator() {
|
||||
return this.settings.description.find(setting => setting.description === 'Authenticator')
|
||||
},
|
||||
pleromaAuthenticatorData() {
|
||||
return this.settings.settings[':pleroma']['Pleroma.Web.Auth.Authenticator']
|
||||
return _.get(this.settings.settings, [':pleroma', 'Pleroma.Web.Auth.Authenticator']) || {}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
import { mapGetters } from 'vuex'
|
||||
import i18n from '@/lang'
|
||||
import Setting from './Setting'
|
||||
import _ from 'lodash'
|
||||
|
||||
export default {
|
||||
name: 'AutoLinker',
|
||||
|
@ -23,13 +24,13 @@ export default {
|
|||
return this.settings.description.find(setting => setting.key === ':opts')
|
||||
},
|
||||
autoLinkerData() {
|
||||
return this.settings.settings[':auto_linker'][':opts']
|
||||
return _.get(this.settings.settings, [':auto_linker', ':opts']) || {}
|
||||
},
|
||||
isMobile() {
|
||||
return this.$store.state.app.device === 'mobile'
|
||||
},
|
||||
labelWidth() {
|
||||
return this.isMobile ? '100px' : '240px'
|
||||
return this.isMobile ? '100px' : '280px'
|
||||
},
|
||||
loading() {
|
||||
return this.settings.loading
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
import { mapGetters } from 'vuex'
|
||||
import i18n from '@/lang'
|
||||
import Setting from './Setting'
|
||||
import _ from 'lodash'
|
||||
|
||||
export default {
|
||||
name: 'Captcha',
|
||||
|
@ -29,7 +30,7 @@ export default {
|
|||
return this.settings.description.find(setting => setting.key === 'Pleroma.Captcha')
|
||||
},
|
||||
captchaData() {
|
||||
return this.settings.settings[':pleroma']['Pleroma.Captcha']
|
||||
return _.get(this.settings.settings, [':pleroma', 'Pleroma.Captcha']) || {}
|
||||
},
|
||||
isMobile() {
|
||||
return this.$store.state.app.device === 'mobile'
|
||||
|
@ -38,10 +39,10 @@ export default {
|
|||
return this.settings.description.find(setting => setting.key === 'Pleroma.Captcha.Kocaptcha')
|
||||
},
|
||||
kocaptchaData() {
|
||||
return this.settings.settings[':pleroma']['Pleroma.Captcha.Kocaptcha']
|
||||
return _.get(this.settings.settings, [':pleroma', 'Pleroma.Captcha.Kocaptcha']) || {}
|
||||
},
|
||||
labelWidth() {
|
||||
return this.isMobile ? '100px' : '240px'
|
||||
return this.isMobile ? '100px' : '280px'
|
||||
},
|
||||
loading() {
|
||||
return this.settings.loading
|
||||
|
|
|
@ -1,59 +0,0 @@
|
|||
<template>
|
||||
<div v-if="!loading">
|
||||
<el-form ref="databaseData" :model="databaseData" :label-width="labelWidth">
|
||||
<setting :setting-group="database" :data="databaseData"/>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="onSubmit">Submit</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapGetters } from 'vuex'
|
||||
import i18n from '@/lang'
|
||||
import Setting from './Setting'
|
||||
|
||||
export default {
|
||||
name: 'Database',
|
||||
components: { Setting },
|
||||
computed: {
|
||||
...mapGetters([
|
||||
'settings'
|
||||
]),
|
||||
database() {
|
||||
return this.settings.description.find(setting => setting.key === ':database')
|
||||
},
|
||||
databaseData() {
|
||||
return this.settings.settings[':pleroma'][':database']
|
||||
},
|
||||
isMobile() {
|
||||
return this.$store.state.app.device === 'mobile'
|
||||
},
|
||||
labelWidth() {
|
||||
return this.isMobile ? '100px' : '240px'
|
||||
},
|
||||
loading() {
|
||||
return this.settings.loading
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async onSubmit() {
|
||||
try {
|
||||
await this.$store.dispatch('SubmitChanges')
|
||||
} catch (e) {
|
||||
return
|
||||
}
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: i18n.t('settings.success')
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style rel='stylesheet/scss' lang='scss'>
|
||||
@import '../styles/main';
|
||||
@include settings
|
||||
</style>
|
|
@ -1,81 +0,0 @@
|
|||
<template>
|
||||
<div v-if="!loading">
|
||||
<el-form ref="endpointData" :model="endpointData" :label-width="labelWidth">
|
||||
<setting :setting-group="endpoint" :data="endpointData"/>
|
||||
</el-form>
|
||||
<div class="line"/>
|
||||
<el-form ref="endpointMetricsExporter" :model="endpointMetricsExporterData" :label-width="labelWidth">
|
||||
<setting :setting-group="endpointMetricsExporter" :data="endpointMetricsExporterData"/>
|
||||
</el-form>
|
||||
<div class="line"/>
|
||||
<el-form ref="remoteIp" :model="remoteIpData" :label-width="labelWidth">
|
||||
<setting :setting-group="remoteIp" :data="remoteIpData"/>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="onSubmit">Submit</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapGetters } from 'vuex'
|
||||
import i18n from '@/lang'
|
||||
import Setting from './Setting'
|
||||
|
||||
export default {
|
||||
name: 'Endpoint',
|
||||
components: {
|
||||
Setting
|
||||
},
|
||||
computed: {
|
||||
...mapGetters([
|
||||
'settings'
|
||||
]),
|
||||
endpoint() {
|
||||
return this.settings.description.find(setting => setting.key === 'Pleroma.Web.Endpoint')
|
||||
},
|
||||
endpointData() {
|
||||
return this.settings.settings[':pleroma']['Pleroma.Web.Endpoint']
|
||||
},
|
||||
endpointMetricsExporter() {
|
||||
return this.settings.description.find(setting => setting.key === 'Pleroma.Web.Endpoint.MetricsExporter')
|
||||
},
|
||||
endpointMetricsExporterData() {
|
||||
return this.settings.settings[':prometheus']['Pleroma.Web.Endpoint.MetricsExporter']
|
||||
},
|
||||
isMobile() {
|
||||
return this.$store.state.app.device === 'mobile'
|
||||
},
|
||||
labelWidth() {
|
||||
return this.isMobile ? '100px' : '240px'
|
||||
},
|
||||
loading() {
|
||||
return this.settings.loading
|
||||
},
|
||||
remoteIp() {
|
||||
return this.settings.description.find(setting => setting.key === 'Pleroma.Plugs.RemoteIp')
|
||||
},
|
||||
remoteIpData() {
|
||||
return this.settings.settings[':pleroma']['Pleroma.Plugs.RemoteIp']
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async onSubmit() {
|
||||
try {
|
||||
await this.$store.dispatch('SubmitChanges')
|
||||
} catch (e) {
|
||||
return
|
||||
}
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: i18n.t('settings.success')
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style rel='stylesheet/scss' lang='scss'>
|
||||
@import '../styles/main';
|
||||
@include settings
|
||||
</style>
|
|
@ -20,6 +20,7 @@
|
|||
import i18n from '@/lang'
|
||||
import { mapGetters } from 'vuex'
|
||||
import Setting from './Setting'
|
||||
import _ from 'lodash'
|
||||
|
||||
export default {
|
||||
name: 'Esshd',
|
||||
|
@ -32,13 +33,13 @@ export default {
|
|||
return this.settings.description.find(setting => setting.group === ':esshd')
|
||||
},
|
||||
esshdData() {
|
||||
return this.settings.settings[':esshd']
|
||||
return _.get(this.settings.settings, [':esshd']) || {}
|
||||
},
|
||||
isMobile() {
|
||||
return this.$store.state.app.device === 'mobile'
|
||||
},
|
||||
labelWidth() {
|
||||
return this.isMobile ? '100px' : '240px'
|
||||
return this.isMobile ? '100px' : '280px'
|
||||
},
|
||||
loading() {
|
||||
return this.settings.loading
|
||||
|
|
|
@ -1,11 +1,6 @@
|
|||
<template>
|
||||
<div v-if="!loading">
|
||||
<el-form ref="frontendData" :model="frontendData" :label-width="labelWidth">
|
||||
<el-form-item>
|
||||
<p class="expl">This form can be used to configure a keyword list that keeps the configuration data for any kind of frontend.
|
||||
By default, settings for <span class="code">pleroma_fe</span> and <span class="code">masto_fe</span> are configured.
|
||||
If you want to add your own configuration your settings need to be complete as they will override the defaults.</p>
|
||||
</el-form-item>
|
||||
<setting :setting-group="frontend" :data="frontendData"/>
|
||||
</el-form>
|
||||
<el-form ref="assetsData" :model="assetsData" :label-width="labelWidth">
|
||||
|
@ -36,6 +31,7 @@
|
|||
import { mapGetters } from 'vuex'
|
||||
import i18n from '@/lang'
|
||||
import Setting from './Setting'
|
||||
import _ from 'lodash'
|
||||
|
||||
export default {
|
||||
name: 'Frontend',
|
||||
|
@ -48,37 +44,37 @@ export default {
|
|||
return this.settings.description.find(setting => setting.key === ':assets')
|
||||
},
|
||||
assetsData() {
|
||||
return this.settings.settings[':pleroma'][':assets']
|
||||
return _.get(this.settings.settings, [':pleroma', ':assets']) || {}
|
||||
},
|
||||
chat() {
|
||||
return this.settings.description.find(setting => setting.key === ':chat')
|
||||
},
|
||||
chatData() {
|
||||
return this.settings.settings[':pleroma'][':chat']
|
||||
return _.get(this.settings.settings, [':pleroma', ':chat']) || {}
|
||||
},
|
||||
emoji() {
|
||||
return this.settings.description.find(setting => setting.key === ':emoji')
|
||||
},
|
||||
emojiData() {
|
||||
return this.settings.settings[':pleroma'][':emoji']
|
||||
return _.get(this.settings.settings, [':pleroma', ':emoji']) || {}
|
||||
},
|
||||
frontend() {
|
||||
return this.settings.description.find(setting => setting.key === ':frontend_configurations')
|
||||
},
|
||||
frontendData() {
|
||||
return this.settings.settings[':pleroma'][':frontend_configurations']
|
||||
return _.get(this.settings.settings, [':pleroma', ':frontend_configurations']) || {}
|
||||
},
|
||||
markup() {
|
||||
return this.settings.description.find(setting => setting.key === ':markup')
|
||||
},
|
||||
markupData() {
|
||||
return this.settings.settings[':pleroma'][':markup']
|
||||
return _.get(this.settings.settings, [':pleroma', ':markup']) || {}
|
||||
},
|
||||
isMobile() {
|
||||
return this.$store.state.app.device === 'mobile'
|
||||
},
|
||||
labelWidth() {
|
||||
return this.isMobile ? '100px' : '240px'
|
||||
return this.isMobile ? '100px' : '280px'
|
||||
},
|
||||
loading() {
|
||||
return this.settings.loading
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
import { mapGetters } from 'vuex'
|
||||
import i18n from '@/lang'
|
||||
import Setting from './Setting'
|
||||
import _ from 'lodash'
|
||||
|
||||
export default {
|
||||
name: 'Gopher',
|
||||
|
@ -23,13 +24,13 @@ export default {
|
|||
return this.settings.description.find(setting => setting.key === ':gopher')
|
||||
},
|
||||
gopherData() {
|
||||
return this.settings.settings[':pleroma'][':gopher']
|
||||
return _.get(this.settings.settings, [':pleroma', ':gopher']) || {}
|
||||
},
|
||||
isMobile() {
|
||||
return this.$store.state.app.device === 'mobile'
|
||||
},
|
||||
labelWidth() {
|
||||
return this.isMobile ? '100px' : '240px'
|
||||
return this.isMobile ? '100px' : '280px'
|
||||
},
|
||||
loading() {
|
||||
return this.settings.loading
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
import { mapGetters } from 'vuex'
|
||||
import i18n from '@/lang'
|
||||
import Setting from './Setting'
|
||||
import _ from 'lodash'
|
||||
|
||||
export default {
|
||||
name: 'HTTP',
|
||||
|
@ -41,31 +42,31 @@ export default {
|
|||
return this.settings.description.find(setting => setting.group === ':cors_plug')
|
||||
},
|
||||
corsPlugData() {
|
||||
return this.settings.settings[':cors_plug']
|
||||
return _.get(this.settings.settings, [':cors_plug']) || {}
|
||||
},
|
||||
http() {
|
||||
return this.settings.description.find(setting => setting.key === ':http')
|
||||
},
|
||||
httpData() {
|
||||
return this.settings.settings[':pleroma'][':http']
|
||||
return _.get(this.settings.settings, [':pleroma', ':http']) || {}
|
||||
},
|
||||
httpSecurity() {
|
||||
return this.settings.description.find(setting => setting.key === ':http_security')
|
||||
},
|
||||
httpSecurityData() {
|
||||
return this.settings.settings[':pleroma'][':http_security']
|
||||
return _.get(this.settings.settings, [':pleroma', ':http_security']) || {}
|
||||
},
|
||||
httpSignatures() {
|
||||
return this.settings.description.find(setting => setting.group === ':http_signatures')
|
||||
},
|
||||
httpSignaturesData() {
|
||||
return this.settings.settings[':http_signatures']
|
||||
return _.get(this.settings.settings, [':http_signatures']) || {}
|
||||
},
|
||||
isMobile() {
|
||||
return this.$store.state.app.device === 'mobile'
|
||||
},
|
||||
labelWidth() {
|
||||
return this.isMobile ? '100px' : '240px'
|
||||
return this.isMobile ? '100px' : '280px'
|
||||
},
|
||||
loading() {
|
||||
return this.settings.loading
|
||||
|
@ -74,7 +75,7 @@ export default {
|
|||
return this.settings.description.find(setting => setting.key === ':web_cache_ttl')
|
||||
},
|
||||
webCacheTtlData() {
|
||||
return this.settings.settings[':pleroma'][':web_cache_ttl']
|
||||
return _.get(this.settings.settings, [':pleroma', ':web_cache_ttl']) || {}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
|
|
@ -1,7 +1,13 @@
|
|||
<template>
|
||||
<el-form-item :label="setting.label" :label-width="customLabelWidth" :class="labelClass">
|
||||
<el-form-item :label-width="customLabelWidth" :class="labelClass">
|
||||
<span slot="label">
|
||||
{{ setting.label }}
|
||||
<el-tooltip v-if="canBeDeleted" :content="$t('settings.removeFromDB')" placement="bottom-end">
|
||||
<el-button icon="el-icon-delete" circle size="mini" style="margin-left:5px" @click="removeSetting"/>
|
||||
</el-tooltip>
|
||||
</span>
|
||||
<el-input
|
||||
v-if="setting.type === 'string'"
|
||||
v-if="setting.type === 'string' || (setting.type.includes('string') && setting.type.includes('atom'))"
|
||||
:value="inputValue"
|
||||
:placeholder="setting.suggestions ? setting.suggestions[0] : null"
|
||||
@input="update($event, settingGroup.group, settingGroup.key, settingParent, setting.key, setting.type, nested)"/>
|
||||
|
@ -36,13 +42,6 @@
|
|||
@change="update($event, settingGroup.group, settingGroup.key, settingParent, setting.key, setting.type, nested)">
|
||||
<el-option v-for="(option, index) in setting.suggestions" :key="index" :value="option"/>
|
||||
</el-select>
|
||||
<editor
|
||||
v-if="setting.key === ':dispatch'"
|
||||
v-model="editorContent"
|
||||
height="150"
|
||||
width="100%"
|
||||
lang="elixir"
|
||||
theme="chrome"/>
|
||||
<el-input
|
||||
v-if="setting.key === ':ip'"
|
||||
:value="inputValue"
|
||||
|
@ -62,7 +61,7 @@
|
|||
:setting-parent="[...settingParent, subSetting]"
|
||||
:setting="subSetting"
|
||||
:data="data[setting.key]"
|
||||
:custom-label-width="'100px'"
|
||||
:custom-label-width="'140px'"
|
||||
:label-class="'center-label'"
|
||||
:input-class="'keyword-inner-input'"
|
||||
:nested="true"/>
|
||||
|
@ -70,11 +69,10 @@
|
|||
</div>
|
||||
<!-- special inputs -->
|
||||
<auto-linker-input v-if="settingGroup.group === ':auto_linker'" :data="data" :setting-group="settingGroup" :setting="setting"/>
|
||||
<mascots-input v-if="setting.key === ':mascots'" :data="data" :setting-group="settingGroup" :setting="setting"/>
|
||||
<editable-keyword-input v-if="editableKeyword(setting.key, setting.type)" :data="data" :setting-group="settingGroup" :setting="setting"/>
|
||||
<icons-input v-if="setting.key === ':icons'" :data="data[':icons']" :setting-group="settingGroup" :setting="setting"/>
|
||||
<mascots-input v-if="setting.key === ':mascots'" :data="keywordData" :setting-group="settingGroup" :setting="setting"/>
|
||||
<editable-keyword-input v-if="editableKeyword(setting.key, setting.type)" :data="keywordData" :setting-group="settingGroup" :setting="setting"/>
|
||||
<icons-input v-if="setting.key === ':icons'" :data="iconsData" :setting-group="settingGroup" :setting="setting"/>
|
||||
<proxy-url-input v-if="setting.key === ':proxy_url'" :data="data[setting.key]" :setting-group="settingGroup" :setting="setting" :parents="settingParent"/>
|
||||
<!-- <ssl-options-input v-if="setting.key === ':ssl_options'" :setting-group="settingGroup" :setting-parent="settingParent" :setting="setting" :data="data" :nested="true" :custom-label-width="'100px'"/> -->
|
||||
<multiple-select v-if="setting.key === ':backends' || setting.key === ':args'" :data="data" :setting-group="settingGroup" :setting="setting"/>
|
||||
<prune-input v-if="setting.key === ':prune'" :data="data[setting.key]" :setting-group="settingGroup" :setting="setting"/>
|
||||
<rate-limit-input v-if="settingGroup.key === ':rate_limit'" :data="data" :setting-group="settingGroup" :setting="setting"/>
|
||||
|
@ -84,16 +82,14 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import AceEditor from 'vue2-ace-editor'
|
||||
import 'brace/mode/elixir'
|
||||
import 'default-passive-events'
|
||||
import { AutoLinkerInput, EditableKeywordInput, IconsInput, MascotsInput, MultipleSelect, ProxyUrlInput, PruneInput, RateLimitInput, SslOptionsInput } from './inputComponents'
|
||||
import i18n from '@/lang'
|
||||
import { AutoLinkerInput, EditableKeywordInput, IconsInput, MascotsInput, MultipleSelect, ProxyUrlInput, PruneInput, RateLimitInput } from './inputComponents'
|
||||
import { processNested } from '@/store/modules/normalizers'
|
||||
import _ from 'lodash'
|
||||
|
||||
export default {
|
||||
name: 'Inputs',
|
||||
components: {
|
||||
editor: AceEditor,
|
||||
AutoLinkerInput,
|
||||
EditableKeywordInput,
|
||||
IconsInput,
|
||||
|
@ -101,8 +97,7 @@ export default {
|
|||
MultipleSelect,
|
||||
ProxyUrlInput,
|
||||
PruneInput,
|
||||
RateLimitInput,
|
||||
SslOptionsInput
|
||||
RateLimitInput
|
||||
},
|
||||
props: {
|
||||
customLabelWidth: {
|
||||
|
@ -159,13 +154,13 @@ export default {
|
|||
}
|
||||
},
|
||||
computed: {
|
||||
editorContent: {
|
||||
get: function() {
|
||||
return this.data[this.setting.key] ? this.data[this.setting.key][0] : ''
|
||||
},
|
||||
set: function(value) {
|
||||
this.processNestedData([value], this.settingGroup.group, this.settingGroup.key, this.settingParent)
|
||||
}
|
||||
canBeDeleted() {
|
||||
const { group, key } = this.settingGroup
|
||||
return _.get(this.$store.state.settings.db, [group, key]) &&
|
||||
this.$store.state.settings.db[group][key].includes(this.setting.key)
|
||||
},
|
||||
iconsData() {
|
||||
return Array.isArray(this.data[':icons']) ? this.data[':icons'] : []
|
||||
},
|
||||
inputValue() {
|
||||
if ([':esshd', ':cors_plug', ':quack', ':http_signatures', ':tesla'].includes(this.settingGroup.group) &&
|
||||
|
@ -178,7 +173,7 @@ export default {
|
|||
this.setting.key === ':admin_token') {
|
||||
return this.data.value
|
||||
} else if (this.settingGroup.group === ':mime' && this.settingParent[0].key === ':types') {
|
||||
return this.data.value[this.setting.key]
|
||||
return this.data.value ? this.data.value[this.setting.key] : []
|
||||
} else if (this.setting.type === 'atom') {
|
||||
return this.data[this.setting.key] && this.data[this.setting.key][0] === ':' ? this.data[this.setting.key].substr(1) : this.data[this.setting.key]
|
||||
} else {
|
||||
|
@ -186,7 +181,10 @@ export default {
|
|||
}
|
||||
},
|
||||
labelWidth() {
|
||||
return this.isMobile ? '100px' : '240px'
|
||||
return this.isMobile ? '100px' : '280px'
|
||||
},
|
||||
keywordData() {
|
||||
return Array.isArray(this.data) ? this.data : []
|
||||
},
|
||||
rewritePolicyValue() {
|
||||
return typeof this.data[this.setting.key] === 'string' ? [this.data[this.setting.key]] : this.data[this.setting.key]
|
||||
|
@ -215,6 +213,20 @@ export default {
|
|||
this.$store.dispatch('UpdateState',
|
||||
{ group, key: parentKey, input: setting.key, value: valueForState })
|
||||
},
|
||||
async removeSetting() {
|
||||
const config = this.settingGroup.key
|
||||
? [{ group: this.settingGroup.group, key: this.settingGroup.key, delete: true, subkeys: [this.setting.key] }]
|
||||
: [{ group: this.settingGroup.group, key: this.setting.key, delete: true }]
|
||||
try {
|
||||
await this.$store.dispatch('RemoveSetting', config)
|
||||
} catch (e) {
|
||||
return
|
||||
}
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: i18n.t('settings.successfullyRemoved')
|
||||
})
|
||||
},
|
||||
renderMultipleSelect(type) {
|
||||
return Array.isArray(type) && this.setting.key !== ':backends' && this.setting.key !== ':args' && (
|
||||
type.includes('module') ||
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
import { mapGetters } from 'vuex'
|
||||
import i18n from '@/lang'
|
||||
import Setting from './Setting'
|
||||
import _ from 'lodash'
|
||||
|
||||
export default {
|
||||
name: 'Instance',
|
||||
|
@ -56,25 +57,25 @@ export default {
|
|||
return this.settings.description.find(setting => setting.description === `Allows to set a token that can be used to authenticate with the admin api without using an actual user by giving it as the 'admin_token' parameter`)
|
||||
},
|
||||
adminTokenData() {
|
||||
return this.settings.settings[':pleroma'][':admin_token']
|
||||
return _.get(this.settings.settings, [':pleroma', ':admin_token']) || {}
|
||||
},
|
||||
fetchInitialPosts() {
|
||||
return this.settings.description.find(setting => setting.key === ':fetch_initial_posts')
|
||||
},
|
||||
fetchInitialPostsData() {
|
||||
return this.settings.settings[':pleroma'][':fetch_initial_posts']
|
||||
return _.get(this.settings.settings, [':pleroma', ':fetch_initial_posts']) || {}
|
||||
},
|
||||
instance() {
|
||||
return this.settings.description.find(setting => setting.key === ':instance')
|
||||
},
|
||||
instanceData() {
|
||||
return this.settings.settings[':pleroma'][':instance']
|
||||
return _.get(this.settings.settings, [':pleroma', ':instance']) || {}
|
||||
},
|
||||
isMobile() {
|
||||
return this.$store.state.app.device === 'mobile'
|
||||
},
|
||||
labelWidth() {
|
||||
return this.isMobile ? '100px' : '240px'
|
||||
return this.isMobile ? '100px' : '280px'
|
||||
},
|
||||
loading() {
|
||||
return this.settings.loading
|
||||
|
@ -83,31 +84,31 @@ export default {
|
|||
return this.settings.description.find(setting => setting.key === ':manifest')
|
||||
},
|
||||
manifestData() {
|
||||
return this.settings.settings[':pleroma'][':manifest']
|
||||
return _.get(this.settings.settings, [':pleroma', ':manifest']) || {}
|
||||
},
|
||||
pleromaUser() {
|
||||
return this.settings.description.find(setting => setting.key === 'Pleroma.User')
|
||||
},
|
||||
pleromaUserData() {
|
||||
return this.settings.settings[':pleroma']['Pleroma.User']
|
||||
return _.get(this.settings.settings, [':pleroma', 'Pleroma.User']) || {}
|
||||
},
|
||||
scheduledActivity() {
|
||||
return this.$store.state.settings.description.find(setting => setting.key === 'Pleroma.ScheduledActivity')
|
||||
},
|
||||
scheduledActivityData() {
|
||||
return this.settings.settings[':pleroma']['Pleroma.ScheduledActivity']
|
||||
return _.get(this.settings.settings, [':pleroma', 'Pleroma.ScheduledActivity']) || {}
|
||||
},
|
||||
suggestions() {
|
||||
return this.$store.state.settings.description.find(setting => setting.key === ':suggestions')
|
||||
},
|
||||
suggestionsData() {
|
||||
return this.settings.settings[':pleroma'][':suggestions']
|
||||
return _.get(this.settings.settings, [':pleroma', ':suggestions']) || {}
|
||||
},
|
||||
uriSchemes() {
|
||||
return this.$store.state.settings.description.find(setting => setting.key === ':uri_schemes')
|
||||
},
|
||||
uriSchemesData() {
|
||||
return this.settings.settings[':pleroma'][':uri_schemes']
|
||||
return _.get(this.settings.settings, [':pleroma', ':uri_schemes']) || {}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
import { mapGetters } from 'vuex'
|
||||
import i18n from '@/lang'
|
||||
import Setting from './Setting'
|
||||
import _ from 'lodash'
|
||||
|
||||
export default {
|
||||
name: 'JobQueue',
|
||||
|
@ -31,13 +32,13 @@ export default {
|
|||
return this.settings.description.find(setting => setting.key === 'Pleroma.ActivityExpiration')
|
||||
},
|
||||
activityExpirationData() {
|
||||
return this.settings.settings[':pleroma']['Pleroma.ActivityExpiration']
|
||||
return _.get(this.settings.settings, [':pleroma', 'Pleroma.ActivityExpiration']) || {}
|
||||
},
|
||||
isMobile() {
|
||||
return this.$store.state.app.device === 'mobile'
|
||||
},
|
||||
labelWidth() {
|
||||
return this.isMobile ? '100px' : '240px'
|
||||
return this.isMobile ? '100px' : '280px'
|
||||
},
|
||||
loading() {
|
||||
return this.settings.loading
|
||||
|
@ -46,13 +47,13 @@ export default {
|
|||
return this.settings.description.find(setting => setting.key === 'Oban')
|
||||
},
|
||||
obanQueuesData() {
|
||||
return this.settings.settings[':pleroma']['Oban']
|
||||
return _.get(this.settings.settings, [':pleroma', 'Oban']) || {}
|
||||
},
|
||||
workers() {
|
||||
return this.settings.description.find(setting => setting.key === ':workers')
|
||||
},
|
||||
workersData() {
|
||||
return this.settings.settings[':pleroma'][':workers']
|
||||
return _.get(this.settings.settings, [':pleroma', ':workers']) || {}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
import { mapGetters } from 'vuex'
|
||||
import i18n from '@/lang'
|
||||
import Setting from './Setting'
|
||||
import _ from 'lodash'
|
||||
|
||||
export default {
|
||||
name: 'Logger',
|
||||
|
@ -38,19 +39,19 @@ export default {
|
|||
return this.settings.description.find(setting => setting.key === ':console')
|
||||
},
|
||||
consoleData() {
|
||||
return this.settings.settings[':logger'][':console']
|
||||
return _.get(this.settings.settings, [':logger', ':console']) || {}
|
||||
},
|
||||
exsyslogger() {
|
||||
return this.settings.description.find(setting => setting.key === ':ex_syslogger')
|
||||
},
|
||||
exsysloggerData() {
|
||||
return this.settings.settings[':logger'][':ex_syslogger']
|
||||
return _.get(this.settings.settings, [':logger', ':ex_syslogger']) || {}
|
||||
},
|
||||
isMobile() {
|
||||
return this.$store.state.app.device === 'mobile'
|
||||
},
|
||||
labelWidth() {
|
||||
return this.isMobile ? '100px' : '240px'
|
||||
return this.isMobile ? '100px' : '280px'
|
||||
},
|
||||
loading() {
|
||||
return this.settings.loading
|
||||
|
@ -59,13 +60,13 @@ export default {
|
|||
return this.settings.description.find(setting => setting.group === ':logger')
|
||||
},
|
||||
loggerData() {
|
||||
return this.settings.settings[':logger'][':backends']
|
||||
return _.get(this.settings.settings, [':logger', ':backends']) || {}
|
||||
},
|
||||
quack() {
|
||||
return this.settings.description.find(setting => setting.group === ':quack')
|
||||
},
|
||||
quackData() {
|
||||
return this.settings.settings[':quack']
|
||||
return _.get(this.settings.settings, [':quack']) || {}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
import { mapGetters } from 'vuex'
|
||||
import i18n from '@/lang'
|
||||
import Setting from './Setting'
|
||||
import _ from 'lodash'
|
||||
|
||||
export default {
|
||||
name: 'MRF',
|
||||
|
@ -51,7 +52,7 @@ export default {
|
|||
return this.$store.state.app.device === 'mobile'
|
||||
},
|
||||
labelWidth() {
|
||||
return this.isMobile ? '100px' : '240px'
|
||||
return this.isMobile ? '100px' : '280px'
|
||||
},
|
||||
loading() {
|
||||
return this.settings.loading
|
||||
|
@ -60,49 +61,49 @@ export default {
|
|||
return this.settings.description.find(setting => setting.key === ':mrf_simple')
|
||||
},
|
||||
mrfSimpleData() {
|
||||
return this.settings.settings[':pleroma'][':mrf_simple']
|
||||
return _.get(this.settings.settings, [':pleroma', ':mrf_simple']) || {}
|
||||
},
|
||||
mrfRejectnonpublic() {
|
||||
return this.settings.description.find(setting => setting.key === ':mrf_rejectnonpublic')
|
||||
},
|
||||
mrfRejectnonpublicData() {
|
||||
return this.settings.settings[':pleroma'][':mrf_rejectnonpublic']
|
||||
return _.get(this.settings.settings, [':pleroma', ':mrf_rejectnonpublic']) || {}
|
||||
},
|
||||
mrfHellthread() {
|
||||
return this.settings.description.find(setting => setting.key === ':mrf_hellthread')
|
||||
},
|
||||
mrfHellthreadData() {
|
||||
return this.settings.settings[':pleroma'][':mrf_hellthread']
|
||||
return _.get(this.settings.settings, [':pleroma', ':mrf_hellthread']) || {}
|
||||
},
|
||||
mrfKeyword() {
|
||||
return this.settings.description.find(setting => setting.key === ':mrf_keyword')
|
||||
},
|
||||
mrfKeywordData() {
|
||||
return this.settings.settings[':pleroma'][':mrf_keyword']
|
||||
return _.get(this.settings.settings, [':pleroma', ':mrf_keyword']) || {}
|
||||
},
|
||||
mrfSubchain() {
|
||||
return this.settings.description.find(setting => setting.key === ':mrf_subchain')
|
||||
},
|
||||
mrfSubchainData() {
|
||||
return this.settings.settings[':pleroma'][':mrf_subchain']
|
||||
return _.get(this.settings.settings, [':pleroma', ':mrf_subchain']) || {}
|
||||
},
|
||||
mrfMention() {
|
||||
return this.settings.description.find(setting => setting.key === ':mrf_mention')
|
||||
},
|
||||
mrfMentionData() {
|
||||
return this.settings.settings[':pleroma'][':mrf_mention']
|
||||
return _.get(this.settings.settings, [':pleroma', ':mrf_mention']) || {}
|
||||
},
|
||||
mrfNormalizeMarkup() {
|
||||
return this.settings.description.find(setting => setting.key === ':mrf_normalize_markup')
|
||||
},
|
||||
mrfNormalizeMarkupData() {
|
||||
return this.settings.settings[':pleroma'][':mrf_normalize_markup']
|
||||
return _.get(this.settings.settings, [':pleroma', ':mrf_normalize_markup']) || {}
|
||||
},
|
||||
mrfVocabulary() {
|
||||
return this.settings.description.find(setting => setting.key === ':mrf_vocabulary')
|
||||
},
|
||||
mrfVocabularyData() {
|
||||
return this.settings.settings[':pleroma'][':mrf_vocabulary']
|
||||
return _.get(this.settings.settings, [':pleroma', ':mrf_vocabulary']) || {}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
import { mapGetters } from 'vuex'
|
||||
import i18n from '@/lang'
|
||||
import Setting from './Setting'
|
||||
import _ from 'lodash'
|
||||
|
||||
export default {
|
||||
name: 'Mailer',
|
||||
|
@ -34,13 +35,13 @@ export default {
|
|||
return this.settings.description.find(setting => setting.key === ':email_notifications')
|
||||
},
|
||||
emailNotificationsData() {
|
||||
return this.settings.settings[':pleroma'][':email_notifications']
|
||||
return _.get(this.settings.settings, [':pleroma', ':email_notifications']) || {}
|
||||
},
|
||||
isMobile() {
|
||||
return this.$store.state.app.device === 'mobile'
|
||||
},
|
||||
labelWidth() {
|
||||
return this.isMobile ? '100px' : '240px'
|
||||
return this.isMobile ? '100px' : '280px'
|
||||
},
|
||||
loading() {
|
||||
return this.$store.state.settings.loading
|
||||
|
@ -49,13 +50,13 @@ export default {
|
|||
return this.settings.description.find(setting => setting.key === 'Pleroma.Emails.Mailer')
|
||||
},
|
||||
mailerData() {
|
||||
return this.settings.settings[':pleroma']['Pleroma.Emails.Mailer']
|
||||
return _.get(this.settings.settings, [':pleroma', 'Pleroma.Emails.Mailer']) || {}
|
||||
},
|
||||
userEmail() {
|
||||
return this.settings.description.find(setting => setting.key === 'Pleroma.Emails.UserEmail')
|
||||
},
|
||||
userEmailData() {
|
||||
return this.settings.settings[':pleroma']['Pleroma.Emails.UserEmail']
|
||||
return _.get(this.settings.settings, [':pleroma', 'Pleroma.Emails.UserEmail']) || {}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
import { mapGetters } from 'vuex'
|
||||
import i18n from '@/lang'
|
||||
import Setting from './Setting'
|
||||
import _ from 'lodash'
|
||||
|
||||
export default {
|
||||
name: 'MediaProxy',
|
||||
|
@ -23,7 +24,7 @@ export default {
|
|||
return this.$store.state.app.device === 'mobile'
|
||||
},
|
||||
labelWidth() {
|
||||
return this.isMobile ? '100px' : '240px'
|
||||
return this.isMobile ? '100px' : '280px'
|
||||
},
|
||||
loading() {
|
||||
return this.settings.loading
|
||||
|
@ -32,7 +33,7 @@ export default {
|
|||
return this.settings.description.find(setting => setting.key === ':media_proxy')
|
||||
},
|
||||
mediaProxyData() {
|
||||
return this.settings.settings[':pleroma'][':media_proxy']
|
||||
return _.get(this.settings.settings, [':pleroma', ':media_proxy']) || {}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
import { mapGetters } from 'vuex'
|
||||
import i18n from '@/lang'
|
||||
import Setting from './Setting'
|
||||
import _ from 'lodash'
|
||||
|
||||
export default {
|
||||
name: 'Metadata',
|
||||
|
@ -29,7 +30,7 @@ export default {
|
|||
return this.$store.state.app.device === 'mobile'
|
||||
},
|
||||
labelWidth() {
|
||||
return this.isMobile ? '100px' : '240px'
|
||||
return this.isMobile ? '100px' : '280px'
|
||||
},
|
||||
loading() {
|
||||
return this.settings.loading
|
||||
|
@ -38,13 +39,13 @@ export default {
|
|||
return this.settings.description.find(setting => setting.key === 'Pleroma.Web.Metadata')
|
||||
},
|
||||
metadataData() {
|
||||
return this.settings.settings[':pleroma']['Pleroma.Web.Metadata']
|
||||
return _.get(this.settings.settings, [':pleroma', 'Pleroma.Web.Metadata']) || {}
|
||||
},
|
||||
richMedia() {
|
||||
return this.settings.description.find(setting => setting.key === ':rich_media')
|
||||
},
|
||||
richMediaData() {
|
||||
return this.settings.settings[':pleroma'][':rich_media']
|
||||
return _.get(this.settings.settings, [':pleroma', ':rich_media']) || {}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
|
|
@ -6,6 +6,9 @@
|
|||
<div class="line"/>
|
||||
<el-form ref="mimeTypes" :model="mimeTypesData" :label-width="labelWidth">
|
||||
<setting :setting-group="mimeTypes" :data="mimeTypesData"/>
|
||||
</el-form>
|
||||
<el-form ref="remoteIp" :model="remoteIpData" :label-width="labelWidth">
|
||||
<setting :setting-group="remoteIp" :data="remoteIpData"/>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="onSubmit">Submit</el-button>
|
||||
</el-form-item>
|
||||
|
@ -17,6 +20,7 @@
|
|||
import { mapGetters } from 'vuex'
|
||||
import i18n from '@/lang'
|
||||
import Setting from './Setting'
|
||||
import _ from 'lodash'
|
||||
|
||||
export default {
|
||||
name: 'Other',
|
||||
|
@ -29,7 +33,7 @@ export default {
|
|||
return this.$store.state.app.device === 'mobile'
|
||||
},
|
||||
labelWidth() {
|
||||
return this.isMobile ? '100px' : '240px'
|
||||
return this.isMobile ? '100px' : '280px'
|
||||
},
|
||||
loading() {
|
||||
return this.settings.loading
|
||||
|
@ -38,13 +42,19 @@ export default {
|
|||
return this.settings.description.find(setting => setting.group === ':mime')
|
||||
},
|
||||
mimeTypesData() {
|
||||
return this.settings.settings[':mime']
|
||||
return _.get(this.settings.settings, [':mime']) || {}
|
||||
},
|
||||
remoteIp() {
|
||||
return this.settings.description.find(setting => setting.key === 'Pleroma.Plugs.RemoteIp')
|
||||
},
|
||||
remoteIpData() {
|
||||
return _.get(this.settings.settings, [':pleroma', 'Pleroma.Plugs.RemoteIp']) || {}
|
||||
},
|
||||
teslaAdapter() {
|
||||
return this.settings.description.find(setting => setting.group === ':tesla')
|
||||
},
|
||||
teslaAdapterData() {
|
||||
return this.settings.settings[':tesla']
|
||||
return _.get(this.settings.settings, [':tesla']) || {}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
import { mapGetters } from 'vuex'
|
||||
import i18n from '@/lang'
|
||||
import Setting from './Setting'
|
||||
import _ from 'lodash'
|
||||
|
||||
export default {
|
||||
name: 'RateLimiters',
|
||||
|
@ -23,13 +24,13 @@ export default {
|
|||
return this.settings.description.find(setting => setting.key === ':rate_limit')
|
||||
},
|
||||
rateLimitersData() {
|
||||
return this.settings.settings[':pleroma'][':rate_limit']
|
||||
return _.get(this.settings.settings, [':pleroma', ':rate_limit']) || {}
|
||||
},
|
||||
isMobile() {
|
||||
return this.$store.state.app.device === 'mobile'
|
||||
},
|
||||
labelWidth() {
|
||||
return this.isMobile ? '100px' : '240px'
|
||||
return this.isMobile ? '100px' : '280px'
|
||||
},
|
||||
loading() {
|
||||
return this.$store.state.settings.loading
|
||||
|
|
|
@ -29,17 +29,30 @@
|
|||
:nested="false"/>
|
||||
</div>
|
||||
<div v-if="compound(setting)">
|
||||
<el-form-item :label="`${setting.label}:`"/>
|
||||
<div v-for="subSetting in setting.children" :key="subSetting.key">
|
||||
<div v-if="!setting.children">
|
||||
<inputs
|
||||
:setting-group="settingGroup"
|
||||
:setting-parent="[setting, subSetting]"
|
||||
:setting="subSetting"
|
||||
:setting="setting"
|
||||
:data="data[setting.key]"
|
||||
:nested="true"/>
|
||||
</div>
|
||||
<div v-if="!setting.children">
|
||||
<inputs :setting-group="settingGroup" :setting="setting" :data="data[setting.key]" :nested="true"/>
|
||||
<div v-else>
|
||||
<el-form-item>
|
||||
<span slot="label">
|
||||
{{ setting.label }}:
|
||||
<el-tooltip v-if="canBeDeleted(setting.key)" :content="$t('settings.removeFromDB')" placement="bottom-end">
|
||||
<el-button icon="el-icon-delete" circle size="mini" style="margin-left:5px" @click="removeSetting(setting.key)"/>
|
||||
</el-tooltip>
|
||||
</span>
|
||||
</el-form-item>
|
||||
<div v-for="subSetting in setting.children" :key="subSetting.key">
|
||||
<inputs
|
||||
:setting-group="settingGroup"
|
||||
:setting-parent="[setting, subSetting]"
|
||||
:setting="subSetting"
|
||||
:data="data[setting.key]"
|
||||
:nested="true"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="line"/>
|
||||
</div>
|
||||
|
@ -49,15 +62,13 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import AceEditor from 'vue2-ace-editor'
|
||||
import Inputs from './Inputs'
|
||||
import 'brace/mode/elixir'
|
||||
import 'default-passive-events'
|
||||
import i18n from '@/lang'
|
||||
import _ from 'lodash'
|
||||
|
||||
export default {
|
||||
name: 'Setting',
|
||||
components: {
|
||||
editor: AceEditor,
|
||||
Inputs
|
||||
},
|
||||
props: {
|
||||
|
@ -84,12 +95,32 @@ export default {
|
|||
}
|
||||
},
|
||||
methods: {
|
||||
canBeDeleted(settingKey) {
|
||||
const { group, key } = this.settingGroup
|
||||
const existingKey = key || settingKey
|
||||
return _.get(this.$store.state.settings.db, [group, existingKey]) &&
|
||||
this.$store.state.settings.db[group][existingKey].includes(settingKey)
|
||||
},
|
||||
compound({ type, key, children }) {
|
||||
return type === 'keyword' ||
|
||||
type === 'map' ||
|
||||
type.includes('keyword') ||
|
||||
key === ':replace'
|
||||
},
|
||||
async removeSetting(key) {
|
||||
const config = this.settingGroup.key
|
||||
? [{ group: this.settingGroup.group, key: this.settingGroup.key, delete: true, subkeys: [key] }]
|
||||
: [{ group: this.settingGroup.group, key, delete: true }]
|
||||
try {
|
||||
await this.$store.dispatch('RemoveSetting', config)
|
||||
} catch (e) {
|
||||
return
|
||||
}
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: i18n.t('settings.successfullyRemoved')
|
||||
})
|
||||
},
|
||||
updateSetting(value, tab, input) {
|
||||
this.$store.dispatch('UpdateSettings', { tab, data: { [input]: value }})
|
||||
}
|
||||
|
|
|
@ -11,10 +11,6 @@
|
|||
<setting :setting-group="uploadersS3" :data="uploadersS3Data"/>
|
||||
</el-form>
|
||||
<div class="line"/>
|
||||
<el-form ref="uploadersMDII" :model="uploadersMDIIData" :label-width="labelWidth">
|
||||
<setting :setting-group="uploadersMDII" :data="uploadersMDIIData"/>
|
||||
</el-form>
|
||||
<div class="line"/>
|
||||
<el-form ref="uploadFilterMogrify" :model="uploadFilterMogrifyData" :label-width="labelWidth">
|
||||
<setting :setting-group="uploadFilterMogrify" :data="uploadFilterMogrifyData"/>
|
||||
</el-form>
|
||||
|
@ -32,6 +28,7 @@
|
|||
import { mapGetters } from 'vuex'
|
||||
import i18n from '@/lang'
|
||||
import Setting from './Setting'
|
||||
import _ from 'lodash'
|
||||
|
||||
export default {
|
||||
name: 'Upload',
|
||||
|
@ -44,7 +41,7 @@ export default {
|
|||
return this.$store.state.app.device === 'mobile'
|
||||
},
|
||||
labelWidth() {
|
||||
return this.isMobile ? '100px' : '240px'
|
||||
return this.isMobile ? '100px' : '280px'
|
||||
},
|
||||
loading() {
|
||||
return this.settings.loading
|
||||
|
@ -53,37 +50,31 @@ export default {
|
|||
return this.settings.description.find(setting => setting.key === 'Pleroma.Upload')
|
||||
},
|
||||
uploadData() {
|
||||
return this.settings.settings[':pleroma']['Pleroma.Upload']
|
||||
return _.get(this.settings.settings, [':pleroma', 'Pleroma.Upload']) || {}
|
||||
},
|
||||
uploadersLocal() {
|
||||
return this.settings.description.find(setting => setting.key === 'Pleroma.Uploaders.Local')
|
||||
},
|
||||
uploadersLocalData() {
|
||||
return this.settings.settings[':pleroma']['Pleroma.Uploaders.Local']
|
||||
return _.get(this.settings.settings, [':pleroma', 'Pleroma.Uploaders.Local']) || {}
|
||||
},
|
||||
uploadersS3() {
|
||||
return this.settings.description.find(setting => setting.key === 'Pleroma.Uploaders.S3')
|
||||
},
|
||||
uploadersS3Data() {
|
||||
return this.settings.settings[':pleroma']['Pleroma.Uploaders.S3']
|
||||
},
|
||||
uploadersMDII() {
|
||||
return this.settings.description.find(setting => setting.key === 'Pleroma.Uploaders.MDII')
|
||||
},
|
||||
uploadersMDIIData() {
|
||||
return this.settings.settings[':pleroma']['Pleroma.Uploaders.MDII']
|
||||
return _.get(this.settings.settings, [':pleroma', 'Pleroma.Uploaders.S3']) || {}
|
||||
},
|
||||
uploadFilterMogrify() {
|
||||
return this.settings.description.find(setting => setting.key === 'Pleroma.Upload.Filter.Mogrify')
|
||||
},
|
||||
uploadFilterMogrifyData() {
|
||||
return this.settings.settings[':pleroma']['Pleroma.Upload.Filter.Mogrify']
|
||||
return _.get(this.settings.settings, [':pleroma', 'Pleroma.Upload.Filter.Mogrify']) || {}
|
||||
},
|
||||
uploadAnonymizeFilename() {
|
||||
return this.settings.description.find(setting => setting.key === 'Pleroma.Upload.Filter.AnonymizeFilename')
|
||||
},
|
||||
uploadAnonymizeFilenameData() {
|
||||
return this.settings.settings[':pleroma']['Pleroma.Upload.Filter.AnonymizeFilename']
|
||||
return _.get(this.settings.settings, [':pleroma', 'Pleroma.Upload.Filter.AnonymizeFilename']) || {}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
import { mapGetters } from 'vuex'
|
||||
import i18n from '@/lang'
|
||||
import Setting from './Setting'
|
||||
import _ from 'lodash'
|
||||
|
||||
export default {
|
||||
name: 'WebPush',
|
||||
|
@ -23,7 +24,7 @@ export default {
|
|||
return this.$store.state.app.device === 'mobile'
|
||||
},
|
||||
labelWidth() {
|
||||
return this.isMobile ? '100px' : '240px'
|
||||
return this.isMobile ? '100px' : '280px'
|
||||
},
|
||||
loading() {
|
||||
return this.settings.loading
|
||||
|
@ -32,7 +33,7 @@ export default {
|
|||
return this.settings.description.find(setting => setting.key === ':vapid_details')
|
||||
},
|
||||
vapidDetailsData() {
|
||||
return this.settings.settings[':web_push_encryption'][':vapid_details']
|
||||
return _.get(this.settings.settings, [':web_push_encryption', ':vapid_details']) || {}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
|
|
@ -2,8 +2,6 @@ export { default as ActivityPub } from './ActivityPub'
|
|||
export { default as Authentication } from './Authentication'
|
||||
export { default as AutoLinker } from './AutoLinker'
|
||||
export { default as Captcha } from './Captcha'
|
||||
export { default as Database } from './Database'
|
||||
export { default as Endpoint } from './Endpoint'
|
||||
export { default as Esshd } from './Esshd'
|
||||
export { default as Frontend } from './Frontend'
|
||||
export { default as Gopher } from './Gopher'
|
||||
|
|
|
@ -32,7 +32,7 @@ export default {
|
|||
name: 'EditableKeywordInput',
|
||||
props: {
|
||||
data: {
|
||||
type: [Object, Array],
|
||||
type: Array,
|
||||
default: function() {
|
||||
return {}
|
||||
}
|
||||
|
@ -95,7 +95,7 @@ export default {
|
|||
updateSetting(value, group, key, input, type) {
|
||||
const updatedSettings = type !== 'map'
|
||||
? value.reduce((acc, element) => {
|
||||
return { ...acc, [Object.keys(element)[0]]: [['list'], Object.values(element)[0].value] }
|
||||
return { ...acc, [Object.keys(element)[0]]: ['list', Object.values(element)[0].value] }
|
||||
}, {})
|
||||
: value.reduce((acc, element) => {
|
||||
return { ...acc, [Object.keys(element)[0]]: Object.values(element)[0].value }
|
||||
|
|
|
@ -28,7 +28,7 @@ export default {
|
|||
name: 'EditableKeywordInput',
|
||||
props: {
|
||||
data: {
|
||||
type: [Object, Array],
|
||||
type: Array,
|
||||
default: function() {
|
||||
return {}
|
||||
}
|
||||
|
@ -45,14 +45,11 @@ export default {
|
|||
return {}
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
||||
},
|
||||
methods: {
|
||||
addIconToIcons() {
|
||||
const updatedValue = [...this.data, [{ key: '', value: '', id: this.generateID() }]]
|
||||
this.updateSetting(updatedValue, this.settingGroup.group, this.settingGroup.key, this.setting.key)
|
||||
this.updateSetting(updatedValue, this.settingGroup.group, this.settingGroup.key, this.setting.key, this.setting.type)
|
||||
},
|
||||
addValueToIcons(index) {
|
||||
const updatedValue = this.data.map((icon, i) => {
|
||||
|
@ -61,11 +58,11 @@ export default {
|
|||
}
|
||||
return icon
|
||||
})
|
||||
this.updateSetting(updatedValue, this.settingGroup.group, this.settingGroup.key, this.setting.key)
|
||||
this.updateSetting(updatedValue, this.settingGroup.group, this.settingGroup.key, this.setting.key, this.setting.type)
|
||||
},
|
||||
deleteIcondRow(index) {
|
||||
const filteredValues = this.data.filter((icon, i) => i !== index)
|
||||
this.updateSetting(filteredValues, this.settingGroup.group, this.settingGroup.key, this.setting.key)
|
||||
this.updateSetting(filteredValues, this.settingGroup.group, this.settingGroup.key, this.setting.key, this.setting.type)
|
||||
},
|
||||
generateID() {
|
||||
return `f${(~~(Math.random() * 1e8)).toString(16)}`
|
||||
|
|
|
@ -23,7 +23,7 @@ export default {
|
|||
name: 'MascotsInput',
|
||||
props: {
|
||||
data: {
|
||||
type: [Object, Array],
|
||||
type: Array,
|
||||
default: function() {
|
||||
return {}
|
||||
}
|
||||
|
@ -88,7 +88,7 @@ export default {
|
|||
updateSetting(value, group, key, input, type) {
|
||||
const mascotsWithoutIDs = value.reduce((acc, mascot) => {
|
||||
const { id, ...mascotValue } = Object.values(mascot)[0]
|
||||
return { ...acc, [Object.keys(mascot)[0]]: mascotValue }
|
||||
return { ...acc, [Object.keys(mascot)[0]]: ['', mascotValue] }
|
||||
}, {})
|
||||
this.$store.dispatch('UpdateSettings', { group, key, input, value: mascotsWithoutIDs, type })
|
||||
this.$store.dispatch('UpdateState', { group, key, input, value })
|
||||
|
|
|
@ -5,7 +5,8 @@
|
|||
:value="rateLimitAllUsers[0]"
|
||||
placeholder="scale"
|
||||
class="scale-input"
|
||||
@input="parseRateLimiter($event, setting.key, 'scale', 'oneLimit', rateLimitAllUsers)"/> :
|
||||
@input="parseRateLimiter($event, setting.key, 'scale', 'oneLimit', rateLimitAllUsers)"/>
|
||||
<span>:</span>
|
||||
<el-input
|
||||
:value="rateLimitAllUsers[1]"
|
||||
placeholder="limit"
|
||||
|
@ -17,24 +18,26 @@
|
|||
</div>
|
||||
</div>
|
||||
<div v-if="rateLimitAuthUsers">
|
||||
<el-form-item label="Unauthenticated users:">
|
||||
<el-form-item label="Unauthenticated users:" label-width="180px" class="rate-limit">
|
||||
<el-input
|
||||
:value="rateLimitUnauthUsers[0]"
|
||||
placeholder="scale"
|
||||
class="scale-input"
|
||||
@input="parseRateLimiter($event, setting.key, 'scale', 'unauthUsersLimit', [rateLimitUnauthUsers, rateLimitAuthUsers])"/> :
|
||||
@input="parseRateLimiter($event, setting.key, 'scale', 'unauthUsersLimit', [rateLimitUnauthUsers, rateLimitAuthUsers])"/>
|
||||
<span>:</span>
|
||||
<el-input
|
||||
:value="rateLimitUnauthUsers[1]"
|
||||
placeholder="limit"
|
||||
class="limit-input"
|
||||
@input="parseRateLimiter($event, setting.key, 'limit', 'unauthUsersLimit', [rateLimitUnauthUsers, rateLimitAuthUsers])"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="Authenticated users:">
|
||||
<el-form-item label="Authenticated users:" label-width="180px" class="rate-limit">
|
||||
<el-input
|
||||
:value="rateLimitAuthUsers[0]"
|
||||
placeholder="scale"
|
||||
class="scale-input"
|
||||
@input="parseRateLimiter($event, setting.key, 'scale', 'authUserslimit', [rateLimitUnauthUsers, rateLimitAuthUsers])"/> :
|
||||
@input="parseRateLimiter($event, setting.key, 'scale', 'authUserslimit', [rateLimitUnauthUsers, rateLimitAuthUsers])"/>
|
||||
<span>:</span>
|
||||
<el-input
|
||||
:value="rateLimitAuthUsers[1]"
|
||||
placeholder="limit"
|
||||
|
|
|
@ -1,93 +0,0 @@
|
|||
<template>
|
||||
<div>
|
||||
<div v-for="subSetting in setting.children" :key="subSetting.key">
|
||||
<el-form-item :label="subSetting.label" :label-width="customLabelWidth">
|
||||
<el-select
|
||||
v-if="subSetting.type.includes('list') && subSetting.type.includes('atom')"
|
||||
:value="subSettingValue(subSetting)"
|
||||
multiple
|
||||
filterable
|
||||
allow-create
|
||||
@change="update($event, subSetting.key)">
|
||||
<el-option v-for="(option, index) in subSetting.suggestions" :key="index" :value="option"/>
|
||||
</el-select>
|
||||
<p class="expl">{{ subSetting.description }}</p>
|
||||
</el-form-item>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'SslOptionsInput',
|
||||
props: {
|
||||
customLabelWidth: {
|
||||
type: String,
|
||||
default: function() {
|
||||
return this.labelWidth
|
||||
},
|
||||
required: false
|
||||
},
|
||||
data: {
|
||||
type: [Object, Array],
|
||||
default: function() {
|
||||
return {}
|
||||
}
|
||||
},
|
||||
nested: {
|
||||
type: Boolean,
|
||||
default: function() {
|
||||
return false
|
||||
}
|
||||
},
|
||||
setting: {
|
||||
type: Object,
|
||||
default: function() {
|
||||
return {}
|
||||
}
|
||||
},
|
||||
settingGroup: {
|
||||
type: Object,
|
||||
default: function() {
|
||||
return {}
|
||||
}
|
||||
},
|
||||
settingParent: {
|
||||
type: Object,
|
||||
default: function() {
|
||||
return {}
|
||||
},
|
||||
required: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
inputValue(key) {
|
||||
return this.data[this.setting.key][key]
|
||||
},
|
||||
subSettingValue(subSetting) {
|
||||
return this.data && this.data[this.setting.key] ? this.data[this.setting.key][subSetting.key] : []
|
||||
},
|
||||
update(value, childKey) {
|
||||
const [group, key, parentKey, input] = [this.settingGroup.group, this.settingGroup.key, this.setting.key, this.settingParent.key]
|
||||
const { updatedSettings, description } = this.$store.state.settings
|
||||
const type = description
|
||||
.find(element => element.group === group && element.key === key).children
|
||||
.find(child => child.key === ':adapter').children.find(child => child.key === ':ssl_options').children
|
||||
.find(child => child.key === childKey).type
|
||||
|
||||
const updatedState = { ...this.data, [parentKey]: { ...this.data[parentKey], [childKey]: value }}
|
||||
const updatedSetting = !updatedSettings[group] || !updatedSettings[group][key]
|
||||
? { [parentKey]: ['keyword', { [childKey]: [type, value] }] }
|
||||
: { ...updatedSettings[group][key][parentKey], [parentKey]: { ...updatedSettings[group][key][parentKey], [childKey]: [type, value] }}
|
||||
|
||||
this.$store.dispatch('UpdateSettings', { group, key, input, value: updatedSetting, type: this.settingParent.type })
|
||||
this.$store.dispatch('UpdateState', { group, key, input, value: updatedState })
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style rel='stylesheet/scss' lang='scss'>
|
||||
@import '../../styles/main';
|
||||
@include settings
|
||||
</style>
|
|
@ -6,4 +6,3 @@ export { default as MultipleSelect } from './MultipleSelect'
|
|||
export { default as ProxyUrlInput } from './ProxyUrlInput'
|
||||
export { default as PruneInput } from './PruneInput'
|
||||
export { default as RateLimitInput } from './RateLimitInput'
|
||||
export { default as SslOptionsInput } from './SslOptionsInput'
|
||||
|
|
|
@ -17,15 +17,9 @@
|
|||
<el-tab-pane :label="$t('settings.captcha')" lazy>
|
||||
<captcha/>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane :label="$t('settings.database')" lazy>
|
||||
<database/>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane :label="$t('settings.emojiPacks')" lazy>
|
||||
<emoji-packs/>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane :label="$t('settings.endpoint')" lazy>
|
||||
<endpoint/>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane :label="$t('settings.frontend')" lazy>
|
||||
<frontend/>
|
||||
</el-tab-pane>
|
||||
|
@ -76,11 +70,11 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import { ActivityPub, Authentication, AutoLinker, Captcha, Database, Endpoint, Esshd, Frontend, Gopher, Http, Instance, JobQueue, Logger, Mailer, MediaProxy, Metadata, Mrf, Other, RateLimiters, Relays, Upload, WebPush } from './components'
|
||||
import { ActivityPub, Authentication, AutoLinker, Captcha, Esshd, Frontend, Gopher, Http, Instance, JobQueue, Logger, Mailer, MediaProxy, Metadata, Mrf, Other, RateLimiters, Relays, Upload, WebPush } from './components'
|
||||
import EmojiPacks from '../emojiPacks/index'
|
||||
|
||||
export default {
|
||||
components: { ActivityPub, Authentication, AutoLinker, Captcha, Database, Endpoint, EmojiPacks, Esshd, Frontend, Gopher, Http, Instance, JobQueue, Logger, Mailer, MediaProxy, Metadata, Mrf, Other, RateLimiters, Relays, Upload, WebPush },
|
||||
components: { ActivityPub, Authentication, AutoLinker, Captcha, EmojiPacks, Esshd, Frontend, Gopher, Http, Instance, JobQueue, Logger, Mailer, MediaProxy, Metadata, Mrf, Other, RateLimiters, Relays, Upload, WebPush },
|
||||
data() {
|
||||
return {
|
||||
activeTab: 'instance'
|
||||
|
|
|
@ -23,6 +23,9 @@
|
|||
.el-form-item {
|
||||
margin-right: 30px;
|
||||
}
|
||||
.el-form-item .rate-limit {
|
||||
margin-right: 0;
|
||||
}
|
||||
.center-label label {
|
||||
text-align: center;
|
||||
}
|
||||
|
@ -95,8 +98,8 @@
|
|||
margin-left: 10px;
|
||||
}
|
||||
.limit-input {
|
||||
width: 48%;
|
||||
margin: 0 0 5px 8px
|
||||
width: 47%;
|
||||
margin: 0 0 5px 1%
|
||||
}
|
||||
.line {
|
||||
width: 100%;
|
||||
|
@ -130,6 +133,15 @@
|
|||
margin-left: 8px;
|
||||
margin-right: 10px
|
||||
}
|
||||
.replacement-input {
|
||||
width: 80%;
|
||||
margin-left: 8px;
|
||||
margin-right: 10px
|
||||
}
|
||||
.scale-input {
|
||||
width: 47%;
|
||||
margin: 0 1% 5px 0
|
||||
}
|
||||
.setting-input {
|
||||
display: flex;
|
||||
margin-bottom: 10px;
|
||||
|
@ -137,22 +149,13 @@
|
|||
.single-input {
|
||||
margin-right: 10px
|
||||
}
|
||||
.scale-input {
|
||||
width: 48%;
|
||||
margin: 0 8px 5px 0
|
||||
}
|
||||
.replacement-input {
|
||||
width: 80%;
|
||||
margin-left: 8px;
|
||||
margin-right: 10px
|
||||
.ssl-tls-opts {
|
||||
margin: 36px 0 0 0;
|
||||
}
|
||||
.text {
|
||||
line-height: 20px;
|
||||
margin-right: 15px
|
||||
}
|
||||
.ssl-tls-opts {
|
||||
margin: 36px 0 0 0;
|
||||
}
|
||||
.upload-container {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
|
|
|
@ -31,7 +31,8 @@ describe('Wrap settings', () => {
|
|||
const result = wrapUpdatedSettings(':mime', settings, {})
|
||||
const expectedResult = [{
|
||||
group: ':mime',
|
||||
key: ':types', value: {
|
||||
key: ':types',
|
||||
value: {
|
||||
'application/ld+json': ['activity+json'],
|
||||
'application/xml': ['xml'],
|
||||
'application/xrd+xml': ['xrd+xml']
|
||||
|
@ -39,4 +40,335 @@ describe('Wrap settings', () => {
|
|||
}]
|
||||
expect(_.isEqual(result, expectedResult)).toBeTruthy()
|
||||
})
|
||||
|
||||
it('wraps :mascots setting in group :assets', () => {
|
||||
const settings = { ':assets': { ':mascots': [['keyword', 'map'], {
|
||||
':pleroma_fox_tan_shy': ['', { ':mime_type': 'image/png', ':url': '/images/pleroma-fox-tan-shy.png' }],
|
||||
':pleroma_fox_tan': ['', { ':mime_type': 'image/png', ':url': '/images/pleroma-fox-tan-smol.png' }],
|
||||
}]}}
|
||||
const state = { ':pleroma': { ':assets': {}}}
|
||||
const result = wrapUpdatedSettings(':pleroma', settings, state)
|
||||
const expectedResult = [{
|
||||
group: ':pleroma',
|
||||
key: ':assets',
|
||||
value: [{ tuple: [':mascots', [
|
||||
{ tuple: [':pleroma_fox_tan_shy', { ':mime_type': 'image/png', ':url': '/images/pleroma-fox-tan-shy.png'}] },
|
||||
{ tuple: [':pleroma_fox_tan', { ':mime_type': 'image/png', ':url': '/images/pleroma-fox-tan-smol.png'}] }
|
||||
]]}]
|
||||
}]
|
||||
expect(_.isEqual(result, expectedResult)).toBeTruthy()
|
||||
})
|
||||
|
||||
it('wraps settings with type keyword', () => {
|
||||
const settings1 = { 'Pleroma.Upload': { ':proxy_opts':
|
||||
[ 'keyword', {
|
||||
':redirect_on_failure': ['boolean', true],
|
||||
':http': ['keyword', { ':proxy_url': [['string', 'tuple'], 'localhost:3090' ]}]
|
||||
}]
|
||||
}}
|
||||
const state1 = { ':pleroma': { 'Pleroma.Upload': {}}}
|
||||
const result1 = wrapUpdatedSettings(':pleroma', settings1, state1)
|
||||
const expectedResult1 = [{
|
||||
group: ':pleroma',
|
||||
key: 'Pleroma.Upload',
|
||||
value: [{ tuple: [':proxy_opts', [
|
||||
{ tuple: [':redirect_on_failure', true] },
|
||||
{ tuple: [':http', [{ tuple: [':proxy_url', 'localhost:3090'] }]] }
|
||||
]]}]
|
||||
}]
|
||||
|
||||
const settings2 = { ':media_proxy': { ':proxy_opts':
|
||||
['keyword', {
|
||||
':max_body_length': ['integer', 26210000],
|
||||
':http': ['keyword', {
|
||||
':proxy_url': [['string', 'tuple'], [':socks5', '127.0.0.1', '9020']],
|
||||
':adapter': ['keyword', {
|
||||
':ssl_options': ['keyword', {
|
||||
':versions': [['list', 'atom'], [':tlsv1', ':tlsv1.1']]
|
||||
}]
|
||||
}]
|
||||
}]
|
||||
}]
|
||||
}}
|
||||
const state2 = { ':pleroma': { ':media_proxy': {}}}
|
||||
const result2 = wrapUpdatedSettings(':pleroma', settings2, state2)
|
||||
const expectedResult2 = [{
|
||||
group: ':pleroma',
|
||||
key: ':media_proxy',
|
||||
value: [{ tuple: [':proxy_opts', [
|
||||
{ tuple: [':max_body_length', 26210000] },
|
||||
{ tuple: [':http',
|
||||
[{ tuple: [ ':proxy_url', { tuple: [ ':socks5', '127.0.0.1', '9020' ] }]},
|
||||
{ tuple: [':adapter',
|
||||
[{ tuple: [':ssl_options', [{ tuple: [':versions', [':tlsv1', ':tlsv1.1']]}]]}]
|
||||
]}]
|
||||
]}
|
||||
]]}]
|
||||
}]
|
||||
|
||||
expect(_.isEqual(result1, expectedResult1)).toBeTruthy()
|
||||
expect(_.isEqual(result2, expectedResult2)).toBeTruthy()
|
||||
})
|
||||
|
||||
it('wraps settings that includes keyword in type', () => {
|
||||
const settings1 = { 'Oban': { ':queues': [
|
||||
['keyword', 'integer'],
|
||||
{ ':activity_expiration': ['integer', 15],
|
||||
':background': ['integer', 10],
|
||||
':federator_incoming': ['integer', 30]}
|
||||
]}}
|
||||
const state1 = { ':pleroma': { 'Oban': {}}}
|
||||
const result1 = wrapUpdatedSettings(':pleroma', settings1, state1)
|
||||
const expectedResult1 = [{
|
||||
group: ':pleroma',
|
||||
key: 'Oban',
|
||||
value: [{ tuple: [':queues', [
|
||||
{ tuple: [':activity_expiration', 15] },
|
||||
{ tuple: [':background', 10] },
|
||||
{ tuple: [':federator_incoming', 30]}
|
||||
]]}]
|
||||
}]
|
||||
|
||||
const settings2 = { ':emoji': { ':groups': [
|
||||
['keyword', 'string', ['list', 'string']],
|
||||
{ ':custom': [['list'], ['/emoji/*.png', '/emoji/**/*.png']],
|
||||
':another_group': ['list', ['/custom_emoji/*.png']]}
|
||||
]}}
|
||||
const state2 = { ':pleroma': { ':emoji': {}}}
|
||||
const result2 = wrapUpdatedSettings(':pleroma', settings2, state2)
|
||||
const expectedResult2 = [{
|
||||
group: ':pleroma',
|
||||
key: ':emoji',
|
||||
value: [{ tuple: [':groups', [
|
||||
{ tuple: [':custom', ['/emoji/*.png', '/emoji/**/*.png']]},
|
||||
{ tuple: [':another_group', ['/custom_emoji/*.png']]}
|
||||
]]}]
|
||||
}]
|
||||
|
||||
expect(_.isEqual(result1, expectedResult1)).toBeTruthy()
|
||||
expect(_.isEqual(result2, expectedResult2)).toBeTruthy()
|
||||
})
|
||||
|
||||
it('wraps :replace setting', () => {
|
||||
const settings = { ':mrf_keyword': { ':replace': [
|
||||
[['tuple', 'string', 'string'], ['tuple', 'regex', 'string']],
|
||||
{ 'pattern': ['list', 'replacement'],
|
||||
'/\w+/': ['list', 'test_replacement']}
|
||||
]}}
|
||||
const state = { ':pleroma': { ':mrf_keyword': {}}}
|
||||
const result = wrapUpdatedSettings(':pleroma', settings, state)
|
||||
const expectedResult = [{
|
||||
group: ':pleroma',
|
||||
key: ':mrf_keyword',
|
||||
value: [{ tuple: [':replace', [
|
||||
{ tuple: ['pattern', 'replacement'] },
|
||||
{ tuple: ['/\w+/', 'test_replacement'] }
|
||||
]]}]
|
||||
}]
|
||||
|
||||
expect(_.isEqual(result, expectedResult)).toBeTruthy()
|
||||
})
|
||||
|
||||
it('wraps settings with type atom', () => {
|
||||
const settings = {
|
||||
':ldap': { ':sslopts': [ 'keyword', { ':verify': ['atom', 'verify_peer']}]},
|
||||
':assets': { ':default_mascot': ['atom', 'pleroma_fox_tan_test']}
|
||||
}
|
||||
const state = { ':pleroma': { ':sslopts': {}, ':assets': {}}}
|
||||
const result = wrapUpdatedSettings(':pleroma', settings, state)
|
||||
const expectedResult = [{
|
||||
group: ':pleroma',
|
||||
key: ':ldap',
|
||||
value: [{ tuple: [':sslopts', [{tuple: [':verify', ':verify_peer']}]]}]
|
||||
}, {
|
||||
group: ':pleroma',
|
||||
key: ':assets',
|
||||
value: [{ tuple: [':default_mascot', ':pleroma_fox_tan_test']}]
|
||||
}]
|
||||
|
||||
expect(_.isEqual(result, expectedResult)).toBeTruthy()
|
||||
})
|
||||
|
||||
it('wraps settings with type string and tuple', () => {
|
||||
const settings1 = { ':media_proxy': { ':proxy_opts':
|
||||
['keyword', {
|
||||
':http': ['keyword', { ':proxy_url': [['string', 'tuple'], 'localhost:9020']}]
|
||||
}]
|
||||
}}
|
||||
const state1 = { ':pleroma': { ':media_proxy': {}}}
|
||||
const result1 = wrapUpdatedSettings(':pleroma', settings1, state1)
|
||||
const expectedResult1 = [{
|
||||
group: ':pleroma',
|
||||
key: ':media_proxy',
|
||||
value: [{ tuple: [':proxy_opts', [
|
||||
{ tuple: [':http',
|
||||
[{ tuple: [':proxy_url', 'localhost:9020'] }]
|
||||
]}
|
||||
]]}]
|
||||
}]
|
||||
|
||||
const settings2 = { ':media_proxy': { ':proxy_opts':
|
||||
['keyword', {
|
||||
':http': ['keyword', { ':proxy_url': [['string', 'tuple'], [':socks5', '127.0.0.1', '9020']]}]
|
||||
}]
|
||||
}}
|
||||
const state2 = { ':pleroma': { ':media_proxy': {}}}
|
||||
const result2 = wrapUpdatedSettings(':pleroma', settings2, state2)
|
||||
const expectedResult2 = [{
|
||||
group: ':pleroma',
|
||||
key: ':media_proxy',
|
||||
value: [{ tuple: [':proxy_opts', [
|
||||
{ tuple: [':http',
|
||||
[{ tuple: [ ':proxy_url', { tuple: [':socks5', '127.0.0.1', '9020'] }]}]
|
||||
]}
|
||||
]]}]
|
||||
}]
|
||||
|
||||
expect(_.isEqual(result1, expectedResult1)).toBeTruthy()
|
||||
expect(_.isEqual(result2, expectedResult2)).toBeTruthy()
|
||||
})
|
||||
|
||||
it('wraps settings with type atom and tuple', () => {
|
||||
const settings1 = { 'Oban': { ':prune': [['atom', 'tuple'], ':disabled']}}
|
||||
const state1 = { ':pleroma': { 'Oban': {}}}
|
||||
const result1 = wrapUpdatedSettings(':pleroma', settings1, state1)
|
||||
const expectedResult1 = [{
|
||||
group: ':pleroma',
|
||||
key: 'Oban',
|
||||
value: [{ tuple: [':prune', ':disabled']}]
|
||||
}]
|
||||
|
||||
const settings2 = { 'Oban': { ':prune':
|
||||
[['atom', 'tuple'], [':maxlen', 1500]]
|
||||
}}
|
||||
const state2 = { ':pleroma': { 'Oban': {}}}
|
||||
const result2 = wrapUpdatedSettings(':pleroma', settings2, state2)
|
||||
const expectedResult2 = [{
|
||||
group: ':pleroma',
|
||||
key: 'Oban',
|
||||
value: [{ tuple: [':prune', {tuple: [':maxlen', 1500]}]}]
|
||||
}]
|
||||
|
||||
expect(_.isEqual(result1, expectedResult1)).toBeTruthy()
|
||||
expect(_.isEqual(result2, expectedResult2)).toBeTruthy()
|
||||
})
|
||||
|
||||
it('wraps settings with type map', () => {
|
||||
const settings1 = { ':instance': { ':poll_limits': ['map', { ':min_expiration': ['integer', 100] }]}}
|
||||
const state1 = { ':pleroma': { ':instance': { ':poll_limits': {
|
||||
':max_expiration': 31536000,
|
||||
':max_option_chars': 200,
|
||||
':max_options': 20,
|
||||
':min_expiration': 100
|
||||
}}}}
|
||||
const result1 = wrapUpdatedSettings(':pleroma', settings1, state1)
|
||||
const expectedResult1 = [{
|
||||
group: ':pleroma',
|
||||
key: ':instance',
|
||||
value: [{ tuple: [':poll_limits', {
|
||||
':max_expiration': 31536000,
|
||||
':max_option_chars': 200,
|
||||
':max_options': 20,
|
||||
':min_expiration': 100
|
||||
}]}]
|
||||
}]
|
||||
|
||||
const settings2 = { ':email_notifications': { ':digest': ['map', {
|
||||
':active': ['boolean', true],
|
||||
':schedule': ['string', '0 0 0'],
|
||||
':inactivity_threshold': ['integer', 10]
|
||||
}]}}
|
||||
const state2 = { ':pleroma': { ':email_notifications': { ':digest': {
|
||||
':active': true,
|
||||
':inactivity_threshold': 10,
|
||||
':interval': 7,
|
||||
':schedule': '0 0 0'
|
||||
}}}}
|
||||
const result2 = wrapUpdatedSettings(':pleroma', settings2, state2)
|
||||
const expectedResult2 = [{
|
||||
group: ':pleroma',
|
||||
key: ':email_notifications',
|
||||
value: [{ tuple: [':digest', {
|
||||
':active': true,
|
||||
':inactivity_threshold': 10,
|
||||
':interval': 7,
|
||||
':schedule': '0 0 0'
|
||||
}]}]
|
||||
}]
|
||||
|
||||
const settings3 = { ':mrf_subchain': { ':match_actor': ['map', {
|
||||
'~r/https:\/\/example.com/s': ['Elixir.Pleroma.Web.ActivityPub.MRF.DropPolicy'],
|
||||
'~r/https:\/\/test.com': ['Elixir.Pleroma.Web.ActivityPub.MRF.TestPolicy']
|
||||
}]}}
|
||||
const state3 = { ':pleroma': { ':mrf_subchain': { ':match_actor': [
|
||||
{ '~r/https:\/\/example.com/s': ['Elixir.Pleroma.Web.ActivityPub.MRF.DropPolicy'] },
|
||||
{ '~r/https:\/\/test.com': ['Elixir.Pleroma.Web.ActivityPub.MRF.TestPolicy'] }
|
||||
]
|
||||
}}}
|
||||
const result3 = wrapUpdatedSettings(':pleroma', settings3, state3)
|
||||
const expectedResult3 = [{
|
||||
group: ':pleroma',
|
||||
key: ':mrf_subchain',
|
||||
value: [{ tuple: [':match_actor', {
|
||||
'~r/https:\/\/example.com/s': ['Elixir.Pleroma.Web.ActivityPub.MRF.DropPolicy'],
|
||||
'~r/https:\/\/test.com': ['Elixir.Pleroma.Web.ActivityPub.MRF.TestPolicy']
|
||||
}]}]
|
||||
}]
|
||||
|
||||
expect(_.isEqual(result1, expectedResult1)).toBeTruthy()
|
||||
expect(_.isEqual(result2, expectedResult2)).toBeTruthy()
|
||||
expect(_.isEqual(result3, expectedResult3)).toBeTruthy()
|
||||
})
|
||||
|
||||
it('wraps IP setting', () => {
|
||||
const settings = { ':gopher': { ':ip': ['tuple', '127.0.0.1']}}
|
||||
const state = { ':pleroma': { ':gopher': {}}}
|
||||
const result = wrapUpdatedSettings(':pleroma', settings, state)
|
||||
const expectedResult = [{
|
||||
group: ':pleroma',
|
||||
key: ':gopher',
|
||||
value: [{ tuple: [':ip', { tuple: [127, 0, 0, 1] }]}]
|
||||
}]
|
||||
|
||||
expect(_.isEqual(result, expectedResult)).toBeTruthy()
|
||||
})
|
||||
|
||||
it('wraps args setting in Pleroma.Upload.Filter.Mogrify group', () => {
|
||||
const settings = { 'Pleroma.Upload.Filter.Mogrify': { ':args': [
|
||||
['string', ['list', 'string'], ['list', 'tuple']],
|
||||
['strip', 'implode']
|
||||
]}}
|
||||
const state = { ':pleroma': { 'Pleroma.Upload.Filter.Mogrify': {}}}
|
||||
const result = wrapUpdatedSettings(':pleroma', settings, state)
|
||||
const expectedResult = [{
|
||||
group: ':pleroma',
|
||||
key: 'Pleroma.Upload.Filter.Mogrify',
|
||||
value: [{tuple: [':args', ['strip', {tuple: ['implode', '1']}]]}]
|
||||
}]
|
||||
|
||||
expect(_.isEqual(result, expectedResult)).toBeTruthy()
|
||||
})
|
||||
|
||||
it('wraps regular settings', () => {
|
||||
const settings = { ':http_security': {
|
||||
':report_uri': ["string", "https://test.com"],
|
||||
':ct_max_age': ["integer", 150000],
|
||||
':sts': ["boolean", true],
|
||||
':methods': [["list", "string"], ["POST", "PUT", "PATCH"]]
|
||||
}}
|
||||
const state = { ':pleroma': { ':http_security': {}}}
|
||||
const result = wrapUpdatedSettings(':pleroma', settings, state)
|
||||
const expectedResult = [{
|
||||
group: ':pleroma',
|
||||
key: ':http_security',
|
||||
value: [
|
||||
{ tuple: [":report_uri", "https://test.com"] },
|
||||
{ tuple: [":ct_max_age", 150000] },
|
||||
{ tuple: [":sts", true] },
|
||||
{ tuple: [":methods", ["POST", "PUT", "PATCH"]] }
|
||||
]
|
||||
}]
|
||||
|
||||
expect(_.isEqual(result, expectedResult)).toBeTruthy()
|
||||
})
|
||||
})
|
||||
|
|
12
yarn.lock
12
yarn.lock
|
@ -1868,11 +1868,6 @@ brace-expansion@^1.1.7:
|
|||
balanced-match "^1.0.0"
|
||||
concat-map "0.0.1"
|
||||
|
||||
brace@^0.11.0:
|
||||
version "0.11.1"
|
||||
resolved "https://registry.yarnpkg.com/brace/-/brace-0.11.1.tgz#4896fcc9d544eef45f4bb7660db320d3b379fe58"
|
||||
integrity sha1-SJb8ydVE7vRfS7dmDbMg07N5/lg=
|
||||
|
||||
braces@^2.2.2, braces@^2.3.1, braces@^2.3.2:
|
||||
version "2.3.2"
|
||||
resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729"
|
||||
|
@ -10207,13 +10202,6 @@ vue-template-es2015-compiler@^1.9.0:
|
|||
resolved "https://registry.yarnpkg.com/vue-template-es2015-compiler/-/vue-template-es2015-compiler-1.9.1.tgz#1ee3bc9a16ecbf5118be334bb15f9c46f82f5825"
|
||||
integrity sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw==
|
||||
|
||||
vue2-ace-editor@^0.0.13:
|
||||
version "0.0.13"
|
||||
resolved "https://registry.yarnpkg.com/vue2-ace-editor/-/vue2-ace-editor-0.0.13.tgz#5528998ce2c13e8ed3a294f714298199fd107dc2"
|
||||
integrity sha512-uQICyvJzYNix16xeYjNAINuNUQhPbqMR7UQsJeI+ycpEd2otsiNNU73jcZqHkpjuz0uaHDHnrpzQuI/RApsKXA==
|
||||
dependencies:
|
||||
brace "^0.11.0"
|
||||
|
||||
vue@^2.6.8:
|
||||
version "2.6.8"
|
||||
resolved "https://registry.yarnpkg.com/vue/-/vue-2.6.8.tgz#f21cbc536bfc14f7d1d792a137bb12f69e60ea91"
|
||||
|
|
Loading…
Reference in a new issue