diff --git a/CHANGELOG.md b/CHANGELOG.md index 90a613433cd7e78aaf664f9c997d3a28f14b029e..58c433f1e9d45fa8923716ad7d0e6e5fbb18dffb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,9 +6,15 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ## [Unreleased] +### Added + +- add ability to configure new settings (UploadS3 bucket namespace, Rate limit for Activity pub routes, Email notifications settings, MRF Vocabulary, user bio and name length and others) + ### Changed - removes "Dashboard" from dropdown menu +- makes all single selects clearable and allow to enter custom values in all multiple selects +- remove legacy activitypub accept_blocks setting ### Fixed diff --git a/src/api/initialDataForConfig.js b/src/api/initialDataForConfig.js index bc425a35ec762143369dbd09753600b9c91b616a..f24ffb9a988c80716056ed5faa7a36c34c5b0027 100644 --- a/src/api/initialDataForConfig.js +++ b/src/api/initialDataForConfig.js @@ -42,7 +42,14 @@ export const initialSettings = [ { 'tuple': [':remote_post_retention_days', 90] }, { 'tuple': [':skip_thread_containment', true] }, { 'tuple': [':limit_to_local_content', ':unauthenticated'] }, - { 'tuple': [':dynamic_configuration', true] } + { 'tuple': [':dynamic_configuration', true] }, + { 'tuple': [':max_account_fields', 10] }, + { 'tuple': [':max_remote_account_fields', 20] }, + { 'tuple': [':account_field_name_length', 255] }, + { 'tuple': [':account_field_value_length', 255] }, + { 'tuple': [':external_user_synchronization', true] }, + { 'tuple': [':user_bio_length', 5000] }, + { 'tuple': [':user_name_length', 100] } ] }, { diff --git a/src/store/getters.js b/src/store/getters.js index 1e0d4791338a7fcd93cf6152641bb8a1784f3c0c..03899ea7895c87b3ebbb3192f5a3ab29472d01fd 100644 --- a/src/store/getters.js +++ b/src/store/getters.js @@ -33,6 +33,7 @@ const getters = { corsPlugMethods: state => state.settings.settings['methods'], database: state => state.settings.settings['database'], ectoRepos: state => state.settings.settings['ecto_repos'], + emailNotifications: state => state.settings.settings['email_notifications'], emoji: state => state.settings.settings['emoji'], enabled: state => state.settings.settings['enabled'], endpoint: state => state.settings.settings['Pleroma.Web.Endpoint'], @@ -67,6 +68,7 @@ const getters = { mrfSimple: state => state.settings.settings['mrf_simple'], mrfSubchain: state => state.settings.settings['mrf_subchain'], mrfUserAllowlist: state => state.settings.settings['mrf_user_allowlist'], + mrfVocabulary: state => state.settings.settings['mrf_vocabulary'], oauth2: state => state.settings.settings['oauth2'], passwordAuthenticator: state => state.settings.settings['password_authenticator'], pleromaAuthenticator: state => state.settings.settings['Pleroma.Web.Auth.Authenticator'], @@ -91,6 +93,7 @@ const getters = { uploadS3: state => state.settings.settings['Pleroma.Uploaders.S3'], uriSchemes: state => state.settings.settings['uri_schemes'], user: state => state.settings.settings['user'], + userEmail: state => state.settings.settings['Pleroma.Emails.UserEmail'], vapidDetails: state => state.settings.settings['vapid_details'], webhookUrl: state => state.settings.settings['webhook_url'] } diff --git a/src/store/modules/normalizers.js b/src/store/modules/normalizers.js index f885df89cceee1867b8a5d181fba0fee55cef3df..c2a9d3e8d8b1bdc9de44d925a8f692b6287a9518 100644 --- a/src/store/modules/normalizers.js +++ b/src/store/modules/normalizers.js @@ -1,6 +1,6 @@ const nonAtomsTuples = ['replace', ':replace'] const nonAtomsObjects = ['match_actor', ':match_actor'] -const objects = ['digest', 'pleroma_fe', 'masto_fe', 'poll_limits'] +const objects = ['digest', 'pleroma_fe', 'masto_fe', 'poll_limits', 'styling'] const objectParents = ['mascots'] const groups = { 'cors_plug': [ @@ -24,6 +24,7 @@ const groups = { 'Pleroma.Captcha', 'Pleroma.Captcha.Kocaptcha', 'Pleroma.Emails.Mailer', + 'Pleroma.Emails.UserEmail', 'Pleroma.Repo', 'Pleroma.ScheduledActivity', 'Pleroma.Upload', @@ -45,6 +46,7 @@ const groups = { 'chat', 'database', 'ecto_repos', + 'email_notifications', 'emoji', 'env', 'fetch_initial_posts', @@ -65,6 +67,7 @@ const groups = { 'mrf_simple', 'mrf_subchain', 'mrf_user_allowlist', + 'mrf_vocabulary', 'oauth2', 'rate_limit', 'rich_media', diff --git a/src/store/modules/settings.js b/src/store/modules/settings.js index 0bf95a36d6de37394e20a1ce5045bc83a94affd3..3ee58c4ebccc0dab005b406959386006cc65b106 100644 --- a/src/store/modules/settings.js +++ b/src/store/modules/settings.js @@ -17,6 +17,7 @@ const settings = { 'credentials': {}, 'database': {}, 'ecto_repos': {}, + 'email_notifications': { digest: {}}, 'emoji': { groups: {}}, 'enabled': {}, 'ex_syslogger': {}, @@ -46,11 +47,13 @@ const settings = { 'mrf_simple': {}, 'mrf_subchain': { match_actor: {}}, 'mrf_user_allowlist': {}, + 'mrf_vocabulary': {}, 'oauth2': {}, 'password_authenticator': {}, 'Pleroma.Captcha': {}, 'Pleroma.Captcha.Kocaptcha': {}, 'Pleroma.Emails.Mailer': {}, + 'Pleroma.Emails.UserEmail': { styling: {}}, 'Pleroma.Repo': {}, 'Pleroma.ScheduledActivity': {}, 'Pleroma.Upload': { proxy_opts: {}}, @@ -136,7 +139,9 @@ const settings = { }, async UploadMedia({ dispatch, getters, state }, { file, tab, inputName, childName }) { const response = await uploadMedia(file, getters.authHost, getters.token) - const updatedValue = { ...state.settings[tab][inputName], ...{ [childName]: response.data.url }} + const updatedValue = childName + ? { ...state.settings[tab][inputName], ...{ [childName]: response.data.url }} + : response.data.url dispatch('UpdateSettings', { tab, data: { [inputName]: updatedValue }}) } } diff --git a/src/views/settings/components/ActivityPub.vue b/src/views/settings/components/ActivityPub.vue index b4638b00e90aa202ba0f71a75eda7a7b2aac93a3..cd14d1f9f944f8d06d23b3383295a606e61520ba 100644 --- a/src/views/settings/components/ActivityPub.vue +++ b/src/views/settings/components/ActivityPub.vue @@ -1,10 +1,6 @@ <template> <div> <el-form ref="activityPub" :model="activityPub" :label-width="labelWidth"> - <el-form-item label="Accept blocks"> - <el-switch :value="activityPub.accept_blocks" @change="updateSetting($event, 'activitypub', 'accept_blocks')"/> - <p class="expl">Whether to accept incoming block activities from other instances</p> - </el-form-item> <el-form-item label="Unfollow blocked"> <el-switch :value="activityPub.unfollow_blocked" @change="updateSetting($event, 'activitypub', 'unfollow_blocked')"/> <p class="expl">Whether blocks result in people getting unfollowed</p> diff --git a/src/views/settings/components/Captcha.vue b/src/views/settings/components/Captcha.vue index 1e92ad61ae9d79c7c7e00d93742f7480409166d7..afc3ae22a297463d858d4c588df056ffe17aea06 100644 --- a/src/views/settings/components/Captcha.vue +++ b/src/views/settings/components/Captcha.vue @@ -10,7 +10,7 @@ <p class="expl">The time in seconds for which the captcha is valid</p> </el-form-item> <el-form-item label="Method"> - <el-select :value="captcha.method" placeholder="Select" @change="updateSetting($event, 'Pleroma.Captcha', 'method')"> + <el-select :value="captcha.method" clearable @change="updateSetting($event, 'Pleroma.Captcha', 'method')"> <el-option label="Pleroma.Captcha.Kocaptcha" value="Pleroma.Captcha.Kocaptcha"/> </el-select> <p class="expl">The method/service to use for captcha</p> diff --git a/src/views/settings/components/Database.vue b/src/views/settings/components/Database.vue index 4133b8033338507094dffc3b603cbb2f7bb60661..ec54d1c98fde3a5af201a58276df3c704254c9b3 100644 --- a/src/views/settings/components/Database.vue +++ b/src/views/settings/components/Database.vue @@ -23,7 +23,7 @@ <div class="line"/> <el-form ref="ectoRepos" :model="ectoRepos" :label-width="labelWidth"> <el-form-item label="Ecto repos"> - <el-select :value="ectoRepos.value || []" multiple allow-create @change="updateSetting($event, 'ecto_repos', 'value')"> + <el-select :value="ectoRepos.value || []" multiple filterable allow-create @change="updateSetting($event, 'ecto_repos', 'value')"> <el-option label="Pleroma.Repo" value="Pleroma.Repo"/> </el-select> </el-form-item> @@ -45,7 +45,7 @@ <p class="expl">An URL that specifies storage information</p> </el-form-item> <el-form-item label="Log level"> - <el-select :value="pleromaRepo.log" @change="updateSetting($event, 'Pleroma.Repo', 'log')"> + <el-select :value="pleromaRepo.log" clearable @change="updateSetting($event, 'Pleroma.Repo', 'log')"> <el-option :value="false" label="False - disables logging for that repository."/> <el-option value=":debug" label=":debug - for debug-related messages"/> <el-option value=":info" label=":info - for information of any kind"/> @@ -59,7 +59,7 @@ <p class="expl">The size of the pool used by the connection module. Defaults to <span class="code">10</span></p> </el-form-item> <el-form-item label="Telemetry prefix"> - <el-select :value="pleromaRepo.telemetry_prefix || []" multiple allow-create @change="updateSetting($event, 'Pleroma.Repo', 'telemetry_prefix')"> + <el-select :value="pleromaRepo.telemetry_prefix || []" multiple filterable allow-create @change="updateSetting($event, 'Pleroma.Repo', 'telemetry_prefix')"> <el-option label=":my_app" value=":my_app"/> <el-option label=":repo" value=":repo"/> <el-option label=":query" value=":query"/> @@ -69,7 +69,7 @@ <el-input :value="pleromaRepo.types" @input="updateSetting($event, 'Pleroma.Repo', 'types')"/> </el-form-item> <el-form-item label="Telemetry event"> - <el-select :value="pleromaRepo.telemetry_event || []" multiple allow-create @change="updateSetting($event, 'Pleroma.Repo', 'telemetry_event')"> + <el-select :value="pleromaRepo.telemetry_event || []" multiple filterable allow-create @change="updateSetting($event, 'Pleroma.Repo', 'telemetry_event')"> <el-option label="Pleroma.Repo.Instrumenter" value="Pleroma.Repo.Instrumenter"/> </el-select> </el-form-item> @@ -120,7 +120,7 @@ <p class="expl">The timeout for establishing new connections. Defaults to 5000</p> </el-form-item> <el-form-item label="Prepare"> - <el-select :value="pleromaRepo.prepare" @change="updateSetting($event, 'Pleroma.Repo', 'prepare')"> + <el-select :value="pleromaRepo.prepare" clearable @change="updateSetting($event, 'Pleroma.Repo', 'prepare')"> <el-option label="named" value=":named"/> <el-option label="unnamed" value=":unnamed"/> </el-select> diff --git a/src/views/settings/components/Frontend.vue b/src/views/settings/components/Frontend.vue index ec912eca9c9e21b91189551d76c4d6b4de002c43..462558365cc49e2fe579a81821f0dbb31cfdd62c 100644 --- a/src/views/settings/components/Frontend.vue +++ b/src/views/settings/components/Frontend.vue @@ -8,7 +8,7 @@ </el-form-item> <el-form-item label="Pleroma FE:"/> <el-form-item label="Theme"> - <el-select :value="frontend.pleroma_fe.theme" @change="processNestedData($event, 'frontend_configurations', 'pleroma_fe', 'theme')"> + <el-select :value="frontend.pleroma_fe.theme" clearable @change="processNestedData($event, 'frontend_configurations', 'pleroma_fe', 'theme')"> <el-option v-for="item in themeOptions" :key="item.value" @@ -80,7 +80,7 @@ <p class="expl">Copy the scope <span class="code">(private/unlisted/public)</span> in replies to posts by default</p> </el-form-item> <el-form-item label="Subject line behavior"> - <el-select :value="frontend.pleroma_fe.subjectLineBehavior" @change="processNestedData($event, 'frontend_configurations', 'pleroma_fe', 'subjectLineBehavior')"> + <el-select :value="frontend.pleroma_fe.subjectLineBehavior" clearable @change="processNestedData($event, 'frontend_configurations', 'pleroma_fe', 'subjectLineBehavior')"> <el-option label="Email" value="email">Email / Copy and preprend re:, as in email</el-option> <el-option label="Masto" value="masto">Masto / Copy verbatim, as in Mastodon</el-option> <el-option label="Noop" value="noop">Noop / Don't copy the subject</el-option> @@ -123,7 +123,7 @@ <div class="line"/> <el-form-item label="Masto FE:"/> <el-form-item label="Theme"> - <el-select :value="frontend.masto_fe.theme" @change="processNestedData($event, 'frontend_configurations', 'masto_fe', 'theme')"> + <el-select :value="frontend.masto_fe.theme" clearable @change="processNestedData($event, 'frontend_configurations', 'masto_fe', 'theme')"> <el-option v-for="item in themeOptions" :key="item.value" @@ -195,7 +195,7 @@ <p class="expl">Copy the scope <span class="code">(private/unlisted/public)</span> in replies to posts by default</p> </el-form-item> <el-form-item label="Subject line behavior"> - <el-select :value="frontend.masto_fe.subjectLineBehavior" @change="processNestedData($event, 'frontend_configurations', 'masto_fe', 'subjectLineBehavior')"> + <el-select :value="frontend.masto_fe.subjectLineBehavior" clearable @change="processNestedData($event, 'frontend_configurations', 'masto_fe', 'subjectLineBehavior')"> <el-option label="Email" value="email">Email / Copy and preprend re:, as in email</el-option> <el-option label="Masto" value="masto">Masto / Copy verbatim, as in Mastodon</el-option> <el-option label="Noop" value="noop">Noop / Don't copy the subject</el-option> @@ -240,7 +240,7 @@ <el-form ref="assets" :model="assets" :label-width="labelWidth"> <el-form-item label="Assets:"/> <el-form-item label="Default mascot"> - <el-select :value="assets.default_mascot" @change="updateSetting($event, 'assets', 'default_mascot')"/> + <el-select :value="assets.default_mascot" clearable @change="updateSetting($event, 'assets', 'default_mascot')"/> <p class="expl">An element from mascots - This will be used as the default mascot on MastoFE (default: <span class="code">:pleroma_fox_tan</span>)</p> </el-form-item> diff --git a/src/views/settings/components/Http.vue b/src/views/settings/components/Http.vue index a34bec315dc18ad7dd349e7f0a8e04bccc9fb657..ec69890e7460d0314b1e8ef7a579e79dec07f14c 100644 --- a/src/views/settings/components/Http.vue +++ b/src/views/settings/components/Http.vue @@ -82,7 +82,7 @@ <p class="expl">The maximum age for the <span class="code">Expect-CT</span> header if sent</p> </el-form-item> <el-form-item label="Referrer policy"> - <el-select :value="httpSecurity.referrer_policy" placeholder="Select" @change="updateSetting($event, 'http_security', 'referrer_policy')"> + <el-select :value="httpSecurity.referrer_policy" clearable @change="updateSetting($event, 'http_security', 'referrer_policy')"> <el-option label="same-origin" value="same-origin"/> <el-option label="no-referrer" value="no-referrer"/> </el-select> diff --git a/src/views/settings/components/Instance.vue b/src/views/settings/components/Instance.vue index 4dd6e114d60dd8f3f3a6f0b35d7ae7438c723bfb..78c8c0a2484737bc17f37309d90ab5a4ac110025 100644 --- a/src/views/settings/components/Instance.vue +++ b/src/views/settings/components/Instance.vue @@ -41,6 +41,14 @@ <el-input-number :value="instance.banner_upload_limit / 1048576" :step="1" :min="0" size="large" @change="updateSetting($event * 1048576, 'instance', 'banner_upload_limit')"/> <p class="expl">File size limit of user’s profile banners</p> </el-form-item> + <el-form-item label="User bio length"> + <el-input-number :value="instance.user_bio_length" :step="1" :min="0" size="large" @change="updateSetting($event, 'instance', 'user_bio_length')"/> + <p class="expl">A user bio maximum length (default: 5000)</p> + </el-form-item> + <el-form-item label="User name length"> + <el-input-number :value="instance.user_name_length" :step="1" :min="0" size="large" @change="updateSetting($event, 'instance', 'user_name_length')"/> + <p class="expl">A user name maximum length (default: 100)</p> + </el-form-item> <el-form-item label="Poll limits:"/> <el-form-item label="Max options"> <el-input-number :value="instance.poll_limits.max_options" :step="1" :min="0" size="large" @change="processNestedData($event, 'instance', 'poll_limits', 'max_options')"/> @@ -84,7 +92,7 @@ <p class="expl">Timeout (in days) of each external federation target being unreachable prior to pausing federating to it</p> </el-form-item> <el-form-item label="Federation publisher modules"> - <el-select :value="instance.federation_publisher_modules || []" multiple @change="updateSetting($event, 'instance', 'federation_publisher_modules')"> + <el-select :value="instance.federation_publisher_modules || []" multiple filterable allow-create @change="updateSetting($event, 'instance', 'federation_publisher_modules')"> <el-option v-for="item in federationPublisherModulesOptions" :key="item.value" @@ -114,7 +122,7 @@ <p class="expl">Makes the client API in authentificated mode-only except for user-profiles. Useful for disabling the Local Timeline and The Whole Known Network</p> </el-form-item> <el-form-item label="Quarantined instances"> - <el-select :value="instance.quarantined_instances || []" multiple placeholder="Select" @change="updateSetting($event, 'instance', 'quarantined_instances')"> + <el-select :value="instance.quarantined_instances || []" multiple filterable allow-create @change="updateSetting($event, 'instance', 'quarantined_instances')"> <el-option v-for="item in quarantinedInstancesOptions" :key="item.value" @@ -132,7 +140,7 @@ <el-input :value="instance.static_dir" @input="updateSetting($event, 'instance', 'static_dir')"/> </el-form-item> <el-form-item label="Allowed post formats"> - <el-select :value="instance.allowed_post_formats || []" multiple placeholder="Select" @change="updateSetting($event, 'instance', 'allowed_post_formats')"> + <el-select :value="instance.allowed_post_formats || []" multiple filterable allow-create @change="updateSetting($event, 'instance', 'allowed_post_formats')"> <el-option label="text/plain" value="text/plain"/> <el-option label="text/html" value="text/html"/> <el-option label="text/markdown" value="text/markdown"/> @@ -152,7 +160,7 @@ <p class="expl">Copy the scope <span class="code">(private/unlisted/public)</span> in replies to posts by default</p> </el-form-item> <el-form-item label="Subject line behavior"> - <el-select :value="instance.subject_line_behavior" @change="updateSetting($event, 'instance', 'subject_line_behavior')"> + <el-select :value="instance.subject_line_behavior" clearable @change="updateSetting($event, 'instance', 'subject_line_behavior')"> <el-option label="Email" value="email">Email / Copy and preprend re:, as in email</el-option> <el-option label="Masto" value="masto">Masto / Copy verbatim, as in Mastodon</el-option> <el-option label="Noop" value="noop">Noop / Don't copy the subject</el-option> @@ -172,7 +180,7 @@ <p class="expl">The maximum number of pinned statuses. '0' will disable the feature</p> </el-form-item> <el-form-item label="Autofollowed nicknames"> - <el-select :value="instance.autofollowed_nicknames || []" multiple placeholder="Select" @change="updateSetting($event, 'instance', 'autofollowed_nicknames')"> + <el-select :value="instance.autofollowed_nicknames || []" multiple filterable allow-create @change="updateSetting($event, 'instance', 'autofollowed_nicknames')"> <el-option v-for="item in autofollowedNicknamesOptions" :key="item.value" @@ -214,7 +222,7 @@ <p class="expl">Skip filter out broken threads.</p> </el-form-item> <el-form-item label="Limit to local content"> - <el-select :value="instance.limit_to_local_content" @change="updateSetting($event, 'instance', 'limit_to_local_content')"> + <el-select :value="instance.limit_to_local_content" clearable @change="updateSetting($event, 'instance', 'limit_to_local_content')"> <el-option label="Unauthenticated" value=":unauthenticated"/> <el-option label="All" value=":all"/> <el-option label="False" value="false"/> @@ -224,6 +232,22 @@ <el-switch :value="instance.dynamic_configuration" @change="updateSetting($event, 'instance', 'dynamic_configuration')"/> <p class="expl">Allow transferring configuration to DB with the subsequent customization from Admin API</p> </el-form-item> + <el-form-item label="Max account fields"> + <el-input-number :value="instance.max_account_fields" :step="1" :min="0" size="large" @change="updateSetting($event, 'instance', 'max_account_fields')"/> + <p class="expl">The maximum number of custom fields in the user profile (Default: 4)</p> + </el-form-item> + <el-form-item label="Max remote account fields"> + <el-input-number :value="instance.max_remote_account_fields" :step="1" :min="0" size="large" @change="updateSetting($event, 'instance', 'max_remote_account_fields')"/> + <p class="expl">The maximum number of custom fields in the remote user profile (Default: 10)</p> + </el-form-item> + <el-form-item label="Account field name length"> + <el-input-number :value="instance.account_field_name_length" :step="1" :min="0" size="large" @change="updateSetting($event, 'instance', 'account_field_name_length')"/> + <p class="expl">An account field name maximum length (Default: 255)</p> + </el-form-item> + <el-form-item label="Account field value length"> + <el-input-number :value="instance.account_field_value_length" :step="1" :min="0" size="large" @change="updateSetting($event, 'instance', 'account_field_value_length')"/> + <p class="expl">An account field value maximum length (Default: 255)</p> + </el-form-item> <el-form-item label="External user synchronization"> <el-switch :value="instance.external_user_synchronization" @change="updateSetting($event, 'instance', 'external_user_synchronization')"/> <p class="expl">Enabling following/followers counters synchronization for external users.</p> @@ -232,7 +256,7 @@ <div class="line"/> <el-form ref="uriSchemes" :model="uriSchemes" :label-width="labelWidth"> <el-form-item label="URI schemes"> - <el-select :value="uriSchemes.valid_schemes || []" multiple filterable allow-create placeholder="Select" @change="updateSetting($event, 'uri_schemes', 'valid_schemes')"> + <el-select :value="uriSchemes.valid_schemes || []" multiple filterable allow-create @change="updateSetting($event, 'uri_schemes', 'valid_schemes')"> <el-option v-for="item in uriSchemesOptions" :key="item.value" diff --git a/src/views/settings/components/Logger.vue b/src/views/settings/components/Logger.vue index 09ca4385865e22da0fc91771e1e1497da2bf1de3..cd7722713babc4929f118d3ac0e76df4676028c1 100644 --- a/src/views/settings/components/Logger.vue +++ b/src/views/settings/components/Logger.vue @@ -2,7 +2,7 @@ <div> <el-form ref="loggerBackends" :model="loggerBackends" :label-width="labelWidth"> <el-form-item label="Backends"> - <el-select :value="loggerBackendsValue" multiple @change="updateloggerBackends($event, 'backends', 'value')"> + <el-select :value="loggerBackendsValue" multiple filterable allow-create @change="updateloggerBackends($event, 'backends', 'value')"> <el-option v-for="(item, index) in loggerBackendsOptions" :key="index" @@ -16,7 +16,7 @@ <el-form ref="consoleLogger" :model="consoleLogger" :label-width="labelWidth"> <el-form-item label="Console logger:"/> <el-form-item label="Level"> - <el-select :value="consoleLogger.level" @change="updateSetting($event, 'console', 'level')"> + <el-select :value="consoleLogger.level" clearable @change="updateSetting($event, 'console', 'level')"> <el-option value=":debug" label=":debug - for debug-related messages"/> <el-option value=":info" label=":info - for information of any kind"/> <el-option value=":warn" label=":warn - for warnings"/> @@ -79,7 +79,7 @@ <el-form ref="exsyslogger" :model="exsyslogger" :label-width="labelWidth"> <el-form-item label="ExSyslogger:"/> <el-form-item label="Level"> - <el-select :value="exsyslogger.level" @change="updateSetting($event, 'ex_syslogger', 'level')"> + <el-select :value="exsyslogger.level" clearable @change="updateSetting($event, 'ex_syslogger', 'level')"> <el-option value=":debug" label=":debug - for debug-related messages"/> <el-option value=":info" label=":info - for information of any kind"/> <el-option value=":warn" label=":warn - for warnings"/> @@ -120,7 +120,7 @@ <p class="expl">Syslog facility to be used. It defaults to <span class="code">:local0</span></p> </el-form-item> <el-form-item label="Options"> - <el-select :value="exsyslogger.option || []" multiple @change="updateSetting($event, 'ex_syslogger', 'option')"> + <el-select :value="exsyslogger.option || []" multiple filterable allow-create @change="updateSetting($event, 'ex_syslogger', 'option')"> <el-option value=":pid"/> <el-option value=":cons"/> <el-option value=":odelay"/> @@ -139,7 +139,7 @@ </el-form> <el-form ref="level" :model="level" :label-width="labelWidth"> <el-form-item label="Level"> - <el-select :value="level.value" @change="updateSetting($event, 'level', 'value')"> + <el-select :value="level.value" clearable @change="updateSetting($event, 'level', 'value')"> <el-option value=":debug" label=":debug - for debug-related messages"/> <el-option value=":info" label=":info - for information of any kind"/> <el-option value=":warn" label=":warn - for warnings"/> diff --git a/src/views/settings/components/MRF.vue b/src/views/settings/components/MRF.vue index 4b2d048f0d9ee101d1978248de32f922441e93af..e4de0bb8c21f3d52efe8c936d645937c2b093329 100644 --- a/src/views/settings/components/MRF.vue +++ b/src/views/settings/components/MRF.vue @@ -124,6 +124,18 @@ <el-form-item label="Scrub policy"> <el-input :value="mrfNormalizeMarkup.scrub_policy" @input="updateSetting($event, 'mrf_normalize_markup', 'scrub_policy')"/> </el-form-item> + </el-form> + <div class="line"/> + <el-form ref="mrfVocabulary" :model="mrfVocabulary" :label-width="labelWidth"> + <el-form-item label="MRF Vocabulary:"/> + <el-form-item label="Accept"> + <el-select :value="mrfVocabulary.accept || []" multiple allow-create filterable @change="updateSetting($event, 'mrf_vocabulary', 'accept')"/> + <p class="expl">A list of ActivityStreams terms to accept. If empty, all supported messages are accepted.</p> + </el-form-item> + <el-form-item label="Reject"> + <el-select :value="mrfVocabulary.reject || []" multiple allow-create filterable @change="updateSetting($event, 'mrf_vocabulary', 'reject')"/> + <p class="expl">A list of ActivityStreams terms to reject. If empty, no messages are rejected.</p> + </el-form-item> <el-form-item> <el-button type="primary" @click="onSubmit">Submit</el-button> </el-form-item> @@ -153,7 +165,8 @@ export default { 'mrfSimple', 'mrfSubchain', 'mrfRejectnonpublic', - 'mrfUserAllowlist' + 'mrfUserAllowlist', + 'mrfVocabulary' ]), matchActor() { return Object.keys(this.mrfSubchain.match_actor).map(key => [key, this.mrfSubchain.match_actor[key]]) diff --git a/src/views/settings/components/Mailer.vue b/src/views/settings/components/Mailer.vue index 21ba90e67a490a97b76c77ddacbbea10237d4042..1b2763244f73c82cb63f5b1b51f3fb15097766e4 100644 --- a/src/views/settings/components/Mailer.vue +++ b/src/views/settings/components/Mailer.vue @@ -1,139 +1,204 @@ <template> - <el-form ref="mailer" :model="mailer" :label-width="labelWidth"> - <el-form-item label="Enabled"> - <el-switch :value="mailer.enabled" @change="updateSetting($event, 'Pleroma.Emails.Mailer', 'enabled')"/> - <p class="expl">Allows to enable or disable sending emails. Defaults to false.</p> - </el-form-item> - <el-form-item label="Adapter"> - <el-select :value="mailer.adapter" @change="updateSetting($event, 'Pleroma.Emails.Mailer', 'adapter')"> - <el-option - v-for="item in adapterOptions" - :key="item.value" - :label="item.label" - :value="item.value"/> - </el-select> - </el-form-item> - <div class="line"/> - <div v-if="mailer.adapter === 'Swoosh.Adapters.Sendmail'"> - <el-form-item label="CMD Path"> - <el-input :value="mailer.cmd_path" @input="updateSetting($event, 'Pleroma.Emails.Mailer', 'cmd_path')"/> - <p class="expl">E. g. <span class="code">/usr/bin/sendmail"</span></p> - </el-form-item> - <el-form-item label="CMD Args"> - <el-input :value="mailer.cmd_args" @input="updateSetting($event, 'Pleroma.Emails.Mailer', 'cmd_args')"/> - <p class="expl">E. g. <span class="code">-N delay,failure,success</span></p> - </el-form-item> - <el-form-item label="Qmail"> - <el-switch :value="mailer.qmail" @change="updateSetting($event, 'Pleroma.Emails.Mailer', 'qmail')"/> - </el-form-item> - </div> - <div v-if="mailer.adapter === 'Swoosh.Adapters.SMTP'"> - <el-form-item label="Relay"> - <el-input :value="mailer.relay" @input="updateSetting($event, 'Pleroma.Emails.Mailer', 'relay')"/> - <p class="expl">E. g. <span class="code">smtp.avengers.com</span></p> - </el-form-item> - <el-form-item label="Username"> - <el-input :value="mailer.username" @input="updateSetting($event, 'Pleroma.Emails.Mailer', 'username')"/> - </el-form-item> - <el-form-item label="Password"> - <el-input :value="mailer.password" @input="updateSetting($event, 'Pleroma.Emails.Mailer', 'password')"/> - </el-form-item> - <el-form-item label="SSL"> - <el-switch :value="mailer.ssl" @change="updateSetting($event, 'Pleroma.Emails.Mailer', 'ssl')"/> - </el-form-item> - <el-form-item label="TLS"> - <el-input :value="mailer.tls" @input="updateSetting($event, 'Pleroma.Emails.Mailer', 'tls')"/> - <p class="expl">E.g. <span class="code">:always</span></p> - </el-form-item> - <el-form-item label="Auth"> - <el-input :value="mailer.auth" @input="updateSetting($event, 'Pleroma.Emails.Mailer', 'auth')"/> - <p class="expl">E.g. <span class="code">:always</span></p> - </el-form-item> - <el-form-item label="Port"> - <el-input :value="mailer.port" @input="updateSetting($event, 'Pleroma.Emails.Mailer', 'port')"/> + <div> + <el-form ref="mailer" :model="mailer" :label-width="labelWidth"> + <el-form-item label="Enabled"> + <el-switch :value="mailer.enabled" @change="updateSetting($event, 'Pleroma.Emails.Mailer', 'enabled')"/> + <p class="expl">Allows to enable or disable sending emails. Defaults to false.</p> </el-form-item> - <el-form-item label="DKIM"> - <editor v-model="editorContent" height="150" width="100%" lang="elixir" theme="chrome"/> + <el-form-item label="Adapter"> + <el-select :value="mailer.adapter" clearable @change="updateSetting($event, 'Pleroma.Emails.Mailer', 'adapter')"> + <el-option + v-for="item in adapterOptions" + :key="item.value" + :label="item.label" + :value="item.value"/> + </el-select> </el-form-item> - <el-form-item label="Retries"> - <el-input-number :value="mailer.retries" :step="1" :min="0" size="large" @change="updateSetting($event, 'Pleroma.Emails.Mailer', 'retries')"/> + <div class="line"/> + <div v-if="mailer.adapter === 'Swoosh.Adapters.Sendmail'"> + <el-form-item label="CMD Path"> + <el-input :value="mailer.cmd_path" @input="updateSetting($event, 'Pleroma.Emails.Mailer', 'cmd_path')"/> + <p class="expl">E. g. <span class="code">/usr/bin/sendmail"</span></p> + </el-form-item> + <el-form-item label="CMD Args"> + <el-input :value="mailer.cmd_args" @input="updateSetting($event, 'Pleroma.Emails.Mailer', 'cmd_args')"/> + <p class="expl">E. g. <span class="code">-N delay,failure,success</span></p> + </el-form-item> + <el-form-item label="Qmail"> + <el-switch :value="mailer.qmail" @change="updateSetting($event, 'Pleroma.Emails.Mailer', 'qmail')"/> + </el-form-item> + </div> + <div v-if="mailer.adapter === 'Swoosh.Adapters.SMTP'"> + <el-form-item label="Relay"> + <el-input :value="mailer.relay" @input="updateSetting($event, 'Pleroma.Emails.Mailer', 'relay')"/> + <p class="expl">E. g. <span class="code">smtp.avengers.com</span></p> + </el-form-item> + <el-form-item label="Username"> + <el-input :value="mailer.username" @input="updateSetting($event, 'Pleroma.Emails.Mailer', 'username')"/> + </el-form-item> + <el-form-item label="Password"> + <el-input :value="mailer.password" @input="updateSetting($event, 'Pleroma.Emails.Mailer', 'password')"/> + </el-form-item> + <el-form-item label="SSL"> + <el-switch :value="mailer.ssl" @change="updateSetting($event, 'Pleroma.Emails.Mailer', 'ssl')"/> + </el-form-item> + <el-form-item label="TLS"> + <el-input :value="mailer.tls" @input="updateSetting($event, 'Pleroma.Emails.Mailer', 'tls')"/> + <p class="expl">E.g. <span class="code">:always</span></p> + </el-form-item> + <el-form-item label="Auth"> + <el-input :value="mailer.auth" @input="updateSetting($event, 'Pleroma.Emails.Mailer', 'auth')"/> + <p class="expl">E.g. <span class="code">:always</span></p> + </el-form-item> + <el-form-item label="Port"> + <el-input :value="mailer.port" @input="updateSetting($event, 'Pleroma.Emails.Mailer', 'port')"/> + </el-form-item> + <el-form-item label="DKIM"> + <editor v-model="editorContent" height="150" width="100%" lang="elixir" theme="chrome"/> + </el-form-item> + <el-form-item label="Retries"> + <el-input-number :value="mailer.retries" :step="1" :min="0" size="large" @change="updateSetting($event, 'Pleroma.Emails.Mailer', 'retries')"/> + </el-form-item> + <el-form-item label="No mx lookups"> + <el-switch :value="mailer.no_mx_lookups" @change="updateSetting($event, 'Pleroma.Emails.Mailer', 'no_mx_lookups')"/> + </el-form-item> + </div> + <div v-if="mailer.adapter === 'Swoosh.Adapters.Sendgrid'"> + <el-form-item label="API key"> + <el-input :value="mailer.api_key" @input="updateSetting($event, 'Pleroma.Emails.Mailer', 'api_key')"/> + </el-form-item> + </div> + <div v-if="mailer.adapter === 'Swoosh.Adapters.Mandrill'"> + <el-form-item label="API key"> + <el-input :value="mailer.api_key" @input="updateSetting($event, 'Pleroma.Emails.Mailer', 'api_key')"/> + </el-form-item> + </div> + <div v-if="mailer.adapter === 'Swoosh.Adapters.Mailgun'"> + <el-form-item label="API key"> + <el-input :value="mailer.api_key" @input="updateSetting($event, 'Pleroma.Emails.Mailer', 'api_key')"/> + </el-form-item> + <el-form-item label="Domain"> + <el-input :value="mailer.domain" @input="updateSetting($event, 'Pleroma.Emails.Mailer', 'domain')"/> + </el-form-item> + </div> + <div v-if="mailer.adapter === 'Swoosh.Adapters.Mailjet'"> + <el-form-item label="API key"> + <el-input :value="mailer.api_key" @input="updateSetting($event, 'Pleroma.Emails.Mailer', 'api_key')"/> + </el-form-item> + <el-form-item label="Secret"> + <el-input :value="mailer.secret" @input="updateSetting($event, 'Pleroma.Emails.Mailer', 'secret')"/> + </el-form-item> + </div> + <div v-if="mailer.adapter === 'Swoosh.Adapters.Postmark'"> + <el-form-item label="API key"> + <el-input :value="mailer.api_key" @input="updateSetting($event, 'Pleroma.Emails.Mailer', 'api_key')"/> + </el-form-item> + </div> + <div v-if="mailer.adapter === 'Swoosh.Adapters.SparkPost'"> + <el-form-item label="API key"> + <el-input :value="mailer.api_key" @input="updateSetting($event, 'Pleroma.Emails.Mailer', 'api_key')"/> + </el-form-item> + <el-form-item label="Endpoint"> + <el-input :value="mailer.endpoint" @input="updateSetting($event, 'Pleroma.Emails.Mailer', 'endpoint')"/> + </el-form-item> + </div> + <div v-if="mailer.adapter === 'Swoosh.Adapters.AmazonSES'"> + <el-form-item label="Region"> + <el-input :value="mailer.region" @input="updateSetting($event, 'Pleroma.Emails.Mailer', 'region')"/> + </el-form-item> + <el-form-item label="Access key"> + <el-input :value="mailer.access_key" @input="updateSetting($event, 'Pleroma.Emails.Mailer', 'access_key')"/> + </el-form-item> + <el-form-item label="Secret"> + <el-input :value="mailer.secret" @input="updateSetting($event, 'Pleroma.Emails.Mailer', 'secret')"/> + </el-form-item> + </div> + <div v-if="mailer.adapter === 'Swoosh.Adapters.Dyn'"> + <el-form-item label="API key"> + <el-input :value="mailer.api_key" @input="updateSetting($event, 'Pleroma.Emails.Mailer', 'api_key')"/> + </el-form-item> + </div> + <div v-if="mailer.adapter === 'Swoosh.Adapters.SocketLabs'"> + <el-form-item label="Server ID"> + <el-input :value="mailer.server_id" @input="updateSetting($event, 'Pleroma.Emails.Mailer', 'server_id')"/> + </el-form-item> + <el-form-item label="API key"> + <el-input :value="mailer.api_key" @input="updateSetting($event, 'Pleroma.Emails.Mailer', 'api_key')"/> + </el-form-item> + </div> + <div v-if="mailer.adapter === 'Swoosh.Adapters.Gmail'"> + <el-form-item label="Access token"> + <el-input :value="mailer.access_token" @input="updateSetting($event, 'Pleroma.Emails.Mailer', 'access_token')"/> + </el-form-item> + </div> + </el-form> + <el-form ref="emailNotifications" :model="emailNotifications" :label-width="labelWidth"> + <el-form-item label="Email notifications"/> + <el-form-item label="Digest:"/> + <el-form-item label="Active"> + <el-switch :value="emailNotifications.digest.active" @change="processNestedData($event, 'email_notifications', 'digest', 'active')"/> + <p class="expl">Globally enable or disable digest emails.</p> </el-form-item> - <el-form-item label="No mx lookups"> - <el-switch :value="mailer.no_mx_lookups" @change="updateSetting($event, 'Pleroma.Emails.Mailer', 'no_mx_lookups')"/> + <el-form-item label="Schedule"> + <el-input :value="emailNotifications.digest.schedule" @input="processNestedData($event, 'email_notifications', 'digest', 'schedule')"/> + <p class="expl">When to send digest email, in <a + href="https://en.wikipedia.org/wiki/Cron" + rel="nofollow noreferrer noopener" + target="_blank"> + crontab format + </a>. + "0 0 * * 0" is the default, meaning "once a week at midnight on Sunday morning"</p> </el-form-item> - </div> - <div v-if="mailer.adapter === 'Swoosh.Adapters.Sendgrid'"> - <el-form-item label="API key"> - <el-input :value="mailer.api_key" @input="updateSetting($event, 'Pleroma.Emails.Mailer', 'api_key')"/> + <el-form-item label="Interval"> + <el-input-number :value="emailNotifications.digest.interval" :step="1" :min="0" size="large" @change="processNestedData($event, 'email_notifications', 'digest', 'interval')"/> + <p class="expl">Minimum interval between digest emails to one user.</p> </el-form-item> - </div> - <div v-if="mailer.adapter === 'Swoosh.Adapters.Mandrill'"> - <el-form-item label="API key"> - <el-input :value="mailer.api_key" @input="updateSetting($event, 'Pleroma.Emails.Mailer', 'api_key')"/> + <el-form-item label="Inactivity threshold"> + <el-input-number :value="emailNotifications.digest.inactivity_threshold" :step="1" :min="0" size="large" @change="processNestedData($event, 'email_notifications', 'digest', 'inactivity_threshold')"/> + <p class="expl">Minimum user inactivity threshold.</p> </el-form-item> - </div> - <div v-if="mailer.adapter === 'Swoosh.Adapters.Mailgun'"> - <el-form-item label="API key"> - <el-input :value="mailer.api_key" @input="updateSetting($event, 'Pleroma.Emails.Mailer', 'api_key')"/> - </el-form-item> - <el-form-item label="Domain"> - <el-input :value="mailer.domain" @input="updateSetting($event, 'Pleroma.Emails.Mailer', 'domain')"/> - </el-form-item> - </div> - <div v-if="mailer.adapter === 'Swoosh.Adapters.Mailjet'"> - <el-form-item label="API key"> - <el-input :value="mailer.api_key" @input="updateSetting($event, 'Pleroma.Emails.Mailer', 'api_key')"/> - </el-form-item> - <el-form-item label="Secret"> - <el-input :value="mailer.secret" @input="updateSetting($event, 'Pleroma.Emails.Mailer', 'secret')"/> - </el-form-item> - </div> - <div v-if="mailer.adapter === 'Swoosh.Adapters.Postmark'"> - <el-form-item label="API key"> - <el-input :value="mailer.api_key" @input="updateSetting($event, 'Pleroma.Emails.Mailer', 'api_key')"/> - </el-form-item> - </div> - <div v-if="mailer.adapter === 'Swoosh.Adapters.SparkPost'"> - <el-form-item label="API key"> - <el-input :value="mailer.api_key" @input="updateSetting($event, 'Pleroma.Emails.Mailer', 'api_key')"/> - </el-form-item> - <el-form-item label="Endpoint"> - <el-input :value="mailer.endpoint" @input="updateSetting($event, 'Pleroma.Emails.Mailer', 'endpoint')"/> + </el-form> + <div class="line"/> + <el-form ref="userEmail" :model="userEmail" :label-width="labelWidth"> + <el-form-item label="Digest template styles:"/> + <el-form-item label="Logo"> + <el-input :value="userEmail.logo" @input="updateSetting($event, 'Pleroma.Emails.UserEmail', 'logo')"/> + <div class="upload-container"> + <p class="text">or</p> + <el-upload + :http-request="sendEmailLogo" + :multiple="false" + :show-file-list="false" + action="/api/v1/media"> + <el-button size="small" type="primary">Click to upload</el-button> + </el-upload> + </div> + <p class="expl">A path to a custom logo.</p> </el-form-item> - </div> - <div v-if="mailer.adapter === 'Swoosh.Adapters.AmazonSES'"> - <el-form-item label="Region"> - <el-input :value="mailer.region" @input="updateSetting($event, 'Pleroma.Emails.Mailer', 'region')"/> + <el-form-item label="Styling:"/> + <el-form-item label="Link color"> + <el-input :value="userEmail.styling.link_color" @input="processNestedData($event, 'Pleroma.Emails.UserEmail', 'styling', 'link_color')"/> </el-form-item> - <el-form-item label="Access key"> - <el-input :value="mailer.access_key" @input="updateSetting($event, 'Pleroma.Emails.Mailer', 'access_key')"/> + <el-form-item label="Background color"> + <el-input :value="userEmail.styling.background_color" @input="processNestedData($event, 'Pleroma.Emails.UserEmail', 'styling', 'background_color')"/> </el-form-item> - <el-form-item label="Secret"> - <el-input :value="mailer.secret" @input="updateSetting($event, 'Pleroma.Emails.Mailer', 'secret')"/> + <el-form-item label="Content background color"> + <el-input :value="userEmail.styling.content_background_color" @input="processNestedData($event, 'Pleroma.Emails.UserEmail', 'styling', 'content_background_color')"/> </el-form-item> - </div> - <div v-if="mailer.adapter === 'Swoosh.Adapters.Dyn'"> - <el-form-item label="API key"> - <el-input :value="mailer.api_key" @input="updateSetting($event, 'Pleroma.Emails.Mailer', 'api_key')"/> + <el-form-item label="Header color"> + <el-input :value="userEmail.styling.header_color" @input="processNestedData($event, 'Pleroma.Emails.UserEmail', 'styling', 'header_color')"/> </el-form-item> - </div> - <div v-if="mailer.adapter === 'Swoosh.Adapters.SocketLabs'"> - <el-form-item label="Server ID"> - <el-input :value="mailer.server_id" @input="updateSetting($event, 'Pleroma.Emails.Mailer', 'server_id')"/> + <el-form-item label="Text color"> + <el-input :value="userEmail.styling.text_color" @input="processNestedData($event, 'Pleroma.Emails.UserEmail', 'styling', 'text_color')"/> </el-form-item> - <el-form-item label="API key"> - <el-input :value="mailer.api_key" @input="updateSetting($event, 'Pleroma.Emails.Mailer', 'api_key')"/> + <el-form-item label="Text muted color"> + <el-input :value="userEmail.styling.text_muted_color" @input="processNestedData($event, 'Pleroma.Emails.UserEmail', 'styling', 'text_muted_color')"/> </el-form-item> - </div> - <div v-if="mailer.adapter === 'Swoosh.Adapters.Gmail'"> - <el-form-item label="Access token"> - <el-input :value="mailer.access_token" @input="updateSetting($event, 'Pleroma.Emails.Mailer', 'access_token')"/> + <el-form-item> + <el-button type="primary" @click="onSubmit">Submit</el-button> </el-form-item> - </div> - <el-form-item> - <el-button type="primary" @click="onSubmit">Submit</el-button> - </el-form-item> - </el-form> + </el-form> + </div> </template> <script> @@ -151,7 +216,9 @@ export default { }, computed: { ...mapGetters([ - 'mailer' + 'emailNotifications', + 'mailer', + 'userEmail' ]), editorContent: { get: function() { @@ -172,6 +239,13 @@ export default { } }, methods: { + processNestedData(value, tab, inputName, childName) { + const updatedValue = { ...this.$store.state.settings.settings[tab][inputName], ...{ [childName]: value }} + this.updateSetting(updatedValue, tab, inputName) + }, + sendEmailLogo({ file }) { + this.$store.dispatch('UploadMedia', { file, tab: 'Pleroma.Emails.UserEmail', inputName: 'logo' }) + }, updateSetting(value, tab, input) { this.$store.dispatch('UpdateSettings', { tab, data: { [input]: value }}) }, diff --git a/src/views/settings/components/MediaProxy.vue b/src/views/settings/components/MediaProxy.vue index fd80ff1bcd4dbd247d2b9e442a6f95b7f90ba6ba..e50ba8de5265afa6b4351091de1296efdc6bde76 100644 --- a/src/views/settings/components/MediaProxy.vue +++ b/src/views/settings/components/MediaProxy.vue @@ -23,7 +23,7 @@ <p class="expl">The total time the connection is allowed to read from the remote upstream</p> </el-form-item> <el-form-item label="Inline content types"> - <el-select :value="inlineContentTypes" @change="processNestedData($event, 'media_proxy', 'proxy_opts', 'inline_content_types')"> + <el-select :value="inlineContentTypes" clearable @change="processNestedData($event, 'media_proxy', 'proxy_opts', 'inline_content_types')"> <el-option :value="true" label="True"/> <el-option :value="false" label="False"/> <el-option value="whitelistedTypeArray" label="List of whitelisted content types"/> @@ -37,7 +37,7 @@ </p> </el-form-item> <el-form-item v-if="inlineContentTypes === 'whitelistedTypeArray'" label="Whitelisted content types"> - <el-select :value="whitelistedContentTypes" multiple @change="processNestedData($event, 'media_proxy', 'proxy_opts', 'inline_content_types')"> + <el-select :value="whitelistedContentTypes" multiple filterable allow-create @change="processNestedData($event, 'media_proxy', 'proxy_opts', 'inline_content_types')"> <el-option v-for="item in whitelistedContentTypesOptions" :label="item.label" @@ -54,7 +54,7 @@ <el-switch :value="http.follow_redirect" @change="processHttpSettings($event, 'media_proxy', 'proxy_opts', 'http', 'follow_redirect')"/> </el-form-item> <el-form-item label="Pool"> - <el-select :value="http.pool" @change="processHttpSettings($event, 'media_proxy', 'proxy_opts', 'http', 'pool')"> + <el-select :value="http.pool" clearable @change="processHttpSettings($event, 'media_proxy', 'proxy_opts', 'http', 'pool')"> <el-option v-for="item in hackneyPoolsOptions" :label="item.label" diff --git a/src/views/settings/components/Metadata.vue b/src/views/settings/components/Metadata.vue index 8850cf363890770d7ea49b4596a52dec0bf2b70d..01af8c9686924cf9d2df92e30c694054db341762 100644 --- a/src/views/settings/components/Metadata.vue +++ b/src/views/settings/components/Metadata.vue @@ -2,7 +2,7 @@ <div> <el-form ref="metadata" :model="metadata" :label-width="labelWidth"> <el-form-item label="Providers"> - <el-select :value="metadata.providers || []" multiple @change="updateSetting($event, 'Pleroma.Web.Metadata', 'providers')"> + <el-select :value="metadata.providers || []" multiple filterable allow-create @change="updateSetting($event, 'Pleroma.Web.Metadata', 'providers')"> <el-option value="Pleroma.Web.Metadata.Providers.OpenGraph"/> <el-option value="Pleroma.Web.Metadata.Providers.TwitterCard"/> <el-option value="Pleroma.Web.Metadata.Providers.RelMe"/> diff --git a/src/views/settings/components/RateLimiters.vue b/src/views/settings/components/RateLimiters.vue index 716cd8e8860fd9ef11aff598a168ad6b8c3108bb..b4afe0e07f7e4ccde228ede06cc051619b594cf0 100644 --- a/src/views/settings/components/RateLimiters.vue +++ b/src/views/settings/components/RateLimiters.vue @@ -192,6 +192,30 @@ </div> </div> </el-form-item> + <el-form-item label="Activity pub routes:"> + <div v-if="!activityPubRoutesAuthUsers"> + <el-input :value="activityPubRoutesAllUsers[0]" placeholder="scale" class="scale-input" @input="parseRateLimiter($event, 'ap_routes', 'scale', 'oneLimit', activityPubRoutesAllUsers)"/> : + <el-input :value="activityPubRoutesAllUsers[1]" placeholder="limit" class="limit-input" @input="parseRateLimiter($event, 'ap_routes', 'limit', 'oneLimit', activityPubRoutesAllUsers)"/> + <div class="limit-button-container"> + <el-button icon="el-icon-plus" circle @click="toggleLimits([{ 'tuple': [null, null] }, { 'tuple': [null, null] }], 'ap_routes')"/> + <p class="expl limit-expl">Set different limits for unauthenticated and authenticated users</p> + </div> + </div> + <div v-if="activityPubRoutesAuthUsers"> + <el-form-item label="Authenticated users:"> + <el-input :value="activityPubRoutesAuthUsers[0]" placeholder="scale" class="scale-input" @input="parseRateLimiter($event, 'ap_routes', 'scale', 'authUserslimit', [activityPubRoutesUnauthUsers, activityPubRoutesAuthUsers])"/> : + <el-input :value="activityPubRoutesAuthUsers[1]" placeholder="limit" class="limit-input" @input="parseRateLimiter($event, 'ap_routes', 'limit', 'authUserslimit', [activityPubRoutesUnauthUsers, activityPubRoutesAuthUsers])"/> + </el-form-item> + <el-form-item label="Unauthenticated users:"> + <el-input :value="activityPubRoutesUnauthUsers[0]" placeholder="scale" class="scale-input" @input="parseRateLimiter($event, 'ap_routes', 'scale', 'unauthUsersLimit', [activityPubRoutesUnauthUsers, activityPubRoutesAuthUsers])"/> : + <el-input :value="activityPubRoutesUnauthUsers[1]" placeholder="limit" class="limit-input" @input="parseRateLimiter($event, 'ap_routes', 'limit', 'unauthUsersLimit', [activityPubRoutesUnauthUsers, activityPubRoutesAuthUsers])"/> + </el-form-item> + <div class="limit-button-container"> + <el-button icon="el-icon-minus" circle @click="toggleLimits({ 'tuple': [null, null] }, 'ap_routes')"/> + <p class="expl limit-expl">Set limit for all users</p> + </div> + </div> + </el-form-item> <el-form-item> <el-button type="primary" @click="onSubmit">Submit</el-button> </el-form-item> @@ -221,6 +245,19 @@ export default { ? this.rateLimiters.account_confirmation_resend[0].tuple : false }, + activityPubRoutesAllUsers() { + return this.rateLimiters.ap_routes ? this.rateLimiters.ap_routes.tuple : [null, null] + }, + activityPubRoutesAuthUsers() { + return Array.isArray(this.rateLimiters.ap_routes) + ? this.rateLimiters.ap_routes[1].tuple + : false + }, + activityPubRoutesUnauthUsers() { + return Array.isArray(this.rateLimiters.ap_routes) + ? this.rateLimiters.ap_routes[0].tuple + : false + }, appAccountCreationAllUsers() { return this.rateLimiters.app_account_creation ? this.rateLimiters.app_account_creation.tuple : [null, null] }, diff --git a/src/views/settings/components/Upload.vue b/src/views/settings/components/Upload.vue index 951f75c4f2c5777ceba40a23428ccb6753e99fcd..1adbc923079543f874619daaed2d30b655a10641 100644 --- a/src/views/settings/components/Upload.vue +++ b/src/views/settings/components/Upload.vue @@ -36,7 +36,7 @@ <p class="expl">The total time the connection is allowed to read from the remote upstream</p> </el-form-item> <el-form-item label="Inline content types"> - <el-select :value="inlineContentTypes" @change="processNestedData($event, 'Pleroma.Upload', 'proxy_opts', 'inline_content_types')"> + <el-select :value="inlineContentTypes" clearable @change="processNestedData($event, 'Pleroma.Upload', 'proxy_opts', 'inline_content_types')"> <el-option :value="true" label="True"/> <el-option :value="false" label="False"/> <el-option value="whitelistedTypeArray" label="List of whitelisted content types"/> @@ -50,7 +50,7 @@ </p> </el-form-item> <el-form-item v-if="inlineContentTypes === 'whitelistedTypeArray'" label="Whitelisted content types"> - <el-select :value="whitelistedContentTypes" multiple @change="processNestedData($event, 'Pleroma.Upload', 'proxy_opts', 'inline_content_types')"> + <el-select :value="whitelistedContentTypes" multiple filterable allow-create @change="processNestedData($event, 'Pleroma.Upload', 'proxy_opts', 'inline_content_types')"> <el-option v-for="item in whitelistedContentTypesOptions" :label="item.label" @@ -67,7 +67,7 @@ <el-switch :value="http.follow_redirect" @change="processHttpSettings($event, 'Pleroma.Upload', 'proxy_opts', 'http', 'follow_redirect')"/> </el-form-item> <el-form-item label="Pool"> - <el-select :value="http.pool" @change="processHttpSettings($event, 'Pleroma.Upload', 'proxy_opts', 'http', 'pool')"> + <el-select :value="http.pool" clearable @change="processHttpSettings($event, 'Pleroma.Upload', 'proxy_opts', 'http', 'pool')"> <el-option v-for="item in hackneyPoolsOptions" :label="item.label" @@ -111,6 +111,10 @@ <el-input :value="uploadS3.bucket" @input="updateSetting($event, 'Pleroma.Uploaders.S3', 'bucket')"/> <p class="expl">S3 bucket name</p> </el-form-item> + <el-form-item label="Bucket namespace"> + <el-input :value="uploadS3.bucket_namespace" @input="updateSetting($event, 'Pleroma.Uploaders.S3', 'bucket_namespace')"/> + <p class="expl">S3 bucket namespace</p> + </el-form-item> <el-form-item label="Public endpoint"> <el-input :value="uploadS3.public_endpoint" @input="updateSetting($event, 'Pleroma.Uploaders.S3', 'public_endpoint')"/> <p class="expl">S3 endpoint that the user finally accesses</p> diff --git a/src/views/settings/components/options.js b/src/views/settings/components/options.js index 0d3484028e99996715431cbc2fd43dca7bfdfea3..67314fb59d6ecfffa4b63c884b23a2eee96b0219 100644 --- a/src/views/settings/components/options.js +++ b/src/views/settings/components/options.js @@ -13,7 +13,8 @@ export const options = { { label: 'EnsureRePrepended', value: 'Pleroma.Web.ActivityPub.MRF.EnsureRePrepended', expl: 'EnsureRePrepended: Rewrites posts to ensure that replies to posts with subjects do not have an identical subject and instead begin with re:' }, { label: 'AntiLinkSpamPolicy', value: 'Pleroma.Web.ActivityPub.MRF.AntiLinkSpamPolicy', expl: 'Rejects posts from likely spambots by rejecting posts from new users that contain links' }, { label: 'MediaProxyWarmingPolicy', value: 'Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicy', expl: 'Crawls attachments using their MediaProxy URLs so that the MediaProxy cache is primed' }, - { label: 'MentionPolicy', value: 'Pleroma.Web.ActivityPub.MRF.MentionPolicy', expl: 'Drops posts mentioning configurable users. (see :mrf_mention section)' } + { label: 'MentionPolicy', value: 'Pleroma.Web.ActivityPub.MRF.MentionPolicy', expl: 'Drops posts mentioning configurable users. (see :mrf_mention section)' }, + { label: 'VocabularyPolicy', value: 'Pleroma.Web.ActivityPub.MRF.VocabularyPolicy', expl: 'Restricts activities to a configured set of vocabulary' } ], quarantinedInstancesOptions: [], autofollowedNicknamesOptions: [],