Use Setting component to render ActivityPub, Authentication and Captcha
This commit is contained in:
parent
b591f58fb2
commit
ba1d3f1f76
4 changed files with 63 additions and 289 deletions
|
@ -1,33 +1,11 @@
|
|||
<template>
|
||||
<div>
|
||||
<el-form ref="activityPub" :model="activityPub" :label-width="labelWidth">
|
||||
<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>
|
||||
</el-form-item>
|
||||
<el-form-item label="Outgoing blocks">
|
||||
<el-switch :value="activityPub.outgoing_blocks" @change="updateSetting($event, 'activitypub', 'outgoing_blocks')"/>
|
||||
<p class="expl">Whether to federate blocks to other instances</p>
|
||||
</el-form-item>
|
||||
<el-form-item label="Follow handshake timeout">
|
||||
<el-input-number
|
||||
:value="activityPub.follow_handshake_timeout"
|
||||
:step="100"
|
||||
:min="0"
|
||||
size="large"
|
||||
class="top-margin"
|
||||
@change="updateSetting($event, 'activitypub', 'follow_handshake_timeout')"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="Sign object fetches">
|
||||
<el-switch :value="activityPub.sign_object_fetches" @change="updateSetting($event, 'activitypub', 'sign_object_fetches')"/>
|
||||
<p class="expl">Sign object fetches with HTTP signatures</p>
|
||||
</el-form-item>
|
||||
<el-form ref="activitypubData" :model="activitypubData" :label-width="labelWidth">
|
||||
<setting :settings-group="activitypub" :data="activitypubData"/>
|
||||
</el-form>
|
||||
<el-form ref="user" :model="user" :label-width="labelWidth">
|
||||
<el-form-item label="Deny follow blocked">
|
||||
<el-switch :value="user.deny_follow_blocked" @change="updateSetting($event, 'user', 'deny_follow_blocked')"/>
|
||||
<p class="expl">Whether to disallow following an account that has blocked the user in question</p>
|
||||
</el-form-item>
|
||||
<div class="line"/>
|
||||
<el-form ref="userData" :model="userData" :label-width="labelWidth">
|
||||
<setting :settings-group="user" :data="userData"/>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="onSubmit">Submit</el-button>
|
||||
</el-form-item>
|
||||
|
@ -38,25 +16,30 @@
|
|||
<script>
|
||||
import { mapGetters } from 'vuex'
|
||||
import i18n from '@/lang'
|
||||
import Setting from './Setting'
|
||||
|
||||
export default {
|
||||
name: 'ActivityPub',
|
||||
components: { Setting },
|
||||
computed: {
|
||||
...mapGetters([
|
||||
'activityPub',
|
||||
'user'
|
||||
'activitypubData',
|
||||
'userData'
|
||||
]),
|
||||
activitypub() {
|
||||
return this.$store.state.settings.description.find(setting => setting.key === ':activitypub')
|
||||
},
|
||||
isMobile() {
|
||||
return this.$store.state.app.device === 'mobile'
|
||||
},
|
||||
labelWidth() {
|
||||
return this.isMobile ? '100px' : '210px'
|
||||
},
|
||||
user() {
|
||||
return this.$store.state.settings.description.find(setting => setting.key === ':user')
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
updateSetting(value, tab, input) {
|
||||
this.$store.dispatch('UpdateSettings', { tab, data: { [input]: value }})
|
||||
},
|
||||
async onSubmit() {
|
||||
try {
|
||||
await this.$store.dispatch('SubmitChanges')
|
||||
|
|
|
@ -1,228 +1,19 @@
|
|||
<template>
|
||||
<div>
|
||||
<el-form ref="pleromaAuthenticator" :model="pleromaAuthenticator" :label-width="labelWidth">
|
||||
<el-form-item label="Authentication type">
|
||||
<el-select :value="pleromaAuthenticator.value" clearable @change="updateSetting($event, 'Pleroma.Web.Auth.Authenticator', 'value')">
|
||||
<el-option label="None" value=""/>
|
||||
<el-option label="Pleroma.Web.Auth.PleromaAuthenticator // Default database authenticator" value="Pleroma.Web.Auth.PleromaAuthenticator"/>
|
||||
<el-option label="Pleroma.Web.Auth.LDAPAuthenticator // LDAP authenticator" value="Pleroma.Web.Auth.LDAPAuthenticator"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form ref="pleromaAuthenticatorData" :model="pleromaAuthenticatorData" :label-width="labelWidth">
|
||||
<setting :settings-group="pleromaAuthenticator" :data="pleromaAuthenticatorData"/>
|
||||
</el-form>
|
||||
<div class="line"/>
|
||||
<el-form ref="auth" :model="auth" :label-width="labelWidth">
|
||||
<el-form-item label="Authentication settings:"/>
|
||||
<el-form-item label="Auth template">
|
||||
<el-input :value="auth.auth_template" @input="updateSetting($event, 'auth', 'auth_template')"/>
|
||||
<p class="expl">Authentication form template. By default it's
|
||||
<span class="code">show.html</span> which corresponds to
|
||||
<span class="code">lib/pleroma/web/templates/o_auth/o_auth/show.html.eex.</span>
|
||||
</p>
|
||||
</el-form-item>
|
||||
<el-form-item label="OAuth consumer template">
|
||||
<el-input :value="auth.oauth_consumer_template" @input="updateSetting($event, 'auth', 'oauth_consumer_template')"/>
|
||||
<p class="expl">OAuth consumer mode authentication form template. By default it's
|
||||
<span class="code">consumer.html</span> which corresponds to
|
||||
<span class="code">lib/pleroma/web/templates/o_auth/o_auth/consumer.html.eex.</span>
|
||||
</p>
|
||||
</el-form-item>
|
||||
<el-form-item label="OAuth consumer strategies">
|
||||
<el-select :value="auth.oauth_consumer_strategies || []" multiple filterable allow-create @change="updateSetting($event, 'auth', 'oauth_consumer_strategies')"/>
|
||||
<p class="expl">The list of enabled OAuth consumer strategies; by default it's set by
|
||||
<span class="code">OAUTH_CONSUMER_STRATEGIES</span>
|
||||
environment variable. You can enter values in the following format: <span class="code">'a:foo b:baz'</span>
|
||||
</p>
|
||||
</el-form-item>
|
||||
<el-form ref="authData" :model="authData" :label-width="labelWidth">
|
||||
<setting :settings-group="auth" :data="authData"/>
|
||||
</el-form>
|
||||
<div class="line"/>
|
||||
<el-form ref="ldap" :model="ldap" :label-width="labelWidth">
|
||||
<el-form-item class="options-paragraph-container">
|
||||
<p class="options-paragraph">Use LDAP for user authentication. When a user logs in to the Pleroma
|
||||
instance, the name and password will be verified by trying to authenticate
|
||||
(bind) to an LDAP server. If a user exists in the LDAP directory but there
|
||||
is no account with the same name yet on the Pleroma instance then a new
|
||||
Pleroma account will be created with the same name as the LDAP user name.</p>
|
||||
</el-form-item>
|
||||
<el-form-item label="LDAP Authenticator:"/>
|
||||
<el-form-item label="Enabled">
|
||||
<el-switch :value="ldap.enabled" @change="updateSetting($event, 'ldap', 'enabled')"/>
|
||||
<p class="expl">Enables LDAP authentication</p>
|
||||
</el-form-item>
|
||||
<el-form-item label="Host">
|
||||
<el-input :value="ldap.host" @input="updateSetting($event, 'ldap', 'host')"/>
|
||||
<p class="expl">LDAP server hostname</p>
|
||||
</el-form-item>
|
||||
<el-form-item label="Port">
|
||||
<el-input :value="ldap.port" @input="updateSetting($event, 'ldap', 'port')"/>
|
||||
<p class="expl">LDAP port, e.g. 389 or 636</p>
|
||||
</el-form-item>
|
||||
<el-form-item label="SSL">
|
||||
<el-switch :value="ldap.ssl" @change="updateSetting($event, 'ldap', 'ssl')"/>
|
||||
<p class="expl">True to use SSL, usually implies the port 636</p>
|
||||
</el-form-item>
|
||||
<el-form-item label="TLS">
|
||||
<el-switch :value="ldap.tls" @change="updateSetting($event, 'ldap', 'tls')"/>
|
||||
<p class="expl">True to start TLS, usually implies the port 389</p>
|
||||
</el-form-item>
|
||||
<el-form-item label="Base">
|
||||
<el-input :value="ldap.base" @input="updateSetting($event, 'ldap', 'base')"/>
|
||||
<p class="expl">LDAP base, e.g. <span class="code">'dc=example,dc=com'</span></p>
|
||||
</el-form-item>
|
||||
<el-form-item label="UID">
|
||||
<el-input :value="ldap.uid" @input="updateSetting($event, 'ldap', 'uid')"/>
|
||||
<p class="expl">LDAP attribute name to authenticate the user, e.g. when
|
||||
<span class="code">'cn'</span>, the filter will be <span class="code">'cn=username,base'</span>
|
||||
</p>
|
||||
</el-form-item>
|
||||
<el-form ref="ldapData" :model="ldapData" :label-width="labelWidth">
|
||||
<setting :settings-group="ldap" :data="ldapData"/>
|
||||
</el-form>
|
||||
<div class="line"/>
|
||||
<el-form ref="ueberauth" :model="ueberauth" :label-width="labelWidth">
|
||||
<el-form-item label="OAuth consumer mode" class="options-paragraph-container">
|
||||
<p class="options-paragraph">
|
||||
OAuth consumer mode allows sign in / sign up via external OAuth providers
|
||||
(e.g. Twitter, Facebook, Google, Microsoft, etc.). Implementation is based on Ueberauth; see the list of
|
||||
<a
|
||||
href="https://github.com/ueberauth/ueberauth/wiki/List-of-Strategies"
|
||||
rel="nofollow noreferrer noopener"
|
||||
target="_blank">
|
||||
available strategies.
|
||||
</a>
|
||||
</p>
|
||||
<p class="options-paragraph">
|
||||
Note: each strategy is shipped as a separate dependency; in order to get the strategies, run
|
||||
<span class="code">OAUTH_CONSUMER_STRATEGIES="..." mix deps.get</span>,
|
||||
e.g. <span class="code">OAUTH_CONSUMER_STRATEGIES="twitter facebook google microsoft" mix deps.get</span>.
|
||||
The server should also be started with <span class="code">OAUTH_CONSUMER_STRATEGIES="..." mix phx.server</span>
|
||||
in case you enable any strategies.
|
||||
</p>
|
||||
<p class="options-paragraph">
|
||||
Note: each strategy requires separate setup (on external provider side and Pleroma side).
|
||||
Below are the guidelines on setting up most popular strategies.
|
||||
</p>
|
||||
<p class="options-paragraph">
|
||||
Note: make sure that <span class="code">'SameSite=Lax'</span> is set in
|
||||
<span class="code">extra_cookie_attrs</span> when you have this feature enabled.
|
||||
OAuth consumer mode will not work with <span class="code">'SameSite=Strict'</span>
|
||||
</p>
|
||||
<p class="options-paragraph">For Twitter,
|
||||
<a
|
||||
href="https://developer.twitter.com/en/apps"
|
||||
rel="nofollow noreferrer noopener"
|
||||
target="_blank">
|
||||
register an app,
|
||||
</a>
|
||||
configure callback URL to <span class="code">https://<your_host>/oauth/twitter/callback</span>
|
||||
</p>
|
||||
<p class="options-paragraph">For Facebook,
|
||||
<a
|
||||
href="https://developers.facebook.com/apps"
|
||||
rel="nofollow noreferrer noopener"
|
||||
target="_blank">
|
||||
register an app,
|
||||
</a>
|
||||
configure callback URL to <span class="code">https://<your_host>/oauth/facebook/callback</span>,
|
||||
enable Facebook Login service at
|
||||
<span class="code">https://developers.facebook.com/apps/<app_id>/fb-login/settings/</span>
|
||||
</p>
|
||||
<p class="options-paragraph">For Google,
|
||||
<a
|
||||
href="https://console.developers.google.com/"
|
||||
rel="nofollow noreferrer noopener"
|
||||
target="_blank">
|
||||
register an app,
|
||||
</a>
|
||||
configure callback URL to <span class="code">https://<your_host>/oauth/google/callback</span>
|
||||
</p>
|
||||
<p class="options-paragraph">For Microsoft,
|
||||
<a
|
||||
href="https://portal.azure.com"
|
||||
rel="nofollow noreferrer noopener"
|
||||
target="_blank">
|
||||
register an app,
|
||||
</a>
|
||||
configure callback URL to <span class="code">https://<your_host>/oauth/microsoft/callback</span>
|
||||
</p>
|
||||
<p class="options-paragraph">
|
||||
Once the app is configured on external OAuth provider side, add app's credentials and strategy-specific settings
|
||||
per strategy's documentation (e.g.
|
||||
<a
|
||||
href="https://github.com/ueberauth/ueberauth_twitter"
|
||||
rel="nofollow noreferrer noopener"
|
||||
target="_blank">
|
||||
ueberauth_twitter
|
||||
</a>).
|
||||
</p>
|
||||
</el-form-item>
|
||||
<el-form-item label="Ueberauth:"/>
|
||||
<el-form-item label="Base path">
|
||||
<el-input :value="ueberauth.base_path" @input="updateSetting($event, 'ueberauth', 'base_path')"/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div class="line"/>
|
||||
<el-form ref="facebook" :model="facebook" :label-width="labelWidth">
|
||||
<el-form-item label="Facebook:"/>
|
||||
<el-form-item label="Client ID">
|
||||
<el-input :value="facebook.client_id" @input="updateSetting($event, 'Ueberauth.Strategy.Facebook.OAuth', 'client_id')"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="Client secret">
|
||||
<el-input :value="facebook.client_secret" @input="updateSetting($event, 'Ueberauth.Strategy.Facebook.OAuth', 'client_secret')"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="Redirect URI">
|
||||
<el-input :value="facebook.redirect_uri" @input="updateSetting($event, 'Ueberauth.Strategy.Facebook.OAuth', 'redirect_uri')"/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div class="line"/>
|
||||
<el-form ref="twitter" :model="twitter" :label-width="labelWidth">
|
||||
<el-form-item label="Twitter:"/>
|
||||
<el-form-item label="Consumer key">
|
||||
<el-input :value="twitter.consumer_key" @input="updateSetting($event, 'Ueberauth.Strategy.Twitter.OAuth', 'consumer_key')"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="Consumer secret">
|
||||
<el-input :value="twitter.consumer_secret" @input="updateSetting($event, 'Ueberauth.Strategy.Twitter.OAuth', 'consumer_secret')"/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div class="line"/>
|
||||
<el-form ref="google" :model="google" :label-width="labelWidth">
|
||||
<el-form-item label="Google:"/>
|
||||
<el-form-item label="Client ID">
|
||||
<el-input :value="google.client_id" @input="updateSetting($event, 'Ueberauth.Strategy.Google.OAuth', 'client_id')"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="Client secret">
|
||||
<el-input :value="google.client_secret" @input="updateSetting($event, 'Ueberauth.Strategy.Google.OAuth', 'client_secret')"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="Redirect URI">
|
||||
<el-input :value="google.redirect_uri" @input="updateSetting($event, 'Ueberauth.Strategy.Google.OAuth', 'redirect_uri')"/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div class="line"/>
|
||||
<el-form ref="microsoft" :model="microsoft" :label-width="labelWidth">
|
||||
<el-form-item label="Microsoft:"/>
|
||||
<el-form-item label="Client ID">
|
||||
<el-input :value="microsoft.client_id" @input="updateSetting($event, 'Ueberauth.Strategy.Microsoft.OAuth', 'client_id')"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="Client secret">
|
||||
<el-input :value="microsoft.client_secret" @input="updateSetting($event, 'Ueberauth.Strategy.Microsoft.OAuth', 'client_secret')"/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div class="line"/>
|
||||
<el-form ref="oauth2" :model="oauth2" :label-width="labelWidth">
|
||||
<el-form-item label="OAuth 2.0 Provider:"/>
|
||||
<el-form-item label="Token expires in (s)">
|
||||
<el-input-number :value="oauth2.token_expires_in" :step="10" :min="0" size="large" @change="updateSetting($event, 'oauth2', 'token_expires_in')"/>
|
||||
<p class="expl">The lifetime in seconds of the access token</p>
|
||||
</el-form-item>
|
||||
<el-form-item label="Issue new refresh token">
|
||||
<el-switch :value="oauth2.issue_new_refresh_token" @change="updateSetting($event, 'oauth2', 'issue_new_refresh_token')"/>
|
||||
<p class="expl">Keeps old refresh token or generate new refresh token when to obtain an access token</p>
|
||||
</el-form-item>
|
||||
<el-form-item label="Clean expired token">
|
||||
<el-switch :value="oauth2.clean_expired_tokens" @change="updateSetting($event, 'oauth2', 'clean_expired_tokens')"/>
|
||||
<p class="expl">Enable a background job to clean expired oauth tokens. Defaults to false.</p>
|
||||
</el-form-item>
|
||||
<el-form-item label="Clean expired token interval">
|
||||
<el-input-number :value="oauth2.clean_expired_tokens_interval / 3600000" :step="1" :min="0" size="large" @change="updateSetting($event * 3600000, 'oauth2', 'clean_expired_tokens_interval')"/>
|
||||
<p class="expl">Interval to run the job to clean expired tokens. Defaults to 24 hours.</p>
|
||||
</el-form-item>
|
||||
<el-form ref="oauth2" :model="oauth2Data" :label-width="labelWidth">
|
||||
<setting :settings-group="oauth2" :data="oauth2Data"/>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="onSubmit">Submit</el-button>
|
||||
</el-form-item>
|
||||
|
@ -233,32 +24,42 @@
|
|||
<script>
|
||||
import { mapGetters } from 'vuex'
|
||||
import i18n from '@/lang'
|
||||
import Setting from './Setting'
|
||||
|
||||
export default {
|
||||
name: 'Authentication',
|
||||
components: { Setting },
|
||||
computed: {
|
||||
...mapGetters([
|
||||
'pleromaAuthenticator',
|
||||
'ldap',
|
||||
'auth',
|
||||
'ueberauth',
|
||||
'oauth2',
|
||||
'facebook',
|
||||
'google',
|
||||
'twitter',
|
||||
'microsoft'
|
||||
'pleromaAuthenticatorData',
|
||||
'ldapData',
|
||||
'authData',
|
||||
'oauth2Data'
|
||||
// 'facebook',
|
||||
// 'google',
|
||||
// 'twitter',
|
||||
// 'microsoft'
|
||||
]),
|
||||
auth() {
|
||||
return this.$store.state.settings.description.find(setting => setting.key === ':auth')
|
||||
},
|
||||
isMobile() {
|
||||
return this.$store.state.app.device === 'mobile'
|
||||
},
|
||||
labelWidth() {
|
||||
return this.isMobile ? '100px' : '210px'
|
||||
},
|
||||
ldap() {
|
||||
return this.$store.state.settings.description.find(setting => setting.key === ':ldap')
|
||||
},
|
||||
oauth2() {
|
||||
return this.$store.state.settings.description.find(setting => setting.key === ':oauth2')
|
||||
},
|
||||
pleromaAuthenticator() {
|
||||
return this.$store.state.settings.description.find(setting => setting.description === 'Authenticator')
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
updateSetting(value, tab, input) {
|
||||
this.$store.dispatch('UpdateSettings', { tab, data: { [input]: value }})
|
||||
},
|
||||
async onSubmit() {
|
||||
try {
|
||||
await this.$store.dispatch('SubmitChanges')
|
||||
|
|
|
@ -1,29 +1,11 @@
|
|||
<template>
|
||||
<div>
|
||||
<el-form ref="captcha" :model="captcha" :label-width="labelWidth">
|
||||
<el-form-item label="Enabled">
|
||||
<el-switch :value="captcha.enabled" @change="updateSetting($event, 'Pleroma.Captcha', 'enabled')"/>
|
||||
<p class="expl">Whether the captcha should be shown on registration</p>
|
||||
</el-form-item>
|
||||
<el-form-item label="Valid for (s)">
|
||||
<el-input-number :value="captcha.seconds_valid" :step="1" :min="0" size="large" @change="updateSetting($event, 'Pleroma.Captcha', 'seconds_valid')"/>
|
||||
<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" 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>
|
||||
</el-form-item>
|
||||
<el-form ref="captchaData" :model="captchaData" :label-width="labelWidth">
|
||||
<setting :settings-group="captcha" :data="captchaData"/>
|
||||
</el-form>
|
||||
<el-form ref="kocaptcha" :model="kocaptcha" :label-width="labelWidth">
|
||||
<el-form-item label="Kocaptcha Endpoint">
|
||||
<el-input :value="kocaptcha.endpoint" @input="updateSetting($event, 'Pleroma.Captcha.Kocaptcha', 'endpoint')"/>
|
||||
<p class="expl">Kocaptcha is a captcha service with a single API endpoint, the source code is
|
||||
<a href="https://github.com/koto-bank/kocaptcha" rel="nofollow noreferrer noopener" target="_blank">here</a>.
|
||||
The default endpoint <span class="code">'https://captcha.kotobank.ch'</span> is hosted by the developer.
|
||||
</p>
|
||||
</el-form-item>
|
||||
<div class="line"/>
|
||||
<el-form ref="kocaptchaData" :model="kocaptchaData" :label-width="labelWidth">
|
||||
<setting :settings-group="kocaptcha" :data="kocaptchaData"/>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="onSubmit">Submit</el-button>
|
||||
</el-form-item>
|
||||
|
@ -34,25 +16,30 @@
|
|||
<script>
|
||||
import { mapGetters } from 'vuex'
|
||||
import i18n from '@/lang'
|
||||
import Setting from './Setting'
|
||||
|
||||
export default {
|
||||
name: 'Captcha',
|
||||
components: { Setting },
|
||||
computed: {
|
||||
...mapGetters([
|
||||
'captcha',
|
||||
'kocaptcha'
|
||||
'captchaData',
|
||||
'kocaptchaData'
|
||||
]),
|
||||
captcha() {
|
||||
return this.$store.state.settings.description.find(setting => setting.key === 'Pleroma.Captcha')
|
||||
},
|
||||
isMobile() {
|
||||
return this.$store.state.app.device === 'mobile'
|
||||
},
|
||||
kocaptcha() {
|
||||
return this.$store.state.settings.description.find(setting => setting.key === 'Pleroma.Captcha.Kocaptcha')
|
||||
},
|
||||
labelWidth() {
|
||||
return this.isMobile ? '100px' : '210px'
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
updateSetting(value, tab, input) {
|
||||
this.$store.dispatch('UpdateSettings', { tab, data: { [input]: value }})
|
||||
},
|
||||
async onSubmit() {
|
||||
try {
|
||||
await this.$store.dispatch('SubmitChanges')
|
||||
|
|
|
@ -97,6 +97,9 @@
|
|||
line-height: 20px;
|
||||
margin-right: 15px
|
||||
}
|
||||
.ssl-tls-opts {
|
||||
margin: 36px 0 0 0;
|
||||
}
|
||||
.upload-container {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
|
|
Loading…
Reference in a new issue