Add hCaptcha.com support to public subscription form. (#1152)

Bots easily bypass the simple `nonce` hack. This commit adds support
for the hcaptcha.com widget.

- New `Security` tab in the admin settings UI.
- Enable/disable CAPTCHA.
- Render CAPTCHA on the public subscription form.

Closes #1116.
This commit is contained in:
Kailash Nadh 2023-01-23 21:50:10 +05:30 committed by GitHub
parent 62d3782d04
commit 8985e5c24a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
36 changed files with 374 additions and 3 deletions

View file

@ -24,6 +24,7 @@ import (
"github.com/knadh/koanf/providers/posflag" "github.com/knadh/koanf/providers/posflag"
"github.com/knadh/listmonk/internal/bounce" "github.com/knadh/listmonk/internal/bounce"
"github.com/knadh/listmonk/internal/bounce/mailbox" "github.com/knadh/listmonk/internal/bounce/mailbox"
"github.com/knadh/listmonk/internal/captcha"
"github.com/knadh/listmonk/internal/i18n" "github.com/knadh/listmonk/internal/i18n"
"github.com/knadh/listmonk/internal/manager" "github.com/knadh/listmonk/internal/manager"
"github.com/knadh/listmonk/internal/media" "github.com/knadh/listmonk/internal/media"
@ -69,6 +70,11 @@ type constants struct {
Exportable map[string]bool `koanf:"-"` Exportable map[string]bool `koanf:"-"`
DomainBlocklist map[string]bool `koanf:"-"` DomainBlocklist map[string]bool `koanf:"-"`
} `koanf:"privacy"` } `koanf:"privacy"`
Security struct {
EnableCaptcha bool `koanf:"enable_captcha"`
CaptchaKey string `koanf:"captcha_key"`
CaptchaSecret string `koanf:"captcha_secret"`
} `koanf:"security"`
AdminUsername []byte `koanf:"admin_username"` AdminUsername []byte `koanf:"admin_username"`
AdminPassword []byte `koanf:"admin_password"` AdminPassword []byte `koanf:"admin_password"`
@ -351,6 +357,9 @@ func initConstants() *constants {
if err := ko.Unmarshal("privacy", &c.Privacy); err != nil { if err := ko.Unmarshal("privacy", &c.Privacy); err != nil {
lo.Fatalf("error loading app.privacy config: %v", err) lo.Fatalf("error loading app.privacy config: %v", err)
} }
if err := ko.Unmarshal("security", &c.Security); err != nil {
lo.Fatalf("error loading app.security config: %v", err)
}
if err := ko.UnmarshalWithConf("appearance", &c.Appearance, koanf.UnmarshalConf{FlatPaths: true}); err != nil { if err := ko.UnmarshalWithConf("appearance", &c.Appearance, koanf.UnmarshalConf{FlatPaths: true}); err != nil {
lo.Fatalf("error loading app.appearance config: %v", err) lo.Fatalf("error loading app.appearance config: %v", err)
} }
@ -735,6 +744,12 @@ func initHTTPServer(app *App) *echo.Echo {
return srv return srv
} }
func initCaptcha() *captcha.Captcha {
return captcha.New(captcha.Opt{
CaptchaSecret: ko.String("security.captcha_secret"),
})
}
func awaitReload(sigChan chan os.Signal, closerWait chan bool, closer func()) chan bool { func awaitReload(sigChan chan os.Signal, closerWait chan bool, closer func()) chan bool {
// The blocking signal handler that main() waits on. // The blocking signal handler that main() waits on.
out := make(chan bool) out := make(chan bool)

View file

@ -17,6 +17,7 @@ import (
"github.com/knadh/koanf/providers/env" "github.com/knadh/koanf/providers/env"
"github.com/knadh/listmonk/internal/bounce" "github.com/knadh/listmonk/internal/bounce"
"github.com/knadh/listmonk/internal/buflog" "github.com/knadh/listmonk/internal/buflog"
"github.com/knadh/listmonk/internal/captcha"
"github.com/knadh/listmonk/internal/core" "github.com/knadh/listmonk/internal/core"
"github.com/knadh/listmonk/internal/i18n" "github.com/knadh/listmonk/internal/i18n"
"github.com/knadh/listmonk/internal/manager" "github.com/knadh/listmonk/internal/manager"
@ -47,6 +48,7 @@ type App struct {
i18n *i18n.I18n i18n *i18n.I18n
bounce *bounce.Manager bounce *bounce.Manager
paginator *paginator.Paginator paginator *paginator.Paginator
captcha *captcha.Captcha
notifTpls *notifTpls notifTpls *notifTpls
log *log.Logger log *log.Logger
bufLog *buflog.BufLog bufLog *buflog.BufLog
@ -168,6 +170,7 @@ func main() {
messengers: make(map[string]messenger.Messenger), messengers: make(map[string]messenger.Messenger),
log: lo, log: lo,
bufLog: bufLog, bufLog: bufLog,
captcha: initCaptcha(),
paginator: paginator.New(paginator.Opt{ paginator: paginator.New(paginator.Opt{
DefaultPerPage: 20, DefaultPerPage: 20,

View file

@ -79,7 +79,8 @@ type msgTpl struct {
type subFormTpl struct { type subFormTpl struct {
publicTpl publicTpl
Lists []models.List Lists []models.List
CaptchaKey string
} }
var ( var (
@ -418,6 +419,10 @@ func handleSubscriptionFormPage(c echo.Context) error {
out.Title = app.i18n.T("public.sub") out.Title = app.i18n.T("public.sub")
out.Lists = lists out.Lists = lists
if app.constants.Security.EnableCaptcha {
out.CaptchaKey = app.constants.Security.CaptchaKey
}
return c.Render(http.StatusOK, "subscription-form", out) return c.Render(http.StatusOK, "subscription-form", out)
} }
@ -433,6 +438,19 @@ func handleSubscriptionForm(c echo.Context) error {
return echo.NewHTTPError(http.StatusBadGateway, app.i18n.T("public.invalidFeature")) return echo.NewHTTPError(http.StatusBadGateway, app.i18n.T("public.invalidFeature"))
} }
// Process CAPTCHA.
if app.constants.Security.EnableCaptcha {
err, ok := app.captcha.Verify(c.FormValue("h-captcha-response"))
if err != nil {
app.log.Printf("Captcha request failed: %v", err)
}
if !ok {
return c.Render(http.StatusBadRequest, tplMessage,
makeMsgTpl(app.i18n.T("public.errorTitle"), "", app.i18n.T("public.invalidCaptcha")))
}
}
hasOptin, err := processSubForm(c) hasOptin, err := processSubForm(c)
if err != nil { if err != nil {
e, ok := err.(*echo.HTTPError) e, ok := err.(*echo.HTTPError)

View file

@ -44,6 +44,7 @@ func handleGetSettings(c echo.Context) error {
} }
s.UploadS3AwsSecretAccessKey = "" s.UploadS3AwsSecretAccessKey = ""
s.SendgridKey = "" s.SendgridKey = ""
s.SecurityCaptchaSecret = ""
return c.JSON(http.StatusOK, okResp{s}) return c.JSON(http.StatusOK, okResp{s})
} }
@ -158,6 +159,9 @@ func handleUpdateSettings(c echo.Context) error {
if set.SendgridKey == "" { if set.SendgridKey == "" {
set.SendgridKey = cur.SendgridKey set.SendgridKey = cur.SendgridKey
} }
if set.SecurityCaptchaSecret == "" {
set.SecurityCaptchaSecret = cur.SecurityCaptchaSecret
}
// Domain blocklist. // Domain blocklist.
doms := make([]string, 0) doms := make([]string, 0)

View file

@ -34,6 +34,7 @@ var migList = []migFunc{
{"v2.1.0", migrations.V2_1_0}, {"v2.1.0", migrations.V2_1_0},
{"v2.2.0", migrations.V2_2_0}, {"v2.2.0", migrations.V2_2_0},
{"v2.3.0", migrations.V2_3_0}, {"v2.3.0", migrations.V2_3_0},
{"v2.4.0", migrations.V2_4_0},
} }
// upgrade upgrades the database to the current version by running SQL migration files // upgrade upgrades the database to the current version by running SQL migration files

View file

@ -34,6 +34,10 @@
<privacy-settings :form="form" :key="key" /> <privacy-settings :form="form" :key="key" />
</b-tab-item><!-- privacy --> </b-tab-item><!-- privacy -->
<b-tab-item :label="$t('settings.security.name')">
<security-settings :form="form" :key="key" />
</b-tab-item><!-- security -->
<b-tab-item :label="$t('settings.media.title')"> <b-tab-item :label="$t('settings.media.title')">
<media-settings :form="form" :key="key" /> <media-settings :form="form" :key="key" />
</b-tab-item><!-- media --> </b-tab-item><!-- media -->
@ -66,6 +70,7 @@ import { mapState } from 'vuex';
import GeneralSettings from './settings/general.vue'; import GeneralSettings from './settings/general.vue';
import PerformanceSettings from './settings/performance.vue'; import PerformanceSettings from './settings/performance.vue';
import PrivacySettings from './settings/privacy.vue'; import PrivacySettings from './settings/privacy.vue';
import SecuritySettings from './settings/security.vue';
import MediaSettings from './settings/media.vue'; import MediaSettings from './settings/media.vue';
import SmtpSettings from './settings/smtp.vue'; import SmtpSettings from './settings/smtp.vue';
import BounceSettings from './settings/bounces.vue'; import BounceSettings from './settings/bounces.vue';
@ -79,6 +84,7 @@ export default Vue.extend({
GeneralSettings, GeneralSettings,
PerformanceSettings, PerformanceSettings,
PrivacySettings, PrivacySettings,
SecuritySettings,
MediaSettings, MediaSettings,
SmtpSettings, SmtpSettings,
BounceSettings, BounceSettings,
@ -136,6 +142,10 @@ export default Vue.extend({
form['bounce.sendgrid_key'] = ''; form['bounce.sendgrid_key'] = '';
} }
if (form['security.captcha_secret'] === dummyPassword) {
form['security.captcha_secret'] = '';
}
for (let i = 0; i < form.messengers.length; i += 1) { for (let i = 0; i < form.messengers.length; i += 1) {
// If it's the dummy UI password placeholder, ignore it. // If it's the dummy UI password placeholder, ignore it.
if (form.messengers[i].password === dummyPassword) { if (form.messengers[i].password === dummyPassword) {
@ -203,6 +213,7 @@ export default Vue.extend({
d['upload.s3.aws_secret_access_key'] = dummyPassword; d['upload.s3.aws_secret_access_key'] = dummyPassword;
} }
d['bounce.sendgrid_key'] = dummyPassword; d['bounce.sendgrid_key'] = dummyPassword;
d['security.captcha_secret'] = dummyPassword;
// Domain blocklist array to multi-line string. // Domain blocklist array to multi-line string.
d['privacy.domain_blocklist'] = d['privacy.domain_blocklist'].join('\n'); d['privacy.domain_blocklist'] = d['privacy.domain_blocklist'].join('\n');

View file

@ -0,0 +1,42 @@
<template>
<div class="items">
<div class="columns">
<div class="column is-4">
<b-field :label="$t('settings.security.enableCaptcha')"
:message="$t('settings.security.enableCaptchaHelp')">
<b-switch v-model="data['security.enable_captcha']"
name="security.captcha" />
</b-field>
</div>
<div class="column is-8">
<b-field :label="$t('settings.security.captchaKey')" label-position="on-border"
:message="$t('settings.security.captchaKeyHelp')">
<b-input v-model="data['security.captcha_key']" name="captcha_key"
:disabled="!data['security.enable_captcha']" :maxlength="200" required />
</b-field>
<b-field :label="$t('settings.security.captchaSecret')" label-position="on-border">
<b-input v-model="data['security.captcha_secret']" name="captcha_secret" type="password"
:disabled="!data['security.enable_captcha']" :maxlength="200" required />
</b-field>
</div>
</div>
</div>
</template>
<script>
import Vue from 'vue';
export default Vue.extend({
props: {
form: {
type: Object,
},
},
data() {
return {
data: this.form,
};
},
});
</script>

View file

@ -304,6 +304,7 @@
"public.errorFetchingLists": "S'ha produït un error en obtenir les llistes. Si us plau, torna-ho a provar.", "public.errorFetchingLists": "S'ha produït un error en obtenir les llistes. Si us plau, torna-ho a provar.",
"public.errorProcessingRequest": "S'ha produït un error en processar la sol·licitud. Si us plau, torna-ho a provar.", "public.errorProcessingRequest": "S'ha produït un error en processar la sol·licitud. Si us plau, torna-ho a provar.",
"public.errorTitle": "Error", "public.errorTitle": "Error",
"public.invalidCaptcha": "Invalid CAPTCHA.",
"public.invalidFeature": "Aquesta funció no està disponible.", "public.invalidFeature": "Aquesta funció no està disponible.",
"public.invalidLink": "Enllaç no vàlid", "public.invalidLink": "Enllaç no vàlid",
"public.managePrefs": "Gestiona les preferències", "public.managePrefs": "Gestiona les preferències",
@ -473,6 +474,12 @@
"settings.privacy.listUnsubHeaderHelp": "Inclou capçaleres de cancel·lació de subscripció que permetin als clients de correu electrònic permetre als usuaris donar-se de baixa amb un sol clic.", "settings.privacy.listUnsubHeaderHelp": "Inclou capçaleres de cancel·lació de subscripció que permetin als clients de correu electrònic permetre als usuaris donar-se de baixa amb un sol clic.",
"settings.privacy.name": "Privadesa", "settings.privacy.name": "Privadesa",
"settings.restart": "Reinicia", "settings.restart": "Reinicia",
"settings.security.captchaKey": "hCaptcha.com SiteKey",
"settings.security.captchaKeyHelp": "Visit www.hcaptcha.com to obtain the key and secret.",
"settings.security.captchaSecret": "hCaptcha.com secret",
"settings.security.enableCaptcha": "Enable CAPTCHA",
"settings.security.enableCaptchaHelp": "Enable CAPTCHA on the public subscription form.",
"settings.security.name": "Security",
"settings.smtp.customHeaders": "Capçaleres personalitzades", "settings.smtp.customHeaders": "Capçaleres personalitzades",
"settings.smtp.customHeadersHelp": "Matriu opcional de capçaleres de correu electrònic per incloure en tots els missatges enviats des d'aquest servidor. p. ex.: [{\"X-Custom\": \"value\"}, {\"X-Custom2\": \"value\"}]", "settings.smtp.customHeadersHelp": "Matriu opcional de capçaleres de correu electrònic per incloure en tots els missatges enviats des d'aquest servidor. p. ex.: [{\"X-Custom\": \"value\"}, {\"X-Custom2\": \"value\"}]",
"settings.smtp.enabled": "Habilitat", "settings.smtp.enabled": "Habilitat",

View file

@ -304,6 +304,7 @@
"public.errorFetchingLists": "Chyba při načítání seznamů. Zopakujte pokus.", "public.errorFetchingLists": "Chyba při načítání seznamů. Zopakujte pokus.",
"public.errorProcessingRequest": "Chyba při zpracování požadavku. Zopakujte pokus.", "public.errorProcessingRequest": "Chyba při zpracování požadavku. Zopakujte pokus.",
"public.errorTitle": "Chyba", "public.errorTitle": "Chyba",
"public.invalidCaptcha": "Invalid CAPTCHA.",
"public.invalidFeature": "Tato funkce není k dispozici.", "public.invalidFeature": "Tato funkce není k dispozici.",
"public.invalidLink": "Neplatný odkaz", "public.invalidLink": "Neplatný odkaz",
"public.managePrefs": "Zpráva předvoleb", "public.managePrefs": "Zpráva předvoleb",
@ -473,6 +474,12 @@
"settings.privacy.listUnsubHeaderHelp": "Zahrnout záhlaví zrušení odběrů, která umožňují e-mailovým klientům, aby povolili uživatelům zrušit odběr jediným klepnutím.", "settings.privacy.listUnsubHeaderHelp": "Zahrnout záhlaví zrušení odběrů, která umožňují e-mailovým klientům, aby povolili uživatelům zrušit odběr jediným klepnutím.",
"settings.privacy.name": "Soukromí", "settings.privacy.name": "Soukromí",
"settings.restart": "Restart", "settings.restart": "Restart",
"settings.security.captchaKey": "hCaptcha.com SiteKey",
"settings.security.captchaKeyHelp": "Visit www.hcaptcha.com to obtain the key and secret.",
"settings.security.captchaSecret": "hCaptcha.com secret",
"settings.security.enableCaptcha": "Enable CAPTCHA",
"settings.security.enableCaptchaHelp": "Enable CAPTCHA on the public subscription form.",
"settings.security.name": "Security",
"settings.smtp.customHeaders": "Vlastní záhlaví", "settings.smtp.customHeaders": "Vlastní záhlaví",
"settings.smtp.customHeadersHelp": "Volitelné pole e-mailových záhlaví, která se mají zahrnout do všech zpráv odeslaných z tohoto serveru. Např.: [{\"X-Custom\": \"value\"}, {\"X-Custom2\": \"value\"}]", "settings.smtp.customHeadersHelp": "Volitelné pole e-mailových záhlaví, která se mají zahrnout do všech zpráv odeslaných z tohoto serveru. Např.: [{\"X-Custom\": \"value\"}, {\"X-Custom2\": \"value\"}]",
"settings.smtp.enabled": "Povoleno", "settings.smtp.enabled": "Povoleno",

View file

@ -304,6 +304,7 @@
"public.errorFetchingLists": "Gwall wrth chwilio am y rhestrau. Rhowch gynnig arall arni.", "public.errorFetchingLists": "Gwall wrth chwilio am y rhestrau. Rhowch gynnig arall arni.",
"public.errorProcessingRequest": "Gwall wrth brosesu'r cais. Rhowch gynnig arall arni.", "public.errorProcessingRequest": "Gwall wrth brosesu'r cais. Rhowch gynnig arall arni.",
"public.errorTitle": "Gwall", "public.errorTitle": "Gwall",
"public.invalidCaptcha": "Invalid CAPTCHA.",
"public.invalidFeature": "Nid yw'r nodwedd ar gael.", "public.invalidFeature": "Nid yw'r nodwedd ar gael.",
"public.invalidLink": "Dolen annilys", "public.invalidLink": "Dolen annilys",
"public.managePrefs": "Rheoli dewisiadau", "public.managePrefs": "Rheoli dewisiadau",
@ -473,6 +474,12 @@
"settings.privacy.listUnsubHeaderHelp": "Cynnwys penynnau dad-danysgrifio sy'n caniatáu i ddefnyddwyr dad-danysgrifio drwy glicio un botwm.", "settings.privacy.listUnsubHeaderHelp": "Cynnwys penynnau dad-danysgrifio sy'n caniatáu i ddefnyddwyr dad-danysgrifio drwy glicio un botwm.",
"settings.privacy.name": "Preifatrwydd", "settings.privacy.name": "Preifatrwydd",
"settings.restart": "Ailgychwyn", "settings.restart": "Ailgychwyn",
"settings.security.captchaKey": "hCaptcha.com SiteKey",
"settings.security.captchaKeyHelp": "Visit www.hcaptcha.com to obtain the key and secret.",
"settings.security.captchaSecret": "hCaptcha.com secret",
"settings.security.enableCaptcha": "Enable CAPTCHA",
"settings.security.enableCaptchaHelp": "Enable CAPTCHA on the public subscription form.",
"settings.security.name": "Security",
"settings.smtp.customHeaders": "Penynnau personol", "settings.smtp.customHeaders": "Penynnau personol",
"settings.smtp.customHeadersHelp": "Ystod eang o bennynau e-bost i'w cynnwys mewn negeseuon a anfonir gan y gweinydd hwn. ee: [{\"\"X-Custom\"\": \"\"gwerth\"\"}", "settings.smtp.customHeadersHelp": "Ystod eang o bennynau e-bost i'w cynnwys mewn negeseuon a anfonir gan y gweinydd hwn. ee: [{\"\"X-Custom\"\": \"\"gwerth\"\"}",
"settings.smtp.enabled": "Wedi galluogi", "settings.smtp.enabled": "Wedi galluogi",

View file

@ -304,6 +304,7 @@
"public.errorFetchingLists": "Fehler beim Abrufen der Listen. Bitte probiere es nochmal.", "public.errorFetchingLists": "Fehler beim Abrufen der Listen. Bitte probiere es nochmal.",
"public.errorProcessingRequest": "Fehler bei der Anfrage. Bitte probiere es nochmal.", "public.errorProcessingRequest": "Fehler bei der Anfrage. Bitte probiere es nochmal.",
"public.errorTitle": "Fehler", "public.errorTitle": "Fehler",
"public.invalidCaptcha": "Invalid CAPTCHA.",
"public.invalidFeature": "Dieses Feature ist nicht verfügbar", "public.invalidFeature": "Dieses Feature ist nicht verfügbar",
"public.invalidLink": "Ungültiger Link", "public.invalidLink": "Ungültiger Link",
"public.managePrefs": "Einstellungen verwalten", "public.managePrefs": "Einstellungen verwalten",
@ -473,6 +474,12 @@
"settings.privacy.listUnsubHeaderHelp": "Inkludiere Header zum einfachen Abmelden in den E-Mails. Erlaubt es, den E-Mail Clients der Nutzer eine \",Ein Klick\"-Abmeldung anzubieten.", "settings.privacy.listUnsubHeaderHelp": "Inkludiere Header zum einfachen Abmelden in den E-Mails. Erlaubt es, den E-Mail Clients der Nutzer eine \",Ein Klick\"-Abmeldung anzubieten.",
"settings.privacy.name": "Privatsphäre", "settings.privacy.name": "Privatsphäre",
"settings.restart": "Neustarten", "settings.restart": "Neustarten",
"settings.security.captchaKey": "hCaptcha.com SiteKey",
"settings.security.captchaKeyHelp": "Visit www.hcaptcha.com to obtain the key and secret.",
"settings.security.captchaSecret": "hCaptcha.com secret",
"settings.security.enableCaptcha": "Enable CAPTCHA",
"settings.security.enableCaptchaHelp": "Enable CAPTCHA on the public subscription form.",
"settings.security.name": "Security",
"settings.smtp.customHeaders": "Benutzerdefinierte Header", "settings.smtp.customHeaders": "Benutzerdefinierte Header",
"settings.smtp.customHeadersHelp": "(Optional) Array von benutzerdefinierten E-Mail Headern, welche in die Nachricht eingefügt werden sollen. Z.B.: [{\"X-Custom\": \"value\"}, {\"X-Custom2\": \"value\"}]", "settings.smtp.customHeadersHelp": "(Optional) Array von benutzerdefinierten E-Mail Headern, welche in die Nachricht eingefügt werden sollen. Z.B.: [{\"X-Custom\": \"value\"}, {\"X-Custom2\": \"value\"}]",
"settings.smtp.enabled": "Aktiviert", "settings.smtp.enabled": "Aktiviert",

View file

@ -304,6 +304,7 @@
"public.errorFetchingLists": "Error fetching lists. Please retry.", "public.errorFetchingLists": "Error fetching lists. Please retry.",
"public.errorProcessingRequest": "Error processing request. Please retry.", "public.errorProcessingRequest": "Error processing request. Please retry.",
"public.errorTitle": "Error", "public.errorTitle": "Error",
"public.invalidCaptcha": "Invalid CAPTCHA.",
"public.invalidFeature": "That feature is not available.", "public.invalidFeature": "That feature is not available.",
"public.invalidLink": "Invalid link", "public.invalidLink": "Invalid link",
"public.managePrefs": "Manage preferences", "public.managePrefs": "Manage preferences",
@ -473,6 +474,12 @@
"settings.privacy.listUnsubHeaderHelp": "Include unsubscription headers that allow e-mail clients to allow users to unsubscribe in a single click.", "settings.privacy.listUnsubHeaderHelp": "Include unsubscription headers that allow e-mail clients to allow users to unsubscribe in a single click.",
"settings.privacy.name": "Privacy", "settings.privacy.name": "Privacy",
"settings.restart": "Restart", "settings.restart": "Restart",
"settings.security.captchaKey": "hCaptcha.com SiteKey",
"settings.security.captchaKeyHelp": "Visit www.hcaptcha.com to obtain the key and secret.",
"settings.security.captchaSecret": "hCaptcha.com secret",
"settings.security.enableCaptcha": "Enable CAPTCHA",
"settings.security.enableCaptchaHelp": "Enable CAPTCHA on the public subscription form.",
"settings.security.name": "Security",
"settings.smtp.customHeaders": "Custom headers", "settings.smtp.customHeaders": "Custom headers",
"settings.smtp.customHeadersHelp": "Optional array of e-mail headers to include in all messages sent from this server. eg: [{\"X-Custom\": \"value\"}, {\"X-Custom2\": \"value\"}]", "settings.smtp.customHeadersHelp": "Optional array of e-mail headers to include in all messages sent from this server. eg: [{\"X-Custom\": \"value\"}, {\"X-Custom2\": \"value\"}]",
"settings.smtp.enabled": "Enabled", "settings.smtp.enabled": "Enabled",

View file

@ -305,6 +305,7 @@
"public.errorFetchingLists": "Error obteniendo listas. Por favor intente nuevamente.", "public.errorFetchingLists": "Error obteniendo listas. Por favor intente nuevamente.",
"public.errorProcessingRequest": "Error al procesar la petición. Por favor intente nuevamente.", "public.errorProcessingRequest": "Error al procesar la petición. Por favor intente nuevamente.",
"public.errorTitle": "Error", "public.errorTitle": "Error",
"public.invalidCaptcha": "Invalid CAPTCHA.",
"public.invalidFeature": "Esta función no está disponible", "public.invalidFeature": "Esta función no está disponible",
"public.invalidLink": "Enlace inválido", "public.invalidLink": "Enlace inválido",
"public.managePrefs": "Gestionar las preferencias", "public.managePrefs": "Gestionar las preferencias",
@ -474,6 +475,12 @@
"settings.privacy.listUnsubHeaderHelp": "Incluye los encabezados de darse de baja para habilitar a los clientes de correo para permitir a los usuarios darse de baja con un solo clic.", "settings.privacy.listUnsubHeaderHelp": "Incluye los encabezados de darse de baja para habilitar a los clientes de correo para permitir a los usuarios darse de baja con un solo clic.",
"settings.privacy.name": "Privacidad", "settings.privacy.name": "Privacidad",
"settings.restart": "Reiniciar", "settings.restart": "Reiniciar",
"settings.security.captchaKey": "hCaptcha.com SiteKey",
"settings.security.captchaKeyHelp": "Visit www.hcaptcha.com to obtain the key and secret.",
"settings.security.captchaSecret": "hCaptcha.com secret",
"settings.security.enableCaptcha": "Enable CAPTCHA",
"settings.security.enableCaptchaHelp": "Enable CAPTCHA on the public subscription form.",
"settings.security.name": "Security",
"settings.smtp.customHeaders": "Encabezados personalizados", "settings.smtp.customHeaders": "Encabezados personalizados",
"settings.smtp.customHeadersHelp": "Lista de encabezados opcionales a incluir en todos los mensajes enviados desde este servidor. Por ejemplo {{\"X-Custom\": \"value\"}, {\"X-Custom2\": \"value\"}]", "settings.smtp.customHeadersHelp": "Lista de encabezados opcionales a incluir en todos los mensajes enviados desde este servidor. Por ejemplo {{\"X-Custom\": \"value\"}, {\"X-Custom2\": \"value\"}]",
"settings.smtp.enabled": "Habilitado", "settings.smtp.enabled": "Habilitado",

View file

@ -305,6 +305,7 @@
"public.errorFetchingLists": "Virhe noutaessa postituslistoja. Ole hyvä ja yritä uudestaan.", "public.errorFetchingLists": "Virhe noutaessa postituslistoja. Ole hyvä ja yritä uudestaan.",
"public.errorProcessingRequest": "Virhe käsitellessä pyyntöäsi. Ole hyvä ja yritä uudestaan.", "public.errorProcessingRequest": "Virhe käsitellessä pyyntöäsi. Ole hyvä ja yritä uudestaan.",
"public.errorTitle": "Tapahtui virhe", "public.errorTitle": "Tapahtui virhe",
"public.invalidCaptcha": "Invalid CAPTCHA.",
"public.invalidFeature": "Tämä ominaisuus ei ole saatavilla.", "public.invalidFeature": "Tämä ominaisuus ei ole saatavilla.",
"public.invalidLink": "Virheellinen linkki", "public.invalidLink": "Virheellinen linkki",
"public.managePrefs": "Manage preferences", "public.managePrefs": "Manage preferences",
@ -474,6 +475,12 @@
"settings.privacy.listUnsubHeaderHelp": "Include unsubscription headers that allow e-mail clients to allow users to unsubscribe in a single click.", "settings.privacy.listUnsubHeaderHelp": "Include unsubscription headers that allow e-mail clients to allow users to unsubscribe in a single click.",
"settings.privacy.name": "Yksityisyys", "settings.privacy.name": "Yksityisyys",
"settings.restart": "Restart", "settings.restart": "Restart",
"settings.security.captchaKey": "hCaptcha.com SiteKey",
"settings.security.captchaKeyHelp": "Visit www.hcaptcha.com to obtain the key and secret.",
"settings.security.captchaSecret": "hCaptcha.com secret",
"settings.security.enableCaptcha": "Enable CAPTCHA",
"settings.security.enableCaptchaHelp": "Enable CAPTCHA on the public subscription form.",
"settings.security.name": "Security",
"settings.smtp.customHeaders": "Custom headers", "settings.smtp.customHeaders": "Custom headers",
"settings.smtp.customHeadersHelp": "Optional array of e-mail headers to include in all messages sent from this server. eg: [{\"X-Custom\": \"value\"}, {\"X-Custom2\": \"value\"}]", "settings.smtp.customHeadersHelp": "Optional array of e-mail headers to include in all messages sent from this server. eg: [{\"X-Custom\": \"value\"}, {\"X-Custom2\": \"value\"}]",
"settings.smtp.enabled": "Enabled", "settings.smtp.enabled": "Enabled",

View file

@ -305,6 +305,7 @@
"public.errorFetchingLists": "Erreur lors de la récupération des listes. Veuillez réessayer.", "public.errorFetchingLists": "Erreur lors de la récupération des listes. Veuillez réessayer.",
"public.errorProcessingRequest": "Erreur lors du traitement de la demande. Veuillez réessayer.", "public.errorProcessingRequest": "Erreur lors du traitement de la demande. Veuillez réessayer.",
"public.errorTitle": "Erreur", "public.errorTitle": "Erreur",
"public.invalidCaptcha": "Invalid CAPTCHA.",
"public.invalidFeature": "Cette fonctionnalité n'est pas disponible.", "public.invalidFeature": "Cette fonctionnalité n'est pas disponible.",
"public.invalidLink": "Lien invalide", "public.invalidLink": "Lien invalide",
"public.managePrefs": "Gérer les préférences", "public.managePrefs": "Gérer les préférences",
@ -474,6 +475,12 @@
"settings.privacy.listUnsubHeaderHelp": "Inclure des en-têtes de désabonnement qui permettent aux utilisateurs de se désabonner en un seul clic depuis leur client de messagerie.", "settings.privacy.listUnsubHeaderHelp": "Inclure des en-têtes de désabonnement qui permettent aux utilisateurs de se désabonner en un seul clic depuis leur client de messagerie.",
"settings.privacy.name": "Vie privée", "settings.privacy.name": "Vie privée",
"settings.restart": "Redémarrer", "settings.restart": "Redémarrer",
"settings.security.captchaKey": "hCaptcha.com SiteKey",
"settings.security.captchaKeyHelp": "Visit www.hcaptcha.com to obtain the key and secret.",
"settings.security.captchaSecret": "hCaptcha.com secret",
"settings.security.enableCaptcha": "Enable CAPTCHA",
"settings.security.enableCaptchaHelp": "Enable CAPTCHA on the public subscription form.",
"settings.security.name": "Security",
"settings.smtp.customHeaders": "En-têtes personnalisées", "settings.smtp.customHeaders": "En-têtes personnalisées",
"settings.smtp.customHeadersHelp": "Tableau facultatif d'en-têtes à inclure dans tous les e-mails envoyés depuis ce serveur. Par exemple : [{\"X-Custom\": \"value\"}, {\"X-Custom2\": \"value\"}]", "settings.smtp.customHeadersHelp": "Tableau facultatif d'en-têtes à inclure dans tous les e-mails envoyés depuis ce serveur. Par exemple : [{\"X-Custom\": \"value\"}, {\"X-Custom2\": \"value\"}]",
"settings.smtp.enabled": "Activé", "settings.smtp.enabled": "Activé",

View file

@ -305,6 +305,7 @@
"public.errorFetchingLists": "Hiba a listák lekérésekor. Kérjük, próbálja újra.", "public.errorFetchingLists": "Hiba a listák lekérésekor. Kérjük, próbálja újra.",
"public.errorProcessingRequest": "Hiba a kérelem feldolgozásakor. Kérjük, próbálja újra.", "public.errorProcessingRequest": "Hiba a kérelem feldolgozásakor. Kérjük, próbálja újra.",
"public.errorTitle": "Hiba", "public.errorTitle": "Hiba",
"public.invalidCaptcha": "Invalid CAPTCHA.",
"public.invalidFeature": "Ez a funkció nem elérhető.", "public.invalidFeature": "Ez a funkció nem elérhető.",
"public.invalidLink": "A link érvénytelen", "public.invalidLink": "A link érvénytelen",
"public.managePrefs": "Manage preferences", "public.managePrefs": "Manage preferences",
@ -474,6 +475,12 @@
"settings.privacy.listUnsubHeaderHelp": "Tartalmazzon leiratkozási fejléceket, amelyek lehetővé teszik az e-mail kliensek számára, hogy a felhasználók egyetlen kattintással leiratkozhassanak.", "settings.privacy.listUnsubHeaderHelp": "Tartalmazzon leiratkozási fejléceket, amelyek lehetővé teszik az e-mail kliensek számára, hogy a felhasználók egyetlen kattintással leiratkozhassanak.",
"settings.privacy.name": "Magánélet", "settings.privacy.name": "Magánélet",
"settings.restart": "Újraindítás", "settings.restart": "Újraindítás",
"settings.security.captchaKey": "hCaptcha.com SiteKey",
"settings.security.captchaKeyHelp": "Visit www.hcaptcha.com to obtain the key and secret.",
"settings.security.captchaSecret": "hCaptcha.com secret",
"settings.security.enableCaptcha": "Enable CAPTCHA",
"settings.security.enableCaptchaHelp": "Enable CAPTCHA on the public subscription form.",
"settings.security.name": "Security",
"settings.smtp.customHeaders": "Egyéni fejlécek", "settings.smtp.customHeaders": "Egyéni fejlécek",
"settings.smtp.customHeadersHelp": "Az e-mail fejlécek opcionális tömbje a szerverről küldött összes üzenetben. eg: [{\"X-Custom\": \"value\"}, {\"X-Custom2\": \"value\"}]", "settings.smtp.customHeadersHelp": "Az e-mail fejlécek opcionális tömbje a szerverről küldött összes üzenetben. eg: [{\"X-Custom\": \"value\"}, {\"X-Custom2\": \"value\"}]",
"settings.smtp.enabled": "Engedélyez", "settings.smtp.enabled": "Engedélyez",

View file

@ -305,6 +305,7 @@
"public.errorFetchingLists": "Errore durante il recupero delle liste. Per favore, riprova.", "public.errorFetchingLists": "Errore durante il recupero delle liste. Per favore, riprova.",
"public.errorProcessingRequest": "Errore durante la gestione della richiesta. Per favore, riprova.", "public.errorProcessingRequest": "Errore durante la gestione della richiesta. Per favore, riprova.",
"public.errorTitle": "Errore", "public.errorTitle": "Errore",
"public.invalidCaptcha": "Invalid CAPTCHA.",
"public.invalidFeature": "Questa funzione non è disponibile.", "public.invalidFeature": "Questa funzione non è disponibile.",
"public.invalidLink": "Link non valido", "public.invalidLink": "Link non valido",
"public.managePrefs": "Gestiona l'impostazinoni", "public.managePrefs": "Gestiona l'impostazinoni",
@ -474,6 +475,12 @@
"settings.privacy.listUnsubHeaderHelp": "Includere intestazioni di annullamento dell'iscrizione che consentono agli utenti di annullare l'iscrizione con un clic dal proprio client di posta elettronica.", "settings.privacy.listUnsubHeaderHelp": "Includere intestazioni di annullamento dell'iscrizione che consentono agli utenti di annullare l'iscrizione con un clic dal proprio client di posta elettronica.",
"settings.privacy.name": "Privacy", "settings.privacy.name": "Privacy",
"settings.restart": "Riavviare", "settings.restart": "Riavviare",
"settings.security.captchaKey": "hCaptcha.com SiteKey",
"settings.security.captchaKeyHelp": "Visit www.hcaptcha.com to obtain the key and secret.",
"settings.security.captchaSecret": "hCaptcha.com secret",
"settings.security.enableCaptcha": "Enable CAPTCHA",
"settings.security.enableCaptchaHelp": "Enable CAPTCHA on the public subscription form.",
"settings.security.name": "Security",
"settings.smtp.customHeaders": "Intestazioni personalizzate", "settings.smtp.customHeaders": "Intestazioni personalizzate",
"settings.smtp.customHeadersHelp": "Matrice facoltativa di intestazioni di posta elettronica da includere in tutti i messaggi inviati da questo server. Ad esempio: [{\"X-Custom\": \"value\"}, {\"X-Custom2\": \"value\"}]", "settings.smtp.customHeadersHelp": "Matrice facoltativa di intestazioni di posta elettronica da includere in tutti i messaggi inviati da questo server. Ad esempio: [{\"X-Custom\": \"value\"}, {\"X-Custom2\": \"value\"}]",
"settings.smtp.enabled": "Attivata", "settings.smtp.enabled": "Attivata",

View file

@ -305,6 +305,7 @@
"public.errorFetchingLists": "リストの取得にエラーがありました。再試行してください。", "public.errorFetchingLists": "リストの取得にエラーがありました。再試行してください。",
"public.errorProcessingRequest": "リクエスト中にエラーがありました。再試行してください。", "public.errorProcessingRequest": "リクエスト中にエラーがありました。再試行してください。",
"public.errorTitle": "エラー", "public.errorTitle": "エラー",
"public.invalidCaptcha": "Invalid CAPTCHA.",
"public.invalidFeature": "その機能は使用できません。", "public.invalidFeature": "その機能は使用できません。",
"public.invalidLink": "無効なリンク", "public.invalidLink": "無効なリンク",
"public.managePrefs": "設定変更", "public.managePrefs": "設定変更",
@ -474,6 +475,12 @@
"settings.privacy.listUnsubHeaderHelp": "メールクライアントがワンクリックで登録解除をできるように登録解除用のヘッダーを含める。", "settings.privacy.listUnsubHeaderHelp": "メールクライアントがワンクリックで登録解除をできるように登録解除用のヘッダーを含める。",
"settings.privacy.name": "プライバシー", "settings.privacy.name": "プライバシー",
"settings.restart": "再起動", "settings.restart": "再起動",
"settings.security.captchaKey": "hCaptcha.com SiteKey",
"settings.security.captchaKeyHelp": "Visit www.hcaptcha.com to obtain the key and secret.",
"settings.security.captchaSecret": "hCaptcha.com secret",
"settings.security.enableCaptcha": "Enable CAPTCHA",
"settings.security.enableCaptchaHelp": "Enable CAPTCHA on the public subscription form.",
"settings.security.name": "Security",
"settings.smtp.customHeaders": "カスタムヘッダー", "settings.smtp.customHeaders": "カスタムヘッダー",
"settings.smtp.customHeadersHelp": "このサーバーから送信する全てのメッセージに含まれる任意のメールヘッダーの配列。 例: [{\"X-カスタム\": \"バリュー\"}, {\"X-カスタム2\": \"バリュー\"}]", "settings.smtp.customHeadersHelp": "このサーバーから送信する全てのメッセージに含まれる任意のメールヘッダーの配列。 例: [{\"X-カスタム\": \"バリュー\"}, {\"X-カスタム2\": \"バリュー\"}]",
"settings.smtp.enabled": "有効", "settings.smtp.enabled": "有効",

View file

@ -304,6 +304,7 @@
"public.errorFetchingLists": "ലിസ്റ്റുകൾ വീണ്ടെടുക്കുന്നതിൽ തടസം നേരിട്ടു. വീണ്ടും ശ്രമിക്കുക.", "public.errorFetchingLists": "ലിസ്റ്റുകൾ വീണ്ടെടുക്കുന്നതിൽ തടസം നേരിട്ടു. വീണ്ടും ശ്രമിക്കുക.",
"public.errorProcessingRequest": "അഭ്യർത്ഥനയിന്മേൽ നടപടിയെടുക്കുന്നതിൽ തടസം നേരിട്ടു. വീണ്ടും ശ്രമിക്കുക.", "public.errorProcessingRequest": "അഭ്യർത്ഥനയിന്മേൽ നടപടിയെടുക്കുന്നതിൽ തടസം നേരിട്ടു. വീണ്ടും ശ്രമിക്കുക.",
"public.errorTitle": "എറർ", "public.errorTitle": "എറർ",
"public.invalidCaptcha": "Invalid CAPTCHA.",
"public.invalidFeature": "ഈ ഫീച്ചർ ലഭ്യമല്ല", "public.invalidFeature": "ഈ ഫീച്ചർ ലഭ്യമല്ല",
"public.invalidLink": "കണ്ണി അസാധുവാണ്", "public.invalidLink": "കണ്ണി അസാധുവാണ്",
"public.managePrefs": "മുൻഗണനകളിൽ മാറ്റം വരുത്തുക", "public.managePrefs": "മുൻഗണനകളിൽ മാറ്റം വരുത്തുക",
@ -473,6 +474,12 @@
"settings.privacy.listUnsubHeaderHelp": "ഒറ്റ ക്ലിക്കിലൂടെ വരിക്കാനല്ലാതാക്കാൻ ഇ-മെയിൽ ക്ലൈന്റിൽ വരിക്കാരനല്ലാതാക്കാനുള്ള തലക്കെട്ട് കൂട്ടിച്ചേർക്കുക.", "settings.privacy.listUnsubHeaderHelp": "ഒറ്റ ക്ലിക്കിലൂടെ വരിക്കാനല്ലാതാക്കാൻ ഇ-മെയിൽ ക്ലൈന്റിൽ വരിക്കാരനല്ലാതാക്കാനുള്ള തലക്കെട്ട് കൂട്ടിച്ചേർക്കുക.",
"settings.privacy.name": "സ്വകാര്യത", "settings.privacy.name": "സ്വകാര്യത",
"settings.restart": "പുനരാരംഭിയ്ക്കുക", "settings.restart": "പുനരാരംഭിയ്ക്കുക",
"settings.security.captchaKey": "hCaptcha.com SiteKey",
"settings.security.captchaKeyHelp": "Visit www.hcaptcha.com to obtain the key and secret.",
"settings.security.captchaSecret": "hCaptcha.com secret",
"settings.security.enableCaptcha": "Enable CAPTCHA",
"settings.security.enableCaptchaHelp": "Enable CAPTCHA on the public subscription form.",
"settings.security.name": "Security",
"settings.smtp.customHeaders": "ഇഷ്ടാനുസൃത തലക്കെട്ടുകൾ", "settings.smtp.customHeaders": "ഇഷ്ടാനുസൃത തലക്കെട്ടുകൾ",
"settings.smtp.customHeadersHelp": "ഈ സേർവറിൽ നിന്നും അയക്കുന്ന എല്ലാ ഈ-മെയിലിലും ഉണ്ടാകേണ്ട ഇഷ്ടാനുസൃത തലക്കെട്ടുകൾ. ഉദാഹരണം: [{\"X-Custom\": \"value\"}, {\"X-Custom2\": \"value\"}]", "settings.smtp.customHeadersHelp": "ഈ സേർവറിൽ നിന്നും അയക്കുന്ന എല്ലാ ഈ-മെയിലിലും ഉണ്ടാകേണ്ട ഇഷ്ടാനുസൃത തലക്കെട്ടുകൾ. ഉദാഹരണം: [{\"X-Custom\": \"value\"}, {\"X-Custom2\": \"value\"}]",
"settings.smtp.enabled": "പ്രവർത്തനക്ഷമമാക്കി", "settings.smtp.enabled": "പ്രവർത്തനക്ഷമമാക്കി",

View file

@ -305,6 +305,7 @@
"public.errorFetchingLists": "Fout bij ophalen lijsten. Probeer opnieuw.", "public.errorFetchingLists": "Fout bij ophalen lijsten. Probeer opnieuw.",
"public.errorProcessingRequest": "Fout bij behandelen verzoek. Probeer opnieuw.", "public.errorProcessingRequest": "Fout bij behandelen verzoek. Probeer opnieuw.",
"public.errorTitle": "Fout", "public.errorTitle": "Fout",
"public.invalidCaptcha": "Invalid CAPTCHA.",
"public.invalidFeature": "Deze functie is niet beschikbaar", "public.invalidFeature": "Deze functie is niet beschikbaar",
"public.invalidLink": "Ongeldige link", "public.invalidLink": "Ongeldige link",
"public.managePrefs": "Manage preferences", "public.managePrefs": "Manage preferences",
@ -474,6 +475,12 @@
"settings.privacy.listUnsubHeaderHelp": "Voeg header toe zodat e-mailprogramma's gebruikers zich kunnen laten uitschrijven in een klik.", "settings.privacy.listUnsubHeaderHelp": "Voeg header toe zodat e-mailprogramma's gebruikers zich kunnen laten uitschrijven in een klik.",
"settings.privacy.name": "Privacy", "settings.privacy.name": "Privacy",
"settings.restart": "Herstarten", "settings.restart": "Herstarten",
"settings.security.captchaKey": "hCaptcha.com SiteKey",
"settings.security.captchaKeyHelp": "Visit www.hcaptcha.com to obtain the key and secret.",
"settings.security.captchaSecret": "hCaptcha.com secret",
"settings.security.enableCaptcha": "Enable CAPTCHA",
"settings.security.enableCaptchaHelp": "Enable CAPTCHA on the public subscription form.",
"settings.security.name": "Security",
"settings.smtp.customHeaders": "Aangepaste headers", "settings.smtp.customHeaders": "Aangepaste headers",
"settings.smtp.customHeadersHelp": "Optionele lijst met e-mail headers om toe te voegen aan alle berichten van deze server. Bv.: [{\"X-Custom\": \"value\"}, {\"X-Custom2\": \"value\"}]", "settings.smtp.customHeadersHelp": "Optionele lijst met e-mail headers om toe te voegen aan alle berichten van deze server. Bv.: [{\"X-Custom\": \"value\"}, {\"X-Custom2\": \"value\"}]",
"settings.smtp.enabled": "Ingeschakeld", "settings.smtp.enabled": "Ingeschakeld",

View file

@ -305,6 +305,7 @@
"public.errorFetchingLists": "Błąd pobierania list. Spróbuj ponownie.", "public.errorFetchingLists": "Błąd pobierania list. Spróbuj ponownie.",
"public.errorProcessingRequest": "Błąd przetwarzania żądania. Spróbuj ponownie.", "public.errorProcessingRequest": "Błąd przetwarzania żądania. Spróbuj ponownie.",
"public.errorTitle": "Błąd", "public.errorTitle": "Błąd",
"public.invalidCaptcha": "Invalid CAPTCHA.",
"public.invalidFeature": "Ta funkcjonalność jest niedostępna.", "public.invalidFeature": "Ta funkcjonalność jest niedostępna.",
"public.invalidLink": "Nieprawidłowy liny.", "public.invalidLink": "Nieprawidłowy liny.",
"public.managePrefs": "Manage preferences", "public.managePrefs": "Manage preferences",
@ -474,6 +475,12 @@
"settings.privacy.listUnsubHeaderHelp": "Dodaj nagłówki do wypisania się z subskrypcji. Niektóre programy pocztowe umożliwiają wypisanie się jednym kliknięciem.", "settings.privacy.listUnsubHeaderHelp": "Dodaj nagłówki do wypisania się z subskrypcji. Niektóre programy pocztowe umożliwiają wypisanie się jednym kliknięciem.",
"settings.privacy.name": "Prywatność", "settings.privacy.name": "Prywatność",
"settings.restart": "Restart", "settings.restart": "Restart",
"settings.security.captchaKey": "hCaptcha.com SiteKey",
"settings.security.captchaKeyHelp": "Visit www.hcaptcha.com to obtain the key and secret.",
"settings.security.captchaSecret": "hCaptcha.com secret",
"settings.security.enableCaptcha": "Enable CAPTCHA",
"settings.security.enableCaptchaHelp": "Enable CAPTCHA on the public subscription form.",
"settings.security.name": "Security",
"settings.smtp.customHeaders": "Niestandardowe nagłówki", "settings.smtp.customHeaders": "Niestandardowe nagłówki",
"settings.smtp.customHeadersHelp": "Opcjonalna lista nagłówków do zamieszczania w wiadomościach we wszystkich wiadomościach wysłanych z tego serwera. np: [{\"X-Custom\": \"value\"}, {\"X-Custom2\": \"value\"}]", "settings.smtp.customHeadersHelp": "Opcjonalna lista nagłówków do zamieszczania w wiadomościach we wszystkich wiadomościach wysłanych z tego serwera. np: [{\"X-Custom\": \"value\"}, {\"X-Custom2\": \"value\"}]",
"settings.smtp.enabled": "Włączone", "settings.smtp.enabled": "Włączone",

View file

@ -304,6 +304,7 @@
"public.errorFetchingLists": "Erro ao obter as listas. Por favor, tente novamente.", "public.errorFetchingLists": "Erro ao obter as listas. Por favor, tente novamente.",
"public.errorProcessingRequest": "Erro ao processar a solicitação. Por favor, tente novamente.", "public.errorProcessingRequest": "Erro ao processar a solicitação. Por favor, tente novamente.",
"public.errorTitle": "Erro", "public.errorTitle": "Erro",
"public.invalidCaptcha": "Invalid CAPTCHA.",
"public.invalidFeature": "Este recurso não está disponível.", "public.invalidFeature": "Este recurso não está disponível.",
"public.invalidLink": "Link inválido", "public.invalidLink": "Link inválido",
"public.managePrefs": "Gerenciar preferências", "public.managePrefs": "Gerenciar preferências",
@ -473,6 +474,12 @@
"settings.privacy.listUnsubHeaderHelp": "Incluir cabeçalhos de desinscrição que permitem aos clientes de e-mail cancelem a inscrição em um único clique.", "settings.privacy.listUnsubHeaderHelp": "Incluir cabeçalhos de desinscrição que permitem aos clientes de e-mail cancelem a inscrição em um único clique.",
"settings.privacy.name": "Privacidade", "settings.privacy.name": "Privacidade",
"settings.restart": "Reiniciar", "settings.restart": "Reiniciar",
"settings.security.captchaKey": "hCaptcha.com SiteKey",
"settings.security.captchaKeyHelp": "Visit www.hcaptcha.com to obtain the key and secret.",
"settings.security.captchaSecret": "hCaptcha.com secret",
"settings.security.enableCaptcha": "Enable CAPTCHA",
"settings.security.enableCaptchaHelp": "Enable CAPTCHA on the public subscription form.",
"settings.security.name": "Security",
"settings.smtp.customHeaders": "Cabeçalhos personalizados", "settings.smtp.customHeaders": "Cabeçalhos personalizados",
"settings.smtp.customHeadersHelp": "Array opcional de cabeçalhos de e-mail para incluir em todas as mensagens enviadas a partir deste servidor. por exemplo: [{\"X-Custom\": \"value\"}, {\"X-Custom2\": \"value\"}]", "settings.smtp.customHeadersHelp": "Array opcional de cabeçalhos de e-mail para incluir em todas as mensagens enviadas a partir deste servidor. por exemplo: [{\"X-Custom\": \"value\"}, {\"X-Custom2\": \"value\"}]",
"settings.smtp.enabled": "Habilitado", "settings.smtp.enabled": "Habilitado",

View file

@ -304,6 +304,7 @@
"public.errorFetchingLists": "Erro ao carregar listas. Por favor tente novamente.", "public.errorFetchingLists": "Erro ao carregar listas. Por favor tente novamente.",
"public.errorProcessingRequest": "Erro ao processar pedido. Por favor tente novamente.", "public.errorProcessingRequest": "Erro ao processar pedido. Por favor tente novamente.",
"public.errorTitle": "Erro", "public.errorTitle": "Erro",
"public.invalidCaptcha": "Invalid CAPTCHA.",
"public.invalidFeature": "That feature is not available", "public.invalidFeature": "That feature is not available",
"public.invalidLink": "Link inválido", "public.invalidLink": "Link inválido",
"public.managePrefs": "Gerir preferências", "public.managePrefs": "Gerir preferências",
@ -473,6 +474,12 @@
"settings.privacy.listUnsubHeaderHelp": "Incluir headers de cancelamento de subscrição que permite aos clientes de email permitir ao utilizadores cancelar a subscrição num único clique.", "settings.privacy.listUnsubHeaderHelp": "Incluir headers de cancelamento de subscrição que permite aos clientes de email permitir ao utilizadores cancelar a subscrição num único clique.",
"settings.privacy.name": "Privacidade", "settings.privacy.name": "Privacidade",
"settings.restart": "Reiniciar", "settings.restart": "Reiniciar",
"settings.security.captchaKey": "hCaptcha.com SiteKey",
"settings.security.captchaKeyHelp": "Visit www.hcaptcha.com to obtain the key and secret.",
"settings.security.captchaSecret": "hCaptcha.com secret",
"settings.security.enableCaptcha": "Enable CAPTCHA",
"settings.security.enableCaptchaHelp": "Enable CAPTCHA on the public subscription form.",
"settings.security.name": "Security",
"settings.smtp.customHeaders": "Headers customizados", "settings.smtp.customHeaders": "Headers customizados",
"settings.smtp.customHeadersHelp": "Array opcional de headers de email a incluir em todas as mensagens enviadas deste servidor. eg: [{\"X-Custom\": \"value\"}, {\"X-Custom2\": \"value\"}]", "settings.smtp.customHeadersHelp": "Array opcional de headers de email a incluir em todas as mensagens enviadas deste servidor. eg: [{\"X-Custom\": \"value\"}, {\"X-Custom2\": \"value\"}]",
"settings.smtp.enabled": "Ativo", "settings.smtp.enabled": "Ativo",

View file

@ -305,6 +305,7 @@
"public.errorFetchingLists": "Eroare la preluarea listelor. Încearcă din nou.", "public.errorFetchingLists": "Eroare la preluarea listelor. Încearcă din nou.",
"public.errorProcessingRequest": "Eroare la procesarea cererii. Încearcă din nou.", "public.errorProcessingRequest": "Eroare la procesarea cererii. Încearcă din nou.",
"public.errorTitle": "Eroare", "public.errorTitle": "Eroare",
"public.invalidCaptcha": "Invalid CAPTCHA.",
"public.invalidFeature": "Această functie nu este disponibilă", "public.invalidFeature": "Această functie nu este disponibilă",
"public.invalidLink": "Link invalid", "public.invalidLink": "Link invalid",
"public.managePrefs": "Manage preferences", "public.managePrefs": "Manage preferences",
@ -474,6 +475,12 @@
"settings.privacy.listUnsubHeaderHelp": "Include anteturi de dezabonare care permit clienților de e-mail să permită utilizatorilor să se dezaboneze printr-un singur clic.", "settings.privacy.listUnsubHeaderHelp": "Include anteturi de dezabonare care permit clienților de e-mail să permită utilizatorilor să se dezaboneze printr-un singur clic.",
"settings.privacy.name": "Confidențialitate", "settings.privacy.name": "Confidențialitate",
"settings.restart": "Restart", "settings.restart": "Restart",
"settings.security.captchaKey": "hCaptcha.com SiteKey",
"settings.security.captchaKeyHelp": "Visit www.hcaptcha.com to obtain the key and secret.",
"settings.security.captchaSecret": "hCaptcha.com secret",
"settings.security.enableCaptcha": "Enable CAPTCHA",
"settings.security.enableCaptchaHelp": "Enable CAPTCHA on the public subscription form.",
"settings.security.name": "Security",
"settings.smtp.customHeaders": "Anteturi personalizate", "settings.smtp.customHeaders": "Anteturi personalizate",
"settings.smtp.customHeadersHelp": "Matrice opțională de antete de e-mail pentru a include în toate mesajele trimise de pe acest server. de exemplu: [{\"X-Custom\": \"value\"}, {\"X-Custom2\": \"value\"}]", "settings.smtp.customHeadersHelp": "Matrice opțională de antete de e-mail pentru a include în toate mesajele trimise de pe acest server. de exemplu: [{\"X-Custom\": \"value\"}, {\"X-Custom2\": \"value\"}]",
"settings.smtp.enabled": "Activat", "settings.smtp.enabled": "Activat",

View file

@ -304,6 +304,7 @@
"public.errorFetchingLists": "Ошибка получения списков. Пожалуйста, повторите.", "public.errorFetchingLists": "Ошибка получения списков. Пожалуйста, повторите.",
"public.errorProcessingRequest": "Ошибка обработки запроса. Пожалуйста, повторите.", "public.errorProcessingRequest": "Ошибка обработки запроса. Пожалуйста, повторите.",
"public.errorTitle": "Ошибка", "public.errorTitle": "Ошибка",
"public.invalidCaptcha": "Invalid CAPTCHA.",
"public.invalidFeature": "Эта функция недоступна.", "public.invalidFeature": "Эта функция недоступна.",
"public.invalidLink": "Неверная ссылка", "public.invalidLink": "Неверная ссылка",
"public.managePrefs": "Параметры письма", "public.managePrefs": "Параметры письма",
@ -473,6 +474,12 @@
"settings.privacy.listUnsubHeaderHelp": "Включать заголовок отписки", "settings.privacy.listUnsubHeaderHelp": "Включать заголовок отписки",
"settings.privacy.name": "Конфиденциальност", "settings.privacy.name": "Конфиденциальност",
"settings.restart": "Перезапустить", "settings.restart": "Перезапустить",
"settings.security.captchaKey": "hCaptcha.com SiteKey",
"settings.security.captchaKeyHelp": "Visit www.hcaptcha.com to obtain the key and secret.",
"settings.security.captchaSecret": "hCaptcha.com secret",
"settings.security.enableCaptcha": "Enable CAPTCHA",
"settings.security.enableCaptchaHelp": "Enable CAPTCHA on the public subscription form.",
"settings.security.name": "Security",
"settings.smtp.customHeaders": "Настраиваемые заголовки", "settings.smtp.customHeaders": "Настраиваемые заголовки",
"settings.smtp.customHeadersHelp": "Необязательный массив заголовков e-mail, которые будут включены во все письма, отправляемые с этого сервера. Например: [{\"X-Custom\": \"значение\"}, {\"X-Custom2\": \"значение\"}]", "settings.smtp.customHeadersHelp": "Необязательный массив заголовков e-mail, которые будут включены во все письма, отправляемые с этого сервера. Например: [{\"X-Custom\": \"значение\"}, {\"X-Custom2\": \"значение\"}]",
"settings.smtp.enabled": "Включено", "settings.smtp.enabled": "Включено",

View file

@ -304,6 +304,7 @@
"public.errorFetchingLists": "Chyba pri načítání zoznamov. Zopakujte pokus.", "public.errorFetchingLists": "Chyba pri načítání zoznamov. Zopakujte pokus.",
"public.errorProcessingRequest": "Chyba pri spracovaní požiadavky. Zopakujte pokus.", "public.errorProcessingRequest": "Chyba pri spracovaní požiadavky. Zopakujte pokus.",
"public.errorTitle": "Chyba", "public.errorTitle": "Chyba",
"public.invalidCaptcha": "Invalid CAPTCHA.",
"public.invalidFeature": "Táto funkcia nie je k dispozícii.", "public.invalidFeature": "Táto funkcia nie je k dispozícii.",
"public.invalidLink": "Neplatný odkaz", "public.invalidLink": "Neplatný odkaz",
"public.managePrefs": "Správa predvolieb", "public.managePrefs": "Správa predvolieb",
@ -473,6 +474,12 @@
"settings.privacy.listUnsubHeaderHelp": "Nastaví hlavičku zrušenia odberov, ktorá umožňuje e-mailovým klientom, aby povolili používateľom zrušiť odber jedným kliknutím.", "settings.privacy.listUnsubHeaderHelp": "Nastaví hlavičku zrušenia odberov, ktorá umožňuje e-mailovým klientom, aby povolili používateľom zrušiť odber jedným kliknutím.",
"settings.privacy.name": "Súkromie", "settings.privacy.name": "Súkromie",
"settings.restart": "Restarť", "settings.restart": "Restarť",
"settings.security.captchaKey": "hCaptcha.com SiteKey",
"settings.security.captchaKeyHelp": "Visit www.hcaptcha.com to obtain the key and secret.",
"settings.security.captchaSecret": "hCaptcha.com secret",
"settings.security.enableCaptcha": "Enable CAPTCHA",
"settings.security.enableCaptchaHelp": "Enable CAPTCHA on the public subscription form.",
"settings.security.name": "Security",
"settings.smtp.customHeaders": "Vlastné hlavičky", "settings.smtp.customHeaders": "Vlastné hlavičky",
"settings.smtp.customHeadersHelp": "Voliteľné polia e-mailových hlavičiek, ktorá sa majú nastaviť do všetkých správ odoslaných z tohoto servera. Napr.: [{\"X-Custom\": \"value\"}, {\"X-Custom2\": \"value\"}]", "settings.smtp.customHeadersHelp": "Voliteľné polia e-mailových hlavičiek, ktorá sa majú nastaviť do všetkých správ odoslaných z tohoto servera. Napr.: [{\"X-Custom\": \"value\"}, {\"X-Custom2\": \"value\"}]",
"settings.smtp.enabled": "Zapnuté", "settings.smtp.enabled": "Zapnuté",

View file

@ -305,6 +305,7 @@
"public.errorFetchingLists": "Listeleri getirme hatası. Lütfen tekrarla.", "public.errorFetchingLists": "Listeleri getirme hatası. Lütfen tekrarla.",
"public.errorProcessingRequest": "İstek işleme hatası. Lütfen tekrarla.", "public.errorProcessingRequest": "İstek işleme hatası. Lütfen tekrarla.",
"public.errorTitle": "Hata", "public.errorTitle": "Hata",
"public.invalidCaptcha": "Invalid CAPTCHA.",
"public.invalidFeature": "Bu özellik geçerli değil.", "public.invalidFeature": "Bu özellik geçerli değil.",
"public.invalidLink": "Geçersiz link", "public.invalidLink": "Geçersiz link",
"public.managePrefs": "Manage preferences", "public.managePrefs": "Manage preferences",
@ -474,6 +475,12 @@
"settings.privacy.listUnsubHeaderHelp": "E-posta istemcilerinin kullanıcıların tek bir tıklamayla abonelikten çıkmalarına olanak tanıyan abonelik iptal başlıklarını ekleyin.", "settings.privacy.listUnsubHeaderHelp": "E-posta istemcilerinin kullanıcıların tek bir tıklamayla abonelikten çıkmalarına olanak tanıyan abonelik iptal başlıklarını ekleyin.",
"settings.privacy.name": "Gizlilik", "settings.privacy.name": "Gizlilik",
"settings.restart": "Yeniden başlat", "settings.restart": "Yeniden başlat",
"settings.security.captchaKey": "hCaptcha.com SiteKey",
"settings.security.captchaKeyHelp": "Visit www.hcaptcha.com to obtain the key and secret.",
"settings.security.captchaSecret": "hCaptcha.com secret",
"settings.security.enableCaptcha": "Enable CAPTCHA",
"settings.security.enableCaptchaHelp": "Enable CAPTCHA on the public subscription form.",
"settings.security.name": "Security",
"settings.smtp.customHeaders": "Özel başlık bilgisi", "settings.smtp.customHeaders": "Özel başlık bilgisi",
"settings.smtp.customHeadersHelp": "Bu sunucudan gönderilen tüm iletilere eklenecek isteğe bağlı e-posta başlıkları dizisi. Örnek: [{\"X-Custom\": \"value\"}, {\"X-Custom2\": \"value\"}]", "settings.smtp.customHeadersHelp": "Bu sunucudan gönderilen tüm iletilere eklenecek isteğe bağlı e-posta başlıkları dizisi. Örnek: [{\"X-Custom\": \"value\"}, {\"X-Custom2\": \"value\"}]",
"settings.smtp.enabled": "Etkinleştirildi", "settings.smtp.enabled": "Etkinleştirildi",

View file

@ -305,6 +305,7 @@
"public.errorFetchingLists": "Lỗi khi tìm nạp danh sách. Xin hãy thử lại.", "public.errorFetchingLists": "Lỗi khi tìm nạp danh sách. Xin hãy thử lại.",
"public.errorProcessingRequest": "Lỗi khi xử lý yêu cầu. Xin hãy thử lại.", "public.errorProcessingRequest": "Lỗi khi xử lý yêu cầu. Xin hãy thử lại.",
"public.errorTitle": "Lỗi", "public.errorTitle": "Lỗi",
"public.invalidCaptcha": "Invalid CAPTCHA.",
"public.invalidFeature": "Tính năng đó không khả dụng.", "public.invalidFeature": "Tính năng đó không khả dụng.",
"public.invalidLink": "Link không khả dụng", "public.invalidLink": "Link không khả dụng",
"public.managePrefs": "Manage preferences", "public.managePrefs": "Manage preferences",
@ -474,6 +475,12 @@
"settings.privacy.listUnsubHeaderHelp": "Bao gồm các tiêu đề hủy đăng ký cho phép ứng dụng e-mail cho phép người dùng hủy đăng ký chỉ bằng một cú nhấp chuột.", "settings.privacy.listUnsubHeaderHelp": "Bao gồm các tiêu đề hủy đăng ký cho phép ứng dụng e-mail cho phép người dùng hủy đăng ký chỉ bằng một cú nhấp chuột.",
"settings.privacy.name": "Sự riêng tư", "settings.privacy.name": "Sự riêng tư",
"settings.restart": "Khởi động lại", "settings.restart": "Khởi động lại",
"settings.security.captchaKey": "hCaptcha.com SiteKey",
"settings.security.captchaKeyHelp": "Visit www.hcaptcha.com to obtain the key and secret.",
"settings.security.captchaSecret": "hCaptcha.com secret",
"settings.security.enableCaptcha": "Enable CAPTCHA",
"settings.security.enableCaptchaHelp": "Enable CAPTCHA on the public subscription form.",
"settings.security.name": "Security",
"settings.smtp.customHeaders": "Tiêu đề tùy chỉnh", "settings.smtp.customHeaders": "Tiêu đề tùy chỉnh",
"settings.smtp.customHeadersHelp": "Mảng tiêu đề e-mail tùy chọn để bao gồm trong tất cả các thư được gửi từ máy chủ này. ví dụ: [{\"X-Custom\": \"value\"}, {\"X-Custom2\": \"value\"}]", "settings.smtp.customHeadersHelp": "Mảng tiêu đề e-mail tùy chọn để bao gồm trong tất cả các thư được gửi từ máy chủ này. ví dụ: [{\"X-Custom\": \"value\"}, {\"X-Custom2\": \"value\"}]",
"settings.smtp.enabled": "Đã bật", "settings.smtp.enabled": "Đã bật",

View file

@ -304,6 +304,7 @@
"public.errorFetchingLists": "获取列表时出错。请重试。", "public.errorFetchingLists": "获取列表时出错。请重试。",
"public.errorProcessingRequest": "处理请求时出错。请重试。", "public.errorProcessingRequest": "处理请求时出错。请重试。",
"public.errorTitle": "错误", "public.errorTitle": "错误",
"public.invalidCaptcha": "Invalid CAPTCHA.",
"public.invalidFeature": "该功能不可用。", "public.invalidFeature": "该功能不可用。",
"public.invalidLink": "无效的链接", "public.invalidLink": "无效的链接",
"public.managePrefs": "管理偏好设置", "public.managePrefs": "管理偏好设置",
@ -473,6 +474,12 @@
"settings.privacy.listUnsubHeaderHelp": "包括允许电子邮件客户端允许用户通过单击取消订阅的取消订阅标题", "settings.privacy.listUnsubHeaderHelp": "包括允许电子邮件客户端允许用户通过单击取消订阅的取消订阅标题",
"settings.privacy.name": "隐私", "settings.privacy.name": "隐私",
"settings.restart": "重新开始", "settings.restart": "重新开始",
"settings.security.captchaKey": "hCaptcha.com SiteKey",
"settings.security.captchaKeyHelp": "Visit www.hcaptcha.com to obtain the key and secret.",
"settings.security.captchaSecret": "hCaptcha.com secret",
"settings.security.enableCaptcha": "Enable CAPTCHA",
"settings.security.enableCaptchaHelp": "Enable CAPTCHA on the public subscription form.",
"settings.security.name": "Security",
"settings.smtp.customHeaders": "自定义标头", "settings.smtp.customHeaders": "自定义标头",
"settings.smtp.customHeadersHelp": "要包含在从此服务器发送的所有消息中的可选电子邮件标头数组。例如: [{\"X-Custom\": \"value\"}, {\"X-Custom2\": \"value\"}]", "settings.smtp.customHeadersHelp": "要包含在从此服务器发送的所有消息中的可选电子邮件标头数组。例如: [{\"X-Custom\": \"value\"}, {\"X-Custom2\": \"value\"}]",
"settings.smtp.enabled": "已启用", "settings.smtp.enabled": "已启用",

View file

@ -305,6 +305,7 @@
"public.errorFetchingLists": "獲取列表時出錯。請重試。", "public.errorFetchingLists": "獲取列表時出錯。請重試。",
"public.errorProcessingRequest": "處理請求時出錯。請重試。", "public.errorProcessingRequest": "處理請求時出錯。請重試。",
"public.errorTitle": "錯誤", "public.errorTitle": "錯誤",
"public.invalidCaptcha": "Invalid CAPTCHA.",
"public.invalidFeature": "該功能不可用。", "public.invalidFeature": "該功能不可用。",
"public.invalidLink": "無效的鏈接", "public.invalidLink": "無效的鏈接",
"public.managePrefs": "Manage preferences", "public.managePrefs": "Manage preferences",
@ -474,6 +475,12 @@
"settings.privacy.listUnsubHeaderHelp": "包括允許電子郵件客戶端允許用戶通過單擊取消訂閱的取消訂閱標題", "settings.privacy.listUnsubHeaderHelp": "包括允許電子郵件客戶端允許用戶通過單擊取消訂閱的取消訂閱標題",
"settings.privacy.name": "隱私", "settings.privacy.name": "隱私",
"settings.restart": "重新開始", "settings.restart": "重新開始",
"settings.security.captchaKey": "hCaptcha.com SiteKey",
"settings.security.captchaKeyHelp": "Visit www.hcaptcha.com to obtain the key and secret.",
"settings.security.captchaSecret": "hCaptcha.com secret",
"settings.security.enableCaptcha": "Enable CAPTCHA",
"settings.security.enableCaptchaHelp": "Enable CAPTCHA on the public subscription form.",
"settings.security.name": "Security",
"settings.smtp.customHeaders": "自定義標頭", "settings.smtp.customHeaders": "自定義標頭",
"settings.smtp.customHeadersHelp": "要包含在從此服務器發送的所有消息中的可選電子郵件標頭數組。例如: [{\"X-Custom\": \"value\"}, {\"X-Custom2\": \"value\"}]", "settings.smtp.customHeadersHelp": "要包含在從此服務器發送的所有消息中的可選電子郵件標頭數組。例如: [{\"X-Custom\": \"value\"}, {\"X-Custom2\": \"value\"}]",
"settings.smtp.enabled": "已啟用", "settings.smtp.enabled": "已啟用",

View file

@ -0,0 +1,76 @@
package captcha
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"net/url"
"strings"
"time"
)
const (
rootURL = "https://hcaptcha.com/siteverify"
)
type captchaResp struct {
Success bool `json:"success"`
ErrorCodes []string `json:"error_codes"`
}
// Captcha is a simple Captcha client.
// It currently implements hcaptcha.com
type Captcha struct {
o Opt
client *http.Client
}
type Opt struct {
CaptchaSecret string `json:"captcha_secret"`
}
// New returns a new instance of the HTTP CAPTCHA client.
func New(o Opt) *Captcha {
timeout := time.Second * 5
return &Captcha{
o: o,
client: &http.Client{
Timeout: timeout,
Transport: &http.Transport{
MaxIdleConnsPerHost: 10,
MaxConnsPerHost: 100,
ResponseHeaderTimeout: timeout,
IdleConnTimeout: timeout,
},
}}
}
// Verify veries a CAPTCHA request.
func (c *Captcha) Verify(token string) (error, bool) {
resp, err := c.client.PostForm(rootURL, url.Values{
"secret": {c.o.CaptchaSecret},
"response": {token},
})
if err != nil {
return err, false
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return err, false
}
var r captchaResp
if json.Unmarshal(body, &r); err != nil {
return err, true
}
if r.Success != true {
return fmt.Errorf("captcha failed: %s", strings.Join(r.ErrorCodes, ",")), false
}
return nil, true
}

View file

@ -0,0 +1,23 @@
package migrations
import (
"github.com/jmoiron/sqlx"
"github.com/knadh/koanf"
"github.com/knadh/stuffbin"
)
// V2_4_0 performs the DB migrations.
func V2_4_0(db *sqlx.DB, fs stuffbin.FileSystem, ko *koanf.Koanf) error {
// Insert new preference settings.
if _, err := db.Exec(`
INSERT INTO settings (key, value) VALUES
('security.enable_captcha', 'false'),
('security.captcha_key', '""'),
('security.captcha_secret', '""')
ON CONFLICT DO NOTHING;
`); err != nil {
return err
}
return nil
}

View file

@ -32,6 +32,10 @@ type Settings struct {
PrivacyExportable []string `json:"privacy.exportable"` PrivacyExportable []string `json:"privacy.exportable"`
DomainBlocklist []string `json:"privacy.domain_blocklist"` DomainBlocklist []string `json:"privacy.domain_blocklist"`
SecurityEnableCaptcha bool `json:"security.enable_captcha"`
SecurityCaptchaKey string `json:"security.captcha_key"`
SecurityCaptchaSecret string `json:"security.captcha_secret"`
UploadProvider string `json:"upload.provider"` UploadProvider string `json:"upload.provider"`
UploadFilesystemUploadPath string `json:"upload.filesystem.upload_path"` UploadFilesystemUploadPath string `json:"upload.filesystem.upload_path"`
UploadFilesystemUploadURI string `json:"upload.filesystem.upload_uri"` UploadFilesystemUploadURI string `json:"upload.filesystem.upload_uri"`

View file

@ -208,6 +208,9 @@ INSERT INTO settings (key, value) VALUES
('privacy.allow_preferences', 'true'), ('privacy.allow_preferences', 'true'),
('privacy.exportable', '["profile", "subscriptions", "campaign_views", "link_clicks"]'), ('privacy.exportable', '["profile", "subscriptions", "campaign_views", "link_clicks"]'),
('privacy.domain_blocklist', '[]'), ('privacy.domain_blocklist', '[]'),
('security.enable_captcha', 'false'),
('security.captcha_key', '""'),
('security.captcha_secret', '""'),
('upload.provider', '"filesystem"'), ('upload.provider', '"filesystem"'),
('upload.filesystem.upload_path', '"uploads"'), ('upload.filesystem.upload_path', '"uploads"'),
('upload.filesystem.upload_uri', '"/uploads"'), ('upload.filesystem.upload_uri', '"/uploads"'),

View file

@ -122,7 +122,7 @@ input[disabled] {
.lists { .lists {
list-style-type: none; list-style-type: none;
padding: 0; padding: 0;
margin-bottom: 30px; margin: 40px 0;
} }
.lists li { .lists li {
margin: 0 0 5px 0; margin: 0 0 5px 0;
@ -137,6 +137,9 @@ input[disabled] {
.form .nonce { .form .nonce {
display: none; display: none;
} }
.form .captcha {
margin-top: 30px;
}
.archive { .archive {
list-style-type: none; list-style-type: none;

View file

@ -15,7 +15,7 @@
<label for="name">{{ L.T "public.subName" }}</label> <label for="name">{{ L.T "public.subName" }}</label>
<input id="name" name="name" type="text" placeholder="{{ L.T "public.subName" }}" > <input id="name" name="name" type="text" placeholder="{{ L.T "public.subName" }}" >
</p> </p>
<br />
<ul class="lists"> <ul class="lists">
<h2>{{ L.T "globals.terms.lists" }}</h2> <h2>{{ L.T "globals.terms.lists" }}</h2>
{{ range $i, $l := .Data.Lists }} {{ range $i, $l := .Data.Lists }}
@ -28,6 +28,13 @@
</li> </li>
{{ end }} {{ end }}
</ul> </ul>
{{ if .Data.CaptchaKey }}
<div class="captcha">
<div class="h-captcha" data-sitekey="{{ .Data.CaptchaKey }}"></div>
<script src="https://js.hcaptcha.com/1/api.js" async defer></script>
</div>
{{ end }}
<p> <p>
<button type="submit" class="button">{{ L.T "public.sub" }}</button> <button type="submit" class="button">{{ L.T "public.sub" }}</button>