Added API part and tests

This commit is contained in:
Antoine Nguyen
2025-09-05 13:38:57 +02:00
parent 5f2ea34f4e
commit d98db498df
100 changed files with 9675 additions and 977 deletions
+14 -1
View File
@@ -25,7 +25,7 @@ services:
volumes:
- ./docker/mariadb:/var/lib/mysql
profiles: [mariadb]
profiles: [amavis]
rq:
build:
@@ -115,6 +115,19 @@ services:
depends_on:
- api
amavis:
container_name: modoboa_amavis
restart: unless-stopped
build:
context: .
dockerfile: docker/Dockerfile.amavis.dev
profiles: [amavis]
ports:
- 9998:9998
volumes:
- ./docker/amavis_config/amavisd.conf:/etc/amavisd.conf
command: amavisd debug
dovecot:
container_name: modoboa_dovecot
restart: unless-stopped
+24 -4
View File
@@ -7,16 +7,36 @@ export default {
releaseSelection(data) {
return repository.post('/amavis/quarantine/release_selection/', data)
},
releaseMessage(mailid, data) {
return repository.post(`/amavis/quarantine/${mailid}/release/`, data)
},
deleteSelection(data) {
return repository.post('/amavis/quarantine/delete_selection/', data)
},
deleteMessage(mailid, data) {
return repository.post(`/amavis/quarantine/${mailid}/delete/`, data)
},
markMessageSelection(data) {
return repository.post('/amavis/quarantine/mark_selection/', data)
},
getMessageContent(mailid, rcpt) {
return repository.get(`/amavis/quarantine/${mailid}/?rcpt=${rcpt}`)
getMessageContent(mailid, rcpt, secretId) {
const params = { rcpt }
if (secretId) {
params.secret_id = secretId
}
return repository.get(`/amavis/quarantine/${mailid}/`, { params })
},
getMessageHeaders(mailid) {
return repository.get(`/amavis/quarantine/${mailid}/headers/`)
getMessageHeaders(mailid, rcpt, secretId) {
const params = { rcpt }
if (secretId) {
params.secret_id = secretId
}
return repository.get(`/amavis/quarantine/${mailid}/headers/`, { params })
},
getDomainPolicy(domainId) {
return repository.get(`/amavis/policies/${domainId}/`)
},
updateDomainPolicy(domainId, data) {
return repository.patch(`/amavis/policies/${domainId}/`, data)
},
}
+7
View File
@@ -0,0 +1,7 @@
import repository from './repository'
export default {
getNotifications() {
return repository.get('/notifications/')
},
}
@@ -172,7 +172,7 @@
</div>
</template>
<script setup lang="js">
<script setup>
import DomainDNSForm from './form_steps/DomainDNSForm.vue'
import DomainGeneralForm from './form_steps/DomainGeneralForm.vue'
import DomainLimitationsForm from './form_steps/DomainLimitationsForm.vue'
@@ -0,0 +1,117 @@
<template>
<div>
<v-card v-if="policy">
<v-card-title>
<span>{{ $gettext('Content filter') }}</span>
<v-btn
class="ml-2"
icon="mdi-circle-edit-outline"
:title="$gettext('Edit content filter settings')"
variant="text"
density="compact"
@click="showEditForm = true"
></v-btn>
</v-card-title>
<v-card-text>
<v-row>
<v-col cols="6">{{ $gettext('Spam filters') }}</v-col>
<v-col cols="6">
<BooleanIcon
v-if="
policy.bypass_spam_checks !== null &&
policy.bypass_spam_checks !== ''
"
:value="policy.bypass_spam_checks !== 'Y'"
variant="flat"
/>
<span v-else>{{ $gettext('Default value') }}</span>
</v-col>
</v-row>
<v-row>
<v-col cols="6">{{ $gettext('Virus filters') }}</v-col>
<v-col cols="6">
<BooleanIcon
v-if="
policy.bypass_virus_checks !== null &&
policy.bypass_virus_checks !== ''
"
:value="policy.bypass_virus_checks !== 'Y'"
variant="flat"
/>
<span v-else>{{ $gettext('Default value') }}</span>
</v-col>
</v-row>
<v-row>
<v-col cols="6">{{ $gettext('Banned filters') }}</v-col>
<v-col cols="6">
<BooleanIcon
v-if="
policy.bypass_banned_checks !== null &&
policy.bypass_banned_checks !== ''
"
:value="policy.bypass_banned_checks !== 'Y'"
variant="flat"
/>
<span v-else>{{ $gettext('Default value') }}</span>
</v-col>
</v-row>
<v-row>
<v-col cols="6">{{
$gettext('Spam classification threshold')
}}</v-col>
<v-col cols="6">
<span v-if="policy.spam_tag2_level !== null">
{{ policy.spam_tag2_level }}
</span>
<span v-else>{{ $gettext('Default value') }}</span>
</v-col>
</v-row>
<v-row>
<v-col cols="6">{{ $gettext('Rejection threshold') }}</v-col>
<v-col cols="6">
<span v-if="policy.spam_kill_level !== null">
{{ policy.spam_kill_level }}
</span>
<span v-else>{{ $gettext('Default value') }}</span>
</v-col>
</v-row>
<v-row>
<v-col cols="6">{{ $gettext('Spam marker') }}</v-col>
<v-col cols="6">
<span v-if="policy.spam_subject_tag2 !== null">
{{ policy.spam_subject_tag2 }}
</span>
<span v-else>{{ $gettext('Default value') }}</span>
</v-col>
</v-row>
</v-card-text>
</v-card>
<v-dialog v-model="showEditForm" width="1000">
<DomainPolicyForm
v-model="policy"
:domain-id="props.domain.pk"
@close="showEditForm = false"
/>
</v-dialog>
</div>
</template>
<script setup>
import { ref } from 'vue'
import BooleanIcon from '@/components/tools/BooleanIcon'
import DomainPolicyForm from './DomainPolicyForm'
import api from '@/api/amavis'
const props = defineProps({
domain: {
type: Object,
default: null,
},
})
const policy = ref(null)
const showEditForm = ref(false)
const resp = await api.getDomainPolicy(props.domain.pk)
policy.value = resp.data
</script>
@@ -0,0 +1,168 @@
<template>
<v-card>
<v-card-title class="text-h5">
<span> {{ $gettext('Content filter settings') }} </span>
</v-card-title>
<v-card-text>
<v-row>
<v-col cols="6">
<YesNoDefaultField
v-model="form.bypass_virus_checks"
:label="$gettext('Disable virus checks')"
color="primary"
hide-details
/>
<YesNoDefaultField
v-model="form.bypass_spam_checks"
:label="$gettext('Disable spam checks')"
color="primary"
class="mt-6"
hide-details
/>
<YesNoDefaultField
v-model="form.bypass_banned_checks"
:label="$gettext('Disable banned checks')"
color="primary"
class="mt-6"
hide-details
/>
</v-col>
<v-col cols="6">
<div>
<label class="v-label mb-4">{{ $gettext('Spam marker') }}</label>
<v-row>
<v-col cols="9">
<v-text-field
v-model="form.spam_subject_tag2"
variant="outlined"
density="compact"
:disabled="useDefaultMarker"
/>
</v-col>
<v-col cols="3">
<v-checkbox
v-model="useDefaultMarker"
:label="$gettext('default')"
color="primary"
density="compact"
hide-details
@update:model-value="clearSpamMarker"
/>
</v-col>
</v-row>
</div>
<div class="v-label mb-4">{{ $gettext('Thresholds') }}</div>
<v-row class="align-center">
<v-col cols="4">
<v-text-field
v-model="form.spam_tag2_level"
variant="outlined"
density="compact"
type="number"
hide-details
>
</v-text-field>
</v-col>
<v-col cols="8">
{{ $gettext('or more is spam') }}
</v-col>
</v-row>
<v-row class="align-center">
<v-col cols="4">
<v-text-field
v-model="form.spam_kill_level"
variant="outlined"
density="compact"
type="number"
hide-details
>
</v-text-field>
</v-col>
<v-col cols="8">
{{ $gettext('or more throw spam message away') }}
</v-col>
</v-row>
</v-col>
</v-row>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn :loading="loading" @click="emit('close')">
{{ $gettext('Cancel') }}
</v-btn>
<v-btn color="primary" :loading="loading" @click="submit">
{{ $gettext('Apply') }}
</v-btn>
</v-card-actions>
</v-card>
</template>
<script setup>
import { ref } from 'vue'
import YesNoDefaultField from '@/components/tools/YesNoDefaultField'
import api from '@/api/amavis'
const props = defineProps({
domainId: {
type: Number,
default: null,
},
modelValue: {
type: Object,
default: () => {},
},
})
const emit = defineEmits(['close', 'update:modelValue'])
const form = ref({})
const loading = ref(false)
const useDefaultMarker = ref(false)
form.value = {
bypass_virus_checks:
props.modelValue.bypass_virus_checks === null
? ''
: props.modelValue.bypass_virus_checks,
bypass_spam_checks:
props.modelValue.bypass_spam_checks === null
? ''
: props.modelValue.bypass_spam_checks,
bypass_banned_checks:
props.modelValue.bypass_banned_checks === null
? ''
: props.modelValue.bypass_banned_checks,
spam_tag2_level: props.modelValue.spam_tag2_level,
spam_kill_level: props.modelValue.spam_kill_level,
spam_subject_tag2: props.modelValue.spam_subject_tag2,
}
if (form.value.spam_subject_tag2 === null) {
useDefaultMarker.value = true
}
const clearSpamMarker = (value) => {
if (value) {
form.value.spam_subject_tag2 = null
}
}
const submit = async () => {
loading.value = true
const data = { ...form.value }
if (data.spam_tag2_level === '') {
data.spam_tag2_level = null
}
if (data.spam_kill_level === '') {
data.spam_kill_level = null
}
try {
const resp = await api.updateDomainPolicy(props.domainId, data)
emit('update:modelValue', resp.data)
emit('close')
} finally {
loading.value = false
}
}
</script>
@@ -0,0 +1,20 @@
<template>
<v-form ref="vFormRef">
<v-switch
v-model="model.bypass_virus_checks"
:label="$gettext('Bypass virus checks')"
/>
</v-form>
</template>
<script setup>
import { ref } from 'vue'
const model = defineModel()
const vFormRef = ref()
defineExpose({
vFormRef,
})
</script>
@@ -87,6 +87,7 @@
>
</v-btn>
<v-btn
v-if="manualLearningEnabled"
class="ml-2"
size="small"
variant="tonal"
@@ -144,6 +145,14 @@
{{ item.type }}
</v-chip>
</template>
<template #[`item.status`]="{ item }">
<v-icon
v-if="item.status"
:icon="getStatusIcon(item)"
:title="getStatusTitle(item)"
size="small"
/>
</template>
<template #[`item.from_address`]="{ item }">
<span :title="item.from_address">
{{ $truncate(item.from_address, 30) }}
@@ -158,23 +167,42 @@
{{ $date(item.datetime) }}
</template>
</v-data-table-server>
<ConfirmDialog ref="learningRecipientRef">
<v-radio-group v-model="learningDatabase" class="mt-4" hide-details>
<v-radio
v-for="lrcpt in learningRecipients"
:key="lrcpt.value"
:value="lrcpt.value"
:label="lrcpt.title"
>
</v-radio>
</v-radio-group>
</ConfirmDialog>
</v-card>
</template>
<script setup>
import { ref } from 'vue'
import { ref, watch } from 'vue'
import { useGettext } from 'vue3-gettext'
import { useRouter } from 'vue-router'
import { useRoute, useRouter } from 'vue-router'
import debounce from 'debounce'
import { useBusStore } from '@/stores'
import { useAuthStore, useBusStore } from '@/stores'
import { useAmavis } from '@/composables/amavis'
import ConfirmDialog from '@/components/tools/ConfirmDialog'
import api from '@/api/amavis'
import constants from '@/constants'
const { $gettext } = useGettext()
const router = useRouter()
const route = useRoute()
const authStore = useAuthStore()
const { displayNotification } = useBusStore()
const { manualLearningEnabled, learningRecipients } = await useAmavis()
const currentPage = ref(1)
const itemsPerPageR = ref(10)
const learningDatabase = ref(null)
const learningRecipientRef = ref(null)
const loading = ref(false)
const messages = ref([])
const search = ref('')
@@ -199,7 +227,8 @@ const messageTypes = [
]
const headers = [
{ title: '', key: 'type' },
{ title: '', key: 'type', width: '5%' },
{ title: '', key: 'status', width: '5%' },
{ title: $gettext('Score'), key: 'score' },
{ title: $gettext('To'), key: 'to_address' },
{ title: $gettext('From'), key: 'from_address' },
@@ -207,6 +236,13 @@ const headers = [
{ title: $gettext('Date'), key: 'datetime' },
]
watch(
() => route.query.requests,
() => {
fetchContent()
}
)
const getRowProps = ({ item }) => {
return {
class: item.style,
@@ -230,6 +266,32 @@ const getTypeColor = (value) => {
return ''
}
const getStatusIcon = (item) => {
if (item.status === 'R') {
return 'mdi-reply'
}
if (item.status === 'S') {
return 'mdi-thumb-down-outline'
}
if (item.status === 'H') {
return 'mdi-thumb-up-outline'
}
return ''
}
const getStatusTitle = (item) => {
if (item.status === 'R') {
return $gettext('Message released')
}
if (item.status === 'S') {
return $gettext('Message marked as spam')
}
if (item.status === 'H') {
return $gettext('Message marked as non-spam')
}
return ''
}
const updatedOptions = async ({ page, itemsPerPage, sortBy }) => {
currentPage.value = page
itemsPerPageR.value = itemsPerPage
@@ -255,6 +317,9 @@ const _fetchContent = async () => {
if (typeFilter.value !== 'all') {
params.msgtype = typeFilter.value
}
if (route.query?.requests === '1') {
params.viewrequests = 1
}
try {
const resp = await api.getQuarantineContent(params)
messages.value = resp.data.results
@@ -313,9 +378,24 @@ const releaseSelection = async () => {
}
const markSelection = async (mtype) => {
if (
manualLearningEnabled.value &&
authStore.authUser.role !== constants.USER
) {
learningDatabase.value =
authStore.authUser.role === constants.SUPER_ADMIN ? 'global' : 'domain'
await learningRecipientRef.value.open(
$gettext('Learning database'),
$gettext('Which database should be used for this learning:'),
{ width: 600, noconfirm: true }
)
}
loading.value = true
const data = prepareSelectionPayload()
data.type = mtype
if (learningDatabase.value) {
data.database = learningDatabase.value
}
try {
await api.markMessageSelection(data)
displayNotification({ msg: $gettext('Selection is being processed...') })
+2 -19
View File
@@ -49,9 +49,6 @@
:title="item.text"
:prepend-icon="item.icon"
>
<template v-if="item.withBell && displayInformationBell" #append>
<v-icon color="red" icon="mdi-bell-alert-outline" />
</template>
</v-list-item>
<v-list-group v-else :value="item.text">
<template #activator="{ props }">
@@ -92,10 +89,9 @@
<script setup>
import { useRouter } from 'vue-router'
import { ref, computed, onMounted } from 'vue'
import { ref, computed } from 'vue'
import { useLogos } from '@/composables/logos'
import { useGlobalStore, useAuthStore, useLayoutStore } from '@/stores'
import constants from '@/constants.json'
import { useAuthStore, useLayoutStore } from '@/stores'
const props = defineProps({
color: {
@@ -113,7 +109,6 @@ const props = defineProps({
},
})
const globalStore = useGlobalStore()
const authStore = useAuthStore()
const layoutStore = useLayoutStore()
const router = useRouter()
@@ -125,12 +120,6 @@ const drawer = ref(true)
const authUser = computed(() => authStore.authUser)
const isAuthenticated = computed(() => authStore.isAuthenticated)
const displayInformationBell = computed(
() =>
globalStore.notifications.length !== undefined &&
globalStore.notifications.length !== 0
)
function displayMenuItem(item) {
if (isAuthenticated.value) {
const condition =
@@ -142,12 +131,6 @@ function displayMenuItem(item) {
}
return false
}
onMounted(() => {
if (authUser.value.role === constants.SUPER_ADMIN) {
globalStore.fetchNotifications()
}
})
</script>
<style lang="scss" scoped>
+61 -21
View File
@@ -1,28 +1,65 @@
<template>
<div v-if="user" class="top-menu">
<v-menu activator="parent" location="bottom">
<template #activator="{ props }">
<v-btn icon="mdi-apps" flat class="mr-4" v-bind="props"></v-btn>
</template>
<v-card min-width="350" max-width="400" class="pa-4">
<v-row class="justify-center">
<v-col
v-for="application in applications"
:key="application.name"
cols="6"
<v-btn
v-if="globalStore.activeNotifications"
icon
color="error"
class="mr-4"
variant="tonal"
size="small"
>
<v-icon icon="mdi-bell" />
<v-menu activator="parent" location="bottom">
<v-list>
<div class="text-center">
<v-list-item :title="$gettext('Notifications')" />
</div>
<v-divider></v-divider>
<v-list-item
v-for="notif in globalStore.notifications"
:key="notif.id"
:to="notif.url"
>
<v-sheet
rounded
class="application text-center pa-4 text-body-2"
@click="$router.push(application.url)"
<template #prepend>
<v-badge
:color="notif.color"
:content="notif.counter"
inline
></v-badge>
</template>
<v-list-item-title>{{ notif.text }}</v-list-item-title>
</v-list-item>
</v-list>
</v-menu>
</v-btn>
<v-btn icon class="mr-4" variant="flat">
<v-icon icon="mdi-apps" />
<v-menu activator="parent" location="bottom">
<v-card min-width="350" max-width="400" class="pa-4">
<v-row class="justify-center">
<v-col
v-for="application in applications"
:key="application.name"
cols="6"
>
<v-icon color="primary" :icon="application.icon" size="x-large" />
<div class="mt-2">{{ application.label }}</div>
</v-sheet>
</v-col>
</v-row>
</v-card>
</v-menu>
<v-sheet
rounded
class="application text-center pa-4 text-body-2"
@click="$router.push(application.url)"
>
<v-icon
color="primary"
:icon="application.icon"
size="x-large"
/>
<div class="mt-2">{{ application.label }}</div>
</v-sheet>
</v-col>
</v-row>
</v-card>
</v-menu>
</v-btn>
<v-btn icon flat color="primary">
{{ userInitials }}
@@ -60,6 +97,7 @@
import { computed, onMounted, ref } from 'vue'
import { getActivePinia } from 'pinia'
import { useGettext } from 'vue3-gettext'
import { useGlobalStore } from '@/stores'
import accountApi from '@/api/account'
const props = defineProps({
@@ -74,6 +112,7 @@ const props = defineProps({
})
const { $gettext } = useGettext()
const globalStore = useGlobalStore()
const applications = ref([])
@@ -112,6 +151,7 @@ onMounted(() => {
accountApi.getAvailableApplications().then((resp) => {
applications.value = resp.data
})
globalStore.fetchNotifications()
})
</script>
@@ -6,7 +6,7 @@
@keydown.esc="cancel"
>
<v-card>
<v-toolbar :color="options.color" density="compact" flat>
<v-toolbar :color="options.color" density="compact" variant="flat">
<v-toolbar-title class="text-body-2 font-weight-bold">
{{ title }}
</v-toolbar-title>
@@ -28,7 +28,7 @@
</v-dialog>
</template>
<script setup lang="js">
<script setup>
import { ref } from 'vue'
import { useGettext } from 'vue3-gettext'
@@ -0,0 +1,11 @@
<template>
<v-radio-group v-model="model" inline>
<v-radio :label="$gettext('yes')" value="Y" />
<v-radio :label="$gettext('no')" value="N" />
<v-radio :label="$gettext('default')" value="" />
</v-radio-group>
</template>
<script setup>
const model = defineModel()
</script>
+51
View File
@@ -0,0 +1,51 @@
import { computed, ref } from 'vue'
import { useGettext } from 'vue3-gettext'
import { useAuthStore } from '@/stores'
import { usePermissions } from './permissions'
import parametersApi from '@/api/parameters'
import constants from '@/constants.json'
export async function useAmavis() {
const authStore = useAuthStore()
const { $gettext } = useGettext()
const { canViewDomain } = usePermissions()
const globalParams = ref(null)
const manualLearningEnabled = computed(() => {
if (globalParams.value && globalParams.value.params.manual_learning) {
if (authStore.authUser.role !== constants.SUPER_ADMIN) {
if (canViewDomain.value) {
return (
globalParams.value.params.domain_level_learning ||
globalParams.value.params.user_level_learning
)
}
return globalParams.value.params.user_level_learning
}
return true
}
return false
})
const learningRecipients = computed(() => {
const result = []
if (authStore.authUser.role === constants.SUPER_ADMIN) {
result.push({ value: 'global', title: $gettext('Global database') })
}
if (globalParams.value.params.domain_level_learning) {
result.push({ value: 'domain', title: $gettext("Domain's database") })
}
if (globalParams.value.params.user_level_learning) {
result.push({ value: 'user', title: $gettext("User's database") })
}
return result
})
const resp = await parametersApi.getGlobalApplication('amavis')
globalParams.value = resp.data
return {
learningRecipients,
manualLearningEnabled,
}
}
+9
View File
@@ -17,8 +17,17 @@ export function usePermissions() {
)
})
const canViewDomain = computed(() => {
return [
constants.DOMAIN_ADMIN,
constants.RESELLER,
constants.SUPER_ADMIN,
].includes(authStore.authUser.role)
})
return {
canSetRole,
canAddDomain,
canViewDomain,
}
}
+6 -7
View File
@@ -5,14 +5,14 @@
<script setup>
import { ref, computed } from 'vue'
import { useGettext } from 'vue3-gettext'
import { useAuthStore, useParametersStore } from '@/stores'
import { useAuthStore, useGlobalStore, useParametersStore } from '@/stores'
import parametersApi from '@/api/parameters'
import capabilitiesApi from '@/api/capabilities'
import ConnectedLayout from '@/layouts/connected/ConnectedLayout.vue'
import constants from '@/constants.json'
const { $gettext } = useGettext()
const authStore = useAuthStore()
const globalStore = useGlobalStore()
const parametersStore = useParametersStore()
const isRspamdVisible = ref(false)
@@ -145,19 +145,18 @@ if (authUser.value.role === constants.SUPER_ADMIN) {
let response = await parametersApi.getGlobalApplications()
registeredApplications.value = response.data
response = await capabilitiesApi.getCapabilities()
const capabilities = response.data?.capabilities
await globalStore.fetchCapabilities()
if (capabilities.imap_migration) {
if (globalStore.capabilities.imap_migration) {
if (parametersStore.imapMigrationEnabled === null) {
response = await parametersApi.getGlobalApplication('imap_migration')
parametersStore.imapMigrationEnabled =
response.data.params.enabled_imapmigration
}
}
isRspamdVisible.value = 'rspamd' in capabilities
isRspamdVisible.value = 'rspamd' in globalStore.capabilities
if (isRspamdVisible.value) {
rspamdUrl.value = capabilities.rspamd.location || '/rspamd'
rspamdUrl.value = globalStore.capabilities.rspamd.location || '/rspamd'
}
}
</script>
@@ -3,7 +3,9 @@
<slot name="navbar">
<NavBar :color="color" :menu-items="menuItems" />
</slot>
<TopMenu :user="authUser" />
<slot name="topbar">
<TopMenu :user="authUser" />
</slot>
<ConnectedView />
<v-snackbar
v-model="snackbar"
@@ -45,6 +47,10 @@ const props = defineProps({
type: Array,
default: null,
},
loadTheme: {
type: Boolean,
default: true,
},
})
const authUser = computed(() => authStore.authUser)
@@ -62,40 +68,43 @@ busStore.$onAction(({ name, after }) => {
}
}, true)
themeApi.getTheme().then((response) => {
if (
response.data.theme_primary_color !==
theme.themes.value.light.colors.primary
) {
theme.themes.value.light.colors.primary = response.data.theme_primary_color
}
if (
response.data.theme_primary_color_light !==
theme.themes.value.light.colors['primary-lighten-1']
) {
theme.themes.value.light.colors['primary-lighten-1'] =
response.data.theme_primary_color_light
}
if (
response.data.theme_primary_color_dark !==
theme.themes.value.light.colors['primary-darken-1']
) {
theme.themes.value.light.colors['primary-darken-1'] =
response.data.theme_primary_color_dark
}
if (
response.data.theme_secondary_color !==
theme.themes.value.light.colors.secondary
) {
theme.themes.value.light.colors.secondary =
response.data.theme_secondary_color
}
if (
response.data.theme_label_color !== theme.themes.value.light.colors.label
) {
theme.themes.value.light.colors.label = response.data.theme_label_color
}
})
if (props.loadTheme) {
themeApi.getTheme().then((response) => {
if (
response.data.theme_primary_color !==
theme.themes.value.light.colors.primary
) {
theme.themes.value.light.colors.primary =
response.data.theme_primary_color
}
if (
response.data.theme_primary_color_light !==
theme.themes.value.light.colors['primary-lighten-1']
) {
theme.themes.value.light.colors['primary-lighten-1'] =
response.data.theme_primary_color_light
}
if (
response.data.theme_primary_color_dark !==
theme.themes.value.light.colors['primary-darken-1']
) {
theme.themes.value.light.colors['primary-darken-1'] =
response.data.theme_primary_color_dark
}
if (
response.data.theme_secondary_color !==
theme.themes.value.light.colors.secondary
) {
theme.themes.value.light.colors.secondary =
response.data.theme_secondary_color
}
if (
response.data.theme_label_color !== theme.themes.value.light.colors.label
) {
theme.themes.value.light.colors.label = response.data.theme_label_color
}
})
}
</script>
<style>
@@ -0,0 +1,10 @@
<template>
<ConnectedLayout>
<template #navbar>&nbsp;</template>
<template #topbar>&nbsp;</template>
</ConnectedLayout>
</template>
<script setup>
import ConnectedLayout from '@/layouts/connected/ConnectedLayout.vue'
</script>
+236 -6
View File
@@ -62,7 +62,7 @@ msgid "Access rules"
msgstr ""
#: src/components/calendars/CalendarAccessRulesForm.vue:42
#: src/components/shared/TopMenu.vue:93
#: src/components/shared/TopMenu.vue:131
#: src/views/admin/identities/AccountView.vue:4
#: src/views/admin/identities/IdentitiesView.vue:23
msgid "Account"
@@ -340,6 +340,7 @@ msgstr "Kont krouet"
msgid "API token deleted"
msgstr "Deiziad krouidigezh"
#: src/components/admin/domains/DomainPolicyForm.vue:96
#: src/components/tools/ChooseColumnsForm.vue:19
#: src/components/tools/TimeSerieChart.vue:22
msgid "Apply"
@@ -429,6 +430,11 @@ msgstr ""
msgid "Backup codes"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:39
#, fuzzy
msgid "Banned filters"
msgstr "Implij"
#: src/components/webmail/ComposeEmailForm.vue:110
#: src/components/webmail/ComposeEmailForm.vue:73
msgid "Bcc"
@@ -443,6 +449,14 @@ msgstr "Stumm Ereet/anvet"
msgid "Birth date"
msgstr "Deiziad ganedigezh"
#: src/components/quarantine/QuarantineList.vue:54
msgid "both"
msgstr ""
#: src/components/admin/domains/form_steps/DomainPolicyForm.vue:5
msgid "Bypass virus checks"
msgstr ""
#: src/components/calendars/EventForm.vue:49
#: src/views/calendars/CalendarView.vue:3
msgid "Calendar"
@@ -477,6 +491,7 @@ msgstr "Profil hizivaet"
#: src/components/account/FilterForm.vue:147
#: src/components/account/FilterSetForm.vue:24
#: src/components/admin/domains/DomainEditForm.vue:161
#: src/components/admin/domains/DomainPolicyForm.vue:93
#: src/components/admin/identities/AccountEditForm.vue:183
#: src/components/admin/identities/AliasEditForm.vue:69
#: src/components/admin/imap_migration/ProviderForm.vue:58
@@ -569,7 +584,7 @@ msgstr ""
#: src/components/tools/ImportForm.vue:51
#: src/components/webmail/AttachmentsDialog.vue:41
#: src/components/webmail/MailboxForm.vue:29
#: src/layouts/connected/ConnectedLayout.vue:17
#: src/layouts/connected/ConnectedLayout.vue:19
msgid "Close"
msgstr "Serriñ"
@@ -629,6 +644,16 @@ msgstr "Darempredoù"
msgid "Content"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:5
#, fuzzy
msgid "Content filter"
msgstr "Chomlec'h postel"
#: src/components/admin/domains/DomainPolicyForm.vue:4
#, fuzzy
msgid "Content filter settings"
msgstr "Hollek"
#: src/components/tools/ImportForm.vue:40
msgid "Continue on error"
msgstr "Kenderc'hel war ar fazi"
@@ -744,6 +769,7 @@ msgstr "Taolenn-stur"
#: src/components/admin/logs/AuditTrailList.vue:51
#: src/components/admin/logs/MessageList.vue:47
#: src/components/quarantine/QuarantineList.vue:240
msgid "Date"
msgstr ""
@@ -751,6 +777,11 @@ msgstr ""
msgid "Day"
msgstr ""
#: src/components/admin/domains/DomainPolicyForm.vue:47
#: src/components/tools/YesNoDefaultField.vue:15
msgid "default"
msgstr ""
#: src/components/admin/domains/DomainCreationForm.vue:193
#: src/components/admin/domains/DomainSummary.vue:23
#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:19
@@ -765,6 +796,16 @@ msgstr ""
"Kota arloet d'ar boestoù-postel. Gellout a ra bezañ ezpleget e Ko, Mo "
"(diouer) pe Go c'hoazh. Un dalvoudegezh \"0\" a dalvez kota ebet."
#: src/components/admin/domains/DomainPolicy.vue:24
#: src/components/admin/domains/DomainPolicy.vue:35
#: src/components/admin/domains/DomainPolicy.vue:46
#: src/components/admin/domains/DomainPolicy.vue:57
#: src/components/admin/domains/DomainPolicy.vue:68
#: src/components/admin/domains/DomainPolicy.vue:79
#, fuzzy
msgid "Default value"
msgstr "Implijout un dalvoudegezh domani dre-ziouer"
#: src/components/admin/alarms/AlarmList.vue:116
#: src/components/admin/alarms/AlarmList.vue:133
#: src/components/admin/domains/DomainAliasForm.vue:39
@@ -786,6 +827,15 @@ msgstr ""
msgid "Delete filter set"
msgstr ""
#: src/views/quarantine/MessageView.vue:32
#, fuzzy
msgid "Delete message"
msgstr "Implij"
#: src/components/quarantine/QuarantineList.vue:84
msgid "Delete selection"
msgstr ""
#: src/layouts/webmail/WebmailLayout.vue:56
#, fuzzy
msgid "Delete this mailbox"
@@ -822,15 +872,35 @@ msgstr "Lazhet"
msgid "Disable 2FA"
msgstr "Lazhet"
#: src/components/admin/domains/DomainPolicyForm.vue:26
#, fuzzy
msgid "Disable banned checks"
msgstr "Lazhet"
#: src/views/webmail/EmailView.vue:74
#, fuzzy
msgid "Disable links"
msgstr "Lazhet"
#: src/components/admin/domains/DomainPolicyForm.vue:18
#, fuzzy
msgid "Disable spam checks"
msgstr "Enaouiñ ar gwiriañ DNS"
#: src/components/admin/domains/DomainPolicyForm.vue:11
#, fuzzy
msgid "Disable virus checks"
msgstr "Lazhet"
#: src/components/admin/domains/DNSStatusChip.vue:18
msgid "Disabled"
msgstr "Lazhet"
#: src/components/quarantine/QuarantineList.vue:125
#, fuzzy
msgid "Display"
msgstr "Diskouez an anv"
#: src/components/contacts/ContactList.vue:23
msgid "Display address book information"
msgstr ""
@@ -1003,6 +1073,11 @@ msgstr ""
msgid "Domain name (ex: domain.tld)"
msgstr ""
#: src/composables/amavis.js:33
#, fuzzy
msgid "Domain's database"
msgstr "Implijout un dalvoudegezh domani dre-ziouer"
#: src/components/admin/identities/AccountEditForm.vue:82
#, fuzzy
msgid "domain's default value"
@@ -1060,6 +1135,10 @@ msgstr "Chomlec'h postel"
msgid "Edit contact"
msgstr "Aozañ an darempred"
#: src/components/admin/domains/DomainPolicy.vue:9
msgid "Edit content filter settings"
msgstr ""
#: src/views/admin/domains/DomainEditView.vue:3
msgid "Edit domain"
msgstr ""
@@ -1315,11 +1394,17 @@ msgstr ""
#: src/components/account/AutoReplyForm.vue:36
#: src/components/admin/logs/MessageList.vue:50
#: src/components/calendars/EventForm.vue:24
#: src/components/quarantine/QuarantineList.vue:238
#: src/components/tools/TimeSerieChart.vue:19
#: src/components/webmail/ComposeEmailForm.vue:29
msgid "From"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:45
#, fuzzy
msgid "From address"
msgstr "Chomlec'h dre-zegouezh"
#: src/components/calendars/CalendarAccessRulesForm.vue:11
#, fuzzy
msgid "Full address"
@@ -1374,6 +1459,10 @@ msgstr ""
msgid "Generated address"
msgstr "Chomlec'hioù ar c'haser"
#: src/composables/amavis.js:30
msgid "Global database"
msgstr ""
#: src/views/admin/InformationView.vue:29
msgid "Go to <strong>Settings > General</strong> section"
msgstr ""
@@ -1389,6 +1478,10 @@ msgid ""
"between [ ] by the appropriate ones."
msgstr ""
#: src/views/quarantine/MessageView.vue:65
msgid "Hide full headers"
msgstr ""
#: src/components/admin/identities/AccountCreationForm.vue:168
#: src/components/admin/identities/AccountCreationForm.vue:95
#: src/components/admin/identities/AccountEditForm.vue:31
@@ -1556,6 +1649,12 @@ msgstr "Stumm staliet"
msgid "Latest version"
msgstr "Stumm staliet"
#: src/components/quarantine/QuarantineList.vue:385
#: src/views/quarantine/MessageView.vue:209
#, fuzzy
msgid "Learning database"
msgstr "Deiziad krouidigezh"
#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:26
msgid "Leave empty for no limit"
msgstr ""
@@ -1583,7 +1682,7 @@ msgstr ""
msgid "Logger"
msgstr "Enroller"
#: src/components/shared/TopMenu.vue:100
#: src/components/shared/TopMenu.vue:138
msgid "Logout"
msgstr "Digevreañ"
@@ -1631,10 +1730,23 @@ msgstr ""
msgid "Mark as followed"
msgstr ""
#: src/views/quarantine/MessageView.vue:47
msgid "Mark as non-spam"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:105
msgid "Mark as not spam"
msgstr ""
#: src/components/webmail/EmailList.vue:62
msgid "Mark as read"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:101
#: src/views/quarantine/MessageView.vue:43
msgid "Mark as spam"
msgstr ""
#: src/components/webmail/EmailList.vue:77
msgid "Mark as unfollowed"
msgstr ""
@@ -1653,7 +1765,7 @@ msgstr ""
msgid "Message"
msgstr "Implij"
#: src/views/webmail/EmailView.vue:254
#: src/views/quarantine/MessageView.vue:196 src/views/webmail/EmailView.vue:254
#, fuzzy
msgid "Message deleted"
msgstr "Implij"
@@ -1677,10 +1789,26 @@ msgstr "Implij"
msgid "Message marked as junk"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:291
#: src/views/quarantine/MessageView.vue:236
msgid "Message marked as non-spam"
msgstr ""
#: src/views/webmail/EmailView.vue:282
msgid "Message marked as not junk"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:288
#: src/views/quarantine/MessageView.vue:232
msgid "Message marked as spam"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:285
#: src/views/quarantine/MessageView.vue:178
#, fuzzy
msgid "Message released"
msgstr "Implij"
#: src/components/admin/domains/DomainCreationForm.vue:197
#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:32
#: src/components/admin/identities/AccountCreationForm.vue:133
@@ -1875,7 +2003,7 @@ msgstr ""
msgid "Next"
msgstr "Da-heul"
#: src/plugins/filters.js:10
#: src/components/tools/YesNoDefaultField.vue:11 src/plugins/filters.js:10
msgid "no"
msgstr ""
@@ -1942,6 +2070,11 @@ msgstr "Neket ganet"
msgid "Note"
msgstr "Notenn"
#: src/components/shared/TopMenu.vue:18
#, fuzzy
msgid "Notifications"
msgstr "Deiziad aozañ diwezhañ"
#: src/components/admin/identities/AccountEditForm.vue:163
#, fuzzy
msgid "Number of allowed mailbox aliases:"
@@ -2005,6 +2138,14 @@ msgstr ""
msgid "Options"
msgstr "Dibarzhioù"
#: src/components/admin/domains/DomainPolicyForm.vue:69
msgid "or more is spam"
msgstr ""
#: src/components/admin/domains/DomainPolicyForm.vue:84
msgid "or more throw spam message away"
msgstr ""
#: src/components/account/ProfileForm.vue:30
msgid "or suggest a new language"
msgstr ""
@@ -2158,6 +2299,15 @@ msgstr "Profil hizivaet"
msgid "Providers"
msgstr "Chomlec'h postel"
#: src/views/quarantine/QuarantineView.vue:4
msgid "Quarantine"
msgstr ""
#: src/views/quarantine/MessageView.vue:4
#, fuzzy
msgid "Quarantined message"
msgstr "Emporzhiañ domanioù"
#: src/components/admin/logs/MessageList.vue:46
msgid "Queue ID"
msgstr ""
@@ -2249,6 +2399,10 @@ msgstr "O vezañ anavezet"
msgid "Registered Webauthn devices"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:61
msgid "Rejection threshold"
msgstr ""
#: src/components/tools/TimeSerieChart.vue:27
msgid "Relative time ranges"
msgstr ""
@@ -2262,6 +2416,24 @@ msgstr ""
msgid "Relay domain"
msgstr "Domani nevez"
#: src/views/quarantine/MessageView.vue:21
#, fuzzy
msgid "Release message"
msgstr "Implij"
#: src/components/quarantine/QuarantineList.vue:372
#: src/views/quarantine/MessageView.vue:176
msgid "Release request sent"
msgstr ""
#: src/views/quarantine/QuarantineView.vue:12
msgid "release requests"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:72
msgid "Release selection"
msgstr ""
#: src/components/admin/alarms/AlarmList.vue:123
msgid "Reload"
msgstr ""
@@ -2335,6 +2507,10 @@ msgstr "Enrollañ"
msgid "Save your changes"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:236
msgid "Score"
msgstr ""
#: src/components/admin/alarms/AlarmList.vue:21
#: src/components/admin/domains/DomainList.vue:19
#: src/components/admin/identities/IdentityList.vue:24
@@ -2345,6 +2521,7 @@ msgstr ""
msgid "Search"
msgstr "Klask"
#: src/components/quarantine/QuarantineList.vue:27
#: src/components/webmail/EmailList.vue:14
#, fuzzy
msgid "Search in messages"
@@ -2382,6 +2559,19 @@ msgstr ""
msgid "Select file"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:359
#, fuzzy
msgid "Selection deleted"
msgstr "Deiziad krouidigezh"
#: src/components/quarantine/QuarantineList.vue:398
msgid "Selection is being processed..."
msgstr ""
#: src/components/quarantine/QuarantineList.vue:374
msgid "Selection released"
msgstr ""
#: src/components/calendars/ImportEventsForm.vue:30
#: src/components/webmail/ComposeEmailForm.vue:13
#, fuzzy
@@ -2458,6 +2648,20 @@ msgstr "Diskouez an alc'hwez"
msgid "Simple user"
msgstr "Implijer diazez"
#: src/components/admin/domains/DomainPolicy.vue:50
msgid "Spam classification threshold"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:17
#, fuzzy
msgid "Spam filters"
msgstr "Implij"
#: src/components/admin/domains/DomainPolicy.vue:72
#: src/components/admin/domains/DomainPolicyForm.vue:34
msgid "Spam marker"
msgstr ""
#: src/components/admin/identities/AccountSenderAddresses.vue:17
msgid "Specify an email address"
msgstr ""
@@ -2493,6 +2697,8 @@ msgid "Status"
msgstr "Statud"
#: src/components/account/AutoReplyForm.vue:12
#: src/components/quarantine/QuarantineList.vue:239
#: src/components/quarantine/QuarantineList.vue:49
#: src/components/webmail/ComposeEmailForm.vue:137
msgid "Subject"
msgstr ""
@@ -2558,12 +2764,18 @@ msgstr ""
msgid "there"
msgstr ""
#: src/components/admin/domains/DomainPolicyForm.vue:56
msgid "Thresholds"
msgstr ""
#: src/components/calendars/EventForm.vue:12
msgid "Title"
msgstr ""
#: src/components/admin/logs/MessageList.vue:49
#: src/components/calendars/EventForm.vue:34
#: src/components/quarantine/QuarantineList.vue:237
#: src/components/quarantine/QuarantineList.vue:52
#: src/components/tools/TimeSerieChart.vue:20
#: src/components/webmail/ComposeEmailForm.vue:46
#: src/views/webmail/EmailView.vue:109
@@ -2710,6 +2922,10 @@ msgstr "Kont nevez"
msgid "Use domain default value"
msgstr "Implijout un dalvoudegezh domani dre-ziouer"
#: src/composables/amavis.js:36
msgid "User's database"
msgstr ""
#: src/components/admin/domains/DomainAdminList.vue:111
#: src/components/admin/identities/AccountCreationForm.vue:97
#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:3
@@ -2729,6 +2945,15 @@ msgstr ""
msgid "Value"
msgstr ""
#: src/views/quarantine/MessageView.vue:62
msgid "View full headers"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:28
#, fuzzy
msgid "Virus filters"
msgstr "Chomlec'h postel"
#: src/components/admin/dashboard/NewsFeedWidget.vue:21
msgid "Visit the official weblog for more information"
msgstr ""
@@ -2770,6 +2995,11 @@ msgstr ""
msgid "Welcome to Modoboa"
msgstr "Degemer mat e-barzh Modoboa"
#: src/components/quarantine/QuarantineList.vue:386
#: src/views/quarantine/MessageView.vue:210
msgid "Which database should be used for this learning:"
msgstr ""
#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:25
msgid "With a mailbox"
msgstr "Gant ur voest-posteloù"
@@ -2787,7 +3017,7 @@ msgstr ""
msgid "Year"
msgstr ""
#: src/plugins/filters.js:10
#: src/components/tools/YesNoDefaultField.vue:7 src/plugins/filters.js:10
msgid "yes"
msgstr ""
+217 -6
View File
@@ -64,7 +64,7 @@ msgid "Access rules"
msgstr ""
#: src/components/calendars/CalendarAccessRulesForm.vue:42
#: src/components/shared/TopMenu.vue:93
#: src/components/shared/TopMenu.vue:131
#: src/views/admin/identities/AccountView.vue:4
#: src/views/admin/identities/IdentitiesView.vue:23
msgid "Account"
@@ -324,6 +324,7 @@ msgstr ""
msgid "API token deleted"
msgstr ""
#: src/components/admin/domains/DomainPolicyForm.vue:96
#: src/components/tools/ChooseColumnsForm.vue:19
#: src/components/tools/TimeSerieChart.vue:22
msgid "Apply"
@@ -411,6 +412,10 @@ msgstr ""
msgid "Backup codes"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:39
msgid "Banned filters"
msgstr ""
#: src/components/webmail/ComposeEmailForm.vue:110
#: src/components/webmail/ComposeEmailForm.vue:73
msgid "Bcc"
@@ -424,6 +429,14 @@ msgstr ""
msgid "Birth date"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:54
msgid "both"
msgstr ""
#: src/components/admin/domains/form_steps/DomainPolicyForm.vue:5
msgid "Bypass virus checks"
msgstr ""
#: src/components/calendars/EventForm.vue:49
#: src/views/calendars/CalendarView.vue:3
msgid "Calendar"
@@ -454,6 +467,7 @@ msgstr ""
#: src/components/account/FilterForm.vue:147
#: src/components/account/FilterSetForm.vue:24
#: src/components/admin/domains/DomainEditForm.vue:161
#: src/components/admin/domains/DomainPolicyForm.vue:93
#: src/components/admin/identities/AccountEditForm.vue:183
#: src/components/admin/identities/AliasEditForm.vue:69
#: src/components/admin/imap_migration/ProviderForm.vue:58
@@ -542,7 +556,7 @@ msgstr ""
#: src/components/tools/ImportForm.vue:51
#: src/components/webmail/AttachmentsDialog.vue:41
#: src/components/webmail/MailboxForm.vue:29
#: src/layouts/connected/ConnectedLayout.vue:17
#: src/layouts/connected/ConnectedLayout.vue:19
msgid "Close"
msgstr ""
@@ -600,6 +614,14 @@ msgstr ""
msgid "Content"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:5
msgid "Content filter"
msgstr ""
#: src/components/admin/domains/DomainPolicyForm.vue:4
msgid "Content filter settings"
msgstr ""
#: src/components/tools/ImportForm.vue:40
msgid "Continue on error"
msgstr ""
@@ -710,6 +732,7 @@ msgstr ""
#: src/components/admin/logs/AuditTrailList.vue:51
#: src/components/admin/logs/MessageList.vue:47
#: src/components/quarantine/QuarantineList.vue:240
msgid "Date"
msgstr ""
@@ -717,6 +740,11 @@ msgstr ""
msgid "Day"
msgstr ""
#: src/components/admin/domains/DomainPolicyForm.vue:47
#: src/components/tools/YesNoDefaultField.vue:15
msgid "default"
msgstr ""
#: src/components/admin/domains/DomainCreationForm.vue:193
#: src/components/admin/domains/DomainSummary.vue:23
#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:19
@@ -729,6 +757,15 @@ msgid ""
"GB. A value of 0 means no quota."
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:24
#: src/components/admin/domains/DomainPolicy.vue:35
#: src/components/admin/domains/DomainPolicy.vue:46
#: src/components/admin/domains/DomainPolicy.vue:57
#: src/components/admin/domains/DomainPolicy.vue:68
#: src/components/admin/domains/DomainPolicy.vue:79
msgid "Default value"
msgstr ""
#: src/components/admin/alarms/AlarmList.vue:116
#: src/components/admin/alarms/AlarmList.vue:133
#: src/components/admin/domains/DomainAliasForm.vue:39
@@ -750,6 +787,14 @@ msgstr ""
msgid "Delete filter set"
msgstr ""
#: src/views/quarantine/MessageView.vue:32
msgid "Delete message"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:84
msgid "Delete selection"
msgstr ""
#: src/layouts/webmail/WebmailLayout.vue:56
msgid "Delete this mailbox"
msgstr ""
@@ -783,14 +828,30 @@ msgstr ""
msgid "Disable 2FA"
msgstr ""
#: src/components/admin/domains/DomainPolicyForm.vue:26
msgid "Disable banned checks"
msgstr ""
#: src/views/webmail/EmailView.vue:74
msgid "Disable links"
msgstr ""
#: src/components/admin/domains/DomainPolicyForm.vue:18
msgid "Disable spam checks"
msgstr ""
#: src/components/admin/domains/DomainPolicyForm.vue:11
msgid "Disable virus checks"
msgstr ""
#: src/components/admin/domains/DNSStatusChip.vue:18
msgid "Disabled"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:125
msgid "Display"
msgstr ""
#: src/components/contacts/ContactList.vue:23
msgid "Display address book information"
msgstr ""
@@ -959,6 +1020,10 @@ msgstr ""
msgid "Domain name (ex: domain.tld)"
msgstr ""
#: src/composables/amavis.js:33
msgid "Domain's database"
msgstr ""
#: src/components/admin/identities/AccountEditForm.vue:82
msgid "domain's default value"
msgstr ""
@@ -1010,6 +1075,10 @@ msgstr ""
msgid "Edit contact"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:9
msgid "Edit content filter settings"
msgstr ""
#: src/views/admin/domains/DomainEditView.vue:3
msgid "Edit domain"
msgstr ""
@@ -1242,11 +1311,16 @@ msgstr ""
#: src/components/account/AutoReplyForm.vue:36
#: src/components/admin/logs/MessageList.vue:50
#: src/components/calendars/EventForm.vue:24
#: src/components/quarantine/QuarantineList.vue:238
#: src/components/tools/TimeSerieChart.vue:19
#: src/components/webmail/ComposeEmailForm.vue:29
msgid "From"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:45
msgid "From address"
msgstr ""
#: src/components/calendars/CalendarAccessRulesForm.vue:11
msgid "Full address"
msgstr ""
@@ -1296,6 +1370,10 @@ msgstr ""
msgid "Generated address"
msgstr ""
#: src/composables/amavis.js:30
msgid "Global database"
msgstr ""
#: src/views/admin/InformationView.vue:29
msgid "Go to <strong>Settings > General</strong> section"
msgstr ""
@@ -1311,6 +1389,10 @@ msgid ""
"between [ ] by the appropriate ones."
msgstr ""
#: src/views/quarantine/MessageView.vue:65
msgid "Hide full headers"
msgstr ""
#: src/components/admin/identities/AccountCreationForm.vue:168
#: src/components/admin/identities/AccountCreationForm.vue:95
#: src/components/admin/identities/AccountEditForm.vue:31
@@ -1469,6 +1551,11 @@ msgstr ""
msgid "Latest version"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:385
#: src/views/quarantine/MessageView.vue:209
msgid "Learning database"
msgstr ""
#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:26
msgid "Leave empty for no limit"
msgstr ""
@@ -1496,7 +1583,7 @@ msgstr ""
msgid "Logger"
msgstr ""
#: src/components/shared/TopMenu.vue:100
#: src/components/shared/TopMenu.vue:138
msgid "Logout"
msgstr ""
@@ -1540,10 +1627,23 @@ msgstr ""
msgid "Mark as followed"
msgstr ""
#: src/views/quarantine/MessageView.vue:47
msgid "Mark as non-spam"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:105
msgid "Mark as not spam"
msgstr ""
#: src/components/webmail/EmailList.vue:62
msgid "Mark as read"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:101
#: src/views/quarantine/MessageView.vue:43
msgid "Mark as spam"
msgstr ""
#: src/components/webmail/EmailList.vue:77
msgid "Mark as unfollowed"
msgstr ""
@@ -1562,7 +1662,7 @@ msgstr ""
msgid "Message"
msgstr ""
#: src/views/webmail/EmailView.vue:254
#: src/views/quarantine/MessageView.vue:196 src/views/webmail/EmailView.vue:254
msgid "Message deleted"
msgstr ""
@@ -1582,10 +1682,25 @@ msgstr ""
msgid "Message marked as junk"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:291
#: src/views/quarantine/MessageView.vue:236
msgid "Message marked as non-spam"
msgstr ""
#: src/views/webmail/EmailView.vue:282
msgid "Message marked as not junk"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:288
#: src/views/quarantine/MessageView.vue:232
msgid "Message marked as spam"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:285
#: src/views/quarantine/MessageView.vue:178
msgid "Message released"
msgstr ""
#: src/components/admin/domains/DomainCreationForm.vue:197
#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:32
#: src/components/admin/identities/AccountCreationForm.vue:133
@@ -1768,7 +1883,7 @@ msgstr ""
msgid "Next"
msgstr ""
#: src/plugins/filters.js:10
#: src/components/tools/YesNoDefaultField.vue:11 src/plugins/filters.js:10
msgid "no"
msgstr ""
@@ -1832,6 +1947,10 @@ msgstr ""
msgid "Note"
msgstr ""
#: src/components/shared/TopMenu.vue:18
msgid "Notifications"
msgstr ""
#: src/components/admin/identities/AccountEditForm.vue:163
msgid "Number of allowed mailbox aliases:"
msgstr ""
@@ -1891,6 +2010,14 @@ msgstr ""
msgid "Options"
msgstr ""
#: src/components/admin/domains/DomainPolicyForm.vue:69
msgid "or more is spam"
msgstr ""
#: src/components/admin/domains/DomainPolicyForm.vue:84
msgid "or more throw spam message away"
msgstr ""
#: src/components/account/ProfileForm.vue:30
msgid "or suggest a new language"
msgstr ""
@@ -2032,6 +2159,14 @@ msgstr ""
msgid "Providers"
msgstr ""
#: src/views/quarantine/QuarantineView.vue:4
msgid "Quarantine"
msgstr ""
#: src/views/quarantine/MessageView.vue:4
msgid "Quarantined message"
msgstr ""
#: src/components/admin/logs/MessageList.vue:46
msgid "Queue ID"
msgstr ""
@@ -2115,6 +2250,10 @@ msgstr ""
msgid "Registered Webauthn devices"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:61
msgid "Rejection threshold"
msgstr ""
#: src/components/tools/TimeSerieChart.vue:27
msgid "Relative time ranges"
msgstr ""
@@ -2127,6 +2266,23 @@ msgstr ""
msgid "Relay domain"
msgstr ""
#: src/views/quarantine/MessageView.vue:21
msgid "Release message"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:372
#: src/views/quarantine/MessageView.vue:176
msgid "Release request sent"
msgstr ""
#: src/views/quarantine/QuarantineView.vue:12
msgid "release requests"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:72
msgid "Release selection"
msgstr ""
#: src/components/admin/alarms/AlarmList.vue:123
msgid "Reload"
msgstr ""
@@ -2199,6 +2355,10 @@ msgstr ""
msgid "Save your changes"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:236
msgid "Score"
msgstr ""
#: src/components/admin/alarms/AlarmList.vue:21
#: src/components/admin/domains/DomainList.vue:19
#: src/components/admin/identities/IdentityList.vue:24
@@ -2209,6 +2369,7 @@ msgstr ""
msgid "Search"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:27
#: src/components/webmail/EmailList.vue:14
msgid "Search in messages"
msgstr ""
@@ -2245,6 +2406,18 @@ msgstr ""
msgid "Select file"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:359
msgid "Selection deleted"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:398
msgid "Selection is being processed..."
msgstr ""
#: src/components/quarantine/QuarantineList.vue:374
msgid "Selection released"
msgstr ""
#: src/components/calendars/ImportEventsForm.vue:30
#: src/components/webmail/ComposeEmailForm.vue:13
msgid "Send"
@@ -2316,6 +2489,19 @@ msgstr ""
msgid "Simple user"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:50
msgid "Spam classification threshold"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:17
msgid "Spam filters"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:72
#: src/components/admin/domains/DomainPolicyForm.vue:34
msgid "Spam marker"
msgstr ""
#: src/components/admin/identities/AccountSenderAddresses.vue:17
msgid "Specify an email address"
msgstr ""
@@ -2350,6 +2536,8 @@ msgid "Status"
msgstr ""
#: src/components/account/AutoReplyForm.vue:12
#: src/components/quarantine/QuarantineList.vue:239
#: src/components/quarantine/QuarantineList.vue:49
#: src/components/webmail/ComposeEmailForm.vue:137
msgid "Subject"
msgstr ""
@@ -2413,12 +2601,18 @@ msgstr ""
msgid "there"
msgstr ""
#: src/components/admin/domains/DomainPolicyForm.vue:56
msgid "Thresholds"
msgstr ""
#: src/components/calendars/EventForm.vue:12
msgid "Title"
msgstr ""
#: src/components/admin/logs/MessageList.vue:49
#: src/components/calendars/EventForm.vue:34
#: src/components/quarantine/QuarantineList.vue:237
#: src/components/quarantine/QuarantineList.vue:52
#: src/components/tools/TimeSerieChart.vue:20
#: src/components/webmail/ComposeEmailForm.vue:46
#: src/views/webmail/EmailView.vue:109
@@ -2553,6 +2747,10 @@ msgstr ""
msgid "Use domain default value"
msgstr ""
#: src/composables/amavis.js:36
msgid "User's database"
msgstr ""
#: src/components/admin/domains/DomainAdminList.vue:111
#: src/components/admin/identities/AccountCreationForm.vue:97
#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:3
@@ -2571,6 +2769,14 @@ msgstr ""
msgid "Value"
msgstr ""
#: src/views/quarantine/MessageView.vue:62
msgid "View full headers"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:28
msgid "Virus filters"
msgstr ""
#: src/components/admin/dashboard/NewsFeedWidget.vue:21
msgid "Visit the official weblog for more information"
msgstr ""
@@ -2611,6 +2817,11 @@ msgstr ""
msgid "Welcome to Modoboa"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:386
#: src/views/quarantine/MessageView.vue:210
msgid "Which database should be used for this learning:"
msgstr ""
#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:25
msgid "With a mailbox"
msgstr ""
@@ -2628,7 +2839,7 @@ msgstr ""
msgid "Year"
msgstr ""
#: src/plugins/filters.js:10
#: src/components/tools/YesNoDefaultField.vue:7 src/plugins/filters.js:10
msgid "yes"
msgstr ""
+236 -6
View File
@@ -79,7 +79,7 @@ msgid "Access rules"
msgstr "Zugriffsregeln"
#: src/components/calendars/CalendarAccessRulesForm.vue:42
#: src/components/shared/TopMenu.vue:93
#: src/components/shared/TopMenu.vue:131
#: src/views/admin/identities/AccountView.vue:4
#: src/views/admin/identities/IdentitiesView.vue:23
msgid "Account"
@@ -344,6 +344,7 @@ msgstr "API-Token erstellt"
msgid "API token deleted"
msgstr "API-Token gelöscht"
#: src/components/admin/domains/DomainPolicyForm.vue:96
#: src/components/tools/ChooseColumnsForm.vue:19
#: src/components/tools/TimeSerieChart.vue:22
msgid "Apply"
@@ -431,6 +432,11 @@ msgstr "Zurück"
msgid "Backup codes"
msgstr "Backupcodes"
#: src/components/admin/domains/DomainPolicy.vue:39
#, fuzzy
msgid "Banned filters"
msgstr "Verwendung"
#: src/components/webmail/ComposeEmailForm.vue:110
#: src/components/webmail/ComposeEmailForm.vue:73
msgid "Bcc"
@@ -444,6 +450,14 @@ msgstr "Gebundenes Format"
msgid "Birth date"
msgstr "Geburtsdatum"
#: src/components/quarantine/QuarantineList.vue:54
msgid "both"
msgstr ""
#: src/components/admin/domains/form_steps/DomainPolicyForm.vue:5
msgid "Bypass virus checks"
msgstr ""
#: src/components/calendars/EventForm.vue:49
#: src/views/calendars/CalendarView.vue:3
msgid "Calendar"
@@ -474,6 +488,7 @@ msgstr "Kalender aktualisiert"
#: src/components/account/FilterForm.vue:147
#: src/components/account/FilterSetForm.vue:24
#: src/components/admin/domains/DomainEditForm.vue:161
#: src/components/admin/domains/DomainPolicyForm.vue:93
#: src/components/admin/identities/AccountEditForm.vue:183
#: src/components/admin/identities/AliasEditForm.vue:69
#: src/components/admin/imap_migration/ProviderForm.vue:58
@@ -562,7 +577,7 @@ msgstr "Hier klicken, zum Schlüssel kopieren"
#: src/components/tools/ImportForm.vue:51
#: src/components/webmail/AttachmentsDialog.vue:41
#: src/components/webmail/MailboxForm.vue:29
#: src/layouts/connected/ConnectedLayout.vue:17
#: src/layouts/connected/ConnectedLayout.vue:19
msgid "Close"
msgstr "Schließen"
@@ -622,6 +637,16 @@ msgstr "Kontakte"
msgid "Content"
msgstr "Inhalt"
#: src/components/admin/domains/DomainPolicy.vue:5
#, fuzzy
msgid "Content filter"
msgstr "Neue Wiederherstellungscodes"
#: src/components/admin/domains/DomainPolicyForm.vue:4
#, fuzzy
msgid "Content filter settings"
msgstr "Allgemein"
#: src/components/tools/ImportForm.vue:40
msgid "Continue on error"
msgstr "Bei Fehler fortfahren"
@@ -732,6 +757,7 @@ msgstr "Dashboard"
#: src/components/admin/logs/AuditTrailList.vue:51
#: src/components/admin/logs/MessageList.vue:47
#: src/components/quarantine/QuarantineList.vue:240
msgid "Date"
msgstr "Datum"
@@ -739,6 +765,11 @@ msgstr "Datum"
msgid "Day"
msgstr "Tag"
#: src/components/admin/domains/DomainPolicyForm.vue:47
#: src/components/tools/YesNoDefaultField.vue:15
msgid "default"
msgstr ""
#: src/components/admin/domains/DomainCreationForm.vue:193
#: src/components/admin/domains/DomainSummary.vue:23
#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:19
@@ -753,6 +784,16 @@ msgstr ""
"Auf Postfächer angewendete Quota. Kann in KB, MB (Voreinstellung) oder GB "
"angegeben werden. 0 eingeben, um keine Quota zu verwenden."
#: src/components/admin/domains/DomainPolicy.vue:24
#: src/components/admin/domains/DomainPolicy.vue:35
#: src/components/admin/domains/DomainPolicy.vue:46
#: src/components/admin/domains/DomainPolicy.vue:57
#: src/components/admin/domains/DomainPolicy.vue:68
#: src/components/admin/domains/DomainPolicy.vue:79
#, fuzzy
msgid "Default value"
msgstr "Standardwert der Domain verwenden"
#: src/components/admin/alarms/AlarmList.vue:116
#: src/components/admin/alarms/AlarmList.vue:133
#: src/components/admin/domains/DomainAliasForm.vue:39
@@ -774,6 +815,15 @@ msgstr "Löschen"
msgid "Delete filter set"
msgstr "Filterset löschen"
#: src/views/quarantine/MessageView.vue:32
#, fuzzy
msgid "Delete message"
msgstr "Verwendung"
#: src/components/quarantine/QuarantineList.vue:84
msgid "Delete selection"
msgstr ""
#: src/layouts/webmail/WebmailLayout.vue:56
msgid "Delete this mailbox"
msgstr "Dieses Postfach löschen"
@@ -807,14 +857,34 @@ msgstr "Deaktivieren"
msgid "Disable 2FA"
msgstr "Deaktiviere 2-Faktor-Authentifizierung"
#: src/components/admin/domains/DomainPolicyForm.vue:26
#, fuzzy
msgid "Disable banned checks"
msgstr "Deaktiviert"
#: src/views/webmail/EmailView.vue:74
msgid "Disable links"
msgstr "Links deaktivieren"
#: src/components/admin/domains/DomainPolicyForm.vue:18
#, fuzzy
msgid "Disable spam checks"
msgstr "Aktiviere DNS Prüfungen"
#: src/components/admin/domains/DomainPolicyForm.vue:11
#, fuzzy
msgid "Disable virus checks"
msgstr "Deaktiviert"
#: src/components/admin/domains/DNSStatusChip.vue:18
msgid "Disabled"
msgstr "Deaktiviert"
#: src/components/quarantine/QuarantineList.vue:125
#, fuzzy
msgid "Display"
msgstr "Vollständiger Name"
#: src/components/contacts/ContactList.vue:23
msgid "Display address book information"
msgstr "Adressbuchinfos anzeigen"
@@ -988,6 +1058,11 @@ msgstr "Domain gelöscht"
msgid "Domain name (ex: domain.tld)"
msgstr "Domainname (z.B. domain.tld)"
#: src/composables/amavis.js:33
#, fuzzy
msgid "Domain's database"
msgstr "Standardwert der Domain verwenden"
#: src/components/admin/identities/AccountEditForm.vue:82
msgid "domain's default value"
msgstr "Domains Standardwert"
@@ -1039,6 +1114,10 @@ msgstr "Kategorie bearbeiten"
msgid "Edit contact"
msgstr "Kontakt bearbeiten"
#: src/components/admin/domains/DomainPolicy.vue:9
msgid "Edit content filter settings"
msgstr ""
#: src/views/admin/domains/DomainEditView.vue:3
msgid "Edit domain"
msgstr "Domäne bearbeiten"
@@ -1271,11 +1350,17 @@ msgstr "Mit ARC weitergeleitet"
#: src/components/account/AutoReplyForm.vue:36
#: src/components/admin/logs/MessageList.vue:50
#: src/components/calendars/EventForm.vue:24
#: src/components/quarantine/QuarantineList.vue:238
#: src/components/tools/TimeSerieChart.vue:19
#: src/components/webmail/ComposeEmailForm.vue:29
msgid "From"
msgstr "Von"
#: src/components/quarantine/QuarantineList.vue:45
#, fuzzy
msgid "From address"
msgstr "Zufällige Adresse"
#: src/components/calendars/CalendarAccessRulesForm.vue:11
msgid "Full address"
msgstr "Ganze Adresse"
@@ -1325,6 +1410,10 @@ msgstr "Neuen DKIM Schlüssel generieren"
msgid "Generated address"
msgstr "Generierte Adresse"
#: src/composables/amavis.js:30
msgid "Global database"
msgstr ""
#: src/views/admin/InformationView.vue:29
msgid "Go to <strong>Settings > General</strong> section"
msgstr "Gehen Sie zum Abschnitt <strong>Einstellungen > Allgemein</strong>"
@@ -1342,6 +1431,10 @@ msgstr ""
"Hier ist ein Beispiel für eine DNS Konfiguration (Bind Format). Ersetzen Sie"
" die Werte zwischen [ ] durch die entsprechenden."
#: src/views/quarantine/MessageView.vue:65
msgid "Hide full headers"
msgstr ""
#: src/components/admin/identities/AccountCreationForm.vue:168
#: src/components/admin/identities/AccountCreationForm.vue:95
#: src/components/admin/identities/AccountEditForm.vue:31
@@ -1511,6 +1604,12 @@ msgstr "Neueste Nachrichten"
msgid "Latest version"
msgstr "Lezte Version"
#: src/components/quarantine/QuarantineList.vue:385
#: src/views/quarantine/MessageView.vue:209
#, fuzzy
msgid "Learning database"
msgstr "Erstellungsdatum"
#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:26
msgid "Leave empty for no limit"
msgstr "Für kein Limit, leer lassen"
@@ -1538,7 +1637,7 @@ msgstr "Lokale Domain (optional)"
msgid "Logger"
msgstr "Logger"
#: src/components/shared/TopMenu.vue:100
#: src/components/shared/TopMenu.vue:138
msgid "Logout"
msgstr "Logout"
@@ -1586,10 +1685,23 @@ msgstr ""
msgid "Mark as followed"
msgstr "Als gefolgt markieren"
#: src/views/quarantine/MessageView.vue:47
msgid "Mark as non-spam"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:105
msgid "Mark as not spam"
msgstr ""
#: src/components/webmail/EmailList.vue:62
msgid "Mark as read"
msgstr "Als gelesen markieren"
#: src/components/quarantine/QuarantineList.vue:101
#: src/views/quarantine/MessageView.vue:43
msgid "Mark as spam"
msgstr ""
#: src/components/webmail/EmailList.vue:77
msgid "Mark as unfollowed"
msgstr "Als nicht gefolgt markieren"
@@ -1608,7 +1720,7 @@ msgstr "MB"
msgid "Message"
msgstr "Verwendung"
#: src/views/webmail/EmailView.vue:254
#: src/views/quarantine/MessageView.vue:196 src/views/webmail/EmailView.vue:254
msgid "Message deleted"
msgstr "Nachricht gelöscht"
@@ -1628,10 +1740,26 @@ msgstr "Nachrichtenlimit"
msgid "Message marked as junk"
msgstr "Als Junk markierte Nachricht"
#: src/components/quarantine/QuarantineList.vue:291
#: src/views/quarantine/MessageView.vue:236
msgid "Message marked as non-spam"
msgstr ""
#: src/views/webmail/EmailView.vue:282
msgid "Message marked as not junk"
msgstr "Nachricht als, kein Junk markiert"
#: src/components/quarantine/QuarantineList.vue:288
#: src/views/quarantine/MessageView.vue:232
msgid "Message marked as spam"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:285
#: src/views/quarantine/MessageView.vue:178
#, fuzzy
msgid "Message released"
msgstr "Verwendung"
#: src/components/admin/domains/DomainCreationForm.vue:197
#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:32
#: src/components/admin/identities/AccountCreationForm.vue:133
@@ -1814,7 +1942,7 @@ msgstr "Neue Wiederherstellungscodes"
msgid "Next"
msgstr "Weiter"
#: src/plugins/filters.js:10
#: src/components/tools/YesNoDefaultField.vue:11 src/plugins/filters.js:10
msgid "no"
msgstr "nein"
@@ -1878,6 +2006,11 @@ msgstr "Nicht generiert"
msgid "Note"
msgstr "Notiz"
#: src/components/shared/TopMenu.vue:18
#, fuzzy
msgid "Notifications"
msgstr "Datum der letzten Änderung"
#: src/components/admin/identities/AccountEditForm.vue:163
msgid "Number of allowed mailbox aliases:"
msgstr "Anzahl der zulässigen Postfachaliase:"
@@ -1941,6 +2074,14 @@ msgstr "Geöffnete Alarme"
msgid "Options"
msgstr "Optionen"
#: src/components/admin/domains/DomainPolicyForm.vue:69
msgid "or more is spam"
msgstr ""
#: src/components/admin/domains/DomainPolicyForm.vue:84
msgid "or more throw spam message away"
msgstr ""
#: src/components/account/ProfileForm.vue:30
msgid "or suggest a new language"
msgstr "oder eine neue Sprache vorschlagen"
@@ -2086,6 +2227,15 @@ msgstr "Provider aktualisiert"
msgid "Providers"
msgstr "Provider"
#: src/views/quarantine/QuarantineView.vue:4
msgid "Quarantine"
msgstr ""
#: src/views/quarantine/MessageView.vue:4
#, fuzzy
msgid "Quarantined message"
msgstr "Domains importieren"
#: src/components/admin/logs/MessageList.vue:46
msgid "Queue ID"
msgstr "Warteschlangen ID"
@@ -2176,6 +2326,10 @@ msgstr "Authentifikator registrieren"
msgid "Registered Webauthn devices"
msgstr "Registrierte Webauthn Geräte"
#: src/components/admin/domains/DomainPolicy.vue:61
msgid "Rejection threshold"
msgstr ""
#: src/components/tools/TimeSerieChart.vue:27
msgid "Relative time ranges"
msgstr "Relative Zeiträume"
@@ -2188,6 +2342,24 @@ msgstr "Relais"
msgid "Relay domain"
msgstr "Relais Domain"
#: src/views/quarantine/MessageView.vue:21
#, fuzzy
msgid "Release message"
msgstr "Verwendung"
#: src/components/quarantine/QuarantineList.vue:372
#: src/views/quarantine/MessageView.vue:176
msgid "Release request sent"
msgstr ""
#: src/views/quarantine/QuarantineView.vue:12
msgid "release requests"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:72
msgid "Release selection"
msgstr ""
#: src/components/admin/alarms/AlarmList.vue:123
msgid "Reload"
msgstr "Neu laden"
@@ -2260,6 +2432,10 @@ msgstr "Speichern"
msgid "Save your changes"
msgstr "Änderungen speichern"
#: src/components/quarantine/QuarantineList.vue:236
msgid "Score"
msgstr ""
#: src/components/admin/alarms/AlarmList.vue:21
#: src/components/admin/domains/DomainList.vue:19
#: src/components/admin/identities/IdentityList.vue:24
@@ -2270,6 +2446,7 @@ msgstr "Änderungen speichern"
msgid "Search"
msgstr "Suchen"
#: src/components/quarantine/QuarantineList.vue:27
#: src/components/webmail/EmailList.vue:14
msgid "Search in messages"
msgstr "In Nachrichten suchen"
@@ -2308,6 +2485,19 @@ msgstr ""
msgid "Select file"
msgstr "Wählen Sie eine Datei aus"
#: src/components/quarantine/QuarantineList.vue:359
#, fuzzy
msgid "Selection deleted"
msgstr "Erstellungsdatum"
#: src/components/quarantine/QuarantineList.vue:398
msgid "Selection is being processed..."
msgstr ""
#: src/components/quarantine/QuarantineList.vue:374
msgid "Selection released"
msgstr ""
#: src/components/calendars/ImportEventsForm.vue:30
#: src/components/webmail/ComposeEmailForm.vue:13
msgid "Send"
@@ -2379,6 +2569,20 @@ msgstr "Zeige Schlüssel"
msgid "Simple user"
msgstr "Normaler Benutzer"
#: src/components/admin/domains/DomainPolicy.vue:50
msgid "Spam classification threshold"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:17
#, fuzzy
msgid "Spam filters"
msgstr "Verwendung"
#: src/components/admin/domains/DomainPolicy.vue:72
#: src/components/admin/domains/DomainPolicyForm.vue:34
msgid "Spam marker"
msgstr ""
#: src/components/admin/identities/AccountSenderAddresses.vue:17
msgid "Specify an email address"
msgstr "E-Mailadresse eingeben"
@@ -2413,6 +2617,8 @@ msgid "Status"
msgstr "Status"
#: src/components/account/AutoReplyForm.vue:12
#: src/components/quarantine/QuarantineList.vue:239
#: src/components/quarantine/QuarantineList.vue:49
#: src/components/webmail/ComposeEmailForm.vue:137
msgid "Subject"
msgstr "Betreff"
@@ -2488,12 +2694,18 @@ msgstr ""
msgid "there"
msgstr "dort"
#: src/components/admin/domains/DomainPolicyForm.vue:56
msgid "Thresholds"
msgstr ""
#: src/components/calendars/EventForm.vue:12
msgid "Title"
msgstr "Titel"
#: src/components/admin/logs/MessageList.vue:49
#: src/components/calendars/EventForm.vue:34
#: src/components/quarantine/QuarantineList.vue:237
#: src/components/quarantine/QuarantineList.vue:52
#: src/components/tools/TimeSerieChart.vue:20
#: src/components/webmail/ComposeEmailForm.vue:46
#: src/views/webmail/EmailView.vue:109
@@ -2636,6 +2848,10 @@ msgstr "Anzahl benutzt"
msgid "Use domain default value"
msgstr "Standardwert der Domain verwenden"
#: src/composables/amavis.js:36
msgid "User's database"
msgstr ""
#: src/components/admin/domains/DomainAdminList.vue:111
#: src/components/admin/identities/AccountCreationForm.vue:97
#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:3
@@ -2654,6 +2870,15 @@ msgstr "Gültig"
msgid "Value"
msgstr "Wert"
#: src/views/quarantine/MessageView.vue:62
msgid "View full headers"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:28
#, fuzzy
msgid "Virus filters"
msgstr "E-Mail Adresse"
#: src/components/admin/dashboard/NewsFeedWidget.vue:21
msgid "Visit the official weblog for more information"
msgstr "Weitere Infos finden Sie im offiziellen Webprotokoll"
@@ -2694,6 +2919,11 @@ msgstr "Woche"
msgid "Welcome to Modoboa"
msgstr "Willkommen zu Modoboa"
#: src/components/quarantine/QuarantineList.vue:386
#: src/views/quarantine/MessageView.vue:210
msgid "Which database should be used for this learning:"
msgstr ""
#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:25
msgid "With a mailbox"
msgstr "Mit einem Postfach"
@@ -2711,7 +2941,7 @@ msgstr "Schreiben"
msgid "Year"
msgstr "Jahr"
#: src/plugins/filters.js:10
#: src/components/tools/YesNoDefaultField.vue:7 src/plugins/filters.js:10
msgid "yes"
msgstr "ja"
+217 -6
View File
@@ -63,7 +63,7 @@ msgid "Access rules"
msgstr ""
#: src/components/calendars/CalendarAccessRulesForm.vue:42
#: src/components/shared/TopMenu.vue:93
#: src/components/shared/TopMenu.vue:131
#: src/views/admin/identities/AccountView.vue:4
#: src/views/admin/identities/IdentitiesView.vue:23
msgid "Account"
@@ -323,6 +323,7 @@ msgstr ""
msgid "API token deleted"
msgstr ""
#: src/components/admin/domains/DomainPolicyForm.vue:96
#: src/components/tools/ChooseColumnsForm.vue:19
#: src/components/tools/TimeSerieChart.vue:22
msgid "Apply"
@@ -410,6 +411,10 @@ msgstr ""
msgid "Backup codes"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:39
msgid "Banned filters"
msgstr ""
#: src/components/webmail/ComposeEmailForm.vue:110
#: src/components/webmail/ComposeEmailForm.vue:73
msgid "Bcc"
@@ -423,6 +428,14 @@ msgstr ""
msgid "Birth date"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:54
msgid "both"
msgstr ""
#: src/components/admin/domains/form_steps/DomainPolicyForm.vue:5
msgid "Bypass virus checks"
msgstr ""
#: src/components/calendars/EventForm.vue:49
#: src/views/calendars/CalendarView.vue:3
msgid "Calendar"
@@ -453,6 +466,7 @@ msgstr ""
#: src/components/account/FilterForm.vue:147
#: src/components/account/FilterSetForm.vue:24
#: src/components/admin/domains/DomainEditForm.vue:161
#: src/components/admin/domains/DomainPolicyForm.vue:93
#: src/components/admin/identities/AccountEditForm.vue:183
#: src/components/admin/identities/AliasEditForm.vue:69
#: src/components/admin/imap_migration/ProviderForm.vue:58
@@ -541,7 +555,7 @@ msgstr ""
#: src/components/tools/ImportForm.vue:51
#: src/components/webmail/AttachmentsDialog.vue:41
#: src/components/webmail/MailboxForm.vue:29
#: src/layouts/connected/ConnectedLayout.vue:17
#: src/layouts/connected/ConnectedLayout.vue:19
msgid "Close"
msgstr ""
@@ -599,6 +613,14 @@ msgstr ""
msgid "Content"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:5
msgid "Content filter"
msgstr ""
#: src/components/admin/domains/DomainPolicyForm.vue:4
msgid "Content filter settings"
msgstr ""
#: src/components/tools/ImportForm.vue:40
msgid "Continue on error"
msgstr ""
@@ -709,6 +731,7 @@ msgstr ""
#: src/components/admin/logs/AuditTrailList.vue:51
#: src/components/admin/logs/MessageList.vue:47
#: src/components/quarantine/QuarantineList.vue:240
msgid "Date"
msgstr ""
@@ -716,6 +739,11 @@ msgstr ""
msgid "Day"
msgstr ""
#: src/components/admin/domains/DomainPolicyForm.vue:47
#: src/components/tools/YesNoDefaultField.vue:15
msgid "default"
msgstr ""
#: src/components/admin/domains/DomainCreationForm.vue:193
#: src/components/admin/domains/DomainSummary.vue:23
#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:19
@@ -728,6 +756,15 @@ msgid ""
"GB. A value of 0 means no quota."
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:24
#: src/components/admin/domains/DomainPolicy.vue:35
#: src/components/admin/domains/DomainPolicy.vue:46
#: src/components/admin/domains/DomainPolicy.vue:57
#: src/components/admin/domains/DomainPolicy.vue:68
#: src/components/admin/domains/DomainPolicy.vue:79
msgid "Default value"
msgstr ""
#: src/components/admin/alarms/AlarmList.vue:116
#: src/components/admin/alarms/AlarmList.vue:133
#: src/components/admin/domains/DomainAliasForm.vue:39
@@ -749,6 +786,14 @@ msgstr ""
msgid "Delete filter set"
msgstr ""
#: src/views/quarantine/MessageView.vue:32
msgid "Delete message"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:84
msgid "Delete selection"
msgstr ""
#: src/layouts/webmail/WebmailLayout.vue:56
msgid "Delete this mailbox"
msgstr ""
@@ -782,14 +827,30 @@ msgstr ""
msgid "Disable 2FA"
msgstr ""
#: src/components/admin/domains/DomainPolicyForm.vue:26
msgid "Disable banned checks"
msgstr ""
#: src/views/webmail/EmailView.vue:74
msgid "Disable links"
msgstr ""
#: src/components/admin/domains/DomainPolicyForm.vue:18
msgid "Disable spam checks"
msgstr ""
#: src/components/admin/domains/DomainPolicyForm.vue:11
msgid "Disable virus checks"
msgstr ""
#: src/components/admin/domains/DNSStatusChip.vue:18
msgid "Disabled"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:125
msgid "Display"
msgstr ""
#: src/components/contacts/ContactList.vue:23
msgid "Display address book information"
msgstr ""
@@ -958,6 +1019,10 @@ msgstr ""
msgid "Domain name (ex: domain.tld)"
msgstr ""
#: src/composables/amavis.js:33
msgid "Domain's database"
msgstr ""
#: src/components/admin/identities/AccountEditForm.vue:82
msgid "domain's default value"
msgstr ""
@@ -1009,6 +1074,10 @@ msgstr ""
msgid "Edit contact"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:9
msgid "Edit content filter settings"
msgstr ""
#: src/views/admin/domains/DomainEditView.vue:3
msgid "Edit domain"
msgstr ""
@@ -1241,11 +1310,16 @@ msgstr ""
#: src/components/account/AutoReplyForm.vue:36
#: src/components/admin/logs/MessageList.vue:50
#: src/components/calendars/EventForm.vue:24
#: src/components/quarantine/QuarantineList.vue:238
#: src/components/tools/TimeSerieChart.vue:19
#: src/components/webmail/ComposeEmailForm.vue:29
msgid "From"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:45
msgid "From address"
msgstr ""
#: src/components/calendars/CalendarAccessRulesForm.vue:11
msgid "Full address"
msgstr ""
@@ -1295,6 +1369,10 @@ msgstr ""
msgid "Generated address"
msgstr ""
#: src/composables/amavis.js:30
msgid "Global database"
msgstr ""
#: src/views/admin/InformationView.vue:29
msgid "Go to <strong>Settings > General</strong> section"
msgstr ""
@@ -1310,6 +1388,10 @@ msgid ""
"between [ ] by the appropriate ones."
msgstr ""
#: src/views/quarantine/MessageView.vue:65
msgid "Hide full headers"
msgstr ""
#: src/components/admin/identities/AccountCreationForm.vue:168
#: src/components/admin/identities/AccountCreationForm.vue:95
#: src/components/admin/identities/AccountEditForm.vue:31
@@ -1468,6 +1550,11 @@ msgstr ""
msgid "Latest version"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:385
#: src/views/quarantine/MessageView.vue:209
msgid "Learning database"
msgstr ""
#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:26
msgid "Leave empty for no limit"
msgstr ""
@@ -1495,7 +1582,7 @@ msgstr ""
msgid "Logger"
msgstr ""
#: src/components/shared/TopMenu.vue:100
#: src/components/shared/TopMenu.vue:138
msgid "Logout"
msgstr ""
@@ -1539,10 +1626,23 @@ msgstr ""
msgid "Mark as followed"
msgstr ""
#: src/views/quarantine/MessageView.vue:47
msgid "Mark as non-spam"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:105
msgid "Mark as not spam"
msgstr ""
#: src/components/webmail/EmailList.vue:62
msgid "Mark as read"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:101
#: src/views/quarantine/MessageView.vue:43
msgid "Mark as spam"
msgstr ""
#: src/components/webmail/EmailList.vue:77
msgid "Mark as unfollowed"
msgstr ""
@@ -1561,7 +1661,7 @@ msgstr ""
msgid "Message"
msgstr ""
#: src/views/webmail/EmailView.vue:254
#: src/views/quarantine/MessageView.vue:196 src/views/webmail/EmailView.vue:254
msgid "Message deleted"
msgstr ""
@@ -1581,10 +1681,25 @@ msgstr ""
msgid "Message marked as junk"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:291
#: src/views/quarantine/MessageView.vue:236
msgid "Message marked as non-spam"
msgstr ""
#: src/views/webmail/EmailView.vue:282
msgid "Message marked as not junk"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:288
#: src/views/quarantine/MessageView.vue:232
msgid "Message marked as spam"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:285
#: src/views/quarantine/MessageView.vue:178
msgid "Message released"
msgstr ""
#: src/components/admin/domains/DomainCreationForm.vue:197
#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:32
#: src/components/admin/identities/AccountCreationForm.vue:133
@@ -1767,7 +1882,7 @@ msgstr ""
msgid "Next"
msgstr ""
#: src/plugins/filters.js:10
#: src/components/tools/YesNoDefaultField.vue:11 src/plugins/filters.js:10
msgid "no"
msgstr ""
@@ -1831,6 +1946,10 @@ msgstr ""
msgid "Note"
msgstr ""
#: src/components/shared/TopMenu.vue:18
msgid "Notifications"
msgstr ""
#: src/components/admin/identities/AccountEditForm.vue:163
msgid "Number of allowed mailbox aliases:"
msgstr ""
@@ -1890,6 +2009,14 @@ msgstr ""
msgid "Options"
msgstr ""
#: src/components/admin/domains/DomainPolicyForm.vue:69
msgid "or more is spam"
msgstr ""
#: src/components/admin/domains/DomainPolicyForm.vue:84
msgid "or more throw spam message away"
msgstr ""
#: src/components/account/ProfileForm.vue:30
msgid "or suggest a new language"
msgstr ""
@@ -2031,6 +2158,14 @@ msgstr ""
msgid "Providers"
msgstr ""
#: src/views/quarantine/QuarantineView.vue:4
msgid "Quarantine"
msgstr ""
#: src/views/quarantine/MessageView.vue:4
msgid "Quarantined message"
msgstr ""
#: src/components/admin/logs/MessageList.vue:46
msgid "Queue ID"
msgstr ""
@@ -2114,6 +2249,10 @@ msgstr ""
msgid "Registered Webauthn devices"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:61
msgid "Rejection threshold"
msgstr ""
#: src/components/tools/TimeSerieChart.vue:27
msgid "Relative time ranges"
msgstr ""
@@ -2126,6 +2265,23 @@ msgstr ""
msgid "Relay domain"
msgstr ""
#: src/views/quarantine/MessageView.vue:21
msgid "Release message"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:372
#: src/views/quarantine/MessageView.vue:176
msgid "Release request sent"
msgstr ""
#: src/views/quarantine/QuarantineView.vue:12
msgid "release requests"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:72
msgid "Release selection"
msgstr ""
#: src/components/admin/alarms/AlarmList.vue:123
msgid "Reload"
msgstr ""
@@ -2198,6 +2354,10 @@ msgstr ""
msgid "Save your changes"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:236
msgid "Score"
msgstr ""
#: src/components/admin/alarms/AlarmList.vue:21
#: src/components/admin/domains/DomainList.vue:19
#: src/components/admin/identities/IdentityList.vue:24
@@ -2208,6 +2368,7 @@ msgstr ""
msgid "Search"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:27
#: src/components/webmail/EmailList.vue:14
msgid "Search in messages"
msgstr ""
@@ -2244,6 +2405,18 @@ msgstr ""
msgid "Select file"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:359
msgid "Selection deleted"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:398
msgid "Selection is being processed..."
msgstr ""
#: src/components/quarantine/QuarantineList.vue:374
msgid "Selection released"
msgstr ""
#: src/components/calendars/ImportEventsForm.vue:30
#: src/components/webmail/ComposeEmailForm.vue:13
msgid "Send"
@@ -2315,6 +2488,19 @@ msgstr ""
msgid "Simple user"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:50
msgid "Spam classification threshold"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:17
msgid "Spam filters"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:72
#: src/components/admin/domains/DomainPolicyForm.vue:34
msgid "Spam marker"
msgstr ""
#: src/components/admin/identities/AccountSenderAddresses.vue:17
msgid "Specify an email address"
msgstr ""
@@ -2349,6 +2535,8 @@ msgid "Status"
msgstr ""
#: src/components/account/AutoReplyForm.vue:12
#: src/components/quarantine/QuarantineList.vue:239
#: src/components/quarantine/QuarantineList.vue:49
#: src/components/webmail/ComposeEmailForm.vue:137
msgid "Subject"
msgstr ""
@@ -2412,12 +2600,18 @@ msgstr ""
msgid "there"
msgstr ""
#: src/components/admin/domains/DomainPolicyForm.vue:56
msgid "Thresholds"
msgstr ""
#: src/components/calendars/EventForm.vue:12
msgid "Title"
msgstr ""
#: src/components/admin/logs/MessageList.vue:49
#: src/components/calendars/EventForm.vue:34
#: src/components/quarantine/QuarantineList.vue:237
#: src/components/quarantine/QuarantineList.vue:52
#: src/components/tools/TimeSerieChart.vue:20
#: src/components/webmail/ComposeEmailForm.vue:46
#: src/views/webmail/EmailView.vue:109
@@ -2552,6 +2746,10 @@ msgstr ""
msgid "Use domain default value"
msgstr ""
#: src/composables/amavis.js:36
msgid "User's database"
msgstr ""
#: src/components/admin/domains/DomainAdminList.vue:111
#: src/components/admin/identities/AccountCreationForm.vue:97
#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:3
@@ -2570,6 +2768,14 @@ msgstr ""
msgid "Value"
msgstr ""
#: src/views/quarantine/MessageView.vue:62
msgid "View full headers"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:28
msgid "Virus filters"
msgstr ""
#: src/components/admin/dashboard/NewsFeedWidget.vue:21
msgid "Visit the official weblog for more information"
msgstr ""
@@ -2610,6 +2816,11 @@ msgstr ""
msgid "Welcome to Modoboa"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:386
#: src/views/quarantine/MessageView.vue:210
msgid "Which database should be used for this learning:"
msgstr ""
#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:25
msgid "With a mailbox"
msgstr ""
@@ -2627,7 +2838,7 @@ msgstr ""
msgid "Year"
msgstr ""
#: src/plugins/filters.js:10
#: src/components/tools/YesNoDefaultField.vue:7 src/plugins/filters.js:10
msgid "yes"
msgstr ""
+217 -6
View File
@@ -55,7 +55,7 @@ msgid "Access rules"
msgstr ""
#: src/components/calendars/CalendarAccessRulesForm.vue:42
#: src/components/shared/TopMenu.vue:93
#: src/components/shared/TopMenu.vue:131
#: src/views/admin/identities/AccountView.vue:4
#: src/views/admin/identities/IdentitiesView.vue:23
msgid "Account"
@@ -315,6 +315,7 @@ msgstr ""
msgid "API token deleted"
msgstr ""
#: src/components/admin/domains/DomainPolicyForm.vue:96
#: src/components/tools/ChooseColumnsForm.vue:19
#: src/components/tools/TimeSerieChart.vue:22
msgid "Apply"
@@ -402,6 +403,10 @@ msgstr ""
msgid "Backup codes"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:39
msgid "Banned filters"
msgstr ""
#: src/components/webmail/ComposeEmailForm.vue:110
#: src/components/webmail/ComposeEmailForm.vue:73
msgid "Bcc"
@@ -415,6 +420,14 @@ msgstr ""
msgid "Birth date"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:54
msgid "both"
msgstr ""
#: src/components/admin/domains/form_steps/DomainPolicyForm.vue:5
msgid "Bypass virus checks"
msgstr ""
#: src/components/calendars/EventForm.vue:49
#: src/views/calendars/CalendarView.vue:3
msgid "Calendar"
@@ -445,6 +458,7 @@ msgstr ""
#: src/components/account/FilterForm.vue:147
#: src/components/account/FilterSetForm.vue:24
#: src/components/admin/domains/DomainEditForm.vue:161
#: src/components/admin/domains/DomainPolicyForm.vue:93
#: src/components/admin/identities/AccountEditForm.vue:183
#: src/components/admin/identities/AliasEditForm.vue:69
#: src/components/admin/imap_migration/ProviderForm.vue:58
@@ -533,7 +547,7 @@ msgstr ""
#: src/components/tools/ImportForm.vue:51
#: src/components/webmail/AttachmentsDialog.vue:41
#: src/components/webmail/MailboxForm.vue:29
#: src/layouts/connected/ConnectedLayout.vue:17
#: src/layouts/connected/ConnectedLayout.vue:19
msgid "Close"
msgstr ""
@@ -591,6 +605,14 @@ msgstr ""
msgid "Content"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:5
msgid "Content filter"
msgstr ""
#: src/components/admin/domains/DomainPolicyForm.vue:4
msgid "Content filter settings"
msgstr ""
#: src/components/tools/ImportForm.vue:40
msgid "Continue on error"
msgstr ""
@@ -701,6 +723,7 @@ msgstr ""
#: src/components/admin/logs/AuditTrailList.vue:51
#: src/components/admin/logs/MessageList.vue:47
#: src/components/quarantine/QuarantineList.vue:240
msgid "Date"
msgstr ""
@@ -708,6 +731,11 @@ msgstr ""
msgid "Day"
msgstr ""
#: src/components/admin/domains/DomainPolicyForm.vue:47
#: src/components/tools/YesNoDefaultField.vue:15
msgid "default"
msgstr ""
#: src/components/admin/domains/DomainCreationForm.vue:193
#: src/components/admin/domains/DomainSummary.vue:23
#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:19
@@ -720,6 +748,15 @@ msgid ""
"GB. A value of 0 means no quota."
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:24
#: src/components/admin/domains/DomainPolicy.vue:35
#: src/components/admin/domains/DomainPolicy.vue:46
#: src/components/admin/domains/DomainPolicy.vue:57
#: src/components/admin/domains/DomainPolicy.vue:68
#: src/components/admin/domains/DomainPolicy.vue:79
msgid "Default value"
msgstr ""
#: src/components/admin/alarms/AlarmList.vue:116
#: src/components/admin/alarms/AlarmList.vue:133
#: src/components/admin/domains/DomainAliasForm.vue:39
@@ -741,6 +778,14 @@ msgstr ""
msgid "Delete filter set"
msgstr ""
#: src/views/quarantine/MessageView.vue:32
msgid "Delete message"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:84
msgid "Delete selection"
msgstr ""
#: src/layouts/webmail/WebmailLayout.vue:56
msgid "Delete this mailbox"
msgstr ""
@@ -774,14 +819,30 @@ msgstr ""
msgid "Disable 2FA"
msgstr ""
#: src/components/admin/domains/DomainPolicyForm.vue:26
msgid "Disable banned checks"
msgstr ""
#: src/views/webmail/EmailView.vue:74
msgid "Disable links"
msgstr ""
#: src/components/admin/domains/DomainPolicyForm.vue:18
msgid "Disable spam checks"
msgstr ""
#: src/components/admin/domains/DomainPolicyForm.vue:11
msgid "Disable virus checks"
msgstr ""
#: src/components/admin/domains/DNSStatusChip.vue:18
msgid "Disabled"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:125
msgid "Display"
msgstr ""
#: src/components/contacts/ContactList.vue:23
msgid "Display address book information"
msgstr ""
@@ -950,6 +1011,10 @@ msgstr ""
msgid "Domain name (ex: domain.tld)"
msgstr ""
#: src/composables/amavis.js:33
msgid "Domain's database"
msgstr ""
#: src/components/admin/identities/AccountEditForm.vue:82
msgid "domain's default value"
msgstr ""
@@ -1001,6 +1066,10 @@ msgstr ""
msgid "Edit contact"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:9
msgid "Edit content filter settings"
msgstr ""
#: src/views/admin/domains/DomainEditView.vue:3
msgid "Edit domain"
msgstr ""
@@ -1233,11 +1302,16 @@ msgstr ""
#: src/components/account/AutoReplyForm.vue:36
#: src/components/admin/logs/MessageList.vue:50
#: src/components/calendars/EventForm.vue:24
#: src/components/quarantine/QuarantineList.vue:238
#: src/components/tools/TimeSerieChart.vue:19
#: src/components/webmail/ComposeEmailForm.vue:29
msgid "From"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:45
msgid "From address"
msgstr ""
#: src/components/calendars/CalendarAccessRulesForm.vue:11
msgid "Full address"
msgstr ""
@@ -1287,6 +1361,10 @@ msgstr ""
msgid "Generated address"
msgstr ""
#: src/composables/amavis.js:30
msgid "Global database"
msgstr ""
#: src/views/admin/InformationView.vue:29
msgid "Go to <strong>Settings > General</strong> section"
msgstr ""
@@ -1302,6 +1380,10 @@ msgid ""
"between [ ] by the appropriate ones."
msgstr ""
#: src/views/quarantine/MessageView.vue:65
msgid "Hide full headers"
msgstr ""
#: src/components/admin/identities/AccountCreationForm.vue:168
#: src/components/admin/identities/AccountCreationForm.vue:95
#: src/components/admin/identities/AccountEditForm.vue:31
@@ -1460,6 +1542,11 @@ msgstr ""
msgid "Latest version"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:385
#: src/views/quarantine/MessageView.vue:209
msgid "Learning database"
msgstr ""
#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:26
msgid "Leave empty for no limit"
msgstr ""
@@ -1487,7 +1574,7 @@ msgstr ""
msgid "Logger"
msgstr ""
#: src/components/shared/TopMenu.vue:100
#: src/components/shared/TopMenu.vue:138
msgid "Logout"
msgstr ""
@@ -1531,10 +1618,23 @@ msgstr ""
msgid "Mark as followed"
msgstr ""
#: src/views/quarantine/MessageView.vue:47
msgid "Mark as non-spam"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:105
msgid "Mark as not spam"
msgstr ""
#: src/components/webmail/EmailList.vue:62
msgid "Mark as read"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:101
#: src/views/quarantine/MessageView.vue:43
msgid "Mark as spam"
msgstr ""
#: src/components/webmail/EmailList.vue:77
msgid "Mark as unfollowed"
msgstr ""
@@ -1553,7 +1653,7 @@ msgstr ""
msgid "Message"
msgstr ""
#: src/views/webmail/EmailView.vue:254
#: src/views/quarantine/MessageView.vue:196 src/views/webmail/EmailView.vue:254
msgid "Message deleted"
msgstr ""
@@ -1573,10 +1673,25 @@ msgstr ""
msgid "Message marked as junk"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:291
#: src/views/quarantine/MessageView.vue:236
msgid "Message marked as non-spam"
msgstr ""
#: src/views/webmail/EmailView.vue:282
msgid "Message marked as not junk"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:288
#: src/views/quarantine/MessageView.vue:232
msgid "Message marked as spam"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:285
#: src/views/quarantine/MessageView.vue:178
msgid "Message released"
msgstr ""
#: src/components/admin/domains/DomainCreationForm.vue:197
#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:32
#: src/components/admin/identities/AccountCreationForm.vue:133
@@ -1759,7 +1874,7 @@ msgstr ""
msgid "Next"
msgstr ""
#: src/plugins/filters.js:10
#: src/components/tools/YesNoDefaultField.vue:11 src/plugins/filters.js:10
msgid "no"
msgstr ""
@@ -1823,6 +1938,10 @@ msgstr ""
msgid "Note"
msgstr ""
#: src/components/shared/TopMenu.vue:18
msgid "Notifications"
msgstr ""
#: src/components/admin/identities/AccountEditForm.vue:163
msgid "Number of allowed mailbox aliases:"
msgstr ""
@@ -1882,6 +2001,14 @@ msgstr ""
msgid "Options"
msgstr ""
#: src/components/admin/domains/DomainPolicyForm.vue:69
msgid "or more is spam"
msgstr ""
#: src/components/admin/domains/DomainPolicyForm.vue:84
msgid "or more throw spam message away"
msgstr ""
#: src/components/account/ProfileForm.vue:30
msgid "or suggest a new language"
msgstr ""
@@ -2023,6 +2150,14 @@ msgstr ""
msgid "Providers"
msgstr ""
#: src/views/quarantine/QuarantineView.vue:4
msgid "Quarantine"
msgstr ""
#: src/views/quarantine/MessageView.vue:4
msgid "Quarantined message"
msgstr ""
#: src/components/admin/logs/MessageList.vue:46
msgid "Queue ID"
msgstr ""
@@ -2106,6 +2241,10 @@ msgstr ""
msgid "Registered Webauthn devices"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:61
msgid "Rejection threshold"
msgstr ""
#: src/components/tools/TimeSerieChart.vue:27
msgid "Relative time ranges"
msgstr ""
@@ -2118,6 +2257,23 @@ msgstr ""
msgid "Relay domain"
msgstr ""
#: src/views/quarantine/MessageView.vue:21
msgid "Release message"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:372
#: src/views/quarantine/MessageView.vue:176
msgid "Release request sent"
msgstr ""
#: src/views/quarantine/QuarantineView.vue:12
msgid "release requests"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:72
msgid "Release selection"
msgstr ""
#: src/components/admin/alarms/AlarmList.vue:123
msgid "Reload"
msgstr ""
@@ -2190,6 +2346,10 @@ msgstr ""
msgid "Save your changes"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:236
msgid "Score"
msgstr ""
#: src/components/admin/alarms/AlarmList.vue:21
#: src/components/admin/domains/DomainList.vue:19
#: src/components/admin/identities/IdentityList.vue:24
@@ -2200,6 +2360,7 @@ msgstr ""
msgid "Search"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:27
#: src/components/webmail/EmailList.vue:14
msgid "Search in messages"
msgstr ""
@@ -2236,6 +2397,18 @@ msgstr ""
msgid "Select file"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:359
msgid "Selection deleted"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:398
msgid "Selection is being processed..."
msgstr ""
#: src/components/quarantine/QuarantineList.vue:374
msgid "Selection released"
msgstr ""
#: src/components/calendars/ImportEventsForm.vue:30
#: src/components/webmail/ComposeEmailForm.vue:13
msgid "Send"
@@ -2307,6 +2480,19 @@ msgstr ""
msgid "Simple user"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:50
msgid "Spam classification threshold"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:17
msgid "Spam filters"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:72
#: src/components/admin/domains/DomainPolicyForm.vue:34
msgid "Spam marker"
msgstr ""
#: src/components/admin/identities/AccountSenderAddresses.vue:17
msgid "Specify an email address"
msgstr ""
@@ -2341,6 +2527,8 @@ msgid "Status"
msgstr ""
#: src/components/account/AutoReplyForm.vue:12
#: src/components/quarantine/QuarantineList.vue:239
#: src/components/quarantine/QuarantineList.vue:49
#: src/components/webmail/ComposeEmailForm.vue:137
msgid "Subject"
msgstr ""
@@ -2404,12 +2592,18 @@ msgstr ""
msgid "there"
msgstr ""
#: src/components/admin/domains/DomainPolicyForm.vue:56
msgid "Thresholds"
msgstr ""
#: src/components/calendars/EventForm.vue:12
msgid "Title"
msgstr ""
#: src/components/admin/logs/MessageList.vue:49
#: src/components/calendars/EventForm.vue:34
#: src/components/quarantine/QuarantineList.vue:237
#: src/components/quarantine/QuarantineList.vue:52
#: src/components/tools/TimeSerieChart.vue:20
#: src/components/webmail/ComposeEmailForm.vue:46
#: src/views/webmail/EmailView.vue:109
@@ -2544,6 +2738,10 @@ msgstr ""
msgid "Use domain default value"
msgstr ""
#: src/composables/amavis.js:36
msgid "User's database"
msgstr ""
#: src/components/admin/domains/DomainAdminList.vue:111
#: src/components/admin/identities/AccountCreationForm.vue:97
#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:3
@@ -2562,6 +2760,14 @@ msgstr ""
msgid "Value"
msgstr ""
#: src/views/quarantine/MessageView.vue:62
msgid "View full headers"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:28
msgid "Virus filters"
msgstr ""
#: src/components/admin/dashboard/NewsFeedWidget.vue:21
msgid "Visit the official weblog for more information"
msgstr ""
@@ -2602,6 +2808,11 @@ msgstr ""
msgid "Welcome to Modoboa"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:386
#: src/views/quarantine/MessageView.vue:210
msgid "Which database should be used for this learning:"
msgstr ""
#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:25
msgid "With a mailbox"
msgstr ""
@@ -2619,7 +2830,7 @@ msgstr ""
msgid "Year"
msgstr ""
#: src/plugins/filters.js:10
#: src/components/tools/YesNoDefaultField.vue:7 src/plugins/filters.js:10
msgid "yes"
msgstr ""
+236 -6
View File
@@ -63,7 +63,7 @@ msgid "Access rules"
msgstr ""
#: src/components/calendars/CalendarAccessRulesForm.vue:42
#: src/components/shared/TopMenu.vue:93
#: src/components/shared/TopMenu.vue:131
#: src/views/admin/identities/AccountView.vue:4
#: src/views/admin/identities/IdentitiesView.vue:23
msgid "Account"
@@ -341,6 +341,7 @@ msgstr "Cuenta creada"
msgid "API token deleted"
msgstr "Fecha de creación"
#: src/components/admin/domains/DomainPolicyForm.vue:96
#: src/components/tools/ChooseColumnsForm.vue:19
#: src/components/tools/TimeSerieChart.vue:22
msgid "Apply"
@@ -430,6 +431,11 @@ msgstr ""
msgid "Backup codes"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:39
#, fuzzy
msgid "Banned filters"
msgstr "Uso"
#: src/components/webmail/ComposeEmailForm.vue:110
#: src/components/webmail/ComposeEmailForm.vue:73
msgid "Bcc"
@@ -444,6 +450,14 @@ msgstr "Formato inválido"
msgid "Birth date"
msgstr "Fecha de nacimiento"
#: src/components/quarantine/QuarantineList.vue:54
msgid "both"
msgstr ""
#: src/components/admin/domains/form_steps/DomainPolicyForm.vue:5
msgid "Bypass virus checks"
msgstr ""
#: src/components/calendars/EventForm.vue:49
#: src/views/calendars/CalendarView.vue:3
msgid "Calendar"
@@ -478,6 +492,7 @@ msgstr "Perfil actualizado"
#: src/components/account/FilterForm.vue:147
#: src/components/account/FilterSetForm.vue:24
#: src/components/admin/domains/DomainEditForm.vue:161
#: src/components/admin/domains/DomainPolicyForm.vue:93
#: src/components/admin/identities/AccountEditForm.vue:183
#: src/components/admin/identities/AliasEditForm.vue:69
#: src/components/admin/imap_migration/ProviderForm.vue:58
@@ -569,7 +584,7 @@ msgstr ""
#: src/components/tools/ImportForm.vue:51
#: src/components/webmail/AttachmentsDialog.vue:41
#: src/components/webmail/MailboxForm.vue:29
#: src/layouts/connected/ConnectedLayout.vue:17
#: src/layouts/connected/ConnectedLayout.vue:19
msgid "Close"
msgstr "Cerrar"
@@ -628,6 +643,16 @@ msgstr "Contactos"
msgid "Content"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:5
#, fuzzy
msgid "Content filter"
msgstr "Dirección de email"
#: src/components/admin/domains/DomainPolicyForm.vue:4
#, fuzzy
msgid "Content filter settings"
msgstr "General"
#: src/components/tools/ImportForm.vue:40
msgid "Continue on error"
msgstr "Continúe en error."
@@ -743,6 +768,7 @@ msgstr "Panel de Control"
#: src/components/admin/logs/AuditTrailList.vue:51
#: src/components/admin/logs/MessageList.vue:47
#: src/components/quarantine/QuarantineList.vue:240
msgid "Date"
msgstr ""
@@ -750,6 +776,11 @@ msgstr ""
msgid "Day"
msgstr "Día"
#: src/components/admin/domains/DomainPolicyForm.vue:47
#: src/components/tools/YesNoDefaultField.vue:15
msgid "default"
msgstr ""
#: src/components/admin/domains/DomainCreationForm.vue:193
#: src/components/admin/domains/DomainSummary.vue:23
#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:19
@@ -763,6 +794,16 @@ msgid ""
msgstr ""
"Cuota de mailbox predeterminda en MB. Un valor de 0 significa ningún limite."
#: src/components/admin/domains/DomainPolicy.vue:24
#: src/components/admin/domains/DomainPolicy.vue:35
#: src/components/admin/domains/DomainPolicy.vue:46
#: src/components/admin/domains/DomainPolicy.vue:57
#: src/components/admin/domains/DomainPolicy.vue:68
#: src/components/admin/domains/DomainPolicy.vue:79
#, fuzzy
msgid "Default value"
msgstr "Usar el valor por defecto del dominio"
#: src/components/admin/alarms/AlarmList.vue:116
#: src/components/admin/alarms/AlarmList.vue:133
#: src/components/admin/domains/DomainAliasForm.vue:39
@@ -784,6 +825,15 @@ msgstr ""
msgid "Delete filter set"
msgstr ""
#: src/views/quarantine/MessageView.vue:32
#, fuzzy
msgid "Delete message"
msgstr "Uso"
#: src/components/quarantine/QuarantineList.vue:84
msgid "Delete selection"
msgstr ""
#: src/layouts/webmail/WebmailLayout.vue:56
#, fuzzy
msgid "Delete this mailbox"
@@ -820,15 +870,35 @@ msgstr "Deshabilitado"
msgid "Disable 2FA"
msgstr "Deshabilitado"
#: src/components/admin/domains/DomainPolicyForm.vue:26
#, fuzzy
msgid "Disable banned checks"
msgstr "Deshabilitado"
#: src/views/webmail/EmailView.vue:74
#, fuzzy
msgid "Disable links"
msgstr "Deshabilitado"
#: src/components/admin/domains/DomainPolicyForm.vue:18
#, fuzzy
msgid "Disable spam checks"
msgstr "Activar comprobación de DNS"
#: src/components/admin/domains/DomainPolicyForm.vue:11
#, fuzzy
msgid "Disable virus checks"
msgstr "Deshabilitado"
#: src/components/admin/domains/DNSStatusChip.vue:18
msgid "Disabled"
msgstr "Deshabilitado"
#: src/components/quarantine/QuarantineList.vue:125
#, fuzzy
msgid "Display"
msgstr "Nombre a mostrar"
#: src/components/contacts/ContactList.vue:23
msgid "Display address book information"
msgstr ""
@@ -1001,6 +1071,11 @@ msgstr ""
msgid "Domain name (ex: domain.tld)"
msgstr ""
#: src/composables/amavis.js:33
#, fuzzy
msgid "Domain's database"
msgstr "Usar el valor por defecto del dominio"
#: src/components/admin/identities/AccountEditForm.vue:82
#, fuzzy
msgid "domain's default value"
@@ -1058,6 +1133,10 @@ msgstr "Dirección de email"
msgid "Edit contact"
msgstr "Editar contacto"
#: src/components/admin/domains/DomainPolicy.vue:9
msgid "Edit content filter settings"
msgstr ""
#: src/views/admin/domains/DomainEditView.vue:3
msgid "Edit domain"
msgstr ""
@@ -1311,11 +1390,17 @@ msgstr ""
#: src/components/account/AutoReplyForm.vue:36
#: src/components/admin/logs/MessageList.vue:50
#: src/components/calendars/EventForm.vue:24
#: src/components/quarantine/QuarantineList.vue:238
#: src/components/tools/TimeSerieChart.vue:19
#: src/components/webmail/ComposeEmailForm.vue:29
msgid "From"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:45
#, fuzzy
msgid "From address"
msgstr "Dirección aleatoria"
#: src/components/calendars/CalendarAccessRulesForm.vue:11
#, fuzzy
msgid "Full address"
@@ -1370,6 +1455,10 @@ msgstr ""
msgid "Generated address"
msgstr "Direcciónes de remitente"
#: src/composables/amavis.js:30
msgid "Global database"
msgstr ""
#: src/views/admin/InformationView.vue:29
msgid "Go to <strong>Settings > General</strong> section"
msgstr ""
@@ -1385,6 +1474,10 @@ msgid ""
"between [ ] by the appropriate ones."
msgstr ""
#: src/views/quarantine/MessageView.vue:65
msgid "Hide full headers"
msgstr ""
#: src/components/admin/identities/AccountCreationForm.vue:168
#: src/components/admin/identities/AccountCreationForm.vue:95
#: src/components/admin/identities/AccountEditForm.vue:31
@@ -1552,6 +1645,12 @@ msgstr "Versión instalada"
msgid "Latest version"
msgstr "Versión instalada"
#: src/components/quarantine/QuarantineList.vue:385
#: src/views/quarantine/MessageView.vue:209
#, fuzzy
msgid "Learning database"
msgstr "Fecha de creación"
#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:26
msgid "Leave empty for no limit"
msgstr ""
@@ -1579,7 +1678,7 @@ msgstr ""
msgid "Logger"
msgstr "Logger"
#: src/components/shared/TopMenu.vue:100
#: src/components/shared/TopMenu.vue:138
msgid "Logout"
msgstr "Salir"
@@ -1627,10 +1726,23 @@ msgstr ""
msgid "Mark as followed"
msgstr ""
#: src/views/quarantine/MessageView.vue:47
msgid "Mark as non-spam"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:105
msgid "Mark as not spam"
msgstr ""
#: src/components/webmail/EmailList.vue:62
msgid "Mark as read"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:101
#: src/views/quarantine/MessageView.vue:43
msgid "Mark as spam"
msgstr ""
#: src/components/webmail/EmailList.vue:77
msgid "Mark as unfollowed"
msgstr ""
@@ -1649,7 +1761,7 @@ msgstr ""
msgid "Message"
msgstr "Uso"
#: src/views/webmail/EmailView.vue:254
#: src/views/quarantine/MessageView.vue:196 src/views/webmail/EmailView.vue:254
#, fuzzy
msgid "Message deleted"
msgstr "Uso"
@@ -1673,10 +1785,26 @@ msgstr "Uso"
msgid "Message marked as junk"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:291
#: src/views/quarantine/MessageView.vue:236
msgid "Message marked as non-spam"
msgstr ""
#: src/views/webmail/EmailView.vue:282
msgid "Message marked as not junk"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:288
#: src/views/quarantine/MessageView.vue:232
msgid "Message marked as spam"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:285
#: src/views/quarantine/MessageView.vue:178
#, fuzzy
msgid "Message released"
msgstr "Uso"
#: src/components/admin/domains/DomainCreationForm.vue:197
#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:32
#: src/components/admin/identities/AccountCreationForm.vue:133
@@ -1871,7 +1999,7 @@ msgstr ""
msgid "Next"
msgstr "Siguiente"
#: src/plugins/filters.js:10
#: src/components/tools/YesNoDefaultField.vue:11 src/plugins/filters.js:10
msgid "no"
msgstr ""
@@ -1937,6 +2065,11 @@ msgstr "Sin definir"
msgid "Note"
msgstr "Nota"
#: src/components/shared/TopMenu.vue:18
#, fuzzy
msgid "Notifications"
msgstr "Última fecha de modificación"
#: src/components/admin/identities/AccountEditForm.vue:163
#, fuzzy
msgid "Number of allowed mailbox aliases:"
@@ -2000,6 +2133,14 @@ msgstr ""
msgid "Options"
msgstr "Opciones"
#: src/components/admin/domains/DomainPolicyForm.vue:69
msgid "or more is spam"
msgstr ""
#: src/components/admin/domains/DomainPolicyForm.vue:84
msgid "or more throw spam message away"
msgstr ""
#: src/components/account/ProfileForm.vue:30
msgid "or suggest a new language"
msgstr ""
@@ -2153,6 +2294,15 @@ msgstr "Perfil actualizado"
msgid "Providers"
msgstr "Dirección de email"
#: src/views/quarantine/QuarantineView.vue:4
msgid "Quarantine"
msgstr ""
#: src/views/quarantine/MessageView.vue:4
#, fuzzy
msgid "Quarantined message"
msgstr "Importar dominios"
#: src/components/admin/logs/MessageList.vue:46
msgid "Queue ID"
msgstr ""
@@ -2241,6 +2391,10 @@ msgstr "Autenticación"
msgid "Registered Webauthn devices"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:61
msgid "Rejection threshold"
msgstr ""
#: src/components/tools/TimeSerieChart.vue:27
msgid "Relative time ranges"
msgstr ""
@@ -2254,6 +2408,24 @@ msgstr ""
msgid "Relay domain"
msgstr "Nuevo dominio"
#: src/views/quarantine/MessageView.vue:21
#, fuzzy
msgid "Release message"
msgstr "Uso"
#: src/components/quarantine/QuarantineList.vue:372
#: src/views/quarantine/MessageView.vue:176
msgid "Release request sent"
msgstr ""
#: src/views/quarantine/QuarantineView.vue:12
msgid "release requests"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:72
msgid "Release selection"
msgstr ""
#: src/components/admin/alarms/AlarmList.vue:123
msgid "Reload"
msgstr ""
@@ -2326,6 +2498,10 @@ msgstr "Guardar"
msgid "Save your changes"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:236
msgid "Score"
msgstr ""
#: src/components/admin/alarms/AlarmList.vue:21
#: src/components/admin/domains/DomainList.vue:19
#: src/components/admin/identities/IdentityList.vue:24
@@ -2336,6 +2512,7 @@ msgstr ""
msgid "Search"
msgstr "Buscar"
#: src/components/quarantine/QuarantineList.vue:27
#: src/components/webmail/EmailList.vue:14
#, fuzzy
msgid "Search in messages"
@@ -2373,6 +2550,19 @@ msgstr ""
msgid "Select file"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:359
#, fuzzy
msgid "Selection deleted"
msgstr "Fecha de creación"
#: src/components/quarantine/QuarantineList.vue:398
msgid "Selection is being processed..."
msgstr ""
#: src/components/quarantine/QuarantineList.vue:374
msgid "Selection released"
msgstr ""
#: src/components/calendars/ImportEventsForm.vue:30
#: src/components/webmail/ComposeEmailForm.vue:13
#, fuzzy
@@ -2449,6 +2639,20 @@ msgstr ""
msgid "Simple user"
msgstr "Usuario normal"
#: src/components/admin/domains/DomainPolicy.vue:50
msgid "Spam classification threshold"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:17
#, fuzzy
msgid "Spam filters"
msgstr "Uso"
#: src/components/admin/domains/DomainPolicy.vue:72
#: src/components/admin/domains/DomainPolicyForm.vue:34
msgid "Spam marker"
msgstr ""
#: src/components/admin/identities/AccountSenderAddresses.vue:17
msgid "Specify an email address"
msgstr ""
@@ -2484,6 +2688,8 @@ msgid "Status"
msgstr "Estatus"
#: src/components/account/AutoReplyForm.vue:12
#: src/components/quarantine/QuarantineList.vue:239
#: src/components/quarantine/QuarantineList.vue:49
#: src/components/webmail/ComposeEmailForm.vue:137
msgid "Subject"
msgstr ""
@@ -2550,12 +2756,18 @@ msgstr ""
msgid "there"
msgstr ""
#: src/components/admin/domains/DomainPolicyForm.vue:56
msgid "Thresholds"
msgstr ""
#: src/components/calendars/EventForm.vue:12
msgid "Title"
msgstr ""
#: src/components/admin/logs/MessageList.vue:49
#: src/components/calendars/EventForm.vue:34
#: src/components/quarantine/QuarantineList.vue:237
#: src/components/quarantine/QuarantineList.vue:52
#: src/components/tools/TimeSerieChart.vue:20
#: src/components/webmail/ComposeEmailForm.vue:46
#: src/views/webmail/EmailView.vue:109
@@ -2702,6 +2914,10 @@ msgstr "Nueva cuenta"
msgid "Use domain default value"
msgstr "Usar el valor por defecto del dominio"
#: src/composables/amavis.js:36
msgid "User's database"
msgstr ""
#: src/components/admin/domains/DomainAdminList.vue:111
#: src/components/admin/identities/AccountCreationForm.vue:97
#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:3
@@ -2721,6 +2937,15 @@ msgstr ""
msgid "Value"
msgstr ""
#: src/views/quarantine/MessageView.vue:62
msgid "View full headers"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:28
#, fuzzy
msgid "Virus filters"
msgstr "Dirección de email"
#: src/components/admin/dashboard/NewsFeedWidget.vue:21
msgid "Visit the official weblog for more information"
msgstr ""
@@ -2762,6 +2987,11 @@ msgstr "Semana"
msgid "Welcome to Modoboa"
msgstr "Bienvenido a Modoboa"
#: src/components/quarantine/QuarantineList.vue:386
#: src/views/quarantine/MessageView.vue:210
msgid "Which database should be used for this learning:"
msgstr ""
#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:25
msgid "With a mailbox"
msgstr "Con una mailbox"
@@ -2779,7 +3009,7 @@ msgstr ""
msgid "Year"
msgstr "Año"
#: src/plugins/filters.js:10
#: src/components/tools/YesNoDefaultField.vue:7 src/plugins/filters.js:10
msgid "yes"
msgstr ""
+238 -9
View File
@@ -70,7 +70,7 @@ msgid "Access rules"
msgstr ""
#: src/components/calendars/CalendarAccessRulesForm.vue:42
#: src/components/shared/TopMenu.vue:93
#: src/components/shared/TopMenu.vue:131
#: src/views/admin/identities/AccountView.vue:4
#: src/views/admin/identities/IdentitiesView.vue:23
msgid "Account"
@@ -353,6 +353,7 @@ msgstr "API-tunniste luotu"
msgid "API token deleted"
msgstr "API-tunniste poistettu"
#: src/components/admin/domains/DomainPolicyForm.vue:96
#: src/components/tools/ChooseColumnsForm.vue:19
#: src/components/tools/TimeSerieChart.vue:22
msgid "Apply"
@@ -444,6 +445,11 @@ msgstr "Takaisin"
msgid "Backup codes"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:39
#, fuzzy
msgid "Banned filters"
msgstr "Viestien historia"
#: src/components/webmail/ComposeEmailForm.vue:110
#: src/components/webmail/ComposeEmailForm.vue:73
msgid "Bcc"
@@ -458,6 +464,14 @@ msgstr "Bind/nimetty muoto. Kopioi klikkaamalla"
msgid "Birth date"
msgstr "Luontipäivä"
#: src/components/quarantine/QuarantineList.vue:54
msgid "both"
msgstr ""
#: src/components/admin/domains/form_steps/DomainPolicyForm.vue:5
msgid "Bypass virus checks"
msgstr ""
#: src/components/calendars/EventForm.vue:49
#: src/views/calendars/CalendarView.vue:3
msgid "Calendar"
@@ -492,6 +506,7 @@ msgstr "Profiili päivitetty"
#: src/components/account/FilterForm.vue:147
#: src/components/account/FilterSetForm.vue:24
#: src/components/admin/domains/DomainEditForm.vue:161
#: src/components/admin/domains/DomainPolicyForm.vue:93
#: src/components/admin/identities/AccountEditForm.vue:183
#: src/components/admin/identities/AliasEditForm.vue:69
#: src/components/admin/imap_migration/ProviderForm.vue:58
@@ -586,7 +601,7 @@ msgstr ""
#: src/components/tools/ImportForm.vue:51
#: src/components/webmail/AttachmentsDialog.vue:41
#: src/components/webmail/MailboxForm.vue:29
#: src/layouts/connected/ConnectedLayout.vue:17
#: src/layouts/connected/ConnectedLayout.vue:19
msgid "Close"
msgstr "Sulje"
@@ -649,6 +664,16 @@ msgstr ""
msgid "Content"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:5
#, fuzzy
msgid "Content filter"
msgstr "Uudet palautuskoodit"
#: src/components/admin/domains/DomainPolicyForm.vue:4
#, fuzzy
msgid "Content filter settings"
msgstr "Yleiset asetukset"
#: src/components/tools/ImportForm.vue:40
msgid "Continue on error"
msgstr "Jatka virheestä"
@@ -764,6 +789,7 @@ msgstr "Työpöytä"
#: src/components/admin/logs/AuditTrailList.vue:51
#: src/components/admin/logs/MessageList.vue:47
#: src/components/quarantine/QuarantineList.vue:240
msgid "Date"
msgstr "Päivämäärä"
@@ -771,6 +797,11 @@ msgstr "Päivämäärä"
msgid "Day"
msgstr "Päivä"
#: src/components/admin/domains/DomainPolicyForm.vue:47
#: src/components/tools/YesNoDefaultField.vue:15
msgid "default"
msgstr ""
#: src/components/admin/domains/DomainCreationForm.vue:193
#: src/components/admin/domains/DomainSummary.vue:23
#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:19
@@ -785,6 +816,16 @@ msgstr ""
"Postilaatikoihin sovellettava oletuskiintiö. Voidaan ilmaista kilotavuina, "
"megatavuina (oletus) tai gigatavuina. Arvo 0 tarkoittaa, ettei kiintiötä ole."
#: src/components/admin/domains/DomainPolicy.vue:24
#: src/components/admin/domains/DomainPolicy.vue:35
#: src/components/admin/domains/DomainPolicy.vue:46
#: src/components/admin/domains/DomainPolicy.vue:57
#: src/components/admin/domains/DomainPolicy.vue:68
#: src/components/admin/domains/DomainPolicy.vue:79
#, fuzzy
msgid "Default value"
msgstr "Verkkotunnuksen oletusarvo"
#: src/components/admin/alarms/AlarmList.vue:116
#: src/components/admin/alarms/AlarmList.vue:133
#: src/components/admin/domains/DomainAliasForm.vue:39
@@ -807,6 +848,16 @@ msgstr "Poista"
msgid "Delete filter set"
msgstr "Valitse tiedosto"
#: src/views/quarantine/MessageView.vue:32
#, fuzzy
msgid "Delete message"
msgstr "viestit"
#: src/components/quarantine/QuarantineList.vue:84
#, fuzzy
msgid "Delete selection"
msgstr "Poista avain"
#: src/layouts/webmail/WebmailLayout.vue:56
#, fuzzy
msgid "Delete this mailbox"
@@ -843,15 +894,35 @@ msgstr "Pois käytöstä"
msgid "Disable 2FA"
msgstr "Poista kaksivaiheinen tunnistautuminen (2FA) käytöstä"
#: src/components/admin/domains/DomainPolicyForm.vue:26
#, fuzzy
msgid "Disable banned checks"
msgstr "Pois käytöstä"
#: src/views/webmail/EmailView.vue:74
#, fuzzy
msgid "Disable links"
msgstr "Pois käytöstä"
#: src/components/admin/domains/DomainPolicyForm.vue:18
#, fuzzy
msgid "Disable spam checks"
msgstr "Ota DNS-tarkistukset käyttöön"
#: src/components/admin/domains/DomainPolicyForm.vue:11
#, fuzzy
msgid "Disable virus checks"
msgstr "Pois käytöstä"
#: src/components/admin/domains/DNSStatusChip.vue:18
msgid "Disabled"
msgstr "Pois käytöstä"
#: src/components/quarantine/QuarantineList.vue:125
#, fuzzy
msgid "Display"
msgstr "Etunimi"
#: src/components/contacts/ContactList.vue:23
msgid "Display address book information"
msgstr ""
@@ -1032,6 +1103,11 @@ msgstr ""
msgid "Domain name (ex: domain.tld)"
msgstr "Verkkotunnus (esim. domain.tld)"
#: src/composables/amavis.js:33
#, fuzzy
msgid "Domain's database"
msgstr "Verkkotunnus päivitetty"
#: src/components/admin/identities/AccountEditForm.vue:82
msgid "domain's default value"
msgstr "verkkotunnuksen oletusarvo"
@@ -1087,6 +1163,10 @@ msgstr "Sähköpostiosoite"
msgid "Edit contact"
msgstr "Muokkaa tiliä"
#: src/components/admin/domains/DomainPolicy.vue:9
msgid "Edit content filter settings"
msgstr ""
#: src/views/admin/domains/DomainEditView.vue:3
msgid "Edit domain"
msgstr "Muokkaa verkkotunnusta"
@@ -1341,11 +1421,17 @@ msgstr ""
#: src/components/account/AutoReplyForm.vue:36
#: src/components/admin/logs/MessageList.vue:50
#: src/components/calendars/EventForm.vue:24
#: src/components/quarantine/QuarantineList.vue:238
#: src/components/tools/TimeSerieChart.vue:19
#: src/components/webmail/ComposeEmailForm.vue:29
msgid "From"
msgstr "Lähde"
#: src/components/quarantine/QuarantineList.vue:45
#, fuzzy
msgid "From address"
msgstr "Satunnainen osoite"
#: src/components/calendars/CalendarAccessRulesForm.vue:11
#, fuzzy
msgid "Full address"
@@ -1398,6 +1484,10 @@ msgstr "Luo uusi DKIM-avain"
msgid "Generated address"
msgstr "Lähettäjän osoitteet"
#: src/composables/amavis.js:30
msgid "Global database"
msgstr ""
#: src/views/admin/InformationView.vue:29
msgid "Go to <strong>Settings > General</strong> section"
msgstr ""
@@ -1415,6 +1505,10 @@ msgstr ""
"Tässä on esimerkki DNS-määrityksistä (bind-muodossa). Korvaa [ ]:n välissä "
"olevat arvot sopivilla arvoilla."
#: src/views/quarantine/MessageView.vue:65
msgid "Hide full headers"
msgstr ""
#: src/components/admin/identities/AccountCreationForm.vue:168
#: src/components/admin/identities/AccountCreationForm.vue:95
#: src/components/admin/identities/AccountEditForm.vue:31
@@ -1591,6 +1685,12 @@ msgstr "Asennettu versio"
msgid "Latest version"
msgstr "Asennettu versio"
#: src/components/quarantine/QuarantineList.vue:385
#: src/views/quarantine/MessageView.vue:209
#, fuzzy
msgid "Learning database"
msgstr "Luontipäivä"
#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:26
msgid "Leave empty for no limit"
msgstr "Jätä tyhjäksi, jos rajaa ei ole"
@@ -1618,7 +1718,7 @@ msgstr ""
msgid "Logger"
msgstr "Lokikirja"
#: src/components/shared/TopMenu.vue:100
#: src/components/shared/TopMenu.vue:138
msgid "Logout"
msgstr "Kirjaudu ulos"
@@ -1666,10 +1766,23 @@ msgstr ""
msgid "Mark as followed"
msgstr ""
#: src/views/quarantine/MessageView.vue:47
msgid "Mark as non-spam"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:105
msgid "Mark as not spam"
msgstr ""
#: src/components/webmail/EmailList.vue:62
msgid "Mark as read"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:101
#: src/views/quarantine/MessageView.vue:43
msgid "Mark as spam"
msgstr ""
#: src/components/webmail/EmailList.vue:77
msgid "Mark as unfollowed"
msgstr ""
@@ -1688,7 +1801,7 @@ msgstr ""
msgid "Message"
msgstr "Viesti"
#: src/views/webmail/EmailView.vue:254
#: src/views/quarantine/MessageView.vue:196 src/views/webmail/EmailView.vue:254
#, fuzzy
msgid "Message deleted"
msgstr "Viestien historia"
@@ -1711,10 +1824,26 @@ msgstr "Viestien lähetysraja"
msgid "Message marked as junk"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:291
#: src/views/quarantine/MessageView.vue:236
msgid "Message marked as non-spam"
msgstr ""
#: src/views/webmail/EmailView.vue:282
msgid "Message marked as not junk"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:288
#: src/views/quarantine/MessageView.vue:232
msgid "Message marked as spam"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:285
#: src/views/quarantine/MessageView.vue:178
#, fuzzy
msgid "Message released"
msgstr "Viestien historia"
#: src/components/admin/domains/DomainCreationForm.vue:197
#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:32
#: src/components/admin/identities/AccountCreationForm.vue:133
@@ -1910,7 +2039,7 @@ msgstr "Uudet palautuskoodit"
msgid "Next"
msgstr "Seuraava"
#: src/plugins/filters.js:10
#: src/components/tools/YesNoDefaultField.vue:11 src/plugins/filters.js:10
msgid "no"
msgstr "ei"
@@ -1978,6 +2107,11 @@ msgstr "Ei luotu"
msgid "Note"
msgstr ""
#: src/components/shared/TopMenu.vue:18
#, fuzzy
msgid "Notifications"
msgstr "Tunniste"
#: src/components/admin/identities/AccountEditForm.vue:163
#, fuzzy
msgid "Number of allowed mailbox aliases:"
@@ -2046,6 +2180,14 @@ msgstr "Avatut hälytykset"
msgid "Options"
msgstr "Vaihtoehdot"
#: src/components/admin/domains/DomainPolicyForm.vue:69
msgid "or more is spam"
msgstr ""
#: src/components/admin/domains/DomainPolicyForm.vue:84
msgid "or more throw spam message away"
msgstr ""
#: src/components/account/ProfileForm.vue:30
msgid "or suggest a new language"
msgstr ""
@@ -2197,6 +2339,15 @@ msgstr "Profiili päivitetty"
msgid "Providers"
msgstr "Etunimi"
#: src/views/quarantine/QuarantineView.vue:4
msgid "Quarantine"
msgstr ""
#: src/views/quarantine/MessageView.vue:4
#, fuzzy
msgid "Quarantined message"
msgstr "Tuo verkkotunnuksia"
#: src/components/admin/logs/MessageList.vue:46
msgid "Queue ID"
msgstr "Jonon ID"
@@ -2289,6 +2440,10 @@ msgstr "Kaksivaiheinent tunnistus"
msgid "Registered Webauthn devices"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:61
msgid "Rejection threshold"
msgstr ""
#: src/components/tools/TimeSerieChart.vue:27
msgid "Relative time ranges"
msgstr "Suhteelliset aikavälialueet"
@@ -2302,6 +2457,24 @@ msgstr "Välitysrele"
msgid "Relay domain"
msgstr "Uusi verkkotunnus"
#: src/views/quarantine/MessageView.vue:21
#, fuzzy
msgid "Release message"
msgstr "viestit"
#: src/components/quarantine/QuarantineList.vue:372
#: src/views/quarantine/MessageView.vue:176
msgid "Release request sent"
msgstr ""
#: src/views/quarantine/QuarantineView.vue:12
msgid "release requests"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:72
msgid "Release selection"
msgstr ""
#: src/components/admin/alarms/AlarmList.vue:123
msgid "Reload"
msgstr ""
@@ -2376,6 +2549,10 @@ msgstr "Tallenna"
msgid "Save your changes"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:236
msgid "Score"
msgstr ""
#: src/components/admin/alarms/AlarmList.vue:21
#: src/components/admin/domains/DomainList.vue:19
#: src/components/admin/identities/IdentityList.vue:24
@@ -2386,6 +2563,7 @@ msgstr ""
msgid "Search"
msgstr "Hae"
#: src/components/quarantine/QuarantineList.vue:27
#: src/components/webmail/EmailList.vue:14
#, fuzzy
msgid "Search in messages"
@@ -2426,6 +2604,20 @@ msgstr ""
msgid "Select file"
msgstr "Valitse tiedosto"
#: src/components/quarantine/QuarantineList.vue:359
#, fuzzy
msgid "Selection deleted"
msgstr "Luontipäivä"
#: src/components/quarantine/QuarantineList.vue:398
msgid "Selection is being processed..."
msgstr ""
#: src/components/quarantine/QuarantineList.vue:374
#, fuzzy
msgid "Selection released"
msgstr "Valitse tiedosto"
#: src/components/calendars/ImportEventsForm.vue:30
#: src/components/webmail/ComposeEmailForm.vue:13
#, fuzzy
@@ -2504,6 +2696,20 @@ msgstr "Näytä avain"
msgid "Simple user"
msgstr "Yksinkertainen käyttäjä"
#: src/components/admin/domains/DomainPolicy.vue:50
msgid "Spam classification threshold"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:17
#, fuzzy
msgid "Spam filters"
msgstr "Viestien historia"
#: src/components/admin/domains/DomainPolicy.vue:72
#: src/components/admin/domains/DomainPolicyForm.vue:34
msgid "Spam marker"
msgstr ""
#: src/components/admin/identities/AccountSenderAddresses.vue:17
msgid "Specify an email address"
msgstr "Määritä sähköpostiosoite"
@@ -2539,6 +2745,8 @@ msgid "Status"
msgstr "Tila"
#: src/components/account/AutoReplyForm.vue:12
#: src/components/quarantine/QuarantineList.vue:239
#: src/components/quarantine/QuarantineList.vue:49
#: src/components/webmail/ComposeEmailForm.vue:137
msgid "Subject"
msgstr ""
@@ -2611,12 +2819,18 @@ msgstr ""
msgid "there"
msgstr ""
#: src/components/admin/domains/DomainPolicyForm.vue:56
msgid "Thresholds"
msgstr ""
#: src/components/calendars/EventForm.vue:12
msgid "Title"
msgstr ""
#: src/components/admin/logs/MessageList.vue:49
#: src/components/calendars/EventForm.vue:34
#: src/components/quarantine/QuarantineList.vue:237
#: src/components/quarantine/QuarantineList.vue:52
#: src/components/tools/TimeSerieChart.vue:20
#: src/components/webmail/ComposeEmailForm.vue:46
#: src/views/webmail/EmailView.vue:109
@@ -2761,6 +2975,10 @@ msgstr "Uusi tili"
msgid "Use domain default value"
msgstr "Käytä verkkotunnuksen oletusarvoa"
#: src/composables/amavis.js:36
msgid "User's database"
msgstr ""
#: src/components/admin/domains/DomainAdminList.vue:111
#: src/components/admin/identities/AccountCreationForm.vue:97
#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:3
@@ -2779,6 +2997,15 @@ msgstr "Kelvollinen"
msgid "Value"
msgstr ""
#: src/views/quarantine/MessageView.vue:62
msgid "View full headers"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:28
#, fuzzy
msgid "Virus filters"
msgstr "Sähköpostiosoite"
#: src/components/admin/dashboard/NewsFeedWidget.vue:21
msgid "Visit the official weblog for more information"
msgstr ""
@@ -2821,6 +3048,11 @@ msgstr "Viikko"
msgid "Welcome to Modoboa"
msgstr "Tervetuloa Modoboaan"
#: src/components/quarantine/QuarantineList.vue:386
#: src/views/quarantine/MessageView.vue:210
msgid "Which database should be used for this learning:"
msgstr ""
#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:25
msgid "With a mailbox"
msgstr "Postilaatikolla"
@@ -2838,7 +3070,7 @@ msgstr ""
msgid "Year"
msgstr "Vuosi"
#: src/plugins/filters.js:10
#: src/components/tools/YesNoDefaultField.vue:7 src/plugins/filters.js:10
msgid "yes"
msgstr "kyllä"
@@ -2978,9 +3210,6 @@ msgstr "Uusi"
#~ msgid "domain"
#~ msgstr "Verkkotunnus"
#~ msgid "Domain updated"
#~ msgstr "Verkkotunnus päivitetty"
#~ msgid "Invalid password"
#~ msgstr "Virheellinen salasana"
+244 -6
View File
@@ -74,7 +74,7 @@ msgid "Access rules"
msgstr "Règles d'accès"
#: src/components/calendars/CalendarAccessRulesForm.vue:42
#: src/components/shared/TopMenu.vue:93
#: src/components/shared/TopMenu.vue:131
#: src/views/admin/identities/AccountView.vue:4
#: src/views/admin/identities/IdentitiesView.vue:23
msgid "Account"
@@ -339,6 +339,7 @@ msgstr "Jeton API créé"
msgid "API token deleted"
msgstr "Jeton API supprimé"
#: src/components/admin/domains/DomainPolicyForm.vue:96
#: src/components/tools/ChooseColumnsForm.vue:19
#: src/components/tools/TimeSerieChart.vue:22
msgid "Apply"
@@ -426,6 +427,11 @@ msgstr "Retour"
msgid "Backup codes"
msgstr "Codes de récupération"
#: src/components/admin/domains/DomainPolicy.vue:39
#, fuzzy
msgid "Banned filters"
msgstr "Filtres de messages"
#: src/components/webmail/ComposeEmailForm.vue:110
#: src/components/webmail/ComposeEmailForm.vue:73
msgid "Bcc"
@@ -439,6 +445,14 @@ msgstr "Format bind/named. Cliquez pour copier"
msgid "Birth date"
msgstr "Date de naissance"
#: src/components/quarantine/QuarantineList.vue:54
msgid "both"
msgstr ""
#: src/components/admin/domains/form_steps/DomainPolicyForm.vue:5
msgid "Bypass virus checks"
msgstr ""
#: src/components/calendars/EventForm.vue:49
#: src/views/calendars/CalendarView.vue:3
msgid "Calendar"
@@ -469,6 +483,7 @@ msgstr "Calendrier mis à jour"
#: src/components/account/FilterForm.vue:147
#: src/components/account/FilterSetForm.vue:24
#: src/components/admin/domains/DomainEditForm.vue:161
#: src/components/admin/domains/DomainPolicyForm.vue:93
#: src/components/admin/identities/AccountEditForm.vue:183
#: src/components/admin/identities/AliasEditForm.vue:69
#: src/components/admin/imap_migration/ProviderForm.vue:58
@@ -560,7 +575,7 @@ msgstr "Cliquer ici pour copier la clé"
#: src/components/tools/ImportForm.vue:51
#: src/components/webmail/AttachmentsDialog.vue:41
#: src/components/webmail/MailboxForm.vue:29
#: src/layouts/connected/ConnectedLayout.vue:17
#: src/layouts/connected/ConnectedLayout.vue:19
msgid "Close"
msgstr "Fermer"
@@ -620,6 +635,16 @@ msgstr "Contacts"
msgid "Content"
msgstr "Contenu"
#: src/components/admin/domains/DomainPolicy.vue:5
#, fuzzy
msgid "Content filter"
msgstr "Contenu"
#: src/components/admin/domains/DomainPolicyForm.vue:4
#, fuzzy
msgid "Content filter settings"
msgstr "Paramètres généraux "
#: src/components/tools/ImportForm.vue:40
msgid "Continue on error"
msgstr "Continuer en cas d'erreur"
@@ -731,6 +756,7 @@ msgstr "Tableau de bord"
#: src/components/admin/logs/AuditTrailList.vue:51
#: src/components/admin/logs/MessageList.vue:47
#: src/components/quarantine/QuarantineList.vue:240
msgid "Date"
msgstr "Date"
@@ -738,6 +764,11 @@ msgstr "Date"
msgid "Day"
msgstr "Jour"
#: src/components/admin/domains/DomainPolicyForm.vue:47
#: src/components/tools/YesNoDefaultField.vue:15
msgid "default"
msgstr ""
#: src/components/admin/domains/DomainCreationForm.vue:193
#: src/components/admin/domains/DomainSummary.vue:23
#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:19
@@ -752,6 +783,16 @@ msgstr ""
"Quota par défaut appliqué aux boîtes aux lettres. Peut être exprimé en Ko, "
"Mo (défaut) ou Go. Une valeur à 0 signifie pas de quota."
#: src/components/admin/domains/DomainPolicy.vue:24
#: src/components/admin/domains/DomainPolicy.vue:35
#: src/components/admin/domains/DomainPolicy.vue:46
#: src/components/admin/domains/DomainPolicy.vue:57
#: src/components/admin/domains/DomainPolicy.vue:68
#: src/components/admin/domains/DomainPolicy.vue:79
#, fuzzy
msgid "Default value"
msgstr "Valeur du domaine par défaut"
#: src/components/admin/alarms/AlarmList.vue:116
#: src/components/admin/alarms/AlarmList.vue:133
#: src/components/admin/domains/DomainAliasForm.vue:39
@@ -773,6 +814,16 @@ msgstr "Supprimer"
msgid "Delete filter set"
msgstr "Supprimer le jeu de filtre"
#: src/views/quarantine/MessageView.vue:32
#, fuzzy
msgid "Delete message"
msgstr "Tous les messages"
#: src/components/quarantine/QuarantineList.vue:84
#, fuzzy
msgid "Delete selection"
msgstr "Supprimer le jeton"
#: src/layouts/webmail/WebmailLayout.vue:56
msgid "Delete this mailbox"
msgstr "Supprimer cette boite aux lettres"
@@ -806,14 +857,34 @@ msgstr "Desactiver"
msgid "Disable 2FA"
msgstr "Désactiver l'authentification à double facteur"
#: src/components/admin/domains/DomainPolicyForm.vue:26
#, fuzzy
msgid "Disable banned checks"
msgstr "Desactiver les liens"
#: src/views/webmail/EmailView.vue:74
msgid "Disable links"
msgstr "Desactiver les liens"
#: src/components/admin/domains/DomainPolicyForm.vue:18
#, fuzzy
msgid "Disable spam checks"
msgstr "Activer les tests DNS"
#: src/components/admin/domains/DomainPolicyForm.vue:11
#, fuzzy
msgid "Disable virus checks"
msgstr "Desactiver les liens"
#: src/components/admin/domains/DNSStatusChip.vue:18
msgid "Disabled"
msgstr "Désactivés"
#: src/components/quarantine/QuarantineList.vue:125
#, fuzzy
msgid "Display"
msgstr "Nom affiché"
#: src/components/contacts/ContactList.vue:23
msgid "Display address book information"
msgstr "Afficher les informations du carnet d'adresse"
@@ -984,6 +1055,11 @@ msgstr "Supprimer le domaine"
msgid "Domain name (ex: domain.tld)"
msgstr "Nom de domaine (ex: domaine.tld)"
#: src/composables/amavis.js:33
#, fuzzy
msgid "Domain's database"
msgstr "La valeur par défaut du domaine"
#: src/components/admin/identities/AccountEditForm.vue:82
msgid "domain's default value"
msgstr "La valeur par défaut du domaine"
@@ -1035,6 +1111,10 @@ msgstr "Modifier la catégorie"
msgid "Edit contact"
msgstr "Modifier le contact"
#: src/components/admin/domains/DomainPolicy.vue:9
msgid "Edit content filter settings"
msgstr ""
#: src/views/admin/domains/DomainEditView.vue:3
msgid "Edit domain"
msgstr "Modifier le domaine"
@@ -1269,11 +1349,17 @@ msgstr "Transporteur avec ARC"
#: src/components/account/AutoReplyForm.vue:36
#: src/components/admin/logs/MessageList.vue:50
#: src/components/calendars/EventForm.vue:24
#: src/components/quarantine/QuarantineList.vue:238
#: src/components/tools/TimeSerieChart.vue:19
#: src/components/webmail/ComposeEmailForm.vue:29
msgid "From"
msgstr "De"
#: src/components/quarantine/QuarantineList.vue:45
#, fuzzy
msgid "From address"
msgstr "Adresse aléatoire"
#: src/components/calendars/CalendarAccessRulesForm.vue:11
msgid "Full address"
msgstr "Adresse complète"
@@ -1323,6 +1409,10 @@ msgstr "Générer une nouvelle clé DKIM"
msgid "Generated address"
msgstr "Adresse générée"
#: src/composables/amavis.js:30
msgid "Global database"
msgstr ""
#: src/views/admin/InformationView.vue:29
msgid "Go to <strong>Settings > General</strong> section"
msgstr "Allez dans la section <strong>Paramètres > Général</strong>"
@@ -1340,6 +1430,10 @@ msgstr ""
"Voici un exemplaire de configuration DNS (format bind). Remplacer les "
"valeurs entre [ ] par les valeurs appropriées."
#: src/views/quarantine/MessageView.vue:65
msgid "Hide full headers"
msgstr ""
#: src/components/admin/identities/AccountCreationForm.vue:168
#: src/components/admin/identities/AccountCreationForm.vue:95
#: src/components/admin/identities/AccountEditForm.vue:31
@@ -1511,6 +1605,12 @@ msgstr "Dernières nouvelles"
msgid "Latest version"
msgstr "Dernière version"
#: src/components/quarantine/QuarantineList.vue:385
#: src/views/quarantine/MessageView.vue:209
#, fuzzy
msgid "Learning database"
msgstr "Date de création"
#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:26
msgid "Leave empty for no limit"
msgstr "Laisser vide pour aucune limite"
@@ -1538,7 +1638,7 @@ msgstr "Domaine local (optionnel)"
msgid "Logger"
msgstr "Logger"
#: src/components/shared/TopMenu.vue:100
#: src/components/shared/TopMenu.vue:138
msgid "Logout"
msgstr "Déconnexion"
@@ -1586,10 +1686,26 @@ msgstr ""
msgid "Mark as followed"
msgstr "Marquer comme suivi"
#: src/views/quarantine/MessageView.vue:47
#, fuzzy
msgid "Mark as non-spam"
msgstr "Marquer comme non lu"
#: src/components/quarantine/QuarantineList.vue:105
#, fuzzy
msgid "Mark as not spam"
msgstr "Marquer comme non lu"
#: src/components/webmail/EmailList.vue:62
msgid "Mark as read"
msgstr "Marqué comme lu"
#: src/components/quarantine/QuarantineList.vue:101
#: src/views/quarantine/MessageView.vue:43
#, fuzzy
msgid "Mark as spam"
msgstr "Marqué comme lu"
#: src/components/webmail/EmailList.vue:77
msgid "Mark as unfollowed"
msgstr "Marqué comme non suivi"
@@ -1608,7 +1724,7 @@ msgstr "Mo"
msgid "Message"
msgstr "Message"
#: src/views/webmail/EmailView.vue:254
#: src/views/quarantine/MessageView.vue:196 src/views/webmail/EmailView.vue:254
msgid "Message deleted"
msgstr "Marquer comme supprimé"
@@ -1628,10 +1744,28 @@ msgstr "Limite de messages"
msgid "Message marked as junk"
msgstr "Message marqué comme pourriel"
#: src/components/quarantine/QuarantineList.vue:291
#: src/views/quarantine/MessageView.vue:236
#, fuzzy
msgid "Message marked as non-spam"
msgstr "Message marqué comme légitime"
#: src/views/webmail/EmailView.vue:282
msgid "Message marked as not junk"
msgstr "Message marqué comme légitime"
#: src/components/quarantine/QuarantineList.vue:288
#: src/views/quarantine/MessageView.vue:232
#, fuzzy
msgid "Message marked as spam"
msgstr "Message marqué comme pourriel"
#: src/components/quarantine/QuarantineList.vue:285
#: src/views/quarantine/MessageView.vue:178
#, fuzzy
msgid "Message released"
msgstr "Marquer comme supprimé"
#: src/components/admin/domains/DomainCreationForm.vue:197
#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:32
#: src/components/admin/identities/AccountCreationForm.vue:133
@@ -1814,7 +1948,7 @@ msgstr "Nouveaux codes de récupération"
msgid "Next"
msgstr "Suivant"
#: src/plugins/filters.js:10
#: src/components/tools/YesNoDefaultField.vue:11 src/plugins/filters.js:10
msgid "no"
msgstr "non"
@@ -1880,6 +2014,11 @@ msgstr "Non générée"
msgid "Note"
msgstr "Note"
#: src/components/shared/TopMenu.vue:18
#, fuzzy
msgid "Notifications"
msgstr "Identification"
#: src/components/admin/identities/AccountEditForm.vue:163
msgid "Number of allowed mailbox aliases:"
msgstr "Nombre d'alias autorisé :"
@@ -1943,6 +2082,14 @@ msgstr "Alarmes ouvertes"
msgid "Options"
msgstr "Options"
#: src/components/admin/domains/DomainPolicyForm.vue:69
msgid "or more is spam"
msgstr ""
#: src/components/admin/domains/DomainPolicyForm.vue:84
msgid "or more throw spam message away"
msgstr ""
#: src/components/account/ProfileForm.vue:30
msgid "or suggest a new language"
msgstr "ou suggérer une nouvelle langue"
@@ -2088,6 +2235,15 @@ msgstr "Fournisseur mis à jour"
msgid "Providers"
msgstr "Fournisseurs"
#: src/views/quarantine/QuarantineView.vue:4
msgid "Quarantine"
msgstr ""
#: src/views/quarantine/MessageView.vue:4
#, fuzzy
msgid "Quarantined message"
msgstr "Messages importants"
#: src/components/admin/logs/MessageList.vue:46
msgid "Queue ID"
msgstr "ID de file"
@@ -2177,6 +2333,10 @@ msgstr "Enregistrer l'authentificateur"
msgid "Registered Webauthn devices"
msgstr "Péréphériques Webauthn enregistrés"
#: src/components/admin/domains/DomainPolicy.vue:61
msgid "Rejection threshold"
msgstr ""
#: src/components/tools/TimeSerieChart.vue:27
msgid "Relative time ranges"
msgstr "Intervalles des temps relatifs"
@@ -2189,6 +2349,25 @@ msgstr "Relais"
msgid "Relay domain"
msgstr "Domaine relais"
#: src/views/quarantine/MessageView.vue:21
#, fuzzy
msgid "Release message"
msgstr "Tous les messages"
#: src/components/quarantine/QuarantineList.vue:372
#: src/views/quarantine/MessageView.vue:176
msgid "Release request sent"
msgstr ""
#: src/views/quarantine/QuarantineView.vue:12
msgid "release requests"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:72
#, fuzzy
msgid "Release selection"
msgstr "Supprimer l'action"
#: src/components/admin/alarms/AlarmList.vue:123
msgid "Reload"
msgstr "Recharger"
@@ -2261,6 +2440,10 @@ msgstr "Enregistrer"
msgid "Save your changes"
msgstr "Sauvegardez vos changements"
#: src/components/quarantine/QuarantineList.vue:236
msgid "Score"
msgstr ""
#: src/components/admin/alarms/AlarmList.vue:21
#: src/components/admin/domains/DomainList.vue:19
#: src/components/admin/identities/IdentityList.vue:24
@@ -2271,6 +2454,7 @@ msgstr "Sauvegardez vos changements"
msgid "Search"
msgstr "Chercher"
#: src/components/quarantine/QuarantineList.vue:27
#: src/components/webmail/EmailList.vue:14
msgid "Search in messages"
msgstr "Chercher dans les messages"
@@ -2308,6 +2492,20 @@ msgstr ""
msgid "Select file"
msgstr "Sélectionner un fichier"
#: src/components/quarantine/QuarantineList.vue:359
#, fuzzy
msgid "Selection deleted"
msgstr "Migration supprimée"
#: src/components/quarantine/QuarantineList.vue:398
msgid "Selection is being processed..."
msgstr ""
#: src/components/quarantine/QuarantineList.vue:374
#, fuzzy
msgid "Selection released"
msgstr "Sélectionner un fichier"
#: src/components/calendars/ImportEventsForm.vue:30
#: src/components/webmail/ComposeEmailForm.vue:13
msgid "Send"
@@ -2379,6 +2577,20 @@ msgstr "Afficher la clé"
msgid "Simple user"
msgstr "Utilisateur simple"
#: src/components/admin/domains/DomainPolicy.vue:50
msgid "Spam classification threshold"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:17
#, fuzzy
msgid "Spam filters"
msgstr "Filtres de messages"
#: src/components/admin/domains/DomainPolicy.vue:72
#: src/components/admin/domains/DomainPolicyForm.vue:34
msgid "Spam marker"
msgstr ""
#: src/components/admin/identities/AccountSenderAddresses.vue:17
msgid "Specify an email address"
msgstr "Spécifier une adresse e-mail"
@@ -2413,6 +2625,8 @@ msgid "Status"
msgstr "Statut"
#: src/components/account/AutoReplyForm.vue:12
#: src/components/quarantine/QuarantineList.vue:239
#: src/components/quarantine/QuarantineList.vue:49
#: src/components/webmail/ComposeEmailForm.vue:137
msgid "Subject"
msgstr "Sujet"
@@ -2490,12 +2704,18 @@ msgstr ""
msgid "there"
msgstr "ici"
#: src/components/admin/domains/DomainPolicyForm.vue:56
msgid "Thresholds"
msgstr ""
#: src/components/calendars/EventForm.vue:12
msgid "Title"
msgstr "Titre"
#: src/components/admin/logs/MessageList.vue:49
#: src/components/calendars/EventForm.vue:34
#: src/components/quarantine/QuarantineList.vue:237
#: src/components/quarantine/QuarantineList.vue:52
#: src/components/tools/TimeSerieChart.vue:20
#: src/components/webmail/ComposeEmailForm.vue:46
#: src/views/webmail/EmailView.vue:109
@@ -2638,6 +2858,10 @@ msgstr "Nombre d'utilisations"
msgid "Use domain default value"
msgstr "Utiliser la valeur par défaut du domaine"
#: src/composables/amavis.js:36
msgid "User's database"
msgstr ""
#: src/components/admin/domains/DomainAdminList.vue:111
#: src/components/admin/identities/AccountCreationForm.vue:97
#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:3
@@ -2656,6 +2880,15 @@ msgstr "Valide"
msgid "Value"
msgstr "Valeur"
#: src/views/quarantine/MessageView.vue:62
msgid "View full headers"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:28
#, fuzzy
msgid "Virus filters"
msgstr "Modifier le filtre"
#: src/components/admin/dashboard/NewsFeedWidget.vue:21
msgid "Visit the official weblog for more information"
msgstr "Visitez le weblog officiel pour plus d'information"
@@ -2696,6 +2929,11 @@ msgstr "Semaine"
msgid "Welcome to Modoboa"
msgstr "Bienvenue dans Modoboa"
#: src/components/quarantine/QuarantineList.vue:386
#: src/views/quarantine/MessageView.vue:210
msgid "Which database should be used for this learning:"
msgstr ""
#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:25
msgid "With a mailbox"
msgstr "Avec une boite aux lettres"
@@ -2713,7 +2951,7 @@ msgstr "Ecriture"
msgid "Year"
msgstr "Année"
#: src/plugins/filters.js:10
#: src/components/tools/YesNoDefaultField.vue:7 src/plugins/filters.js:10
msgid "yes"
msgstr "oui"
+236 -6
View File
@@ -63,7 +63,7 @@ msgid "Access rules"
msgstr ""
#: src/components/calendars/CalendarAccessRulesForm.vue:42
#: src/components/shared/TopMenu.vue:93
#: src/components/shared/TopMenu.vue:131
#: src/views/admin/identities/AccountView.vue:4
#: src/views/admin/identities/IdentitiesView.vue:23
msgid "Account"
@@ -341,6 +341,7 @@ msgstr "Account creato"
msgid "API token deleted"
msgstr "Data di creazione"
#: src/components/admin/domains/DomainPolicyForm.vue:96
#: src/components/tools/ChooseColumnsForm.vue:19
#: src/components/tools/TimeSerieChart.vue:22
msgid "Apply"
@@ -430,6 +431,11 @@ msgstr ""
msgid "Backup codes"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:39
#, fuzzy
msgid "Banned filters"
msgstr "Utilizzo"
#: src/components/webmail/ComposeEmailForm.vue:110
#: src/components/webmail/ComposeEmailForm.vue:73
msgid "Bcc"
@@ -444,6 +450,14 @@ msgstr "Formato bind/named"
msgid "Birth date"
msgstr "Data di nascita"
#: src/components/quarantine/QuarantineList.vue:54
msgid "both"
msgstr ""
#: src/components/admin/domains/form_steps/DomainPolicyForm.vue:5
msgid "Bypass virus checks"
msgstr ""
#: src/components/calendars/EventForm.vue:49
#: src/views/calendars/CalendarView.vue:3
msgid "Calendar"
@@ -478,6 +492,7 @@ msgstr "Profilo aggiornato"
#: src/components/account/FilterForm.vue:147
#: src/components/account/FilterSetForm.vue:24
#: src/components/admin/domains/DomainEditForm.vue:161
#: src/components/admin/domains/DomainPolicyForm.vue:93
#: src/components/admin/identities/AccountEditForm.vue:183
#: src/components/admin/identities/AliasEditForm.vue:69
#: src/components/admin/imap_migration/ProviderForm.vue:58
@@ -569,7 +584,7 @@ msgstr ""
#: src/components/tools/ImportForm.vue:51
#: src/components/webmail/AttachmentsDialog.vue:41
#: src/components/webmail/MailboxForm.vue:29
#: src/layouts/connected/ConnectedLayout.vue:17
#: src/layouts/connected/ConnectedLayout.vue:19
msgid "Close"
msgstr "Chiudi"
@@ -629,6 +644,16 @@ msgstr "Contatti"
msgid "Content"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:5
#, fuzzy
msgid "Content filter"
msgstr "Indirizzo email"
#: src/components/admin/domains/DomainPolicyForm.vue:4
#, fuzzy
msgid "Content filter settings"
msgstr "Generale"
#: src/components/tools/ImportForm.vue:40
msgid "Continue on error"
msgstr "Continuare in caso di errore"
@@ -744,6 +769,7 @@ msgstr ""
#: src/components/admin/logs/AuditTrailList.vue:51
#: src/components/admin/logs/MessageList.vue:47
#: src/components/quarantine/QuarantineList.vue:240
msgid "Date"
msgstr ""
@@ -751,6 +777,11 @@ msgstr ""
msgid "Day"
msgstr "Giorno"
#: src/components/admin/domains/DomainPolicyForm.vue:47
#: src/components/tools/YesNoDefaultField.vue:15
msgid "default"
msgstr ""
#: src/components/admin/domains/DomainCreationForm.vue:193
#: src/components/admin/domains/DomainSummary.vue:23
#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:19
@@ -766,6 +797,16 @@ msgstr ""
"essere espresso in KB, MB (predefinito) o GB. Il valore 0 indica nessun "
"limite."
#: src/components/admin/domains/DomainPolicy.vue:24
#: src/components/admin/domains/DomainPolicy.vue:35
#: src/components/admin/domains/DomainPolicy.vue:46
#: src/components/admin/domains/DomainPolicy.vue:57
#: src/components/admin/domains/DomainPolicy.vue:68
#: src/components/admin/domains/DomainPolicy.vue:79
#, fuzzy
msgid "Default value"
msgstr "Usa il valore predefinito"
#: src/components/admin/alarms/AlarmList.vue:116
#: src/components/admin/alarms/AlarmList.vue:133
#: src/components/admin/domains/DomainAliasForm.vue:39
@@ -787,6 +828,15 @@ msgstr ""
msgid "Delete filter set"
msgstr ""
#: src/views/quarantine/MessageView.vue:32
#, fuzzy
msgid "Delete message"
msgstr "Utilizzo"
#: src/components/quarantine/QuarantineList.vue:84
msgid "Delete selection"
msgstr ""
#: src/layouts/webmail/WebmailLayout.vue:56
#, fuzzy
msgid "Delete this mailbox"
@@ -823,15 +873,35 @@ msgstr "Disabilitato"
msgid "Disable 2FA"
msgstr "Disabilitato"
#: src/components/admin/domains/DomainPolicyForm.vue:26
#, fuzzy
msgid "Disable banned checks"
msgstr "Disabilitato"
#: src/views/webmail/EmailView.vue:74
#, fuzzy
msgid "Disable links"
msgstr "Disabilitato"
#: src/components/admin/domains/DomainPolicyForm.vue:18
#, fuzzy
msgid "Disable spam checks"
msgstr "Abilita i controlli DNS"
#: src/components/admin/domains/DomainPolicyForm.vue:11
#, fuzzy
msgid "Disable virus checks"
msgstr "Disabilitato"
#: src/components/admin/domains/DNSStatusChip.vue:18
msgid "Disabled"
msgstr "Disabilitato"
#: src/components/quarantine/QuarantineList.vue:125
#, fuzzy
msgid "Display"
msgstr "Nome visualizzato"
#: src/components/contacts/ContactList.vue:23
msgid "Display address book information"
msgstr ""
@@ -1004,6 +1074,11 @@ msgstr ""
msgid "Domain name (ex: domain.tld)"
msgstr ""
#: src/composables/amavis.js:33
#, fuzzy
msgid "Domain's database"
msgstr "Usa il valore predefinito"
#: src/components/admin/identities/AccountEditForm.vue:82
#, fuzzy
msgid "domain's default value"
@@ -1061,6 +1136,10 @@ msgstr "Indirizzo email"
msgid "Edit contact"
msgstr "Modifica contatto"
#: src/components/admin/domains/DomainPolicy.vue:9
msgid "Edit content filter settings"
msgstr ""
#: src/views/admin/domains/DomainEditView.vue:3
msgid "Edit domain"
msgstr ""
@@ -1316,11 +1395,17 @@ msgstr ""
#: src/components/account/AutoReplyForm.vue:36
#: src/components/admin/logs/MessageList.vue:50
#: src/components/calendars/EventForm.vue:24
#: src/components/quarantine/QuarantineList.vue:238
#: src/components/tools/TimeSerieChart.vue:19
#: src/components/webmail/ComposeEmailForm.vue:29
msgid "From"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:45
#, fuzzy
msgid "From address"
msgstr "Indirizzo casuale"
#: src/components/calendars/CalendarAccessRulesForm.vue:11
#, fuzzy
msgid "Full address"
@@ -1375,6 +1460,10 @@ msgstr ""
msgid "Generated address"
msgstr "Indirizzi mittenti"
#: src/composables/amavis.js:30
msgid "Global database"
msgstr ""
#: src/views/admin/InformationView.vue:29
msgid "Go to <strong>Settings > General</strong> section"
msgstr ""
@@ -1390,6 +1479,10 @@ msgid ""
"between [ ] by the appropriate ones."
msgstr ""
#: src/views/quarantine/MessageView.vue:65
msgid "Hide full headers"
msgstr ""
#: src/components/admin/identities/AccountCreationForm.vue:168
#: src/components/admin/identities/AccountCreationForm.vue:95
#: src/components/admin/identities/AccountEditForm.vue:31
@@ -1557,6 +1650,12 @@ msgstr "Versione installata"
msgid "Latest version"
msgstr "Versione installata"
#: src/components/quarantine/QuarantineList.vue:385
#: src/views/quarantine/MessageView.vue:209
#, fuzzy
msgid "Learning database"
msgstr "Data di creazione"
#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:26
msgid "Leave empty for no limit"
msgstr ""
@@ -1584,7 +1683,7 @@ msgstr ""
msgid "Logger"
msgstr "Logger"
#: src/components/shared/TopMenu.vue:100
#: src/components/shared/TopMenu.vue:138
msgid "Logout"
msgstr "Esci"
@@ -1632,10 +1731,23 @@ msgstr ""
msgid "Mark as followed"
msgstr ""
#: src/views/quarantine/MessageView.vue:47
msgid "Mark as non-spam"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:105
msgid "Mark as not spam"
msgstr ""
#: src/components/webmail/EmailList.vue:62
msgid "Mark as read"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:101
#: src/views/quarantine/MessageView.vue:43
msgid "Mark as spam"
msgstr ""
#: src/components/webmail/EmailList.vue:77
msgid "Mark as unfollowed"
msgstr ""
@@ -1654,7 +1766,7 @@ msgstr ""
msgid "Message"
msgstr "Utilizzo"
#: src/views/webmail/EmailView.vue:254
#: src/views/quarantine/MessageView.vue:196 src/views/webmail/EmailView.vue:254
#, fuzzy
msgid "Message deleted"
msgstr "Utilizzo"
@@ -1678,10 +1790,26 @@ msgstr "Utilizzo"
msgid "Message marked as junk"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:291
#: src/views/quarantine/MessageView.vue:236
msgid "Message marked as non-spam"
msgstr ""
#: src/views/webmail/EmailView.vue:282
msgid "Message marked as not junk"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:288
#: src/views/quarantine/MessageView.vue:232
msgid "Message marked as spam"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:285
#: src/views/quarantine/MessageView.vue:178
#, fuzzy
msgid "Message released"
msgstr "Utilizzo"
#: src/components/admin/domains/DomainCreationForm.vue:197
#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:32
#: src/components/admin/identities/AccountCreationForm.vue:133
@@ -1876,7 +2004,7 @@ msgstr ""
msgid "Next"
msgstr "Successivo"
#: src/plugins/filters.js:10
#: src/components/tools/YesNoDefaultField.vue:11 src/plugins/filters.js:10
msgid "no"
msgstr ""
@@ -1943,6 +2071,11 @@ msgstr "Non generata"
msgid "Note"
msgstr "Note"
#: src/components/shared/TopMenu.vue:18
#, fuzzy
msgid "Notifications"
msgstr "Data dell'ultima modifica"
#: src/components/admin/identities/AccountEditForm.vue:163
#, fuzzy
msgid "Number of allowed mailbox aliases:"
@@ -2006,6 +2139,14 @@ msgstr ""
msgid "Options"
msgstr "Opzioni"
#: src/components/admin/domains/DomainPolicyForm.vue:69
msgid "or more is spam"
msgstr ""
#: src/components/admin/domains/DomainPolicyForm.vue:84
msgid "or more throw spam message away"
msgstr ""
#: src/components/account/ProfileForm.vue:30
msgid "or suggest a new language"
msgstr ""
@@ -2159,6 +2300,15 @@ msgstr "Profilo aggiornato"
msgid "Providers"
msgstr "Indirizzo email"
#: src/views/quarantine/QuarantineView.vue:4
msgid "Quarantine"
msgstr ""
#: src/views/quarantine/MessageView.vue:4
#, fuzzy
msgid "Quarantined message"
msgstr "Importa domini"
#: src/components/admin/logs/MessageList.vue:46
msgid "Queue ID"
msgstr ""
@@ -2250,6 +2400,10 @@ msgstr "Autenticazione"
msgid "Registered Webauthn devices"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:61
msgid "Rejection threshold"
msgstr ""
#: src/components/tools/TimeSerieChart.vue:27
msgid "Relative time ranges"
msgstr ""
@@ -2263,6 +2417,24 @@ msgstr ""
msgid "Relay domain"
msgstr "Nuovo dominio"
#: src/views/quarantine/MessageView.vue:21
#, fuzzy
msgid "Release message"
msgstr "Utilizzo"
#: src/components/quarantine/QuarantineList.vue:372
#: src/views/quarantine/MessageView.vue:176
msgid "Release request sent"
msgstr ""
#: src/views/quarantine/QuarantineView.vue:12
msgid "release requests"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:72
msgid "Release selection"
msgstr ""
#: src/components/admin/alarms/AlarmList.vue:123
msgid "Reload"
msgstr ""
@@ -2336,6 +2508,10 @@ msgstr "Salva"
msgid "Save your changes"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:236
msgid "Score"
msgstr ""
#: src/components/admin/alarms/AlarmList.vue:21
#: src/components/admin/domains/DomainList.vue:19
#: src/components/admin/identities/IdentityList.vue:24
@@ -2346,6 +2522,7 @@ msgstr ""
msgid "Search"
msgstr "Cerca"
#: src/components/quarantine/QuarantineList.vue:27
#: src/components/webmail/EmailList.vue:14
#, fuzzy
msgid "Search in messages"
@@ -2383,6 +2560,19 @@ msgstr ""
msgid "Select file"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:359
#, fuzzy
msgid "Selection deleted"
msgstr "Data di creazione"
#: src/components/quarantine/QuarantineList.vue:398
msgid "Selection is being processed..."
msgstr ""
#: src/components/quarantine/QuarantineList.vue:374
msgid "Selection released"
msgstr ""
#: src/components/calendars/ImportEventsForm.vue:30
#: src/components/webmail/ComposeEmailForm.vue:13
#, fuzzy
@@ -2459,6 +2649,20 @@ msgstr "Visualizza chiave"
msgid "Simple user"
msgstr "Utente semplice"
#: src/components/admin/domains/DomainPolicy.vue:50
msgid "Spam classification threshold"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:17
#, fuzzy
msgid "Spam filters"
msgstr "Utilizzo"
#: src/components/admin/domains/DomainPolicy.vue:72
#: src/components/admin/domains/DomainPolicyForm.vue:34
msgid "Spam marker"
msgstr ""
#: src/components/admin/identities/AccountSenderAddresses.vue:17
msgid "Specify an email address"
msgstr ""
@@ -2494,6 +2698,8 @@ msgid "Status"
msgstr "Stato"
#: src/components/account/AutoReplyForm.vue:12
#: src/components/quarantine/QuarantineList.vue:239
#: src/components/quarantine/QuarantineList.vue:49
#: src/components/webmail/ComposeEmailForm.vue:137
msgid "Subject"
msgstr ""
@@ -2558,12 +2764,18 @@ msgstr ""
msgid "there"
msgstr ""
#: src/components/admin/domains/DomainPolicyForm.vue:56
msgid "Thresholds"
msgstr ""
#: src/components/calendars/EventForm.vue:12
msgid "Title"
msgstr ""
#: src/components/admin/logs/MessageList.vue:49
#: src/components/calendars/EventForm.vue:34
#: src/components/quarantine/QuarantineList.vue:237
#: src/components/quarantine/QuarantineList.vue:52
#: src/components/tools/TimeSerieChart.vue:20
#: src/components/webmail/ComposeEmailForm.vue:46
#: src/views/webmail/EmailView.vue:109
@@ -2710,6 +2922,10 @@ msgstr "Nuovo account"
msgid "Use domain default value"
msgstr "Usa il valore predefinito"
#: src/composables/amavis.js:36
msgid "User's database"
msgstr ""
#: src/components/admin/domains/DomainAdminList.vue:111
#: src/components/admin/identities/AccountCreationForm.vue:97
#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:3
@@ -2729,6 +2945,15 @@ msgstr ""
msgid "Value"
msgstr ""
#: src/views/quarantine/MessageView.vue:62
msgid "View full headers"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:28
#, fuzzy
msgid "Virus filters"
msgstr "Indirizzo email"
#: src/components/admin/dashboard/NewsFeedWidget.vue:21
msgid "Visit the official weblog for more information"
msgstr ""
@@ -2770,6 +2995,11 @@ msgstr "Settimana"
msgid "Welcome to Modoboa"
msgstr "Benvenuti in Modoboa"
#: src/components/quarantine/QuarantineList.vue:386
#: src/views/quarantine/MessageView.vue:210
msgid "Which database should be used for this learning:"
msgstr ""
#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:25
msgid "With a mailbox"
msgstr "Con una casella di posta"
@@ -2787,7 +3017,7 @@ msgstr ""
msgid "Year"
msgstr "Anno"
#: src/plugins/filters.js:10
#: src/components/tools/YesNoDefaultField.vue:7 src/plugins/filters.js:10
msgid "yes"
msgstr ""
+217 -6
View File
@@ -62,7 +62,7 @@ msgid "Access rules"
msgstr ""
#: src/components/calendars/CalendarAccessRulesForm.vue:42
#: src/components/shared/TopMenu.vue:93
#: src/components/shared/TopMenu.vue:131
#: src/views/admin/identities/AccountView.vue:4
#: src/views/admin/identities/IdentitiesView.vue:23
msgid "Account"
@@ -322,6 +322,7 @@ msgstr ""
msgid "API token deleted"
msgstr ""
#: src/components/admin/domains/DomainPolicyForm.vue:96
#: src/components/tools/ChooseColumnsForm.vue:19
#: src/components/tools/TimeSerieChart.vue:22
msgid "Apply"
@@ -409,6 +410,10 @@ msgstr ""
msgid "Backup codes"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:39
msgid "Banned filters"
msgstr ""
#: src/components/webmail/ComposeEmailForm.vue:110
#: src/components/webmail/ComposeEmailForm.vue:73
msgid "Bcc"
@@ -422,6 +427,14 @@ msgstr ""
msgid "Birth date"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:54
msgid "both"
msgstr ""
#: src/components/admin/domains/form_steps/DomainPolicyForm.vue:5
msgid "Bypass virus checks"
msgstr ""
#: src/components/calendars/EventForm.vue:49
#: src/views/calendars/CalendarView.vue:3
msgid "Calendar"
@@ -452,6 +465,7 @@ msgstr ""
#: src/components/account/FilterForm.vue:147
#: src/components/account/FilterSetForm.vue:24
#: src/components/admin/domains/DomainEditForm.vue:161
#: src/components/admin/domains/DomainPolicyForm.vue:93
#: src/components/admin/identities/AccountEditForm.vue:183
#: src/components/admin/identities/AliasEditForm.vue:69
#: src/components/admin/imap_migration/ProviderForm.vue:58
@@ -540,7 +554,7 @@ msgstr ""
#: src/components/tools/ImportForm.vue:51
#: src/components/webmail/AttachmentsDialog.vue:41
#: src/components/webmail/MailboxForm.vue:29
#: src/layouts/connected/ConnectedLayout.vue:17
#: src/layouts/connected/ConnectedLayout.vue:19
msgid "Close"
msgstr ""
@@ -598,6 +612,14 @@ msgstr ""
msgid "Content"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:5
msgid "Content filter"
msgstr ""
#: src/components/admin/domains/DomainPolicyForm.vue:4
msgid "Content filter settings"
msgstr ""
#: src/components/tools/ImportForm.vue:40
msgid "Continue on error"
msgstr ""
@@ -708,6 +730,7 @@ msgstr ""
#: src/components/admin/logs/AuditTrailList.vue:51
#: src/components/admin/logs/MessageList.vue:47
#: src/components/quarantine/QuarantineList.vue:240
msgid "Date"
msgstr ""
@@ -715,6 +738,11 @@ msgstr ""
msgid "Day"
msgstr ""
#: src/components/admin/domains/DomainPolicyForm.vue:47
#: src/components/tools/YesNoDefaultField.vue:15
msgid "default"
msgstr ""
#: src/components/admin/domains/DomainCreationForm.vue:193
#: src/components/admin/domains/DomainSummary.vue:23
#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:19
@@ -727,6 +755,15 @@ msgid ""
"GB. A value of 0 means no quota."
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:24
#: src/components/admin/domains/DomainPolicy.vue:35
#: src/components/admin/domains/DomainPolicy.vue:46
#: src/components/admin/domains/DomainPolicy.vue:57
#: src/components/admin/domains/DomainPolicy.vue:68
#: src/components/admin/domains/DomainPolicy.vue:79
msgid "Default value"
msgstr ""
#: src/components/admin/alarms/AlarmList.vue:116
#: src/components/admin/alarms/AlarmList.vue:133
#: src/components/admin/domains/DomainAliasForm.vue:39
@@ -748,6 +785,14 @@ msgstr ""
msgid "Delete filter set"
msgstr ""
#: src/views/quarantine/MessageView.vue:32
msgid "Delete message"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:84
msgid "Delete selection"
msgstr ""
#: src/layouts/webmail/WebmailLayout.vue:56
msgid "Delete this mailbox"
msgstr ""
@@ -781,14 +826,30 @@ msgstr ""
msgid "Disable 2FA"
msgstr ""
#: src/components/admin/domains/DomainPolicyForm.vue:26
msgid "Disable banned checks"
msgstr ""
#: src/views/webmail/EmailView.vue:74
msgid "Disable links"
msgstr ""
#: src/components/admin/domains/DomainPolicyForm.vue:18
msgid "Disable spam checks"
msgstr ""
#: src/components/admin/domains/DomainPolicyForm.vue:11
msgid "Disable virus checks"
msgstr ""
#: src/components/admin/domains/DNSStatusChip.vue:18
msgid "Disabled"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:125
msgid "Display"
msgstr ""
#: src/components/contacts/ContactList.vue:23
msgid "Display address book information"
msgstr ""
@@ -957,6 +1018,10 @@ msgstr ""
msgid "Domain name (ex: domain.tld)"
msgstr ""
#: src/composables/amavis.js:33
msgid "Domain's database"
msgstr ""
#: src/components/admin/identities/AccountEditForm.vue:82
msgid "domain's default value"
msgstr ""
@@ -1008,6 +1073,10 @@ msgstr ""
msgid "Edit contact"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:9
msgid "Edit content filter settings"
msgstr ""
#: src/views/admin/domains/DomainEditView.vue:3
msgid "Edit domain"
msgstr ""
@@ -1240,11 +1309,16 @@ msgstr ""
#: src/components/account/AutoReplyForm.vue:36
#: src/components/admin/logs/MessageList.vue:50
#: src/components/calendars/EventForm.vue:24
#: src/components/quarantine/QuarantineList.vue:238
#: src/components/tools/TimeSerieChart.vue:19
#: src/components/webmail/ComposeEmailForm.vue:29
msgid "From"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:45
msgid "From address"
msgstr ""
#: src/components/calendars/CalendarAccessRulesForm.vue:11
msgid "Full address"
msgstr ""
@@ -1294,6 +1368,10 @@ msgstr ""
msgid "Generated address"
msgstr ""
#: src/composables/amavis.js:30
msgid "Global database"
msgstr ""
#: src/views/admin/InformationView.vue:29
msgid "Go to <strong>Settings > General</strong> section"
msgstr ""
@@ -1309,6 +1387,10 @@ msgid ""
"between [ ] by the appropriate ones."
msgstr ""
#: src/views/quarantine/MessageView.vue:65
msgid "Hide full headers"
msgstr ""
#: src/components/admin/identities/AccountCreationForm.vue:168
#: src/components/admin/identities/AccountCreationForm.vue:95
#: src/components/admin/identities/AccountEditForm.vue:31
@@ -1467,6 +1549,11 @@ msgstr ""
msgid "Latest version"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:385
#: src/views/quarantine/MessageView.vue:209
msgid "Learning database"
msgstr ""
#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:26
msgid "Leave empty for no limit"
msgstr ""
@@ -1494,7 +1581,7 @@ msgstr ""
msgid "Logger"
msgstr ""
#: src/components/shared/TopMenu.vue:100
#: src/components/shared/TopMenu.vue:138
msgid "Logout"
msgstr ""
@@ -1538,10 +1625,23 @@ msgstr ""
msgid "Mark as followed"
msgstr ""
#: src/views/quarantine/MessageView.vue:47
msgid "Mark as non-spam"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:105
msgid "Mark as not spam"
msgstr ""
#: src/components/webmail/EmailList.vue:62
msgid "Mark as read"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:101
#: src/views/quarantine/MessageView.vue:43
msgid "Mark as spam"
msgstr ""
#: src/components/webmail/EmailList.vue:77
msgid "Mark as unfollowed"
msgstr ""
@@ -1560,7 +1660,7 @@ msgstr ""
msgid "Message"
msgstr ""
#: src/views/webmail/EmailView.vue:254
#: src/views/quarantine/MessageView.vue:196 src/views/webmail/EmailView.vue:254
msgid "Message deleted"
msgstr ""
@@ -1580,10 +1680,25 @@ msgstr ""
msgid "Message marked as junk"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:291
#: src/views/quarantine/MessageView.vue:236
msgid "Message marked as non-spam"
msgstr ""
#: src/views/webmail/EmailView.vue:282
msgid "Message marked as not junk"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:288
#: src/views/quarantine/MessageView.vue:232
msgid "Message marked as spam"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:285
#: src/views/quarantine/MessageView.vue:178
msgid "Message released"
msgstr ""
#: src/components/admin/domains/DomainCreationForm.vue:197
#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:32
#: src/components/admin/identities/AccountCreationForm.vue:133
@@ -1766,7 +1881,7 @@ msgstr ""
msgid "Next"
msgstr ""
#: src/plugins/filters.js:10
#: src/components/tools/YesNoDefaultField.vue:11 src/plugins/filters.js:10
msgid "no"
msgstr ""
@@ -1830,6 +1945,10 @@ msgstr ""
msgid "Note"
msgstr ""
#: src/components/shared/TopMenu.vue:18
msgid "Notifications"
msgstr ""
#: src/components/admin/identities/AccountEditForm.vue:163
msgid "Number of allowed mailbox aliases:"
msgstr ""
@@ -1889,6 +2008,14 @@ msgstr ""
msgid "Options"
msgstr ""
#: src/components/admin/domains/DomainPolicyForm.vue:69
msgid "or more is spam"
msgstr ""
#: src/components/admin/domains/DomainPolicyForm.vue:84
msgid "or more throw spam message away"
msgstr ""
#: src/components/account/ProfileForm.vue:30
msgid "or suggest a new language"
msgstr ""
@@ -2030,6 +2157,14 @@ msgstr ""
msgid "Providers"
msgstr ""
#: src/views/quarantine/QuarantineView.vue:4
msgid "Quarantine"
msgstr ""
#: src/views/quarantine/MessageView.vue:4
msgid "Quarantined message"
msgstr ""
#: src/components/admin/logs/MessageList.vue:46
msgid "Queue ID"
msgstr ""
@@ -2113,6 +2248,10 @@ msgstr ""
msgid "Registered Webauthn devices"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:61
msgid "Rejection threshold"
msgstr ""
#: src/components/tools/TimeSerieChart.vue:27
msgid "Relative time ranges"
msgstr ""
@@ -2125,6 +2264,23 @@ msgstr ""
msgid "Relay domain"
msgstr ""
#: src/views/quarantine/MessageView.vue:21
msgid "Release message"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:372
#: src/views/quarantine/MessageView.vue:176
msgid "Release request sent"
msgstr ""
#: src/views/quarantine/QuarantineView.vue:12
msgid "release requests"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:72
msgid "Release selection"
msgstr ""
#: src/components/admin/alarms/AlarmList.vue:123
msgid "Reload"
msgstr ""
@@ -2197,6 +2353,10 @@ msgstr ""
msgid "Save your changes"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:236
msgid "Score"
msgstr ""
#: src/components/admin/alarms/AlarmList.vue:21
#: src/components/admin/domains/DomainList.vue:19
#: src/components/admin/identities/IdentityList.vue:24
@@ -2207,6 +2367,7 @@ msgstr ""
msgid "Search"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:27
#: src/components/webmail/EmailList.vue:14
msgid "Search in messages"
msgstr ""
@@ -2243,6 +2404,18 @@ msgstr ""
msgid "Select file"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:359
msgid "Selection deleted"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:398
msgid "Selection is being processed..."
msgstr ""
#: src/components/quarantine/QuarantineList.vue:374
msgid "Selection released"
msgstr ""
#: src/components/calendars/ImportEventsForm.vue:30
#: src/components/webmail/ComposeEmailForm.vue:13
msgid "Send"
@@ -2314,6 +2487,19 @@ msgstr ""
msgid "Simple user"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:50
msgid "Spam classification threshold"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:17
msgid "Spam filters"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:72
#: src/components/admin/domains/DomainPolicyForm.vue:34
msgid "Spam marker"
msgstr ""
#: src/components/admin/identities/AccountSenderAddresses.vue:17
msgid "Specify an email address"
msgstr ""
@@ -2348,6 +2534,8 @@ msgid "Status"
msgstr ""
#: src/components/account/AutoReplyForm.vue:12
#: src/components/quarantine/QuarantineList.vue:239
#: src/components/quarantine/QuarantineList.vue:49
#: src/components/webmail/ComposeEmailForm.vue:137
msgid "Subject"
msgstr ""
@@ -2411,12 +2599,18 @@ msgstr ""
msgid "there"
msgstr ""
#: src/components/admin/domains/DomainPolicyForm.vue:56
msgid "Thresholds"
msgstr ""
#: src/components/calendars/EventForm.vue:12
msgid "Title"
msgstr ""
#: src/components/admin/logs/MessageList.vue:49
#: src/components/calendars/EventForm.vue:34
#: src/components/quarantine/QuarantineList.vue:237
#: src/components/quarantine/QuarantineList.vue:52
#: src/components/tools/TimeSerieChart.vue:20
#: src/components/webmail/ComposeEmailForm.vue:46
#: src/views/webmail/EmailView.vue:109
@@ -2551,6 +2745,10 @@ msgstr ""
msgid "Use domain default value"
msgstr ""
#: src/composables/amavis.js:36
msgid "User's database"
msgstr ""
#: src/components/admin/domains/DomainAdminList.vue:111
#: src/components/admin/identities/AccountCreationForm.vue:97
#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:3
@@ -2569,6 +2767,14 @@ msgstr ""
msgid "Value"
msgstr ""
#: src/views/quarantine/MessageView.vue:62
msgid "View full headers"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:28
msgid "Virus filters"
msgstr ""
#: src/components/admin/dashboard/NewsFeedWidget.vue:21
msgid "Visit the official weblog for more information"
msgstr ""
@@ -2609,6 +2815,11 @@ msgstr ""
msgid "Welcome to Modoboa"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:386
#: src/views/quarantine/MessageView.vue:210
msgid "Which database should be used for this learning:"
msgstr ""
#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:25
msgid "With a mailbox"
msgstr ""
@@ -2626,7 +2837,7 @@ msgstr ""
msgid "Year"
msgstr ""
#: src/plugins/filters.js:10
#: src/components/tools/YesNoDefaultField.vue:7 src/plugins/filters.js:10
msgid "yes"
msgstr ""
+217 -3
View File
@@ -41,7 +41,7 @@ msgid "Access rules"
msgstr ""
#: src/components/calendars/CalendarAccessRulesForm.vue:42
#: src/components/shared/TopMenu.vue:93
#: src/components/shared/TopMenu.vue:131
#: src/views/admin/identities/AccountView.vue:4
#: src/views/admin/identities/IdentitiesView.vue:23
msgid "Account"
@@ -296,6 +296,7 @@ msgstr ""
msgid "API token deleted"
msgstr ""
#: src/components/admin/domains/DomainPolicyForm.vue:96
#: src/components/tools/ChooseColumnsForm.vue:19
#: src/components/tools/TimeSerieChart.vue:22
msgid "Apply"
@@ -384,6 +385,10 @@ msgstr ""
msgid "Backup codes"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:39
msgid "Banned filters"
msgstr ""
#: src/components/webmail/ComposeEmailForm.vue:110
#: src/components/webmail/ComposeEmailForm.vue:73
msgid "Bcc"
@@ -397,6 +402,14 @@ msgstr ""
msgid "Birth date"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:54
msgid "both"
msgstr ""
#: src/components/admin/domains/form_steps/DomainPolicyForm.vue:5
msgid "Bypass virus checks"
msgstr ""
#: src/components/calendars/EventForm.vue:49
#: src/views/calendars/CalendarView.vue:3
msgid "Calendar"
@@ -427,6 +440,7 @@ msgstr ""
#: src/components/account/FilterForm.vue:147
#: src/components/account/FilterSetForm.vue:24
#: src/components/admin/domains/DomainEditForm.vue:161
#: src/components/admin/domains/DomainPolicyForm.vue:93
#: src/components/admin/identities/AccountEditForm.vue:183
#: src/components/admin/identities/AliasEditForm.vue:69
#: src/components/admin/imap_migration/ProviderForm.vue:58
@@ -515,7 +529,7 @@ msgstr ""
#: src/components/tools/ImportForm.vue:51
#: src/components/webmail/AttachmentsDialog.vue:41
#: src/components/webmail/MailboxForm.vue:29
#: src/layouts/connected/ConnectedLayout.vue:17
#: src/layouts/connected/ConnectedLayout.vue:19
msgid "Close"
msgstr ""
@@ -572,6 +586,14 @@ msgstr ""
msgid "Content"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:5
msgid "Content filter"
msgstr ""
#: src/components/admin/domains/DomainPolicyForm.vue:4
msgid "Content filter settings"
msgstr ""
#: src/components/tools/ImportForm.vue:40
msgid "Continue on error"
msgstr ""
@@ -682,6 +704,7 @@ msgstr ""
#: src/components/admin/logs/AuditTrailList.vue:51
#: src/components/admin/logs/MessageList.vue:47
#: src/components/quarantine/QuarantineList.vue:240
msgid "Date"
msgstr ""
@@ -689,6 +712,11 @@ msgstr ""
msgid "Day"
msgstr ""
#: src/components/admin/domains/DomainPolicyForm.vue:47
#: src/components/tools/YesNoDefaultField.vue:15
msgid "default"
msgstr ""
#: src/components/admin/domains/DomainCreationForm.vue:193
#: src/components/admin/domains/DomainSummary.vue:23
#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:19
@@ -699,6 +727,15 @@ msgstr ""
msgid "Default quota applied to mailboxes. Can be expressed in KB, MB (default) or GB. A value of 0 means no quota."
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:24
#: src/components/admin/domains/DomainPolicy.vue:35
#: src/components/admin/domains/DomainPolicy.vue:46
#: src/components/admin/domains/DomainPolicy.vue:57
#: src/components/admin/domains/DomainPolicy.vue:68
#: src/components/admin/domains/DomainPolicy.vue:79
msgid "Default value"
msgstr ""
#: src/components/admin/alarms/AlarmList.vue:116
#: src/components/admin/alarms/AlarmList.vue:133
#: src/components/admin/domains/DomainAliasForm.vue:39
@@ -720,6 +757,14 @@ msgstr ""
msgid "Delete filter set"
msgstr ""
#: src/views/quarantine/MessageView.vue:32
msgid "Delete message"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:84
msgid "Delete selection"
msgstr ""
#: src/layouts/webmail/WebmailLayout.vue:56
msgid "Delete this mailbox"
msgstr ""
@@ -753,14 +798,30 @@ msgstr ""
msgid "Disable 2FA"
msgstr ""
#: src/components/admin/domains/DomainPolicyForm.vue:26
msgid "Disable banned checks"
msgstr ""
#: src/views/webmail/EmailView.vue:74
msgid "Disable links"
msgstr ""
#: src/components/admin/domains/DomainPolicyForm.vue:18
msgid "Disable spam checks"
msgstr ""
#: src/components/admin/domains/DomainPolicyForm.vue:11
msgid "Disable virus checks"
msgstr ""
#: src/components/admin/domains/DNSStatusChip.vue:18
msgid "Disabled"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:125
msgid "Display"
msgstr ""
#: src/components/contacts/ContactList.vue:23
msgid "Display address book information"
msgstr ""
@@ -927,6 +988,10 @@ msgstr ""
msgid "Domain name (ex: domain.tld)"
msgstr ""
#: src/composables/amavis.js:33
msgid "Domain's database"
msgstr ""
#: src/components/admin/identities/AccountEditForm.vue:82
msgid "domain's default value"
msgstr ""
@@ -978,6 +1043,10 @@ msgstr ""
msgid "Edit contact"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:9
msgid "Edit content filter settings"
msgstr ""
#: src/views/admin/domains/DomainEditView.vue:3
msgid "Edit domain"
msgstr ""
@@ -1211,11 +1280,16 @@ msgstr ""
#: src/components/account/AutoReplyForm.vue:36
#: src/components/admin/logs/MessageList.vue:50
#: src/components/calendars/EventForm.vue:24
#: src/components/quarantine/QuarantineList.vue:238
#: src/components/tools/TimeSerieChart.vue:19
#: src/components/webmail/ComposeEmailForm.vue:29
msgid "From"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:45
msgid "From address"
msgstr ""
#: src/components/calendars/CalendarAccessRulesForm.vue:11
msgid "Full address"
msgstr ""
@@ -1265,6 +1339,10 @@ msgstr ""
msgid "Generated address"
msgstr ""
#: src/composables/amavis.js:30
msgid "Global database"
msgstr ""
#: src/views/admin/InformationView.vue:29
msgid "Go to <strong>Settings > General</strong> section"
msgstr ""
@@ -1278,6 +1356,10 @@ msgstr ""
msgid "Here is an example of DNS configuration (bind format). Replace values between [ ] by the appropriate ones."
msgstr ""
#: src/views/quarantine/MessageView.vue:65
msgid "Hide full headers"
msgstr ""
#: src/components/admin/identities/AccountCreationForm.vue:168
#: src/components/admin/identities/AccountCreationForm.vue:95
#: src/components/admin/identities/AccountEditForm.vue:31
@@ -1428,6 +1510,11 @@ msgstr ""
msgid "Latest version"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:385
#: src/views/quarantine/MessageView.vue:209
msgid "Learning database"
msgstr ""
#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:26
msgid "Leave empty for no limit"
msgstr ""
@@ -1455,7 +1542,7 @@ msgstr ""
msgid "Logger"
msgstr ""
#: src/components/shared/TopMenu.vue:100
#: src/components/shared/TopMenu.vue:138
msgid "Logout"
msgstr ""
@@ -1498,10 +1585,23 @@ msgstr ""
msgid "Mark as followed"
msgstr ""
#: src/views/quarantine/MessageView.vue:47
msgid "Mark as non-spam"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:105
msgid "Mark as not spam"
msgstr ""
#: src/components/webmail/EmailList.vue:62
msgid "Mark as read"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:101
#: src/views/quarantine/MessageView.vue:43
msgid "Mark as spam"
msgstr ""
#: src/components/webmail/EmailList.vue:77
msgid "Mark as unfollowed"
msgstr ""
@@ -1520,6 +1620,7 @@ msgstr ""
msgid "Message"
msgstr ""
#: src/views/quarantine/MessageView.vue:196
#: src/views/webmail/EmailView.vue:254
msgid "Message deleted"
msgstr ""
@@ -1540,10 +1641,25 @@ msgstr ""
msgid "Message marked as junk"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:291
#: src/views/quarantine/MessageView.vue:236
msgid "Message marked as non-spam"
msgstr ""
#: src/views/webmail/EmailView.vue:282
msgid "Message marked as not junk"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:288
#: src/views/quarantine/MessageView.vue:232
msgid "Message marked as spam"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:285
#: src/views/quarantine/MessageView.vue:178
msgid "Message released"
msgstr ""
#: src/components/admin/domains/DomainCreationForm.vue:197
#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:32
#: src/components/admin/identities/AccountCreationForm.vue:133
@@ -1726,6 +1842,7 @@ msgstr ""
msgid "Next"
msgstr ""
#: src/components/tools/YesNoDefaultField.vue:11
#: src/plugins/filters.js:10
msgid "no"
msgstr ""
@@ -1790,6 +1907,10 @@ msgstr ""
msgid "Note"
msgstr ""
#: src/components/shared/TopMenu.vue:18
msgid "Notifications"
msgstr ""
#: src/components/admin/identities/AccountEditForm.vue:163
msgid "Number of allowed mailbox aliases:"
msgstr ""
@@ -1847,6 +1968,14 @@ msgstr ""
msgid "Options"
msgstr ""
#: src/components/admin/domains/DomainPolicyForm.vue:69
msgid "or more is spam"
msgstr ""
#: src/components/admin/domains/DomainPolicyForm.vue:84
msgid "or more throw spam message away"
msgstr ""
#: src/components/account/ProfileForm.vue:30
msgid "or suggest a new language"
msgstr ""
@@ -1986,6 +2115,14 @@ msgstr ""
msgid "Providers"
msgstr ""
#: src/views/quarantine/QuarantineView.vue:4
msgid "Quarantine"
msgstr ""
#: src/views/quarantine/MessageView.vue:4
msgid "Quarantined message"
msgstr ""
#: src/components/admin/logs/MessageList.vue:46
msgid "Queue ID"
msgstr ""
@@ -2064,6 +2201,10 @@ msgstr ""
msgid "Registered Webauthn devices"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:61
msgid "Rejection threshold"
msgstr ""
#: src/components/tools/TimeSerieChart.vue:27
msgid "Relative time ranges"
msgstr ""
@@ -2076,6 +2217,23 @@ msgstr ""
msgid "Relay domain"
msgstr ""
#: src/views/quarantine/MessageView.vue:21
msgid "Release message"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:372
#: src/views/quarantine/MessageView.vue:176
msgid "Release request sent"
msgstr ""
#: src/views/quarantine/QuarantineView.vue:12
msgid "release requests"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:72
msgid "Release selection"
msgstr ""
#: src/components/admin/alarms/AlarmList.vue:123
msgid "Reload"
msgstr ""
@@ -2148,6 +2306,10 @@ msgstr ""
msgid "Save your changes"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:236
msgid "Score"
msgstr ""
#: src/components/admin/alarms/AlarmList.vue:21
#: src/components/admin/domains/DomainList.vue:19
#: src/components/admin/identities/IdentityList.vue:24
@@ -2158,6 +2320,7 @@ msgstr ""
msgid "Search"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:27
#: src/components/webmail/EmailList.vue:14
msgid "Search in messages"
msgstr ""
@@ -2194,6 +2357,18 @@ msgstr ""
msgid "Select file"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:359
msgid "Selection deleted"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:398
msgid "Selection is being processed..."
msgstr ""
#: src/components/quarantine/QuarantineList.vue:374
msgid "Selection released"
msgstr ""
#: src/components/calendars/ImportEventsForm.vue:30
#: src/components/webmail/ComposeEmailForm.vue:13
msgid "Send"
@@ -2265,6 +2440,19 @@ msgstr ""
msgid "Simple user"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:50
msgid "Spam classification threshold"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:17
msgid "Spam filters"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:72
#: src/components/admin/domains/DomainPolicyForm.vue:34
msgid "Spam marker"
msgstr ""
#: src/components/admin/identities/AccountSenderAddresses.vue:17
msgid "Specify an email address"
msgstr ""
@@ -2299,6 +2487,8 @@ msgid "Status"
msgstr ""
#: src/components/account/AutoReplyForm.vue:12
#: src/components/quarantine/QuarantineList.vue:239
#: src/components/quarantine/QuarantineList.vue:49
#: src/components/webmail/ComposeEmailForm.vue:137
msgid "Subject"
msgstr ""
@@ -2350,12 +2540,18 @@ msgstr ""
msgid "there"
msgstr ""
#: src/components/admin/domains/DomainPolicyForm.vue:56
msgid "Thresholds"
msgstr ""
#: src/components/calendars/EventForm.vue:12
msgid "Title"
msgstr ""
#: src/components/admin/logs/MessageList.vue:49
#: src/components/calendars/EventForm.vue:34
#: src/components/quarantine/QuarantineList.vue:237
#: src/components/quarantine/QuarantineList.vue:52
#: src/components/tools/TimeSerieChart.vue:20
#: src/components/webmail/ComposeEmailForm.vue:46
#: src/views/webmail/EmailView.vue:109
@@ -2482,6 +2678,10 @@ msgstr ""
msgid "Use domain default value"
msgstr ""
#: src/composables/amavis.js:36
msgid "User's database"
msgstr ""
#: src/components/admin/domains/DomainAdminList.vue:111
#: src/components/admin/identities/AccountCreationForm.vue:97
#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:3
@@ -2500,6 +2700,14 @@ msgstr ""
msgid "Value"
msgstr ""
#: src/views/quarantine/MessageView.vue:62
msgid "View full headers"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:28
msgid "Virus filters"
msgstr ""
#: src/components/admin/dashboard/NewsFeedWidget.vue:21
msgid "Visit the official weblog for more information"
msgstr ""
@@ -2540,6 +2748,11 @@ msgstr ""
msgid "Welcome to Modoboa"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:386
#: src/views/quarantine/MessageView.vue:210
msgid "Which database should be used for this learning:"
msgstr ""
#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:25
msgid "With a mailbox"
msgstr ""
@@ -2557,6 +2770,7 @@ msgstr ""
msgid "Year"
msgstr ""
#: src/components/tools/YesNoDefaultField.vue:7
#: src/plugins/filters.js:10
msgid "yes"
msgstr ""
+217 -6
View File
@@ -63,7 +63,7 @@ msgid "Access rules"
msgstr ""
#: src/components/calendars/CalendarAccessRulesForm.vue:42
#: src/components/shared/TopMenu.vue:93
#: src/components/shared/TopMenu.vue:131
#: src/views/admin/identities/AccountView.vue:4
#: src/views/admin/identities/IdentitiesView.vue:23
msgid "Account"
@@ -323,6 +323,7 @@ msgstr ""
msgid "API token deleted"
msgstr ""
#: src/components/admin/domains/DomainPolicyForm.vue:96
#: src/components/tools/ChooseColumnsForm.vue:19
#: src/components/tools/TimeSerieChart.vue:22
msgid "Apply"
@@ -410,6 +411,10 @@ msgstr ""
msgid "Backup codes"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:39
msgid "Banned filters"
msgstr ""
#: src/components/webmail/ComposeEmailForm.vue:110
#: src/components/webmail/ComposeEmailForm.vue:73
msgid "Bcc"
@@ -423,6 +428,14 @@ msgstr ""
msgid "Birth date"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:54
msgid "both"
msgstr ""
#: src/components/admin/domains/form_steps/DomainPolicyForm.vue:5
msgid "Bypass virus checks"
msgstr ""
#: src/components/calendars/EventForm.vue:49
#: src/views/calendars/CalendarView.vue:3
msgid "Calendar"
@@ -453,6 +466,7 @@ msgstr ""
#: src/components/account/FilterForm.vue:147
#: src/components/account/FilterSetForm.vue:24
#: src/components/admin/domains/DomainEditForm.vue:161
#: src/components/admin/domains/DomainPolicyForm.vue:93
#: src/components/admin/identities/AccountEditForm.vue:183
#: src/components/admin/identities/AliasEditForm.vue:69
#: src/components/admin/imap_migration/ProviderForm.vue:58
@@ -541,7 +555,7 @@ msgstr ""
#: src/components/tools/ImportForm.vue:51
#: src/components/webmail/AttachmentsDialog.vue:41
#: src/components/webmail/MailboxForm.vue:29
#: src/layouts/connected/ConnectedLayout.vue:17
#: src/layouts/connected/ConnectedLayout.vue:19
msgid "Close"
msgstr ""
@@ -599,6 +613,14 @@ msgstr ""
msgid "Content"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:5
msgid "Content filter"
msgstr ""
#: src/components/admin/domains/DomainPolicyForm.vue:4
msgid "Content filter settings"
msgstr ""
#: src/components/tools/ImportForm.vue:40
msgid "Continue on error"
msgstr ""
@@ -709,6 +731,7 @@ msgstr ""
#: src/components/admin/logs/AuditTrailList.vue:51
#: src/components/admin/logs/MessageList.vue:47
#: src/components/quarantine/QuarantineList.vue:240
msgid "Date"
msgstr ""
@@ -716,6 +739,11 @@ msgstr ""
msgid "Day"
msgstr ""
#: src/components/admin/domains/DomainPolicyForm.vue:47
#: src/components/tools/YesNoDefaultField.vue:15
msgid "default"
msgstr ""
#: src/components/admin/domains/DomainCreationForm.vue:193
#: src/components/admin/domains/DomainSummary.vue:23
#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:19
@@ -728,6 +756,15 @@ msgid ""
"GB. A value of 0 means no quota."
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:24
#: src/components/admin/domains/DomainPolicy.vue:35
#: src/components/admin/domains/DomainPolicy.vue:46
#: src/components/admin/domains/DomainPolicy.vue:57
#: src/components/admin/domains/DomainPolicy.vue:68
#: src/components/admin/domains/DomainPolicy.vue:79
msgid "Default value"
msgstr ""
#: src/components/admin/alarms/AlarmList.vue:116
#: src/components/admin/alarms/AlarmList.vue:133
#: src/components/admin/domains/DomainAliasForm.vue:39
@@ -749,6 +786,14 @@ msgstr ""
msgid "Delete filter set"
msgstr ""
#: src/views/quarantine/MessageView.vue:32
msgid "Delete message"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:84
msgid "Delete selection"
msgstr ""
#: src/layouts/webmail/WebmailLayout.vue:56
msgid "Delete this mailbox"
msgstr ""
@@ -782,14 +827,30 @@ msgstr ""
msgid "Disable 2FA"
msgstr ""
#: src/components/admin/domains/DomainPolicyForm.vue:26
msgid "Disable banned checks"
msgstr ""
#: src/views/webmail/EmailView.vue:74
msgid "Disable links"
msgstr ""
#: src/components/admin/domains/DomainPolicyForm.vue:18
msgid "Disable spam checks"
msgstr ""
#: src/components/admin/domains/DomainPolicyForm.vue:11
msgid "Disable virus checks"
msgstr ""
#: src/components/admin/domains/DNSStatusChip.vue:18
msgid "Disabled"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:125
msgid "Display"
msgstr ""
#: src/components/contacts/ContactList.vue:23
msgid "Display address book information"
msgstr ""
@@ -958,6 +1019,10 @@ msgstr ""
msgid "Domain name (ex: domain.tld)"
msgstr ""
#: src/composables/amavis.js:33
msgid "Domain's database"
msgstr ""
#: src/components/admin/identities/AccountEditForm.vue:82
msgid "domain's default value"
msgstr ""
@@ -1009,6 +1074,10 @@ msgstr ""
msgid "Edit contact"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:9
msgid "Edit content filter settings"
msgstr ""
#: src/views/admin/domains/DomainEditView.vue:3
msgid "Edit domain"
msgstr ""
@@ -1241,11 +1310,16 @@ msgstr ""
#: src/components/account/AutoReplyForm.vue:36
#: src/components/admin/logs/MessageList.vue:50
#: src/components/calendars/EventForm.vue:24
#: src/components/quarantine/QuarantineList.vue:238
#: src/components/tools/TimeSerieChart.vue:19
#: src/components/webmail/ComposeEmailForm.vue:29
msgid "From"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:45
msgid "From address"
msgstr ""
#: src/components/calendars/CalendarAccessRulesForm.vue:11
msgid "Full address"
msgstr ""
@@ -1295,6 +1369,10 @@ msgstr ""
msgid "Generated address"
msgstr ""
#: src/composables/amavis.js:30
msgid "Global database"
msgstr ""
#: src/views/admin/InformationView.vue:29
msgid "Go to <strong>Settings > General</strong> section"
msgstr ""
@@ -1310,6 +1388,10 @@ msgid ""
"between [ ] by the appropriate ones."
msgstr ""
#: src/views/quarantine/MessageView.vue:65
msgid "Hide full headers"
msgstr ""
#: src/components/admin/identities/AccountCreationForm.vue:168
#: src/components/admin/identities/AccountCreationForm.vue:95
#: src/components/admin/identities/AccountEditForm.vue:31
@@ -1468,6 +1550,11 @@ msgstr ""
msgid "Latest version"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:385
#: src/views/quarantine/MessageView.vue:209
msgid "Learning database"
msgstr ""
#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:26
msgid "Leave empty for no limit"
msgstr ""
@@ -1495,7 +1582,7 @@ msgstr ""
msgid "Logger"
msgstr ""
#: src/components/shared/TopMenu.vue:100
#: src/components/shared/TopMenu.vue:138
msgid "Logout"
msgstr ""
@@ -1539,10 +1626,23 @@ msgstr ""
msgid "Mark as followed"
msgstr ""
#: src/views/quarantine/MessageView.vue:47
msgid "Mark as non-spam"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:105
msgid "Mark as not spam"
msgstr ""
#: src/components/webmail/EmailList.vue:62
msgid "Mark as read"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:101
#: src/views/quarantine/MessageView.vue:43
msgid "Mark as spam"
msgstr ""
#: src/components/webmail/EmailList.vue:77
msgid "Mark as unfollowed"
msgstr ""
@@ -1561,7 +1661,7 @@ msgstr ""
msgid "Message"
msgstr ""
#: src/views/webmail/EmailView.vue:254
#: src/views/quarantine/MessageView.vue:196 src/views/webmail/EmailView.vue:254
msgid "Message deleted"
msgstr ""
@@ -1581,10 +1681,25 @@ msgstr ""
msgid "Message marked as junk"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:291
#: src/views/quarantine/MessageView.vue:236
msgid "Message marked as non-spam"
msgstr ""
#: src/views/webmail/EmailView.vue:282
msgid "Message marked as not junk"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:288
#: src/views/quarantine/MessageView.vue:232
msgid "Message marked as spam"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:285
#: src/views/quarantine/MessageView.vue:178
msgid "Message released"
msgstr ""
#: src/components/admin/domains/DomainCreationForm.vue:197
#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:32
#: src/components/admin/identities/AccountCreationForm.vue:133
@@ -1767,7 +1882,7 @@ msgstr ""
msgid "Next"
msgstr ""
#: src/plugins/filters.js:10
#: src/components/tools/YesNoDefaultField.vue:11 src/plugins/filters.js:10
msgid "no"
msgstr ""
@@ -1831,6 +1946,10 @@ msgstr ""
msgid "Note"
msgstr ""
#: src/components/shared/TopMenu.vue:18
msgid "Notifications"
msgstr ""
#: src/components/admin/identities/AccountEditForm.vue:163
msgid "Number of allowed mailbox aliases:"
msgstr ""
@@ -1890,6 +2009,14 @@ msgstr ""
msgid "Options"
msgstr ""
#: src/components/admin/domains/DomainPolicyForm.vue:69
msgid "or more is spam"
msgstr ""
#: src/components/admin/domains/DomainPolicyForm.vue:84
msgid "or more throw spam message away"
msgstr ""
#: src/components/account/ProfileForm.vue:30
msgid "or suggest a new language"
msgstr ""
@@ -2031,6 +2158,14 @@ msgstr ""
msgid "Providers"
msgstr ""
#: src/views/quarantine/QuarantineView.vue:4
msgid "Quarantine"
msgstr ""
#: src/views/quarantine/MessageView.vue:4
msgid "Quarantined message"
msgstr ""
#: src/components/admin/logs/MessageList.vue:46
msgid "Queue ID"
msgstr ""
@@ -2114,6 +2249,10 @@ msgstr ""
msgid "Registered Webauthn devices"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:61
msgid "Rejection threshold"
msgstr ""
#: src/components/tools/TimeSerieChart.vue:27
msgid "Relative time ranges"
msgstr ""
@@ -2126,6 +2265,23 @@ msgstr ""
msgid "Relay domain"
msgstr ""
#: src/views/quarantine/MessageView.vue:21
msgid "Release message"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:372
#: src/views/quarantine/MessageView.vue:176
msgid "Release request sent"
msgstr ""
#: src/views/quarantine/QuarantineView.vue:12
msgid "release requests"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:72
msgid "Release selection"
msgstr ""
#: src/components/admin/alarms/AlarmList.vue:123
msgid "Reload"
msgstr ""
@@ -2198,6 +2354,10 @@ msgstr ""
msgid "Save your changes"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:236
msgid "Score"
msgstr ""
#: src/components/admin/alarms/AlarmList.vue:21
#: src/components/admin/domains/DomainList.vue:19
#: src/components/admin/identities/IdentityList.vue:24
@@ -2208,6 +2368,7 @@ msgstr ""
msgid "Search"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:27
#: src/components/webmail/EmailList.vue:14
msgid "Search in messages"
msgstr ""
@@ -2244,6 +2405,18 @@ msgstr ""
msgid "Select file"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:359
msgid "Selection deleted"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:398
msgid "Selection is being processed..."
msgstr ""
#: src/components/quarantine/QuarantineList.vue:374
msgid "Selection released"
msgstr ""
#: src/components/calendars/ImportEventsForm.vue:30
#: src/components/webmail/ComposeEmailForm.vue:13
msgid "Send"
@@ -2315,6 +2488,19 @@ msgstr ""
msgid "Simple user"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:50
msgid "Spam classification threshold"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:17
msgid "Spam filters"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:72
#: src/components/admin/domains/DomainPolicyForm.vue:34
msgid "Spam marker"
msgstr ""
#: src/components/admin/identities/AccountSenderAddresses.vue:17
msgid "Specify an email address"
msgstr ""
@@ -2349,6 +2535,8 @@ msgid "Status"
msgstr ""
#: src/components/account/AutoReplyForm.vue:12
#: src/components/quarantine/QuarantineList.vue:239
#: src/components/quarantine/QuarantineList.vue:49
#: src/components/webmail/ComposeEmailForm.vue:137
msgid "Subject"
msgstr ""
@@ -2412,12 +2600,18 @@ msgstr ""
msgid "there"
msgstr ""
#: src/components/admin/domains/DomainPolicyForm.vue:56
msgid "Thresholds"
msgstr ""
#: src/components/calendars/EventForm.vue:12
msgid "Title"
msgstr ""
#: src/components/admin/logs/MessageList.vue:49
#: src/components/calendars/EventForm.vue:34
#: src/components/quarantine/QuarantineList.vue:237
#: src/components/quarantine/QuarantineList.vue:52
#: src/components/tools/TimeSerieChart.vue:20
#: src/components/webmail/ComposeEmailForm.vue:46
#: src/views/webmail/EmailView.vue:109
@@ -2552,6 +2746,10 @@ msgstr ""
msgid "Use domain default value"
msgstr ""
#: src/composables/amavis.js:36
msgid "User's database"
msgstr ""
#: src/components/admin/domains/DomainAdminList.vue:111
#: src/components/admin/identities/AccountCreationForm.vue:97
#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:3
@@ -2570,6 +2768,14 @@ msgstr ""
msgid "Value"
msgstr ""
#: src/views/quarantine/MessageView.vue:62
msgid "View full headers"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:28
msgid "Virus filters"
msgstr ""
#: src/components/admin/dashboard/NewsFeedWidget.vue:21
msgid "Visit the official weblog for more information"
msgstr ""
@@ -2610,6 +2816,11 @@ msgstr ""
msgid "Welcome to Modoboa"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:386
#: src/views/quarantine/MessageView.vue:210
msgid "Which database should be used for this learning:"
msgstr ""
#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:25
msgid "With a mailbox"
msgstr ""
@@ -2627,7 +2838,7 @@ msgstr ""
msgid "Year"
msgstr ""
#: src/plugins/filters.js:10
#: src/components/tools/YesNoDefaultField.vue:7 src/plugins/filters.js:10
msgid "yes"
msgstr ""
+217 -6
View File
@@ -65,7 +65,7 @@ msgid "Access rules"
msgstr ""
#: src/components/calendars/CalendarAccessRulesForm.vue:42
#: src/components/shared/TopMenu.vue:93
#: src/components/shared/TopMenu.vue:131
#: src/views/admin/identities/AccountView.vue:4
#: src/views/admin/identities/IdentitiesView.vue:23
msgid "Account"
@@ -325,6 +325,7 @@ msgstr ""
msgid "API token deleted"
msgstr ""
#: src/components/admin/domains/DomainPolicyForm.vue:96
#: src/components/tools/ChooseColumnsForm.vue:19
#: src/components/tools/TimeSerieChart.vue:22
msgid "Apply"
@@ -412,6 +413,10 @@ msgstr ""
msgid "Backup codes"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:39
msgid "Banned filters"
msgstr ""
#: src/components/webmail/ComposeEmailForm.vue:110
#: src/components/webmail/ComposeEmailForm.vue:73
msgid "Bcc"
@@ -425,6 +430,14 @@ msgstr ""
msgid "Birth date"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:54
msgid "both"
msgstr ""
#: src/components/admin/domains/form_steps/DomainPolicyForm.vue:5
msgid "Bypass virus checks"
msgstr ""
#: src/components/calendars/EventForm.vue:49
#: src/views/calendars/CalendarView.vue:3
msgid "Calendar"
@@ -455,6 +468,7 @@ msgstr ""
#: src/components/account/FilterForm.vue:147
#: src/components/account/FilterSetForm.vue:24
#: src/components/admin/domains/DomainEditForm.vue:161
#: src/components/admin/domains/DomainPolicyForm.vue:93
#: src/components/admin/identities/AccountEditForm.vue:183
#: src/components/admin/identities/AliasEditForm.vue:69
#: src/components/admin/imap_migration/ProviderForm.vue:58
@@ -543,7 +557,7 @@ msgstr ""
#: src/components/tools/ImportForm.vue:51
#: src/components/webmail/AttachmentsDialog.vue:41
#: src/components/webmail/MailboxForm.vue:29
#: src/layouts/connected/ConnectedLayout.vue:17
#: src/layouts/connected/ConnectedLayout.vue:19
msgid "Close"
msgstr ""
@@ -601,6 +615,14 @@ msgstr ""
msgid "Content"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:5
msgid "Content filter"
msgstr ""
#: src/components/admin/domains/DomainPolicyForm.vue:4
msgid "Content filter settings"
msgstr ""
#: src/components/tools/ImportForm.vue:40
msgid "Continue on error"
msgstr ""
@@ -711,6 +733,7 @@ msgstr ""
#: src/components/admin/logs/AuditTrailList.vue:51
#: src/components/admin/logs/MessageList.vue:47
#: src/components/quarantine/QuarantineList.vue:240
msgid "Date"
msgstr ""
@@ -718,6 +741,11 @@ msgstr ""
msgid "Day"
msgstr ""
#: src/components/admin/domains/DomainPolicyForm.vue:47
#: src/components/tools/YesNoDefaultField.vue:15
msgid "default"
msgstr ""
#: src/components/admin/domains/DomainCreationForm.vue:193
#: src/components/admin/domains/DomainSummary.vue:23
#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:19
@@ -730,6 +758,15 @@ msgid ""
"GB. A value of 0 means no quota."
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:24
#: src/components/admin/domains/DomainPolicy.vue:35
#: src/components/admin/domains/DomainPolicy.vue:46
#: src/components/admin/domains/DomainPolicy.vue:57
#: src/components/admin/domains/DomainPolicy.vue:68
#: src/components/admin/domains/DomainPolicy.vue:79
msgid "Default value"
msgstr ""
#: src/components/admin/alarms/AlarmList.vue:116
#: src/components/admin/alarms/AlarmList.vue:133
#: src/components/admin/domains/DomainAliasForm.vue:39
@@ -751,6 +788,14 @@ msgstr ""
msgid "Delete filter set"
msgstr ""
#: src/views/quarantine/MessageView.vue:32
msgid "Delete message"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:84
msgid "Delete selection"
msgstr ""
#: src/layouts/webmail/WebmailLayout.vue:56
msgid "Delete this mailbox"
msgstr ""
@@ -784,14 +829,30 @@ msgstr ""
msgid "Disable 2FA"
msgstr ""
#: src/components/admin/domains/DomainPolicyForm.vue:26
msgid "Disable banned checks"
msgstr ""
#: src/views/webmail/EmailView.vue:74
msgid "Disable links"
msgstr ""
#: src/components/admin/domains/DomainPolicyForm.vue:18
msgid "Disable spam checks"
msgstr ""
#: src/components/admin/domains/DomainPolicyForm.vue:11
msgid "Disable virus checks"
msgstr ""
#: src/components/admin/domains/DNSStatusChip.vue:18
msgid "Disabled"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:125
msgid "Display"
msgstr ""
#: src/components/contacts/ContactList.vue:23
msgid "Display address book information"
msgstr ""
@@ -960,6 +1021,10 @@ msgstr ""
msgid "Domain name (ex: domain.tld)"
msgstr ""
#: src/composables/amavis.js:33
msgid "Domain's database"
msgstr ""
#: src/components/admin/identities/AccountEditForm.vue:82
msgid "domain's default value"
msgstr ""
@@ -1011,6 +1076,10 @@ msgstr ""
msgid "Edit contact"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:9
msgid "Edit content filter settings"
msgstr ""
#: src/views/admin/domains/DomainEditView.vue:3
msgid "Edit domain"
msgstr ""
@@ -1243,11 +1312,16 @@ msgstr ""
#: src/components/account/AutoReplyForm.vue:36
#: src/components/admin/logs/MessageList.vue:50
#: src/components/calendars/EventForm.vue:24
#: src/components/quarantine/QuarantineList.vue:238
#: src/components/tools/TimeSerieChart.vue:19
#: src/components/webmail/ComposeEmailForm.vue:29
msgid "From"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:45
msgid "From address"
msgstr ""
#: src/components/calendars/CalendarAccessRulesForm.vue:11
msgid "Full address"
msgstr ""
@@ -1297,6 +1371,10 @@ msgstr ""
msgid "Generated address"
msgstr ""
#: src/composables/amavis.js:30
msgid "Global database"
msgstr ""
#: src/views/admin/InformationView.vue:29
msgid "Go to <strong>Settings > General</strong> section"
msgstr ""
@@ -1312,6 +1390,10 @@ msgid ""
"between [ ] by the appropriate ones."
msgstr ""
#: src/views/quarantine/MessageView.vue:65
msgid "Hide full headers"
msgstr ""
#: src/components/admin/identities/AccountCreationForm.vue:168
#: src/components/admin/identities/AccountCreationForm.vue:95
#: src/components/admin/identities/AccountEditForm.vue:31
@@ -1470,6 +1552,11 @@ msgstr ""
msgid "Latest version"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:385
#: src/views/quarantine/MessageView.vue:209
msgid "Learning database"
msgstr ""
#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:26
msgid "Leave empty for no limit"
msgstr ""
@@ -1497,7 +1584,7 @@ msgstr ""
msgid "Logger"
msgstr ""
#: src/components/shared/TopMenu.vue:100
#: src/components/shared/TopMenu.vue:138
msgid "Logout"
msgstr ""
@@ -1541,10 +1628,23 @@ msgstr ""
msgid "Mark as followed"
msgstr ""
#: src/views/quarantine/MessageView.vue:47
msgid "Mark as non-spam"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:105
msgid "Mark as not spam"
msgstr ""
#: src/components/webmail/EmailList.vue:62
msgid "Mark as read"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:101
#: src/views/quarantine/MessageView.vue:43
msgid "Mark as spam"
msgstr ""
#: src/components/webmail/EmailList.vue:77
msgid "Mark as unfollowed"
msgstr ""
@@ -1563,7 +1663,7 @@ msgstr ""
msgid "Message"
msgstr ""
#: src/views/webmail/EmailView.vue:254
#: src/views/quarantine/MessageView.vue:196 src/views/webmail/EmailView.vue:254
msgid "Message deleted"
msgstr ""
@@ -1583,10 +1683,25 @@ msgstr ""
msgid "Message marked as junk"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:291
#: src/views/quarantine/MessageView.vue:236
msgid "Message marked as non-spam"
msgstr ""
#: src/views/webmail/EmailView.vue:282
msgid "Message marked as not junk"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:288
#: src/views/quarantine/MessageView.vue:232
msgid "Message marked as spam"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:285
#: src/views/quarantine/MessageView.vue:178
msgid "Message released"
msgstr ""
#: src/components/admin/domains/DomainCreationForm.vue:197
#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:32
#: src/components/admin/identities/AccountCreationForm.vue:133
@@ -1769,7 +1884,7 @@ msgstr ""
msgid "Next"
msgstr ""
#: src/plugins/filters.js:10
#: src/components/tools/YesNoDefaultField.vue:11 src/plugins/filters.js:10
msgid "no"
msgstr ""
@@ -1833,6 +1948,10 @@ msgstr ""
msgid "Note"
msgstr ""
#: src/components/shared/TopMenu.vue:18
msgid "Notifications"
msgstr ""
#: src/components/admin/identities/AccountEditForm.vue:163
msgid "Number of allowed mailbox aliases:"
msgstr ""
@@ -1892,6 +2011,14 @@ msgstr ""
msgid "Options"
msgstr ""
#: src/components/admin/domains/DomainPolicyForm.vue:69
msgid "or more is spam"
msgstr ""
#: src/components/admin/domains/DomainPolicyForm.vue:84
msgid "or more throw spam message away"
msgstr ""
#: src/components/account/ProfileForm.vue:30
msgid "or suggest a new language"
msgstr ""
@@ -2033,6 +2160,14 @@ msgstr ""
msgid "Providers"
msgstr ""
#: src/views/quarantine/QuarantineView.vue:4
msgid "Quarantine"
msgstr ""
#: src/views/quarantine/MessageView.vue:4
msgid "Quarantined message"
msgstr ""
#: src/components/admin/logs/MessageList.vue:46
msgid "Queue ID"
msgstr ""
@@ -2116,6 +2251,10 @@ msgstr ""
msgid "Registered Webauthn devices"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:61
msgid "Rejection threshold"
msgstr ""
#: src/components/tools/TimeSerieChart.vue:27
msgid "Relative time ranges"
msgstr ""
@@ -2128,6 +2267,23 @@ msgstr ""
msgid "Relay domain"
msgstr ""
#: src/views/quarantine/MessageView.vue:21
msgid "Release message"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:372
#: src/views/quarantine/MessageView.vue:176
msgid "Release request sent"
msgstr ""
#: src/views/quarantine/QuarantineView.vue:12
msgid "release requests"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:72
msgid "Release selection"
msgstr ""
#: src/components/admin/alarms/AlarmList.vue:123
msgid "Reload"
msgstr ""
@@ -2200,6 +2356,10 @@ msgstr ""
msgid "Save your changes"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:236
msgid "Score"
msgstr ""
#: src/components/admin/alarms/AlarmList.vue:21
#: src/components/admin/domains/DomainList.vue:19
#: src/components/admin/identities/IdentityList.vue:24
@@ -2210,6 +2370,7 @@ msgstr ""
msgid "Search"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:27
#: src/components/webmail/EmailList.vue:14
msgid "Search in messages"
msgstr ""
@@ -2246,6 +2407,18 @@ msgstr ""
msgid "Select file"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:359
msgid "Selection deleted"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:398
msgid "Selection is being processed..."
msgstr ""
#: src/components/quarantine/QuarantineList.vue:374
msgid "Selection released"
msgstr ""
#: src/components/calendars/ImportEventsForm.vue:30
#: src/components/webmail/ComposeEmailForm.vue:13
msgid "Send"
@@ -2317,6 +2490,19 @@ msgstr ""
msgid "Simple user"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:50
msgid "Spam classification threshold"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:17
msgid "Spam filters"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:72
#: src/components/admin/domains/DomainPolicyForm.vue:34
msgid "Spam marker"
msgstr ""
#: src/components/admin/identities/AccountSenderAddresses.vue:17
msgid "Specify an email address"
msgstr ""
@@ -2351,6 +2537,8 @@ msgid "Status"
msgstr ""
#: src/components/account/AutoReplyForm.vue:12
#: src/components/quarantine/QuarantineList.vue:239
#: src/components/quarantine/QuarantineList.vue:49
#: src/components/webmail/ComposeEmailForm.vue:137
msgid "Subject"
msgstr ""
@@ -2414,12 +2602,18 @@ msgstr ""
msgid "there"
msgstr ""
#: src/components/admin/domains/DomainPolicyForm.vue:56
msgid "Thresholds"
msgstr ""
#: src/components/calendars/EventForm.vue:12
msgid "Title"
msgstr ""
#: src/components/admin/logs/MessageList.vue:49
#: src/components/calendars/EventForm.vue:34
#: src/components/quarantine/QuarantineList.vue:237
#: src/components/quarantine/QuarantineList.vue:52
#: src/components/tools/TimeSerieChart.vue:20
#: src/components/webmail/ComposeEmailForm.vue:46
#: src/views/webmail/EmailView.vue:109
@@ -2554,6 +2748,10 @@ msgstr ""
msgid "Use domain default value"
msgstr ""
#: src/composables/amavis.js:36
msgid "User's database"
msgstr ""
#: src/components/admin/domains/DomainAdminList.vue:111
#: src/components/admin/identities/AccountCreationForm.vue:97
#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:3
@@ -2572,6 +2770,14 @@ msgstr ""
msgid "Value"
msgstr ""
#: src/views/quarantine/MessageView.vue:62
msgid "View full headers"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:28
msgid "Virus filters"
msgstr ""
#: src/components/admin/dashboard/NewsFeedWidget.vue:21
msgid "Visit the official weblog for more information"
msgstr ""
@@ -2612,6 +2818,11 @@ msgstr ""
msgid "Welcome to Modoboa"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:386
#: src/views/quarantine/MessageView.vue:210
msgid "Which database should be used for this learning:"
msgstr ""
#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:25
msgid "With a mailbox"
msgstr ""
@@ -2629,7 +2840,7 @@ msgstr ""
msgid "Year"
msgstr ""
#: src/plugins/filters.js:10
#: src/components/tools/YesNoDefaultField.vue:7 src/plugins/filters.js:10
msgid "yes"
msgstr ""
+239 -9
View File
@@ -73,7 +73,7 @@ msgid "Access rules"
msgstr "Regras de acesso"
#: src/components/calendars/CalendarAccessRulesForm.vue:42
#: src/components/shared/TopMenu.vue:93
#: src/components/shared/TopMenu.vue:131
#: src/views/admin/identities/AccountView.vue:4
#: src/views/admin/identities/IdentitiesView.vue:23
msgid "Account"
@@ -341,6 +341,7 @@ msgstr "Token de API criado"
msgid "API token deleted"
msgstr "Token de API removido"
#: src/components/admin/domains/DomainPolicyForm.vue:96
#: src/components/tools/ChooseColumnsForm.vue:19
#: src/components/tools/TimeSerieChart.vue:22
msgid "Apply"
@@ -428,6 +429,11 @@ msgstr "Voltar"
msgid "Backup codes"
msgstr "Códigos de backup"
#: src/components/admin/domains/DomainPolicy.vue:39
#, fuzzy
msgid "Banned filters"
msgstr "Filtros de mensagem"
#: src/components/webmail/ComposeEmailForm.vue:110
#: src/components/webmail/ComposeEmailForm.vue:73
msgid "Bcc"
@@ -441,6 +447,14 @@ msgstr "Formato de associação/nomeado. Clique para copiar"
msgid "Birth date"
msgstr "Data de nascimento"
#: src/components/quarantine/QuarantineList.vue:54
msgid "both"
msgstr ""
#: src/components/admin/domains/form_steps/DomainPolicyForm.vue:5
msgid "Bypass virus checks"
msgstr ""
#: src/components/calendars/EventForm.vue:49
#: src/views/calendars/CalendarView.vue:3
msgid "Calendar"
@@ -471,6 +485,7 @@ msgstr "Calendário atualizado"
#: src/components/account/FilterForm.vue:147
#: src/components/account/FilterSetForm.vue:24
#: src/components/admin/domains/DomainEditForm.vue:161
#: src/components/admin/domains/DomainPolicyForm.vue:93
#: src/components/admin/identities/AccountEditForm.vue:183
#: src/components/admin/identities/AliasEditForm.vue:69
#: src/components/admin/imap_migration/ProviderForm.vue:58
@@ -561,7 +576,7 @@ msgstr "Clique aqui para copiar a chave"
#: src/components/tools/ImportForm.vue:51
#: src/components/webmail/AttachmentsDialog.vue:41
#: src/components/webmail/MailboxForm.vue:29
#: src/layouts/connected/ConnectedLayout.vue:17
#: src/layouts/connected/ConnectedLayout.vue:19
msgid "Close"
msgstr "Fechar"
@@ -623,6 +638,16 @@ msgstr "Contatos"
msgid "Content"
msgstr "Conteúdo"
#: src/components/admin/domains/DomainPolicy.vue:5
#, fuzzy
msgid "Content filter"
msgstr "Conteúdo"
#: src/components/admin/domains/DomainPolicyForm.vue:4
#, fuzzy
msgid "Content filter settings"
msgstr "Configurações gerais"
#: src/components/tools/ImportForm.vue:40
msgid "Continue on error"
msgstr "Continuar em caso de erro"
@@ -737,6 +762,7 @@ msgstr "Painel"
#: src/components/admin/logs/AuditTrailList.vue:51
#: src/components/admin/logs/MessageList.vue:47
#: src/components/quarantine/QuarantineList.vue:240
msgid "Date"
msgstr "Data"
@@ -744,6 +770,11 @@ msgstr "Data"
msgid "Day"
msgstr "Dia"
#: src/components/admin/domains/DomainPolicyForm.vue:47
#: src/components/tools/YesNoDefaultField.vue:15
msgid "default"
msgstr ""
#: src/components/admin/domains/DomainCreationForm.vue:193
#: src/components/admin/domains/DomainSummary.vue:23
#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:19
@@ -758,6 +789,16 @@ msgstr ""
"Cota padrão aplicada para caixas de correio. Pode ser expresso em KB, MB "
"(padrão) ou GB. Um valor 0 significa que não há cota."
#: src/components/admin/domains/DomainPolicy.vue:24
#: src/components/admin/domains/DomainPolicy.vue:35
#: src/components/admin/domains/DomainPolicy.vue:46
#: src/components/admin/domains/DomainPolicy.vue:57
#: src/components/admin/domains/DomainPolicy.vue:68
#: src/components/admin/domains/DomainPolicy.vue:79
#, fuzzy
msgid "Default value"
msgstr "Valor padrão do domínio"
#: src/components/admin/alarms/AlarmList.vue:116
#: src/components/admin/alarms/AlarmList.vue:133
#: src/components/admin/domains/DomainAliasForm.vue:39
@@ -779,6 +820,16 @@ msgstr "Remover"
msgid "Delete filter set"
msgstr "Remover conjunto de filtros"
#: src/views/quarantine/MessageView.vue:32
#, fuzzy
msgid "Delete message"
msgstr "Todas as mensagens"
#: src/components/quarantine/QuarantineList.vue:84
#, fuzzy
msgid "Delete selection"
msgstr "Remover token"
#: src/layouts/webmail/WebmailLayout.vue:56
#, fuzzy
msgid "Delete this mailbox"
@@ -814,15 +865,35 @@ msgstr "Desabilitar"
msgid "Disable 2FA"
msgstr "Desabilitar 2FA"
#: src/components/admin/domains/DomainPolicyForm.vue:26
#, fuzzy
msgid "Disable banned checks"
msgstr "Desabilitar"
#: src/views/webmail/EmailView.vue:74
#, fuzzy
msgid "Disable links"
msgstr "Desabilitar"
#: src/components/admin/domains/DomainPolicyForm.vue:18
#, fuzzy
msgid "Disable spam checks"
msgstr "Habilitar verificações de DNS"
#: src/components/admin/domains/DomainPolicyForm.vue:11
#, fuzzy
msgid "Disable virus checks"
msgstr "Desabilitar"
#: src/components/admin/domains/DNSStatusChip.vue:18
msgid "Disabled"
msgstr "Desabilitado"
#: src/components/quarantine/QuarantineList.vue:125
#, fuzzy
msgid "Display"
msgstr "Nome de exibição"
#: src/components/contacts/ContactList.vue:23
msgid "Display address book information"
msgstr "Exibir informações do catálogo de endereços"
@@ -997,6 +1068,11 @@ msgstr "Domínio removido"
msgid "Domain name (ex: domain.tld)"
msgstr "Nome do domínio (ex: domain.tld)"
#: src/composables/amavis.js:33
#, fuzzy
msgid "Domain's database"
msgstr "Domínio atualizado"
#: src/components/admin/identities/AccountEditForm.vue:82
msgid "domain's default value"
msgstr "Valor padrão do domínio "
@@ -1048,6 +1124,10 @@ msgstr "Editar categoria"
msgid "Edit contact"
msgstr "Editar contato"
#: src/components/admin/domains/DomainPolicy.vue:9
msgid "Edit content filter settings"
msgstr ""
#: src/views/admin/domains/DomainEditView.vue:3
msgid "Edit domain"
msgstr "Editar domínio"
@@ -1287,11 +1367,17 @@ msgstr "Forwarders com ARC"
#: src/components/account/AutoReplyForm.vue:36
#: src/components/admin/logs/MessageList.vue:50
#: src/components/calendars/EventForm.vue:24
#: src/components/quarantine/QuarantineList.vue:238
#: src/components/tools/TimeSerieChart.vue:19
#: src/components/webmail/ComposeEmailForm.vue:29
msgid "From"
msgstr "De"
#: src/components/quarantine/QuarantineList.vue:45
#, fuzzy
msgid "From address"
msgstr "Endereço aleatório"
#: src/components/calendars/CalendarAccessRulesForm.vue:11
msgid "Full address"
msgstr "Endereço completo"
@@ -1341,6 +1427,10 @@ msgstr "Gerar uma nova chave DKIM"
msgid "Generated address"
msgstr "Endereço gerado"
#: src/composables/amavis.js:30
msgid "Global database"
msgstr ""
#: src/views/admin/InformationView.vue:29
msgid "Go to <strong>Settings > General</strong> section"
msgstr "Vá para a seção <strong>Configurações > Geral</strong>"
@@ -1358,6 +1448,10 @@ msgstr ""
"Aqui está um exemplo de configuração de DNS (formato bind). Substitua os "
"valores entre [ ] pelos apropriados."
#: src/views/quarantine/MessageView.vue:65
msgid "Hide full headers"
msgstr ""
#: src/components/admin/identities/AccountCreationForm.vue:168
#: src/components/admin/identities/AccountCreationForm.vue:95
#: src/components/admin/identities/AccountEditForm.vue:31
@@ -1529,6 +1623,12 @@ msgstr "Última versão"
msgid "Latest version"
msgstr "Última versão"
#: src/components/quarantine/QuarantineList.vue:385
#: src/views/quarantine/MessageView.vue:209
#, fuzzy
msgid "Learning database"
msgstr "Data de criação"
#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:26
msgid "Leave empty for no limit"
msgstr "Deixe em branco para ilimitado"
@@ -1556,7 +1656,7 @@ msgstr "Domínio local (opcional)"
msgid "Logger"
msgstr "Registrador"
#: src/components/shared/TopMenu.vue:100
#: src/components/shared/TopMenu.vue:138
msgid "Logout"
msgstr "Sair"
@@ -1607,10 +1707,23 @@ msgstr ""
msgid "Mark as followed"
msgstr ""
#: src/views/quarantine/MessageView.vue:47
msgid "Mark as non-spam"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:105
msgid "Mark as not spam"
msgstr ""
#: src/components/webmail/EmailList.vue:62
msgid "Mark as read"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:101
#: src/views/quarantine/MessageView.vue:43
msgid "Mark as spam"
msgstr ""
#: src/components/webmail/EmailList.vue:77
msgid "Mark as unfollowed"
msgstr ""
@@ -1629,7 +1742,7 @@ msgstr "MB"
msgid "Message"
msgstr "Mensagem"
#: src/views/webmail/EmailView.vue:254
#: src/views/quarantine/MessageView.vue:196 src/views/webmail/EmailView.vue:254
#, fuzzy
msgid "Message deleted"
msgstr "Filtros de mensagem"
@@ -1651,10 +1764,26 @@ msgstr "Limite de envio de mensagens"
msgid "Message marked as junk"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:291
#: src/views/quarantine/MessageView.vue:236
msgid "Message marked as non-spam"
msgstr ""
#: src/views/webmail/EmailView.vue:282
msgid "Message marked as not junk"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:288
#: src/views/quarantine/MessageView.vue:232
msgid "Message marked as spam"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:285
#: src/views/quarantine/MessageView.vue:178
#, fuzzy
msgid "Message released"
msgstr "Filtros de mensagem"
#: src/components/admin/domains/DomainCreationForm.vue:197
#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:32
#: src/components/admin/identities/AccountCreationForm.vue:133
@@ -1839,7 +1968,7 @@ msgstr "Novos códigos de recuperação"
msgid "Next"
msgstr "Próximo"
#: src/plugins/filters.js:10
#: src/components/tools/YesNoDefaultField.vue:11 src/plugins/filters.js:10
msgid "no"
msgstr "não"
@@ -1906,6 +2035,11 @@ msgstr "Não gerado"
msgid "Note"
msgstr "Nota"
#: src/components/shared/TopMenu.vue:18
#, fuzzy
msgid "Notifications"
msgstr "Identificação"
#: src/components/admin/identities/AccountEditForm.vue:163
msgid "Number of allowed mailbox aliases:"
msgstr "Número de apelidos de caixa de correio permitidos:"
@@ -1969,6 +2103,14 @@ msgstr "Alarmes abertos"
msgid "Options"
msgstr "Opções"
#: src/components/admin/domains/DomainPolicyForm.vue:69
msgid "or more is spam"
msgstr ""
#: src/components/admin/domains/DomainPolicyForm.vue:84
msgid "or more throw spam message away"
msgstr ""
#: src/components/account/ProfileForm.vue:30
msgid "or suggest a new language"
msgstr "ou sugira um novo idioma"
@@ -2115,6 +2257,15 @@ msgstr "Provedor atualizado"
msgid "Providers"
msgstr "Provedores"
#: src/views/quarantine/QuarantineView.vue:4
msgid "Quarantine"
msgstr ""
#: src/views/quarantine/MessageView.vue:4
#, fuzzy
msgid "Quarantined message"
msgstr "Mensagens importantes"
#: src/components/admin/logs/MessageList.vue:46
msgid "Queue ID"
msgstr "ID da fila"
@@ -2204,6 +2355,10 @@ msgstr "Autenticador de registro"
msgid "Registered Webauthn devices"
msgstr "Dispositivos Webauthn registrados"
#: src/components/admin/domains/DomainPolicy.vue:61
msgid "Rejection threshold"
msgstr ""
#: src/components/tools/TimeSerieChart.vue:27
msgid "Relative time ranges"
msgstr "Intervalos de tempo relativos"
@@ -2217,6 +2372,25 @@ msgstr "Relay"
msgid "Relay domain"
msgstr "relaydomain"
#: src/views/quarantine/MessageView.vue:21
#, fuzzy
msgid "Release message"
msgstr "Todas as mensagens"
#: src/components/quarantine/QuarantineList.vue:372
#: src/views/quarantine/MessageView.vue:176
msgid "Release request sent"
msgstr ""
#: src/views/quarantine/QuarantineView.vue:12
msgid "release requests"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:72
#, fuzzy
msgid "Release selection"
msgstr "Remover ação"
#: src/components/admin/alarms/AlarmList.vue:123
msgid "Reload"
msgstr "Recarregar"
@@ -2289,6 +2463,10 @@ msgstr "Salvar"
msgid "Save your changes"
msgstr "Salve suas alterações"
#: src/components/quarantine/QuarantineList.vue:236
msgid "Score"
msgstr ""
#: src/components/admin/alarms/AlarmList.vue:21
#: src/components/admin/domains/DomainList.vue:19
#: src/components/admin/identities/IdentityList.vue:24
@@ -2299,6 +2477,7 @@ msgstr "Salve suas alterações"
msgid "Search"
msgstr "Busca"
#: src/components/quarantine/QuarantineList.vue:27
#: src/components/webmail/EmailList.vue:14
#, fuzzy
msgid "Search in messages"
@@ -2336,6 +2515,20 @@ msgstr "Selecione um arquivo ICS para importar e clique no botão \"Enviar\""
msgid "Select file"
msgstr "Selecionar arquivo"
#: src/components/quarantine/QuarantineList.vue:359
#, fuzzy
msgid "Selection deleted"
msgstr "Migração removida"
#: src/components/quarantine/QuarantineList.vue:398
msgid "Selection is being processed..."
msgstr ""
#: src/components/quarantine/QuarantineList.vue:374
#, fuzzy
msgid "Selection released"
msgstr "Selecionar arquivo"
#: src/components/calendars/ImportEventsForm.vue:30
#: src/components/webmail/ComposeEmailForm.vue:13
msgid "Send"
@@ -2408,6 +2601,20 @@ msgstr "Mostrar chave"
msgid "Simple user"
msgstr "Usuário simples"
#: src/components/admin/domains/DomainPolicy.vue:50
msgid "Spam classification threshold"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:17
#, fuzzy
msgid "Spam filters"
msgstr "Filtros de mensagem"
#: src/components/admin/domains/DomainPolicy.vue:72
#: src/components/admin/domains/DomainPolicyForm.vue:34
msgid "Spam marker"
msgstr ""
#: src/components/admin/identities/AccountSenderAddresses.vue:17
msgid "Specify an email address"
msgstr "Especifique um endereço de e-mail"
@@ -2442,6 +2649,8 @@ msgid "Status"
msgstr "Status"
#: src/components/account/AutoReplyForm.vue:12
#: src/components/quarantine/QuarantineList.vue:239
#: src/components/quarantine/QuarantineList.vue:49
#: src/components/webmail/ComposeEmailForm.vue:137
msgid "Subject"
msgstr "Assunto"
@@ -2518,12 +2727,18 @@ msgstr ""
msgid "there"
msgstr "ali"
#: src/components/admin/domains/DomainPolicyForm.vue:56
msgid "Thresholds"
msgstr ""
#: src/components/calendars/EventForm.vue:12
msgid "Title"
msgstr "Título"
#: src/components/admin/logs/MessageList.vue:49
#: src/components/calendars/EventForm.vue:34
#: src/components/quarantine/QuarantineList.vue:237
#: src/components/quarantine/QuarantineList.vue:52
#: src/components/tools/TimeSerieChart.vue:20
#: src/components/webmail/ComposeEmailForm.vue:46
#: src/views/webmail/EmailView.vue:109
@@ -2668,6 +2883,10 @@ msgstr "Usar contagem"
msgid "Use domain default value"
msgstr "Usar valor padrão de domínio"
#: src/composables/amavis.js:36
msgid "User's database"
msgstr ""
#: src/components/admin/domains/DomainAdminList.vue:111
#: src/components/admin/identities/AccountCreationForm.vue:97
#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:3
@@ -2686,6 +2905,15 @@ msgstr "Válido"
msgid "Value"
msgstr "Valor"
#: src/views/quarantine/MessageView.vue:62
msgid "View full headers"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:28
#, fuzzy
msgid "Virus filters"
msgstr "Editar filtro"
#: src/components/admin/dashboard/NewsFeedWidget.vue:21
msgid "Visit the official weblog for more information"
msgstr ""
@@ -2728,6 +2956,11 @@ msgstr "Semana"
msgid "Welcome to Modoboa"
msgstr "Bem-vindo ao Modoboa"
#: src/components/quarantine/QuarantineList.vue:386
#: src/views/quarantine/MessageView.vue:210
msgid "Which database should be used for this learning:"
msgstr ""
#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:25
msgid "With a mailbox"
msgstr "Com uma caixa de e-mail"
@@ -2745,7 +2978,7 @@ msgstr "Escrita"
msgid "Year"
msgstr "Ano"
#: src/plugins/filters.js:10
#: src/components/tools/YesNoDefaultField.vue:7 src/plugins/filters.js:10
msgid "yes"
msgstr "sim"
@@ -2887,9 +3120,6 @@ msgstr "Novo"
#~ msgid "domain"
#~ msgstr "domínio"
#~ msgid "Domain updated"
#~ msgstr "Domínio atualizado"
#~ msgid "Invalid password"
#~ msgstr "Senha inválida"
+236 -6
View File
@@ -65,7 +65,7 @@ msgid "Access rules"
msgstr ""
#: src/components/calendars/CalendarAccessRulesForm.vue:42
#: src/components/shared/TopMenu.vue:93
#: src/components/shared/TopMenu.vue:131
#: src/views/admin/identities/AccountView.vue:4
#: src/views/admin/identities/IdentitiesView.vue:23
msgid "Account"
@@ -343,6 +343,7 @@ msgstr "Аккаунт создан"
msgid "API token deleted"
msgstr "Дата создания"
#: src/components/admin/domains/DomainPolicyForm.vue:96
#: src/components/tools/ChooseColumnsForm.vue:19
#: src/components/tools/TimeSerieChart.vue:22
msgid "Apply"
@@ -432,6 +433,11 @@ msgstr ""
msgid "Backup codes"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:39
#, fuzzy
msgid "Banned filters"
msgstr "использование (%%)"
#: src/components/webmail/ComposeEmailForm.vue:110
#: src/components/webmail/ComposeEmailForm.vue:73
msgid "Bcc"
@@ -446,6 +452,14 @@ msgstr "Неверный формат"
msgid "Birth date"
msgstr "Дата создания"
#: src/components/quarantine/QuarantineList.vue:54
msgid "both"
msgstr ""
#: src/components/admin/domains/form_steps/DomainPolicyForm.vue:5
msgid "Bypass virus checks"
msgstr ""
#: src/components/calendars/EventForm.vue:49
#: src/views/calendars/CalendarView.vue:3
msgid "Calendar"
@@ -480,6 +494,7 @@ msgstr "Профиль обновлен"
#: src/components/account/FilterForm.vue:147
#: src/components/account/FilterSetForm.vue:24
#: src/components/admin/domains/DomainEditForm.vue:161
#: src/components/admin/domains/DomainPolicyForm.vue:93
#: src/components/admin/identities/AccountEditForm.vue:183
#: src/components/admin/identities/AliasEditForm.vue:69
#: src/components/admin/imap_migration/ProviderForm.vue:58
@@ -569,7 +584,7 @@ msgstr ""
#: src/components/tools/ImportForm.vue:51
#: src/components/webmail/AttachmentsDialog.vue:41
#: src/components/webmail/MailboxForm.vue:29
#: src/layouts/connected/ConnectedLayout.vue:17
#: src/layouts/connected/ConnectedLayout.vue:19
msgid "Close"
msgstr ""
@@ -628,6 +643,16 @@ msgstr ""
msgid "Content"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:5
#, fuzzy
msgid "Content filter"
msgstr "Е-майл адрес"
#: src/components/admin/domains/DomainPolicyForm.vue:4
#, fuzzy
msgid "Content filter settings"
msgstr "Основные"
#: src/components/tools/ImportForm.vue:40
msgid "Continue on error"
msgstr "Продолжать при ошибке"
@@ -741,6 +766,7 @@ msgstr "Приборная панель"
#: src/components/admin/logs/AuditTrailList.vue:51
#: src/components/admin/logs/MessageList.vue:47
#: src/components/quarantine/QuarantineList.vue:240
msgid "Date"
msgstr ""
@@ -748,6 +774,11 @@ msgstr ""
msgid "Day"
msgstr "День"
#: src/components/admin/domains/DomainPolicyForm.vue:47
#: src/components/tools/YesNoDefaultField.vue:15
msgid "default"
msgstr ""
#: src/components/admin/domains/DomainCreationForm.vue:193
#: src/components/admin/domains/DomainSummary.vue:23
#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:19
@@ -760,6 +791,16 @@ msgid ""
"GB. A value of 0 means no quota."
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:24
#: src/components/admin/domains/DomainPolicy.vue:35
#: src/components/admin/domains/DomainPolicy.vue:46
#: src/components/admin/domains/DomainPolicy.vue:57
#: src/components/admin/domains/DomainPolicy.vue:68
#: src/components/admin/domains/DomainPolicy.vue:79
#, fuzzy
msgid "Default value"
msgstr "Используются значения домена по умолчанию "
#: src/components/admin/alarms/AlarmList.vue:116
#: src/components/admin/alarms/AlarmList.vue:133
#: src/components/admin/domains/DomainAliasForm.vue:39
@@ -781,6 +822,15 @@ msgstr ""
msgid "Delete filter set"
msgstr ""
#: src/views/quarantine/MessageView.vue:32
#, fuzzy
msgid "Delete message"
msgstr "использование (%%)"
#: src/components/quarantine/QuarantineList.vue:84
msgid "Delete selection"
msgstr ""
#: src/layouts/webmail/WebmailLayout.vue:56
msgid "Delete this mailbox"
msgstr ""
@@ -816,15 +866,35 @@ msgstr "Разрешен"
msgid "Disable 2FA"
msgstr "Разрешен"
#: src/components/admin/domains/DomainPolicyForm.vue:26
#, fuzzy
msgid "Disable banned checks"
msgstr "Разрешен"
#: src/views/webmail/EmailView.vue:74
#, fuzzy
msgid "Disable links"
msgstr "Разрешен"
#: src/components/admin/domains/DomainPolicyForm.vue:18
#, fuzzy
msgid "Disable spam checks"
msgstr "Разрешен"
#: src/components/admin/domains/DomainPolicyForm.vue:11
#, fuzzy
msgid "Disable virus checks"
msgstr "Разрешен"
#: src/components/admin/domains/DNSStatusChip.vue:18
msgid "Disabled"
msgstr "Разрешен"
#: src/components/quarantine/QuarantineList.vue:125
#, fuzzy
msgid "Display"
msgstr "Имя файла"
#: src/components/contacts/ContactList.vue:23
msgid "Display address book information"
msgstr ""
@@ -997,6 +1067,11 @@ msgstr ""
msgid "Domain name (ex: domain.tld)"
msgstr ""
#: src/composables/amavis.js:33
#, fuzzy
msgid "Domain's database"
msgstr "Используются значения домена по умолчанию "
#: src/components/admin/identities/AccountEditForm.vue:82
#, fuzzy
msgid "domain's default value"
@@ -1054,6 +1129,10 @@ msgstr "Е-майл адрес"
msgid "Edit contact"
msgstr "Новый аккаунт"
#: src/components/admin/domains/DomainPolicy.vue:9
msgid "Edit content filter settings"
msgstr ""
#: src/views/admin/domains/DomainEditView.vue:3
msgid "Edit domain"
msgstr ""
@@ -1308,11 +1387,17 @@ msgstr ""
#: src/components/account/AutoReplyForm.vue:36
#: src/components/admin/logs/MessageList.vue:50
#: src/components/calendars/EventForm.vue:24
#: src/components/quarantine/QuarantineList.vue:238
#: src/components/tools/TimeSerieChart.vue:19
#: src/components/webmail/ComposeEmailForm.vue:29
msgid "From"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:45
#, fuzzy
msgid "From address"
msgstr "Ошибочный запрос"
#: src/components/calendars/CalendarAccessRulesForm.vue:11
#, fuzzy
msgid "Full address"
@@ -1367,6 +1452,10 @@ msgstr ""
msgid "Generated address"
msgstr "Ошибочный запрос"
#: src/composables/amavis.js:30
msgid "Global database"
msgstr ""
#: src/views/admin/InformationView.vue:29
msgid "Go to <strong>Settings > General</strong> section"
msgstr ""
@@ -1382,6 +1471,10 @@ msgid ""
"between [ ] by the appropriate ones."
msgstr ""
#: src/views/quarantine/MessageView.vue:65
msgid "Hide full headers"
msgstr ""
#: src/components/admin/identities/AccountCreationForm.vue:168
#: src/components/admin/identities/AccountCreationForm.vue:95
#: src/components/admin/identities/AccountEditForm.vue:31
@@ -1548,6 +1641,12 @@ msgstr "Установленная версия"
msgid "Latest version"
msgstr "Установленная версия"
#: src/components/quarantine/QuarantineList.vue:385
#: src/views/quarantine/MessageView.vue:209
#, fuzzy
msgid "Learning database"
msgstr "Дата создания"
#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:26
msgid "Leave empty for no limit"
msgstr ""
@@ -1575,7 +1674,7 @@ msgstr ""
msgid "Logger"
msgstr "Логгер"
#: src/components/shared/TopMenu.vue:100
#: src/components/shared/TopMenu.vue:138
msgid "Logout"
msgstr "Завершить сеанс"
@@ -1623,10 +1722,23 @@ msgstr ""
msgid "Mark as followed"
msgstr ""
#: src/views/quarantine/MessageView.vue:47
msgid "Mark as non-spam"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:105
msgid "Mark as not spam"
msgstr ""
#: src/components/webmail/EmailList.vue:62
msgid "Mark as read"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:101
#: src/views/quarantine/MessageView.vue:43
msgid "Mark as spam"
msgstr ""
#: src/components/webmail/EmailList.vue:77
msgid "Mark as unfollowed"
msgstr ""
@@ -1645,7 +1757,7 @@ msgstr ""
msgid "Message"
msgstr "использование (%%)"
#: src/views/webmail/EmailView.vue:254
#: src/views/quarantine/MessageView.vue:196 src/views/webmail/EmailView.vue:254
#, fuzzy
msgid "Message deleted"
msgstr "использование (%%)"
@@ -1669,10 +1781,26 @@ msgstr "использование (%%)"
msgid "Message marked as junk"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:291
#: src/views/quarantine/MessageView.vue:236
msgid "Message marked as non-spam"
msgstr ""
#: src/views/webmail/EmailView.vue:282
msgid "Message marked as not junk"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:288
#: src/views/quarantine/MessageView.vue:232
msgid "Message marked as spam"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:285
#: src/views/quarantine/MessageView.vue:178
#, fuzzy
msgid "Message released"
msgstr "использование (%%)"
#: src/components/admin/domains/DomainCreationForm.vue:197
#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:32
#: src/components/admin/identities/AccountCreationForm.vue:133
@@ -1867,7 +1995,7 @@ msgstr ""
msgid "Next"
msgstr "Следующая"
#: src/plugins/filters.js:10
#: src/components/tools/YesNoDefaultField.vue:11 src/plugins/filters.js:10
msgid "no"
msgstr ""
@@ -1933,6 +2061,11 @@ msgstr "Получатель не определен"
msgid "Note"
msgstr ""
#: src/components/shared/TopMenu.vue:18
#, fuzzy
msgid "Notifications"
msgstr "Дата последней модификации"
#: src/components/admin/identities/AccountEditForm.vue:163
#, fuzzy
msgid "Number of allowed mailbox aliases:"
@@ -1996,6 +2129,14 @@ msgstr ""
msgid "Options"
msgstr "Опции"
#: src/components/admin/domains/DomainPolicyForm.vue:69
msgid "or more is spam"
msgstr ""
#: src/components/admin/domains/DomainPolicyForm.vue:84
msgid "or more throw spam message away"
msgstr ""
#: src/components/account/ProfileForm.vue:30
msgid "or suggest a new language"
msgstr ""
@@ -2148,6 +2289,15 @@ msgstr "Профиль обновлен"
msgid "Providers"
msgstr "Е-майл адрес"
#: src/views/quarantine/QuarantineView.vue:4
msgid "Quarantine"
msgstr ""
#: src/views/quarantine/MessageView.vue:4
#, fuzzy
msgid "Quarantined message"
msgstr "Импорт доменов"
#: src/components/admin/logs/MessageList.vue:46
msgid "Queue ID"
msgstr ""
@@ -2236,6 +2386,10 @@ msgstr "Аутентификация"
msgid "Registered Webauthn devices"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:61
msgid "Rejection threshold"
msgstr ""
#: src/components/tools/TimeSerieChart.vue:27
msgid "Relative time ranges"
msgstr ""
@@ -2249,6 +2403,24 @@ msgstr ""
msgid "Relay domain"
msgstr "Новый домен"
#: src/views/quarantine/MessageView.vue:21
#, fuzzy
msgid "Release message"
msgstr "использование (%%)"
#: src/components/quarantine/QuarantineList.vue:372
#: src/views/quarantine/MessageView.vue:176
msgid "Release request sent"
msgstr ""
#: src/views/quarantine/QuarantineView.vue:12
msgid "release requests"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:72
msgid "Release selection"
msgstr ""
#: src/components/admin/alarms/AlarmList.vue:123
msgid "Reload"
msgstr ""
@@ -2321,6 +2493,10 @@ msgstr "Сохранить"
msgid "Save your changes"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:236
msgid "Score"
msgstr ""
#: src/components/admin/alarms/AlarmList.vue:21
#: src/components/admin/domains/DomainList.vue:19
#: src/components/admin/identities/IdentityList.vue:24
@@ -2331,6 +2507,7 @@ msgstr ""
msgid "Search"
msgstr "Поиск"
#: src/components/quarantine/QuarantineList.vue:27
#: src/components/webmail/EmailList.vue:14
#, fuzzy
msgid "Search in messages"
@@ -2368,6 +2545,19 @@ msgstr ""
msgid "Select file"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:359
#, fuzzy
msgid "Selection deleted"
msgstr "Дата создания"
#: src/components/quarantine/QuarantineList.vue:398
msgid "Selection is being processed..."
msgstr ""
#: src/components/quarantine/QuarantineList.vue:374
msgid "Selection released"
msgstr ""
#: src/components/calendars/ImportEventsForm.vue:30
#: src/components/webmail/ComposeEmailForm.vue:13
#, fuzzy
@@ -2444,6 +2634,20 @@ msgstr ""
msgid "Simple user"
msgstr "Обычный пользователь"
#: src/components/admin/domains/DomainPolicy.vue:50
msgid "Spam classification threshold"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:17
#, fuzzy
msgid "Spam filters"
msgstr "использование (%%)"
#: src/components/admin/domains/DomainPolicy.vue:72
#: src/components/admin/domains/DomainPolicyForm.vue:34
msgid "Spam marker"
msgstr ""
#: src/components/admin/identities/AccountSenderAddresses.vue:17
msgid "Specify an email address"
msgstr ""
@@ -2479,6 +2683,8 @@ msgid "Status"
msgstr "Статистика"
#: src/components/account/AutoReplyForm.vue:12
#: src/components/quarantine/QuarantineList.vue:239
#: src/components/quarantine/QuarantineList.vue:49
#: src/components/webmail/ComposeEmailForm.vue:137
msgid "Subject"
msgstr ""
@@ -2543,12 +2749,18 @@ msgstr ""
msgid "there"
msgstr ""
#: src/components/admin/domains/DomainPolicyForm.vue:56
msgid "Thresholds"
msgstr ""
#: src/components/calendars/EventForm.vue:12
msgid "Title"
msgstr ""
#: src/components/admin/logs/MessageList.vue:49
#: src/components/calendars/EventForm.vue:34
#: src/components/quarantine/QuarantineList.vue:237
#: src/components/quarantine/QuarantineList.vue:52
#: src/components/tools/TimeSerieChart.vue:20
#: src/components/webmail/ComposeEmailForm.vue:46
#: src/views/webmail/EmailView.vue:109
@@ -2692,6 +2904,10 @@ msgstr "Новый аккаунт"
msgid "Use domain default value"
msgstr "Используются значения домена по умолчанию "
#: src/composables/amavis.js:36
msgid "User's database"
msgstr ""
#: src/components/admin/domains/DomainAdminList.vue:111
#: src/components/admin/identities/AccountCreationForm.vue:97
#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:3
@@ -2711,6 +2927,15 @@ msgstr ""
msgid "Value"
msgstr ""
#: src/views/quarantine/MessageView.vue:62
msgid "View full headers"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:28
#, fuzzy
msgid "Virus filters"
msgstr "Е-майл адрес"
#: src/components/admin/dashboard/NewsFeedWidget.vue:21
msgid "Visit the official weblog for more information"
msgstr ""
@@ -2751,6 +2976,11 @@ msgstr "Неделя"
msgid "Welcome to Modoboa"
msgstr "Добро пожаловать в Modoboa!"
#: src/components/quarantine/QuarantineList.vue:386
#: src/views/quarantine/MessageView.vue:210
msgid "Which database should be used for this learning:"
msgstr ""
#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:25
msgid "With a mailbox"
msgstr ""
@@ -2768,7 +2998,7 @@ msgstr ""
msgid "Year"
msgstr "Год"
#: src/plugins/filters.js:10
#: src/components/tools/YesNoDefaultField.vue:7 src/plugins/filters.js:10
msgid "yes"
msgstr ""
+244 -9
View File
@@ -69,7 +69,7 @@ msgid "Access rules"
msgstr "Åtkomstregler"
#: src/components/calendars/CalendarAccessRulesForm.vue:42
#: src/components/shared/TopMenu.vue:93
#: src/components/shared/TopMenu.vue:131
#: src/views/admin/identities/AccountView.vue:4
#: src/views/admin/identities/IdentitiesView.vue:23
msgid "Account"
@@ -336,6 +336,7 @@ msgstr "API token skapat"
msgid "API token deleted"
msgstr "API token raderat"
#: src/components/admin/domains/DomainPolicyForm.vue:96
#: src/components/tools/ChooseColumnsForm.vue:19
#: src/components/tools/TimeSerieChart.vue:22
msgid "Apply"
@@ -423,6 +424,11 @@ msgstr "Tillbaka"
msgid "Backup codes"
msgstr "Säkerhetskopieringskoder"
#: src/components/admin/domains/DomainPolicy.vue:39
#, fuzzy
msgid "Banned filters"
msgstr "Meddelandefilter"
#: src/components/webmail/ComposeEmailForm.vue:110
#: src/components/webmail/ComposeEmailForm.vue:73
msgid "Bcc"
@@ -436,6 +442,14 @@ msgstr "Bind/named formatterat. Klicka för att kopiera"
msgid "Birth date"
msgstr "Födelsedatum"
#: src/components/quarantine/QuarantineList.vue:54
msgid "both"
msgstr ""
#: src/components/admin/domains/form_steps/DomainPolicyForm.vue:5
msgid "Bypass virus checks"
msgstr ""
#: src/components/calendars/EventForm.vue:49
#: src/views/calendars/CalendarView.vue:3
msgid "Calendar"
@@ -466,6 +480,7 @@ msgstr "Kalender uppdaterad"
#: src/components/account/FilterForm.vue:147
#: src/components/account/FilterSetForm.vue:24
#: src/components/admin/domains/DomainEditForm.vue:161
#: src/components/admin/domains/DomainPolicyForm.vue:93
#: src/components/admin/identities/AccountEditForm.vue:183
#: src/components/admin/identities/AliasEditForm.vue:69
#: src/components/admin/imap_migration/ProviderForm.vue:58
@@ -555,7 +570,7 @@ msgstr "Klicka här för att kopiera nyckeln"
#: src/components/tools/ImportForm.vue:51
#: src/components/webmail/AttachmentsDialog.vue:41
#: src/components/webmail/MailboxForm.vue:29
#: src/layouts/connected/ConnectedLayout.vue:17
#: src/layouts/connected/ConnectedLayout.vue:19
msgid "Close"
msgstr "Stäng"
@@ -615,6 +630,16 @@ msgstr "Kontakter"
msgid "Content"
msgstr "Innehåll"
#: src/components/admin/domains/DomainPolicy.vue:5
#, fuzzy
msgid "Content filter"
msgstr "Innehåll"
#: src/components/admin/domains/DomainPolicyForm.vue:4
#, fuzzy
msgid "Content filter settings"
msgstr "Allmänna inställningar"
#: src/components/tools/ImportForm.vue:40
msgid "Continue on error"
msgstr "Fortsätt vid fel"
@@ -727,6 +752,7 @@ msgstr "Instrumentbräda"
#: src/components/admin/logs/AuditTrailList.vue:51
#: src/components/admin/logs/MessageList.vue:47
#: src/components/quarantine/QuarantineList.vue:240
msgid "Date"
msgstr "Datum"
@@ -734,6 +760,11 @@ msgstr "Datum"
msgid "Day"
msgstr "Dag"
#: src/components/admin/domains/DomainPolicyForm.vue:47
#: src/components/tools/YesNoDefaultField.vue:15
msgid "default"
msgstr ""
#: src/components/admin/domains/DomainCreationForm.vue:193
#: src/components/admin/domains/DomainSummary.vue:23
#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:19
@@ -748,6 +779,16 @@ msgstr ""
"Standardkvot tillämpas på postlådor. Kan uttryckas i KB, MB (standard) eller "
"GB. Ett värde på 0 betyder ingen kvot."
#: src/components/admin/domains/DomainPolicy.vue:24
#: src/components/admin/domains/DomainPolicy.vue:35
#: src/components/admin/domains/DomainPolicy.vue:46
#: src/components/admin/domains/DomainPolicy.vue:57
#: src/components/admin/domains/DomainPolicy.vue:68
#: src/components/admin/domains/DomainPolicy.vue:79
#, fuzzy
msgid "Default value"
msgstr "Domän standardvärde"
#: src/components/admin/alarms/AlarmList.vue:116
#: src/components/admin/alarms/AlarmList.vue:133
#: src/components/admin/domains/DomainAliasForm.vue:39
@@ -769,6 +810,16 @@ msgstr "Radera"
msgid "Delete filter set"
msgstr "Ta bort filteruppsättning"
#: src/views/quarantine/MessageView.vue:32
#, fuzzy
msgid "Delete message"
msgstr "Alla meddelanden"
#: src/components/quarantine/QuarantineList.vue:84
#, fuzzy
msgid "Delete selection"
msgstr "Radera token"
#: src/layouts/webmail/WebmailLayout.vue:56
msgid "Delete this mailbox"
msgstr "Ta bort den här brevlådan"
@@ -802,14 +853,34 @@ msgstr "Inaktivera"
msgid "Disable 2FA"
msgstr "Inaktivear 2FA"
#: src/components/admin/domains/DomainPolicyForm.vue:26
#, fuzzy
msgid "Disable banned checks"
msgstr "Inaktivera länkar"
#: src/views/webmail/EmailView.vue:74
msgid "Disable links"
msgstr "Inaktivera länkar"
#: src/components/admin/domains/DomainPolicyForm.vue:18
#, fuzzy
msgid "Disable spam checks"
msgstr "Aktivera DNS kontroller"
#: src/components/admin/domains/DomainPolicyForm.vue:11
#, fuzzy
msgid "Disable virus checks"
msgstr "Inaktivera länkar"
#: src/components/admin/domains/DNSStatusChip.vue:18
msgid "Disabled"
msgstr "Inaktiverad"
#: src/components/quarantine/QuarantineList.vue:125
#, fuzzy
msgid "Display"
msgstr "Display name"
#: src/components/contacts/ContactList.vue:23
msgid "Display address book information"
msgstr "Visa adressboksinformation"
@@ -982,6 +1053,11 @@ msgstr "Domän raderad"
msgid "Domain name (ex: domain.tld)"
msgstr "Domännamn (ex: domain.tld)"
#: src/composables/amavis.js:33
#, fuzzy
msgid "Domain's database"
msgstr "Domän uppdaterad"
#: src/components/admin/identities/AccountEditForm.vue:82
msgid "domain's default value"
msgstr "domänens standardvärde"
@@ -1033,6 +1109,10 @@ msgstr "Redigera kategori"
msgid "Edit contact"
msgstr "Redigera kontakt"
#: src/components/admin/domains/DomainPolicy.vue:9
msgid "Edit content filter settings"
msgstr ""
#: src/views/admin/domains/DomainEditView.vue:3
msgid "Edit domain"
msgstr "Redigera domän"
@@ -1267,11 +1347,17 @@ msgstr "Vidarebefordrare med ARC"
#: src/components/account/AutoReplyForm.vue:36
#: src/components/admin/logs/MessageList.vue:50
#: src/components/calendars/EventForm.vue:24
#: src/components/quarantine/QuarantineList.vue:238
#: src/components/tools/TimeSerieChart.vue:19
#: src/components/webmail/ComposeEmailForm.vue:29
msgid "From"
msgstr "Från"
#: src/components/quarantine/QuarantineList.vue:45
#, fuzzy
msgid "From address"
msgstr "Slumpmässig adress"
#: src/components/calendars/CalendarAccessRulesForm.vue:11
msgid "Full address"
msgstr "Fullständig adress"
@@ -1321,6 +1407,10 @@ msgstr "Generera en ny DKIM nyckel"
msgid "Generated address"
msgstr "Genererad adress"
#: src/composables/amavis.js:30
msgid "Global database"
msgstr ""
#: src/views/admin/InformationView.vue:29
msgid "Go to <strong>Settings > General</strong> section"
msgstr "Gå till avsnittet <strong>Inställningar > Allmänt</strong>"
@@ -1338,6 +1428,10 @@ msgstr ""
"Här är ett exempel på DNS-konfiguration (bind-format). Ersätt värdena mellan "
"[ ] med de lämpliga värdena."
#: src/views/quarantine/MessageView.vue:65
msgid "Hide full headers"
msgstr ""
#: src/components/admin/identities/AccountCreationForm.vue:168
#: src/components/admin/identities/AccountCreationForm.vue:95
#: src/components/admin/identities/AccountEditForm.vue:31
@@ -1509,6 +1603,12 @@ msgstr "Senaste version"
msgid "Latest version"
msgstr "Senaste version"
#: src/components/quarantine/QuarantineList.vue:385
#: src/views/quarantine/MessageView.vue:209
#, fuzzy
msgid "Learning database"
msgstr "Datum skapad"
#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:26
msgid "Leave empty for no limit"
msgstr "Lämna tomt för ingen gräns"
@@ -1536,7 +1636,7 @@ msgstr "Lokal domän (valfritt)§"
msgid "Logger"
msgstr "Logger"
#: src/components/shared/TopMenu.vue:100
#: src/components/shared/TopMenu.vue:138
msgid "Logout"
msgstr "Logga ut"
@@ -1583,10 +1683,26 @@ msgstr ""
msgid "Mark as followed"
msgstr "Markera enligt följande"
#: src/views/quarantine/MessageView.vue:47
#, fuzzy
msgid "Mark as non-spam"
msgstr "Markera som oläst"
#: src/components/quarantine/QuarantineList.vue:105
#, fuzzy
msgid "Mark as not spam"
msgstr "Markera som oläst"
#: src/components/webmail/EmailList.vue:62
msgid "Mark as read"
msgstr "Markera som läst"
#: src/components/quarantine/QuarantineList.vue:101
#: src/views/quarantine/MessageView.vue:43
#, fuzzy
msgid "Mark as spam"
msgstr "Markera som läst"
#: src/components/webmail/EmailList.vue:77
msgid "Mark as unfollowed"
msgstr "Markera som ej följt"
@@ -1605,7 +1721,7 @@ msgstr "MB"
msgid "Message"
msgstr "Meddelande"
#: src/views/webmail/EmailView.vue:254
#: src/views/quarantine/MessageView.vue:196 src/views/webmail/EmailView.vue:254
msgid "Message deleted"
msgstr "Meddelandet raderat"
@@ -1626,10 +1742,28 @@ msgstr "Begränsning för meddelandesändning"
msgid "Message marked as junk"
msgstr "Meddelande markerat som skräp"
#: src/components/quarantine/QuarantineList.vue:291
#: src/views/quarantine/MessageView.vue:236
#, fuzzy
msgid "Message marked as non-spam"
msgstr "Meddelandet markerat som inte skräp"
#: src/views/webmail/EmailView.vue:282
msgid "Message marked as not junk"
msgstr "Meddelandet markerat som inte skräp"
#: src/components/quarantine/QuarantineList.vue:288
#: src/views/quarantine/MessageView.vue:232
#, fuzzy
msgid "Message marked as spam"
msgstr "Meddelande markerat som skräp"
#: src/components/quarantine/QuarantineList.vue:285
#: src/views/quarantine/MessageView.vue:178
#, fuzzy
msgid "Message released"
msgstr "Meddelandet raderat"
#: src/components/admin/domains/DomainCreationForm.vue:197
#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:32
#: src/components/admin/identities/AccountCreationForm.vue:133
@@ -1812,7 +1946,7 @@ msgstr "Nya återställningskoder"
msgid "Next"
msgstr "Nästa"
#: src/plugins/filters.js:10
#: src/components/tools/YesNoDefaultField.vue:11 src/plugins/filters.js:10
msgid "no"
msgstr "nej"
@@ -1878,6 +2012,11 @@ msgstr "Ej genererad"
msgid "Note"
msgstr "Anteckning"
#: src/components/shared/TopMenu.vue:18
#, fuzzy
msgid "Notifications"
msgstr "Identifikation"
#: src/components/admin/identities/AccountEditForm.vue:163
msgid "Number of allowed mailbox aliases:"
msgstr "Antal tillåtna postlådealias:"
@@ -1941,6 +2080,14 @@ msgstr "Öppnade alarm"
msgid "Options"
msgstr "Alternativ"
#: src/components/admin/domains/DomainPolicyForm.vue:69
msgid "or more is spam"
msgstr ""
#: src/components/admin/domains/DomainPolicyForm.vue:84
msgid "or more throw spam message away"
msgstr ""
#: src/components/account/ProfileForm.vue:30
msgid "or suggest a new language"
msgstr "eller föreslå ett nytt språk"
@@ -2084,6 +2231,15 @@ msgstr "Leverantör uppdaterad"
msgid "Providers"
msgstr "Leverantörer"
#: src/views/quarantine/QuarantineView.vue:4
msgid "Quarantine"
msgstr ""
#: src/views/quarantine/MessageView.vue:4
#, fuzzy
msgid "Quarantined message"
msgstr "Viktiga meddelanden"
#: src/components/admin/logs/MessageList.vue:46
msgid "Queue ID"
msgstr "Kö ID"
@@ -2172,6 +2328,10 @@ msgstr "Registrera autentiseringsverktyg"
msgid "Registered Webauthn devices"
msgstr "Registrerade Webauthn-enheter"
#: src/components/admin/domains/DomainPolicy.vue:61
msgid "Rejection threshold"
msgstr ""
#: src/components/tools/TimeSerieChart.vue:27
msgid "Relative time ranges"
msgstr "Relativa tidsintervall"
@@ -2185,6 +2345,25 @@ msgstr "Relä"
msgid "Relay domain"
msgstr "relädomän"
#: src/views/quarantine/MessageView.vue:21
#, fuzzy
msgid "Release message"
msgstr "Alla meddelanden"
#: src/components/quarantine/QuarantineList.vue:372
#: src/views/quarantine/MessageView.vue:176
msgid "Release request sent"
msgstr ""
#: src/views/quarantine/QuarantineView.vue:12
msgid "release requests"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:72
#, fuzzy
msgid "Release selection"
msgstr "Ta bort åtgärd"
#: src/components/admin/alarms/AlarmList.vue:123
msgid "Reload"
msgstr "Ladda om"
@@ -2257,6 +2436,10 @@ msgstr "Spara"
msgid "Save your changes"
msgstr "Spara dina ändringar"
#: src/components/quarantine/QuarantineList.vue:236
msgid "Score"
msgstr ""
#: src/components/admin/alarms/AlarmList.vue:21
#: src/components/admin/domains/DomainList.vue:19
#: src/components/admin/identities/IdentityList.vue:24
@@ -2267,6 +2450,7 @@ msgstr "Spara dina ändringar"
msgid "Search"
msgstr "Sök"
#: src/components/quarantine/QuarantineList.vue:27
#: src/components/webmail/EmailList.vue:14
msgid "Search in messages"
msgstr "Sök i meddelanden"
@@ -2303,6 +2487,20 @@ msgstr "Välj en ICS-fil att importera och klicka på knappen Skicka"
msgid "Select file"
msgstr "Välj fil"
#: src/components/quarantine/QuarantineList.vue:359
#, fuzzy
msgid "Selection deleted"
msgstr "Migrering raderad"
#: src/components/quarantine/QuarantineList.vue:398
msgid "Selection is being processed..."
msgstr ""
#: src/components/quarantine/QuarantineList.vue:374
#, fuzzy
msgid "Selection released"
msgstr "Välj fil"
#: src/components/calendars/ImportEventsForm.vue:30
#: src/components/webmail/ComposeEmailForm.vue:13
msgid "Send"
@@ -2375,6 +2573,20 @@ msgstr "Visa nyckel"
msgid "Simple user"
msgstr "Enkel användare"
#: src/components/admin/domains/DomainPolicy.vue:50
msgid "Spam classification threshold"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:17
#, fuzzy
msgid "Spam filters"
msgstr "Meddelandefilter"
#: src/components/admin/domains/DomainPolicy.vue:72
#: src/components/admin/domains/DomainPolicyForm.vue:34
msgid "Spam marker"
msgstr ""
#: src/components/admin/identities/AccountSenderAddresses.vue:17
msgid "Specify an email address"
msgstr "Ange en e-postadress"
@@ -2409,6 +2621,8 @@ msgid "Status"
msgstr "Status"
#: src/components/account/AutoReplyForm.vue:12
#: src/components/quarantine/QuarantineList.vue:239
#: src/components/quarantine/QuarantineList.vue:49
#: src/components/webmail/ComposeEmailForm.vue:137
msgid "Subject"
msgstr "Ämne"
@@ -2486,12 +2700,18 @@ msgstr ""
msgid "there"
msgstr "där"
#: src/components/admin/domains/DomainPolicyForm.vue:56
msgid "Thresholds"
msgstr ""
#: src/components/calendars/EventForm.vue:12
msgid "Title"
msgstr "Titel"
#: src/components/admin/logs/MessageList.vue:49
#: src/components/calendars/EventForm.vue:34
#: src/components/quarantine/QuarantineList.vue:237
#: src/components/quarantine/QuarantineList.vue:52
#: src/components/tools/TimeSerieChart.vue:20
#: src/components/webmail/ComposeEmailForm.vue:46
#: src/views/webmail/EmailView.vue:109
@@ -2634,6 +2854,10 @@ msgstr "Använd antal"
msgid "Use domain default value"
msgstr "Använd domänens standardvärde"
#: src/composables/amavis.js:36
msgid "User's database"
msgstr ""
#: src/components/admin/domains/DomainAdminList.vue:111
#: src/components/admin/identities/AccountCreationForm.vue:97
#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:3
@@ -2652,6 +2876,15 @@ msgstr "Giltig"
msgid "Value"
msgstr "Värde"
#: src/views/quarantine/MessageView.vue:62
msgid "View full headers"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:28
#, fuzzy
msgid "Virus filters"
msgstr "Redigera filter"
#: src/components/admin/dashboard/NewsFeedWidget.vue:21
msgid "Visit the official weblog for more information"
msgstr ""
@@ -2693,6 +2926,11 @@ msgstr "Vecka"
msgid "Welcome to Modoboa"
msgstr "Välkommen till Modoboa"
#: src/components/quarantine/QuarantineList.vue:386
#: src/views/quarantine/MessageView.vue:210
msgid "Which database should be used for this learning:"
msgstr ""
#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:25
msgid "With a mailbox"
msgstr "Med en brevlåda"
@@ -2710,7 +2948,7 @@ msgstr "Skriv"
msgid "Year"
msgstr "År"
#: src/plugins/filters.js:10
#: src/components/tools/YesNoDefaultField.vue:7 src/plugins/filters.js:10
msgid "yes"
msgstr "ja"
@@ -2851,9 +3089,6 @@ msgstr "Ny"
#~ msgid "domain"
#~ msgstr "domän"
#~ msgid "Domain updated"
#~ msgstr "Domän uppdaterad"
#~ msgid "Invalid password"
#~ msgstr "Ogiltigt lösenord"
+231 -6
View File
@@ -63,7 +63,7 @@ msgid "Access rules"
msgstr ""
#: src/components/calendars/CalendarAccessRulesForm.vue:42
#: src/components/shared/TopMenu.vue:93
#: src/components/shared/TopMenu.vue:131
#: src/views/admin/identities/AccountView.vue:4
#: src/views/admin/identities/IdentitiesView.vue:23
msgid "Account"
@@ -332,6 +332,7 @@ msgstr "Profil güncellendi"
msgid "API token deleted"
msgstr ""
#: src/components/admin/domains/DomainPolicyForm.vue:96
#: src/components/tools/ChooseColumnsForm.vue:19
#: src/components/tools/TimeSerieChart.vue:22
msgid "Apply"
@@ -419,6 +420,11 @@ msgstr ""
msgid "Backup codes"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:39
#, fuzzy
msgid "Banned filters"
msgstr "İleti"
#: src/components/webmail/ComposeEmailForm.vue:110
#: src/components/webmail/ComposeEmailForm.vue:73
msgid "Bcc"
@@ -432,6 +438,14 @@ msgstr ""
msgid "Birth date"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:54
msgid "both"
msgstr ""
#: src/components/admin/domains/form_steps/DomainPolicyForm.vue:5
msgid "Bypass virus checks"
msgstr ""
#: src/components/calendars/EventForm.vue:49
#: src/views/calendars/CalendarView.vue:3
msgid "Calendar"
@@ -466,6 +480,7 @@ msgstr "Profil güncellendi"
#: src/components/account/FilterForm.vue:147
#: src/components/account/FilterSetForm.vue:24
#: src/components/admin/domains/DomainEditForm.vue:161
#: src/components/admin/domains/DomainPolicyForm.vue:93
#: src/components/admin/identities/AccountEditForm.vue:183
#: src/components/admin/identities/AliasEditForm.vue:69
#: src/components/admin/imap_migration/ProviderForm.vue:58
@@ -556,7 +571,7 @@ msgstr ""
#: src/components/tools/ImportForm.vue:51
#: src/components/webmail/AttachmentsDialog.vue:41
#: src/components/webmail/MailboxForm.vue:29
#: src/layouts/connected/ConnectedLayout.vue:17
#: src/layouts/connected/ConnectedLayout.vue:19
msgid "Close"
msgstr "Kapat"
@@ -620,6 +635,16 @@ msgstr ""
msgid "Content"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:5
#, fuzzy
msgid "Content filter"
msgstr "Yeni kurtarma kodları"
#: src/components/admin/domains/DomainPolicyForm.vue:4
#, fuzzy
msgid "Content filter settings"
msgstr "Genel"
#: src/components/tools/ImportForm.vue:40
msgid "Continue on error"
msgstr ""
@@ -733,6 +758,7 @@ msgstr "Gösterge Paneli"
#: src/components/admin/logs/AuditTrailList.vue:51
#: src/components/admin/logs/MessageList.vue:47
#: src/components/quarantine/QuarantineList.vue:240
msgid "Date"
msgstr "Tarih"
@@ -740,6 +766,11 @@ msgstr "Tarih"
msgid "Day"
msgstr ""
#: src/components/admin/domains/DomainPolicyForm.vue:47
#: src/components/tools/YesNoDefaultField.vue:15
msgid "default"
msgstr ""
#: src/components/admin/domains/DomainCreationForm.vue:193
#: src/components/admin/domains/DomainSummary.vue:23
#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:19
@@ -752,6 +783,15 @@ msgid ""
"GB. A value of 0 means no quota."
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:24
#: src/components/admin/domains/DomainPolicy.vue:35
#: src/components/admin/domains/DomainPolicy.vue:46
#: src/components/admin/domains/DomainPolicy.vue:57
#: src/components/admin/domains/DomainPolicy.vue:68
#: src/components/admin/domains/DomainPolicy.vue:79
msgid "Default value"
msgstr ""
#: src/components/admin/alarms/AlarmList.vue:116
#: src/components/admin/alarms/AlarmList.vue:133
#: src/components/admin/domains/DomainAliasForm.vue:39
@@ -773,6 +813,15 @@ msgstr ""
msgid "Delete filter set"
msgstr ""
#: src/views/quarantine/MessageView.vue:32
#, fuzzy
msgid "Delete message"
msgstr "İleti"
#: src/components/quarantine/QuarantineList.vue:84
msgid "Delete selection"
msgstr ""
#: src/layouts/webmail/WebmailLayout.vue:56
msgid "Delete this mailbox"
msgstr ""
@@ -807,15 +856,34 @@ msgstr "2FA'yı devre dışı bırak"
msgid "Disable 2FA"
msgstr "2FA'yı devre dışı bırak"
#: src/components/admin/domains/DomainPolicyForm.vue:26
#, fuzzy
msgid "Disable banned checks"
msgstr "2FA'yı devre dışı bırak"
#: src/views/webmail/EmailView.vue:74
#, fuzzy
msgid "Disable links"
msgstr "2FA'yı devre dışı bırak"
#: src/components/admin/domains/DomainPolicyForm.vue:18
#, fuzzy
msgid "Disable spam checks"
msgstr "2FA'yı devre dışı bırak"
#: src/components/admin/domains/DomainPolicyForm.vue:11
#, fuzzy
msgid "Disable virus checks"
msgstr "2FA'yı devre dışı bırak"
#: src/components/admin/domains/DNSStatusChip.vue:18
msgid "Disabled"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:125
msgid "Display"
msgstr ""
#: src/components/contacts/ContactList.vue:23
msgid "Display address book information"
msgstr ""
@@ -984,6 +1052,10 @@ msgstr ""
msgid "Domain name (ex: domain.tld)"
msgstr ""
#: src/composables/amavis.js:33
msgid "Domain's database"
msgstr ""
#: src/components/admin/identities/AccountEditForm.vue:82
msgid "domain's default value"
msgstr ""
@@ -1037,6 +1109,10 @@ msgstr "Yeni kurtarma kodları"
msgid "Edit contact"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:9
msgid "Edit content filter settings"
msgstr ""
#: src/views/admin/domains/DomainEditView.vue:3
msgid "Edit domain"
msgstr ""
@@ -1284,11 +1360,16 @@ msgstr ""
#: src/components/account/AutoReplyForm.vue:36
#: src/components/admin/logs/MessageList.vue:50
#: src/components/calendars/EventForm.vue:24
#: src/components/quarantine/QuarantineList.vue:238
#: src/components/tools/TimeSerieChart.vue:19
#: src/components/webmail/ComposeEmailForm.vue:29
msgid "From"
msgstr "Kimden"
#: src/components/quarantine/QuarantineList.vue:45
msgid "From address"
msgstr ""
#: src/components/calendars/CalendarAccessRulesForm.vue:11
msgid "Full address"
msgstr ""
@@ -1340,6 +1421,10 @@ msgstr ""
msgid "Generated address"
msgstr ""
#: src/composables/amavis.js:30
msgid "Global database"
msgstr ""
#: src/views/admin/InformationView.vue:29
msgid "Go to <strong>Settings > General</strong> section"
msgstr ""
@@ -1355,6 +1440,10 @@ msgid ""
"between [ ] by the appropriate ones."
msgstr ""
#: src/views/quarantine/MessageView.vue:65
msgid "Hide full headers"
msgstr ""
#: src/components/admin/identities/AccountCreationForm.vue:168
#: src/components/admin/identities/AccountCreationForm.vue:95
#: src/components/admin/identities/AccountEditForm.vue:31
@@ -1519,6 +1608,11 @@ msgstr "Kurulu sürüm"
msgid "Latest version"
msgstr "Kurulu sürüm"
#: src/components/quarantine/QuarantineList.vue:385
#: src/views/quarantine/MessageView.vue:209
msgid "Learning database"
msgstr ""
#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:26
msgid "Leave empty for no limit"
msgstr ""
@@ -1546,7 +1640,7 @@ msgstr ""
msgid "Logger"
msgstr "Kayıtçı"
#: src/components/shared/TopMenu.vue:100
#: src/components/shared/TopMenu.vue:138
msgid "Logout"
msgstr "Çıkış Yapın"
@@ -1592,10 +1686,23 @@ msgstr ""
msgid "Mark as followed"
msgstr ""
#: src/views/quarantine/MessageView.vue:47
msgid "Mark as non-spam"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:105
msgid "Mark as not spam"
msgstr ""
#: src/components/webmail/EmailList.vue:62
msgid "Mark as read"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:101
#: src/views/quarantine/MessageView.vue:43
msgid "Mark as spam"
msgstr ""
#: src/components/webmail/EmailList.vue:77
msgid "Mark as unfollowed"
msgstr ""
@@ -1614,7 +1721,7 @@ msgstr ""
msgid "Message"
msgstr "İleti"
#: src/views/webmail/EmailView.vue:254
#: src/views/quarantine/MessageView.vue:196 src/views/webmail/EmailView.vue:254
#, fuzzy
msgid "Message deleted"
msgstr "İleti"
@@ -1638,10 +1745,26 @@ msgstr "İleti"
msgid "Message marked as junk"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:291
#: src/views/quarantine/MessageView.vue:236
msgid "Message marked as non-spam"
msgstr ""
#: src/views/webmail/EmailView.vue:282
msgid "Message marked as not junk"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:288
#: src/views/quarantine/MessageView.vue:232
msgid "Message marked as spam"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:285
#: src/views/quarantine/MessageView.vue:178
#, fuzzy
msgid "Message released"
msgstr "İleti"
#: src/components/admin/domains/DomainCreationForm.vue:197
#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:32
#: src/components/admin/identities/AccountCreationForm.vue:133
@@ -1834,7 +1957,7 @@ msgstr "Yeni kurtarma kodları"
msgid "Next"
msgstr "Sonraki"
#: src/plugins/filters.js:10
#: src/components/tools/YesNoDefaultField.vue:11 src/plugins/filters.js:10
msgid "no"
msgstr ""
@@ -1902,6 +2025,11 @@ msgstr ""
msgid "Note"
msgstr ""
#: src/components/shared/TopMenu.vue:18
#, fuzzy
msgid "Notifications"
msgstr "Onayla"
#: src/components/admin/identities/AccountEditForm.vue:163
msgid "Number of allowed mailbox aliases:"
msgstr ""
@@ -1962,6 +2090,14 @@ msgstr ""
msgid "Options"
msgstr ""
#: src/components/admin/domains/DomainPolicyForm.vue:69
msgid "or more is spam"
msgstr ""
#: src/components/admin/domains/DomainPolicyForm.vue:84
msgid "or more throw spam message away"
msgstr ""
#: src/components/account/ProfileForm.vue:30
msgid "or suggest a new language"
msgstr ""
@@ -2113,6 +2249,15 @@ msgstr "Profil güncellendi"
msgid "Providers"
msgstr "Yeni kurtarma kodları"
#: src/views/quarantine/QuarantineView.vue:4
msgid "Quarantine"
msgstr ""
#: src/views/quarantine/MessageView.vue:4
#, fuzzy
msgid "Quarantined message"
msgstr "İleti"
#: src/components/admin/logs/MessageList.vue:46
msgid "Queue ID"
msgstr ""
@@ -2197,6 +2342,10 @@ msgstr "Kimlik Doğrulama"
msgid "Registered Webauthn devices"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:61
msgid "Rejection threshold"
msgstr ""
#: src/components/tools/TimeSerieChart.vue:27
msgid "Relative time ranges"
msgstr ""
@@ -2209,6 +2358,24 @@ msgstr ""
msgid "Relay domain"
msgstr ""
#: src/views/quarantine/MessageView.vue:21
#, fuzzy
msgid "Release message"
msgstr "İleti"
#: src/components/quarantine/QuarantineList.vue:372
#: src/views/quarantine/MessageView.vue:176
msgid "Release request sent"
msgstr ""
#: src/views/quarantine/QuarantineView.vue:12
msgid "release requests"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:72
msgid "Release selection"
msgstr ""
#: src/components/admin/alarms/AlarmList.vue:123
msgid "Reload"
msgstr ""
@@ -2282,6 +2449,10 @@ msgstr "Kaydet"
msgid "Save your changes"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:236
msgid "Score"
msgstr ""
#: src/components/admin/alarms/AlarmList.vue:21
#: src/components/admin/domains/DomainList.vue:19
#: src/components/admin/identities/IdentityList.vue:24
@@ -2292,6 +2463,7 @@ msgstr ""
msgid "Search"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:27
#: src/components/webmail/EmailList.vue:14
#, fuzzy
msgid "Search in messages"
@@ -2330,6 +2502,19 @@ msgstr ""
msgid "Select file"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:359
#, fuzzy
msgid "Selection deleted"
msgstr "Onayla"
#: src/components/quarantine/QuarantineList.vue:398
msgid "Selection is being processed..."
msgstr ""
#: src/components/quarantine/QuarantineList.vue:374
msgid "Selection released"
msgstr ""
#: src/components/calendars/ImportEventsForm.vue:30
#: src/components/webmail/ComposeEmailForm.vue:13
msgid "Send"
@@ -2401,6 +2586,20 @@ msgstr ""
msgid "Simple user"
msgstr "Basit kullanıcı"
#: src/components/admin/domains/DomainPolicy.vue:50
msgid "Spam classification threshold"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:17
#, fuzzy
msgid "Spam filters"
msgstr "İleti"
#: src/components/admin/domains/DomainPolicy.vue:72
#: src/components/admin/domains/DomainPolicyForm.vue:34
msgid "Spam marker"
msgstr ""
#: src/components/admin/identities/AccountSenderAddresses.vue:17
msgid "Specify an email address"
msgstr ""
@@ -2435,6 +2634,8 @@ msgid "Status"
msgstr ""
#: src/components/account/AutoReplyForm.vue:12
#: src/components/quarantine/QuarantineList.vue:239
#: src/components/quarantine/QuarantineList.vue:49
#: src/components/webmail/ComposeEmailForm.vue:137
msgid "Subject"
msgstr ""
@@ -2500,12 +2701,18 @@ msgstr ""
msgid "there"
msgstr ""
#: src/components/admin/domains/DomainPolicyForm.vue:56
msgid "Thresholds"
msgstr ""
#: src/components/calendars/EventForm.vue:12
msgid "Title"
msgstr ""
#: src/components/admin/logs/MessageList.vue:49
#: src/components/calendars/EventForm.vue:34
#: src/components/quarantine/QuarantineList.vue:237
#: src/components/quarantine/QuarantineList.vue:52
#: src/components/tools/TimeSerieChart.vue:20
#: src/components/webmail/ComposeEmailForm.vue:46
#: src/views/webmail/EmailView.vue:109
@@ -2652,6 +2859,10 @@ msgstr ""
msgid "Use domain default value"
msgstr ""
#: src/composables/amavis.js:36
msgid "User's database"
msgstr ""
#: src/components/admin/domains/DomainAdminList.vue:111
#: src/components/admin/identities/AccountCreationForm.vue:97
#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:3
@@ -2671,6 +2882,15 @@ msgstr ""
msgid "Value"
msgstr ""
#: src/views/quarantine/MessageView.vue:62
msgid "View full headers"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:28
#, fuzzy
msgid "Virus filters"
msgstr "Yeni kurtarma kodları"
#: src/components/admin/dashboard/NewsFeedWidget.vue:21
msgid "Visit the official weblog for more information"
msgstr ""
@@ -2711,6 +2931,11 @@ msgstr ""
msgid "Welcome to Modoboa"
msgstr "Modoboa'ya hoş geldiniz"
#: src/components/quarantine/QuarantineList.vue:386
#: src/views/quarantine/MessageView.vue:210
msgid "Which database should be used for this learning:"
msgstr ""
#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:25
msgid "With a mailbox"
msgstr ""
@@ -2728,7 +2953,7 @@ msgstr ""
msgid "Year"
msgstr ""
#: src/plugins/filters.js:10
#: src/components/tools/YesNoDefaultField.vue:7 src/plugins/filters.js:10
msgid "yes"
msgstr ""
+217 -6
View File
@@ -62,7 +62,7 @@ msgid "Access rules"
msgstr ""
#: src/components/calendars/CalendarAccessRulesForm.vue:42
#: src/components/shared/TopMenu.vue:93
#: src/components/shared/TopMenu.vue:131
#: src/views/admin/identities/AccountView.vue:4
#: src/views/admin/identities/IdentitiesView.vue:23
msgid "Account"
@@ -322,6 +322,7 @@ msgstr ""
msgid "API token deleted"
msgstr ""
#: src/components/admin/domains/DomainPolicyForm.vue:96
#: src/components/tools/ChooseColumnsForm.vue:19
#: src/components/tools/TimeSerieChart.vue:22
msgid "Apply"
@@ -409,6 +410,10 @@ msgstr ""
msgid "Backup codes"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:39
msgid "Banned filters"
msgstr ""
#: src/components/webmail/ComposeEmailForm.vue:110
#: src/components/webmail/ComposeEmailForm.vue:73
msgid "Bcc"
@@ -422,6 +427,14 @@ msgstr ""
msgid "Birth date"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:54
msgid "both"
msgstr ""
#: src/components/admin/domains/form_steps/DomainPolicyForm.vue:5
msgid "Bypass virus checks"
msgstr ""
#: src/components/calendars/EventForm.vue:49
#: src/views/calendars/CalendarView.vue:3
msgid "Calendar"
@@ -452,6 +465,7 @@ msgstr ""
#: src/components/account/FilterForm.vue:147
#: src/components/account/FilterSetForm.vue:24
#: src/components/admin/domains/DomainEditForm.vue:161
#: src/components/admin/domains/DomainPolicyForm.vue:93
#: src/components/admin/identities/AccountEditForm.vue:183
#: src/components/admin/identities/AliasEditForm.vue:69
#: src/components/admin/imap_migration/ProviderForm.vue:58
@@ -540,7 +554,7 @@ msgstr ""
#: src/components/tools/ImportForm.vue:51
#: src/components/webmail/AttachmentsDialog.vue:41
#: src/components/webmail/MailboxForm.vue:29
#: src/layouts/connected/ConnectedLayout.vue:17
#: src/layouts/connected/ConnectedLayout.vue:19
msgid "Close"
msgstr ""
@@ -598,6 +612,14 @@ msgstr ""
msgid "Content"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:5
msgid "Content filter"
msgstr ""
#: src/components/admin/domains/DomainPolicyForm.vue:4
msgid "Content filter settings"
msgstr ""
#: src/components/tools/ImportForm.vue:40
msgid "Continue on error"
msgstr ""
@@ -708,6 +730,7 @@ msgstr ""
#: src/components/admin/logs/AuditTrailList.vue:51
#: src/components/admin/logs/MessageList.vue:47
#: src/components/quarantine/QuarantineList.vue:240
msgid "Date"
msgstr ""
@@ -715,6 +738,11 @@ msgstr ""
msgid "Day"
msgstr ""
#: src/components/admin/domains/DomainPolicyForm.vue:47
#: src/components/tools/YesNoDefaultField.vue:15
msgid "default"
msgstr ""
#: src/components/admin/domains/DomainCreationForm.vue:193
#: src/components/admin/domains/DomainSummary.vue:23
#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:19
@@ -727,6 +755,15 @@ msgid ""
"GB. A value of 0 means no quota."
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:24
#: src/components/admin/domains/DomainPolicy.vue:35
#: src/components/admin/domains/DomainPolicy.vue:46
#: src/components/admin/domains/DomainPolicy.vue:57
#: src/components/admin/domains/DomainPolicy.vue:68
#: src/components/admin/domains/DomainPolicy.vue:79
msgid "Default value"
msgstr ""
#: src/components/admin/alarms/AlarmList.vue:116
#: src/components/admin/alarms/AlarmList.vue:133
#: src/components/admin/domains/DomainAliasForm.vue:39
@@ -748,6 +785,14 @@ msgstr ""
msgid "Delete filter set"
msgstr ""
#: src/views/quarantine/MessageView.vue:32
msgid "Delete message"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:84
msgid "Delete selection"
msgstr ""
#: src/layouts/webmail/WebmailLayout.vue:56
msgid "Delete this mailbox"
msgstr ""
@@ -781,14 +826,30 @@ msgstr ""
msgid "Disable 2FA"
msgstr ""
#: src/components/admin/domains/DomainPolicyForm.vue:26
msgid "Disable banned checks"
msgstr ""
#: src/views/webmail/EmailView.vue:74
msgid "Disable links"
msgstr ""
#: src/components/admin/domains/DomainPolicyForm.vue:18
msgid "Disable spam checks"
msgstr ""
#: src/components/admin/domains/DomainPolicyForm.vue:11
msgid "Disable virus checks"
msgstr ""
#: src/components/admin/domains/DNSStatusChip.vue:18
msgid "Disabled"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:125
msgid "Display"
msgstr ""
#: src/components/contacts/ContactList.vue:23
msgid "Display address book information"
msgstr ""
@@ -957,6 +1018,10 @@ msgstr ""
msgid "Domain name (ex: domain.tld)"
msgstr ""
#: src/composables/amavis.js:33
msgid "Domain's database"
msgstr ""
#: src/components/admin/identities/AccountEditForm.vue:82
msgid "domain's default value"
msgstr ""
@@ -1008,6 +1073,10 @@ msgstr ""
msgid "Edit contact"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:9
msgid "Edit content filter settings"
msgstr ""
#: src/views/admin/domains/DomainEditView.vue:3
msgid "Edit domain"
msgstr ""
@@ -1240,11 +1309,16 @@ msgstr ""
#: src/components/account/AutoReplyForm.vue:36
#: src/components/admin/logs/MessageList.vue:50
#: src/components/calendars/EventForm.vue:24
#: src/components/quarantine/QuarantineList.vue:238
#: src/components/tools/TimeSerieChart.vue:19
#: src/components/webmail/ComposeEmailForm.vue:29
msgid "From"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:45
msgid "From address"
msgstr ""
#: src/components/calendars/CalendarAccessRulesForm.vue:11
msgid "Full address"
msgstr ""
@@ -1294,6 +1368,10 @@ msgstr ""
msgid "Generated address"
msgstr ""
#: src/composables/amavis.js:30
msgid "Global database"
msgstr ""
#: src/views/admin/InformationView.vue:29
msgid "Go to <strong>Settings > General</strong> section"
msgstr ""
@@ -1309,6 +1387,10 @@ msgid ""
"between [ ] by the appropriate ones."
msgstr ""
#: src/views/quarantine/MessageView.vue:65
msgid "Hide full headers"
msgstr ""
#: src/components/admin/identities/AccountCreationForm.vue:168
#: src/components/admin/identities/AccountCreationForm.vue:95
#: src/components/admin/identities/AccountEditForm.vue:31
@@ -1467,6 +1549,11 @@ msgstr ""
msgid "Latest version"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:385
#: src/views/quarantine/MessageView.vue:209
msgid "Learning database"
msgstr ""
#: src/components/admin/identities/form_steps/AccountMailboxForm.vue:26
msgid "Leave empty for no limit"
msgstr ""
@@ -1494,7 +1581,7 @@ msgstr ""
msgid "Logger"
msgstr ""
#: src/components/shared/TopMenu.vue:100
#: src/components/shared/TopMenu.vue:138
msgid "Logout"
msgstr ""
@@ -1538,10 +1625,23 @@ msgstr ""
msgid "Mark as followed"
msgstr ""
#: src/views/quarantine/MessageView.vue:47
msgid "Mark as non-spam"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:105
msgid "Mark as not spam"
msgstr ""
#: src/components/webmail/EmailList.vue:62
msgid "Mark as read"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:101
#: src/views/quarantine/MessageView.vue:43
msgid "Mark as spam"
msgstr ""
#: src/components/webmail/EmailList.vue:77
msgid "Mark as unfollowed"
msgstr ""
@@ -1560,7 +1660,7 @@ msgstr ""
msgid "Message"
msgstr ""
#: src/views/webmail/EmailView.vue:254
#: src/views/quarantine/MessageView.vue:196 src/views/webmail/EmailView.vue:254
msgid "Message deleted"
msgstr ""
@@ -1580,10 +1680,25 @@ msgstr ""
msgid "Message marked as junk"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:291
#: src/views/quarantine/MessageView.vue:236
msgid "Message marked as non-spam"
msgstr ""
#: src/views/webmail/EmailView.vue:282
msgid "Message marked as not junk"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:288
#: src/views/quarantine/MessageView.vue:232
msgid "Message marked as spam"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:285
#: src/views/quarantine/MessageView.vue:178
msgid "Message released"
msgstr ""
#: src/components/admin/domains/DomainCreationForm.vue:197
#: src/components/admin/domains/form_steps/DomainLimitationsForm.vue:32
#: src/components/admin/identities/AccountCreationForm.vue:133
@@ -1766,7 +1881,7 @@ msgstr ""
msgid "Next"
msgstr ""
#: src/plugins/filters.js:10
#: src/components/tools/YesNoDefaultField.vue:11 src/plugins/filters.js:10
msgid "no"
msgstr ""
@@ -1830,6 +1945,10 @@ msgstr ""
msgid "Note"
msgstr ""
#: src/components/shared/TopMenu.vue:18
msgid "Notifications"
msgstr ""
#: src/components/admin/identities/AccountEditForm.vue:163
msgid "Number of allowed mailbox aliases:"
msgstr ""
@@ -1889,6 +2008,14 @@ msgstr ""
msgid "Options"
msgstr ""
#: src/components/admin/domains/DomainPolicyForm.vue:69
msgid "or more is spam"
msgstr ""
#: src/components/admin/domains/DomainPolicyForm.vue:84
msgid "or more throw spam message away"
msgstr ""
#: src/components/account/ProfileForm.vue:30
msgid "or suggest a new language"
msgstr ""
@@ -2030,6 +2157,14 @@ msgstr ""
msgid "Providers"
msgstr ""
#: src/views/quarantine/QuarantineView.vue:4
msgid "Quarantine"
msgstr ""
#: src/views/quarantine/MessageView.vue:4
msgid "Quarantined message"
msgstr ""
#: src/components/admin/logs/MessageList.vue:46
msgid "Queue ID"
msgstr ""
@@ -2113,6 +2248,10 @@ msgstr ""
msgid "Registered Webauthn devices"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:61
msgid "Rejection threshold"
msgstr ""
#: src/components/tools/TimeSerieChart.vue:27
msgid "Relative time ranges"
msgstr ""
@@ -2125,6 +2264,23 @@ msgstr ""
msgid "Relay domain"
msgstr ""
#: src/views/quarantine/MessageView.vue:21
msgid "Release message"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:372
#: src/views/quarantine/MessageView.vue:176
msgid "Release request sent"
msgstr ""
#: src/views/quarantine/QuarantineView.vue:12
msgid "release requests"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:72
msgid "Release selection"
msgstr ""
#: src/components/admin/alarms/AlarmList.vue:123
msgid "Reload"
msgstr ""
@@ -2197,6 +2353,10 @@ msgstr ""
msgid "Save your changes"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:236
msgid "Score"
msgstr ""
#: src/components/admin/alarms/AlarmList.vue:21
#: src/components/admin/domains/DomainList.vue:19
#: src/components/admin/identities/IdentityList.vue:24
@@ -2207,6 +2367,7 @@ msgstr ""
msgid "Search"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:27
#: src/components/webmail/EmailList.vue:14
msgid "Search in messages"
msgstr ""
@@ -2243,6 +2404,18 @@ msgstr ""
msgid "Select file"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:359
msgid "Selection deleted"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:398
msgid "Selection is being processed..."
msgstr ""
#: src/components/quarantine/QuarantineList.vue:374
msgid "Selection released"
msgstr ""
#: src/components/calendars/ImportEventsForm.vue:30
#: src/components/webmail/ComposeEmailForm.vue:13
msgid "Send"
@@ -2314,6 +2487,19 @@ msgstr ""
msgid "Simple user"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:50
msgid "Spam classification threshold"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:17
msgid "Spam filters"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:72
#: src/components/admin/domains/DomainPolicyForm.vue:34
msgid "Spam marker"
msgstr ""
#: src/components/admin/identities/AccountSenderAddresses.vue:17
msgid "Specify an email address"
msgstr ""
@@ -2348,6 +2534,8 @@ msgid "Status"
msgstr ""
#: src/components/account/AutoReplyForm.vue:12
#: src/components/quarantine/QuarantineList.vue:239
#: src/components/quarantine/QuarantineList.vue:49
#: src/components/webmail/ComposeEmailForm.vue:137
msgid "Subject"
msgstr ""
@@ -2411,12 +2599,18 @@ msgstr ""
msgid "there"
msgstr ""
#: src/components/admin/domains/DomainPolicyForm.vue:56
msgid "Thresholds"
msgstr ""
#: src/components/calendars/EventForm.vue:12
msgid "Title"
msgstr ""
#: src/components/admin/logs/MessageList.vue:49
#: src/components/calendars/EventForm.vue:34
#: src/components/quarantine/QuarantineList.vue:237
#: src/components/quarantine/QuarantineList.vue:52
#: src/components/tools/TimeSerieChart.vue:20
#: src/components/webmail/ComposeEmailForm.vue:46
#: src/views/webmail/EmailView.vue:109
@@ -2551,6 +2745,10 @@ msgstr ""
msgid "Use domain default value"
msgstr ""
#: src/composables/amavis.js:36
msgid "User's database"
msgstr ""
#: src/components/admin/domains/DomainAdminList.vue:111
#: src/components/admin/identities/AccountCreationForm.vue:97
#: src/components/admin/identities/form_steps/AccountGeneralForm.vue:3
@@ -2569,6 +2767,14 @@ msgstr ""
msgid "Value"
msgstr ""
#: src/views/quarantine/MessageView.vue:62
msgid "View full headers"
msgstr ""
#: src/components/admin/domains/DomainPolicy.vue:28
msgid "Virus filters"
msgstr ""
#: src/components/admin/dashboard/NewsFeedWidget.vue:21
msgid "Visit the official weblog for more information"
msgstr ""
@@ -2609,6 +2815,11 @@ msgstr ""
msgid "Welcome to Modoboa"
msgstr ""
#: src/components/quarantine/QuarantineList.vue:386
#: src/views/quarantine/MessageView.vue:210
msgid "Which database should be used for this learning:"
msgstr ""
#: src/components/admin/domains/form_steps/DomainOptionsForm.vue:25
msgid "With a mailbox"
msgstr ""
@@ -2626,7 +2837,7 @@ msgstr ""
msgid "Year"
msgstr ""
#: src/plugins/filters.js:10
#: src/components/tools/YesNoDefaultField.vue:7 src/plugins/filters.js:10
msgid "yes"
msgstr ""
+16 -1
View File
@@ -451,6 +451,21 @@ const routes = [
},
],
},
{
path: 'selfquarantine',
component: () => import('@/layouts/quarantine/SelfServiceLayout.vue'),
props: { loadTheme: false },
meta: {
requiresAuth: false,
},
children: [
{
path: ':mailid/:rcpt',
name: 'SelfQuarantineMessageView',
component: () => import('@/views/quarantine/MessageView.vue'),
},
],
},
],
},
{
@@ -471,7 +486,7 @@ router.beforeEach(async (to, from, next) => {
document.title = config.HTML_PAGE_TITLE
? config.HTML_PAGE_TITLE
: 'Welcome to Modoboa'
if (to.meta.requiresAuth !== undefined) {
if (to.meta?.requiresAuth === true) {
const previousPage = window.location.href
sessionStorage.setItem('previousPage', previousPage)
const authStore = useAuthStore()
+28 -4
View File
@@ -1,12 +1,18 @@
import { ref } from 'vue'
import { computed, ref } from 'vue'
import { defineStore } from 'pinia'
import adminApi from '@/api/admin'
import capabilitiesApi from '@/api/capabilities'
import notificationsApi from '@/api/notifications'
export const useGlobalStore = defineStore('global', () => {
const capabilities = ref([])
const notifications = ref([])
async function fetchCapabilities() {
const response = await capabilitiesApi.getCapabilities()
capabilities.value = response.data.capabilities
}
async function fetchNotifications() {
const response = await adminApi.getNotifications()
const response = await notificationsApi.getNotifications()
notifications.value = response.data
}
@@ -15,8 +21,26 @@ export const useGlobalStore = defineStore('global', () => {
}
async function $reset() {
capabilities.value = []
notifications.value = []
}
return { notifications, fetchNotifications, getNotificationById, $reset }
const activeNotifications = computed(() => {
return notifications.value.length !== 0
})
const adminNotifications = computed(() => {
return notifications.value.filter((notif) => notif.target === 'admin')
})
return {
capabilities,
notifications,
fetchCapabilities,
fetchNotifications,
getNotificationById,
activeNotifications,
adminNotifications,
$reset,
}
})
+3 -3
View File
@@ -3,16 +3,16 @@
<v-toolbar flat>
<v-toolbar-title>{{ $gettext('Information') }}</v-toolbar-title>
</v-toolbar>
<v-card v-if="globalStore.notifications.length" class="my-6">
<v-card v-if="globalStore.adminNotifications.length" class="my-6">
<v-card-title>
{{ $gettext('Important messages') }}
</v-card-title>
<v-card-text>
<v-alert
v-for="notification in globalStore.notifications"
v-for="notification in globalStore.adminNotifications"
:key="notification.id"
:type="notification.level"
:type="notification.color"
:title="notification.text"
border="start"
variant="tonal"
@@ -40,6 +40,8 @@
<div class="mt-4" />
</template>
<DomainAdminList :domain="domain" />
<div class="mt-4" />
<DomainPolicy v-if="isAmavisEnabled" :domain="domain" />
</v-col>
<v-col cols="12" md="6">
<DNSDetail v-model="domain" />
@@ -83,27 +85,34 @@
</div>
</template>
<script setup lang="js">
<script setup>
import DomainAdminList from '@/components/admin/domains/DomainAdminList.vue'
import DmarcAligmentChart from '@/components/admin/dmarc/DmarcAligmentChart.vue'
import DNSDetail from '@/components/admin/domains/DNSDetail.vue'
import DomainSummary from '@/components/admin/domains/DomainSummary.vue'
import RelayDomainSummary from '@/components/admin/domains/RelayDomainSummary.vue'
import DomainPolicy from '@/components/admin/domains/DomainPolicy.vue'
import LoadingData from '@/components/tools/LoadingData.vue'
import ResourcesForm from '@/components/tools/ResourcesForm.vue'
import TimeSerieChart from '@/components/tools/TimeSerieChart.vue'
import { useGettext } from 'vue3-gettext'
import { ref } from 'vue'
import { computed, ref } from 'vue'
import { useRoute } from 'vue-router'
import { useGlobalStore } from '@/stores'
import domainsApi from '@/api/domains'
const { $gettext } = useGettext()
const route = useRoute()
const globalStore = useGlobalStore()
const domain = ref(null)
const limitsConfig = ref({})
const tab = ref(null)
const isAmavisEnabled = computed(() => {
return 'amavis' in globalStore.capabilities
})
function refreshDomain() {
domainsApi.getDomain(route.params.id).then((resp) => {
domain.value = resp.data
+93 -24
View File
@@ -1,11 +1,12 @@
<template>
<div>
<div class="text-h5 ml-4">
{{ $gettext('Quarantine') }}
{{ $gettext('Quarantined message') }}
</div>
<div class="bg-white rounded-lg pa-4 position-relative mt-6 h-100">
<v-toolbar color="white">
<v-btn
v-if="!selfServiceMode"
icon="mdi-arrow-left"
size="small"
variant="flat"
@@ -33,21 +34,29 @@
@click="deleteMessage"
>
</v-btn>
<v-btn class="ml-2" variant="tonal" icon size="small">
<v-icon icon="mdi-cog" />
<v-menu activator="parent">
<v-list density="compact">
<v-list-item
:title="$gettext('Mark as spam')"
@click="markAsSpam"
/>
<v-list-item
:title="$gettext('Mark as non-spam')"
@click="markAsHam"
/>
</v-list>
</v-menu>
</v-btn>
<template v-if="!selfServiceMode">
<v-btn
v-if="manualLearningEnabled"
class="ml-2"
variant="tonal"
icon
size="small"
>
<v-icon icon="mdi-cog" />
<v-menu activator="parent">
<v-list density="compact">
<v-list-item
:title="$gettext('Mark as spam')"
@click="markAsSpam"
/>
<v-list-item
:title="$gettext('Mark as non-spam')"
@click="markAsHam"
/>
</v-list>
</v-menu>
</v-btn>
</template>
<v-btn
class="ml-2"
variant="tonal"
@@ -83,6 +92,17 @@
</div>
<div class="mt-4" v-html="message.body" />
</div>
<ConfirmDialog ref="learningRecipientRef">
<v-radio-group v-model="learningDatabase" class="mt-4" hide-details>
<v-radio
v-for="lrcpt in learningRecipients"
:key="lrcpt.value"
:value="lrcpt.value"
:label="lrcpt.title"
>
</v-radio>
</v-radio-group>
</ConfirmDialog>
</div>
</template>
@@ -90,15 +110,21 @@
import { computed, ref } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { useGettext } from 'vue3-gettext'
import { useBusStore } from '@/stores'
import { useAuthStore, useBusStore } from '@/stores'
import { useAmavis } from '@/composables/amavis'
import ConfirmDialog from '@/components/tools/ConfirmDialog'
import api from '@/api/amavis'
import constants from '@/constants'
const route = useRoute()
const router = useRouter()
const { $gettext } = useGettext()
const authStore = useAuthStore()
const { displayNotification } = useBusStore()
const fullHeaders = ref(null)
const learningDatabase = ref(null)
const learningRecipientRef = ref(null)
const loading = ref(false)
const message = ref(null)
@@ -109,6 +135,15 @@ const headers = computed(() => {
return fullHeaders.value
})
const selfServiceMode = computed(() => {
return route.query?.secret_id !== undefined
})
if (selfServiceMode.value) {
const manualLearningEnabled = ref(false)
} else {
const { manualLearningEnabled } = await useAmavis()
}
const close = () => {
router.go(-1)
}
@@ -120,7 +155,11 @@ const toggleFullHeaders = async () => {
}
loading.value = true
try {
const resp = await api.getMessageHeaders(route.params.mailid)
const resp = await api.getMessageHeaders(
route.params.mailid,
route.params.rcpt,
route.query.secret_id
)
fullHeaders.value = resp.data.headers
} finally {
loading.value = false
@@ -130,10 +169,14 @@ const toggleFullHeaders = async () => {
const releaseMessage = async () => {
loading.value = true
const data = {
selection: [{ rcpt: route.rcpt, mailid: route.mailid }],
rcpt: route.params.rcpt,
mailid: route.params.mailid,
}
if (selfServiceMode.value) {
data.secret_id = route.query.secret_id
}
try {
const resp = await api.releaseSelection(data)
const resp = await api.releaseMessage(route.params.mailid, data)
if (resp.data.status === 'pending') {
displayNotification({ msg: $gettext('Release request sent') })
} else {
@@ -147,23 +190,45 @@ const releaseMessage = async () => {
const deleteMessage = async () => {
loading.value = true
const data = {
selection: [{ rcpt: route.params.rcpt, mailid: route.params.mailid }],
rcpt: route.params.rcpt,
mailid: route.params.mailid,
}
if (selfServiceMode.value) {
data.secret_id = route.query.secret_id
}
try {
await api.deleteSelection(data)
await api.deleteMessage(route.params.mailid, data)
displayNotification({ msg: $gettext('Message deleted') })
router.push({ name: 'QuarantineView' })
if (!selfServiceMode.value) {
router.push({ name: 'QuarantineView' })
}
} finally {
loading.value = false
}
}
const mark = async (mtype, msg) => {
if (
manualLearningEnabled.value &&
authStore.authUser.role !== constants.USER
) {
learningDatabase.value =
authStore.authUser.role === constants.SUPER_ADMIN ? 'global' : 'domain'
await learningRecipientRef.value.open(
$gettext('Learning database'),
$gettext('Which database should be used for this learning:'),
{ width: 600, noconfirm: true }
)
}
loading.value = true
const data = {
type: mtype,
selection: [{ rcpt: route.params.rcpt, mailid: route.params.mailid }],
}
if (learningDatabase.value) {
data.database = learningDatabase.value
}
try {
await api.markMessageSelection(data)
displayNotification({ msg })
@@ -180,6 +245,10 @@ const markAsHam = async () => {
await mark('ham', $gettext('Message marked as non-spam'))
}
const resp = await api.getMessageContent(route.params.mailid, route.params.rcpt)
const resp = await api.getMessageContent(
route.params.mailid,
route.params.rcpt,
route.query.secret_id
)
message.value = resp.data
</script>
@@ -2,6 +2,15 @@
<div>
<div class="text-h5 ml-4">
{{ $gettext('Quarantine') }}
<v-chip
v-if="route.query.requests === '1'"
color="primary"
variant="tonal"
class="ml-2"
closable
@click:close="showAllContent"
>{{ $gettext('release requests') }}</v-chip
>
</div>
<QuarantineList />
@@ -9,5 +18,13 @@
</template>
<script setup>
import { useRoute, useRouter } from 'vue-router'
import QuarantineList from '@/components/quarantine/QuarantineList'
const route = useRoute()
const router = useRouter()
const showAllContent = () => {
router.replace({ name: 'QuarantineView' })
}
</script>
+3
View File
@@ -0,0 +1,3 @@
"""The amavis frontend of Modoboa."""
default_app_config = "modoboa.amavis.apps.AmavisConfig"
+276
View File
@@ -0,0 +1,276 @@
import collections
from django.utils.translation import gettext_lazy
GLOBAL_PARAMETERS_STRUCT = collections.OrderedDict(
[
(
"amavis",
{
"label": gettext_lazy("Amavis settings"),
"params": collections.OrderedDict(
[
(
"localpart_is_case_sensitive",
{
"label": gettext_lazy("Localpart is case sensitive"),
"help_text": gettext_lazy(
"Value should match amavisd.conf variable "
"$localpart_is_case_sensitive"
),
},
),
(
"recipient_delimiter",
{
"label": gettext_lazy("Recipient delimiter"),
"help_text": gettext_lazy(
"Value should match amavisd.conf variable "
"$recipient_delimiter"
),
},
),
]
),
},
),
(
"quarantine",
{
"label": gettext_lazy("Quarantine settings"),
"params": collections.OrderedDict(
[
(
"max_messages_age",
{
"label": gettext_lazy("Maximum message age"),
"help_text": gettext_lazy(
"Quarantine messages maximum age (in days) before deletion"
),
},
)
]
),
},
),
(
"releasing",
{
"label": gettext_lazy("Message releasing"),
"params": collections.OrderedDict(
[
(
"released_msgs_cleanup",
{
"label": gettext_lazy("Remove released messages"),
"help_text": gettext_lazy(
"Remove messages marked as released while cleaning up "
"the database"
),
},
),
(
"am_pdp_mode",
{
"label": gettext_lazy("Amavis connection mode"),
"help_text": gettext_lazy(
"Mode used to access the PDP server"
),
},
),
(
"am_pdp_host",
{
"label": gettext_lazy("PDP server address"),
"help_text": gettext_lazy(
"PDP server address (if inet mode)"
),
"display": "am_pdp_mode=inet",
},
),
(
"am_pdp_port",
{
"label": gettext_lazy("PDP server port"),
"help_text": gettext_lazy(
"PDP server port (if inet mode)"
),
"display": "am_pdp_mode=inet",
},
),
(
"am_pdp_socket",
{
"label": gettext_lazy("PDP server socket"),
"help_text": gettext_lazy(
"Path to the PDP server socket (if unix mode)"
),
"display": "am_pdp_mode=unix",
},
),
(
"user_can_release",
{
"label": gettext_lazy("Allow direct release"),
"help_text": gettext_lazy(
"Allow users to directly release their messages"
),
},
),
(
"self_service",
{
"label": gettext_lazy("Enable self-service mode"),
"help_text": gettext_lazy(
"Activate the 'self-service' mode"
),
},
),
(
"notifications_sender",
{
"label": gettext_lazy("Notifications sender"),
"help_text": gettext_lazy(
"The e-mail address used to send notitications"
),
},
),
]
),
},
),
(
"learning",
{
"label": gettext_lazy("Manual learning"),
"params": collections.OrderedDict(
[
(
"manual_learning",
{
"label": gettext_lazy("Enable manual learning"),
"help_text": gettext_lazy(
"Allow super administrators to manually train Spamassassin"
),
},
),
(
"sa_is_local",
{
"label": gettext_lazy("Is Spamassassin local?"),
"help_text": gettext_lazy(
"Tell if Spamassassin is running on the same server than modoboa"
),
"display": "manual_learning=true",
},
),
(
"default_user",
{
"label": gettext_lazy("Default user"),
"help_text": gettext_lazy(
"Name of the user owning the default bayesian database"
),
"display": "manual_learning=true",
},
),
(
"spamd_address",
{
"label": gettext_lazy("Spamd address"),
"help_text": gettext_lazy(
"The IP address where spamd can be reached"
),
"display": "sa_is_local=false",
},
),
(
"spamd_port",
{
"label": gettext_lazy("Spamd port"),
"help_text": gettext_lazy(
"The TCP port spamd is listening on"
),
"display": "sa_is_local=false",
},
),
(
"domain_level_learning",
{
"label": gettext_lazy(
"Enable per-domain manual learning"
),
"help_text": gettext_lazy(
"Allow domain administrators to train Spamassassin "
"(within dedicated per-domain databases)"
),
"display": "manual_learning=true",
},
),
(
"user_level_learning",
{
"label": gettext_lazy(
"Enable per-user manual learning"
),
"help_text": gettext_lazy(
"Allow simple users to personally train Spamassassin "
"(within a dedicated database)"
),
"display": "manual_learning=true",
},
),
]
),
},
),
]
)
USER_PREFERENCES_STRUCT = collections.OrderedDict(
[
(
"display",
{
"label": gettext_lazy("Display"),
"params": collections.OrderedDict(
[
(
"messages_per_page",
{
"label": gettext_lazy(
"Number of displayed emails per page"
),
"help_text": gettext_lazy(
"Set the maximum number of messages displayed in a page"
),
},
)
]
),
},
)
]
)
def load_settings():
"""Load amavis settings."""
from modoboa.parameters import tools as param_tools
from modoboa.amavis import serializers
param_tools.registry.add(
"global",
"amavis",
gettext_lazy("Amavis"),
GLOBAL_PARAMETERS_STRUCT,
serializers.GlobalParametersSerializer,
)
param_tools.registry.add(
"user",
"amavis",
gettext_lazy("Amavis"),
USER_PREFERENCES_STRUCT,
serializers.UserPreferencesSerializer,
)
+18
View File
@@ -0,0 +1,18 @@
"""AppConfig for amavis."""
from django.apps import AppConfig
class AmavisConfig(AppConfig):
"""App configuration."""
name = "modoboa.amavis"
verbose_name = "Modoboa amavis frontend"
def ready(self):
# Import these to force registration of checks and signals
from . import checks # NOQA:F401
from . import handlers # NOQA:F401
from modoboa.amavis.app_settings import load_settings
load_settings()
+2
View File
@@ -0,0 +1,2 @@
# Import these to force registration of checks
from . import settings_checks # NOQA:F401
+59
View File
@@ -0,0 +1,59 @@
from django.conf import settings
from django.core.checks import Warning, register
from django.db import connections
from django.utils.translation import gettext as _
W001 = Warning(
_(
"AMAVIS_DEFAULT_DATABASE_ENCODING does not match the character "
"encoding used by the Amavis database."
),
hint=_(
"Check your database character encoding and set/update "
"AMAVIS_DEFAULT_DATABASE_ENCODING."
),
id="modoboa-amavis.W001",
)
W002 = Warning(
_("Modoboa Amavis has not been tested using the selected database engine."),
hint=_("Try using PostgreSQL, MySQL or MariaDB."),
id="modoboa-amavis.W002",
)
@register(deploy=True)
def check_amavis_database_encoding(app_configs, **kwargs):
"""Ensure AMAVIS_DEFAULT_DATABASE_ENCODING is set to the correct value."""
errors = []
db_engine = settings.DATABASES["amavis"]["ENGINE"]
sql_query = None
if "postgresql" in db_engine:
sql_query = (
"SELECT pg_encoding_to_char(encoding) "
"FROM pg_database "
"WHERE datname = %s;"
)
elif "mysql" in db_engine:
sql_query = (
"SELECT DEFAULT_CHARACTER_SET_NAME "
"FROM INFORMATION_SCHEMA.SCHEMATA "
"WHERE SCHEMA_NAME = %s;"
)
elif "sqlite" in db_engine:
sql_query = "PRAGMA encoding;"
else:
errors.append(W002)
return errors
with connections["amavis"].cursor() as cursor:
if "sqlite" in db_engine:
cursor.execute(sql_query)
else:
cursor.execute(sql_query, [settings.DATABASES["amavis"]["NAME"]])
encoding = cursor.fetchone()[0]
if encoding.lower() != settings.AMAVIS_DEFAULT_DATABASE_ENCODING.lower():
errors.append(W001)
return errors
+33
View File
@@ -0,0 +1,33 @@
"""Modoboa amavis constants."""
import collections
from django.utils.translation import gettext_lazy as _
MESSAGE_TYPES = collections.OrderedDict(
(
("C", _("Clean")),
("S", _("Spam")),
("Y", _("Spammy")),
("V", _("Virus")),
("H", _("Bad Header")),
("M", _("Bad MIME")),
("B", _("Banned")),
("O", _("Over sized")),
("T", _("MTA error")),
("U", _("Unchecked")),
)
)
MESSAGE_TYPE_COLORS = {
"C": "success",
"S": "danger",
"Y": "warning",
"V": "danger",
"H": "warning",
"M": "warning",
"B": "warning",
"O": "warning",
"T": "warning",
"U": "default",
}
+35
View File
@@ -0,0 +1,35 @@
class AmavisRouter:
"""A router to control all database operations on models in
the amavis application"""
def db_for_read(self, model, **hints):
"""Point all operations on amavis models to 'amavis'."""
if model._meta.app_label == "amavis":
return "amavis"
return None
def db_for_write(self, model, **hints):
"""Point all operations on amavis models to 'amavis'."""
if model._meta.app_label == "amavis":
return "amavis"
return None
def allow_relation(self, obj1, obj2, **hints):
"""Allow any relation if a model in amavis is involved."""
if obj1._meta.app_label == "amavis" or obj2._meta.app_label == "amavis":
return True
return None
def allow_migrate(self, db, app_label, model=None, **hints):
"""
Make sure the auth app only appears in the 'amavis'
database.
"""
if app_label == "amavis":
# modoboa_amavis migrations should be created in the amavis
# database.
return db == "amavis"
elif db == "amavis":
# Don't create non modoboa_amavis migrations in the amavis database.
return False
return None
+164
View File
@@ -0,0 +1,164 @@
"""Amavis factories."""
import datetime
import time
import factory
from . import models
from .utils import smart_bytes
SPAM_BODY = """X-Envelope-To: <{rcpt}>
X-Envelope-To-Blocked: <{rcpt}>
X-Quarantine-ID: <nq6ekd4wtXZg>
X-Spam-Flag: YES
X-Spam-Score: 1000.985
X-Spam-Level: ****************************************************************
X-Spam-Status: Yes, score=1000.985 tag=2 tag2=6.31 kill=6.31
tests=[ALL_TRUSTED=-1, GTUBE=1000, PYZOR_CHECK=1.985]
autolearn=no autolearn_force=no
Received: from demo.modoboa.org ([127.0.0.1])
by localhost (demo.modoboa.org [127.0.0.1]) (amavisd-new, port 10024)
with ESMTP id nq6ekd4wtXZg for <user@demo.local>;
Thu, 9 Nov 2017 15:59:52 +0100 (CET)
Received: from demo.modoboa.org (localhost [127.0.0.1])
by demo.modoboa.org (Postfix) with ESMTP
for <user@demo.local>; Thu, 9 Nov 2017 15:59:52 +0100 (CET)
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: quoted-printable
Subject: Sample message
From: {sender}
To: {rcpt}
Message-ID: <151023959268.5550.5713670714483771838@demo.modoboa.org>
Date: Thu, 09 Nov 2017 15:59:52 +0100
This is the GTUBE, the
Generic
Test for
Unsolicited
Bulk
Email
If your spam filter supports it, the GTUBE provides a test by which you
can verify that the filter is installed correctly and is detecting incoming
spam. You can send yourself a test mail containing the following string of
characters (in upper case and with no white spaces and line breaks):
XJS*C4JDBQADN1.NSBN3*2IDNEN*GTUBE-STANDARD-ANTI-UBE-TEST-EMAIL*C.34X
You should send this test mail from an account outside of your network.
"""
VIRUS_BODY = r"""Subject: Virus Test Message (EICAR)
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="huq684BweRXVnRxX"
Content-Disposition: inline
Date: Sun, 06 Nov 2011 10:08:18 -0800
--huq684BweRXVnRxX
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
This is a virus test message. It contains an attached file 'eicar.com',
which contains the EICAR virus <http://eicar.org/86-0-Intended-use.html>
test pattern.
--huq684BweRXVnRxX
Content-Type: application/x-msdos-program
Content-Disposition: attachment; filename="eicar.com"
Content-Transfer-Encoding: quoted-printable
X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*=0A
--huq684BweRXVnRxX--
"""
class MaddrFactory(factory.django.DjangoModelFactory):
"""Factory for Maddr."""
class Meta:
model = models.Maddr
django_get_or_create = ("email",)
id = factory.Sequence(lambda n: n) # NOQA:A003
email = factory.Sequence(lambda n: f"user_{n}@domain.test")
domain = "test.domain"
class MsgsFactory(factory.django.DjangoModelFactory):
"""Factory for Mailaddr."""
class Meta:
model = models.Msgs
mail_id = factory.Sequence(lambda n: f"mailid{n}".encode("ascii"))
secret_id = factory.Sequence(lambda n: smart_bytes(f"id{n}"))
sid = factory.SubFactory(MaddrFactory)
client_addr = "127.0.0.1"
originating = "Y"
dsn_sent = "N"
subject = factory.Sequence(lambda n: f"Test message {n}")
time_num = factory.LazyAttribute(lambda o: int(time.time()))
time_iso = factory.LazyAttribute(
lambda o: datetime.datetime.fromtimestamp(o.time_num).isoformat()
)
size = 100
class MsgrcptFactory(factory.django.DjangoModelFactory):
"""Factory for Msgrcpt."""
class Meta:
model = models.Msgrcpt
rseqnum = 1
is_local = "Y"
bl = "N"
wl = "N"
mail = factory.SubFactory(MsgsFactory)
rid = factory.SubFactory(MaddrFactory)
class QuarantineFactory(factory.django.DjangoModelFactory):
"""Factory for Quarantine."""
class Meta:
model = models.Quarantine
chunk_ind = 1
mail = factory.SubFactory(MsgsFactory)
def create_quarantined_msg(rcpt, sender, rs, body, **kwargs):
"""Create a quarantined msg."""
msgrcpt = MsgrcptFactory(
rs=rs,
rid__email=rcpt,
rid__domain="com.test", # FIXME
mail__sid__email=smart_bytes(sender),
mail__sid__domain="", # FIXME
**kwargs,
)
QuarantineFactory(
mail=msgrcpt.mail,
mail_text=smart_bytes(SPAM_BODY.format(rcpt=rcpt, sender=sender)),
)
return msgrcpt
def create_spam(rcpt, sender="spam@evil.corp", rs=" "):
"""Create a spam."""
body = SPAM_BODY.format(rcpt=rcpt, sender=sender)
body += "fóó bár"
return create_quarantined_msg(
rcpt, sender, rs, body, bspam_level=999.0, content="S"
)
def create_virus(rcpt, sender="virus@evil.corp", rs=" "):
"""Create a virus."""
return create_quarantined_msg(rcpt, sender, rs, VIRUS_BODY, content="V")
+146
View File
@@ -0,0 +1,146 @@
"""Amavis handlers."""
from django.db.models import signals
from django.dispatch import receiver
from django.utils.translation import gettext as _
from modoboa.admin import models as admin_models
from modoboa.core import signals as core_signals
from modoboa.lib import signals as lib_signals
from modoboa.parameters import tools as param_tools
from .lib import (
create_user_and_policy,
create_user_and_use_policy,
delete_user,
delete_user_and_policy,
update_user_and_policy,
)
from .models import Policy, Users
from .sql_connector import SQLconnector
@receiver(signals.post_save, sender=admin_models.Domain)
def manage_domain_policy(sender, instance, **kwargs):
"""Create user and policy when a domain is added."""
if kwargs.get("created"):
create_user_and_policy(f"@{instance.name}")
else:
update_user_and_policy(f"@{instance.oldname}", f"@{instance.name}")
@receiver(signals.pre_delete, sender=admin_models.Domain)
def on_domain_deleted(sender, instance, **kwargs):
"""Delete user and policy for domain."""
delete_user_and_policy(f"@{instance.name}")
@receiver(signals.post_save, sender=admin_models.DomainAlias)
def on_domain_alias_created(sender, instance, **kwargs):
"""Create user and use domain policy for domain alias."""
if not kwargs.get("created"):
return
create_user_and_use_policy(f"@{instance.name}", f"@{instance.target.name}")
@receiver(signals.pre_delete, sender=admin_models.DomainAlias)
def on_domain_alias_deleted(sender, instance, **kwargs):
"""Delete user for domain alias."""
delete_user(f"@{instance.name}")
@receiver(signals.post_save, sender=admin_models.Mailbox)
def on_mailbox_modified(sender, instance, **kwargs):
"""Update amavis records if address has changed."""
condition = (
not param_tools.get_global_parameter("manual_learning")
or not hasattr(instance, "old_full_address")
or instance.full_address == instance.old_full_address
)
if condition:
return
try:
user = Users.objects.select_related("policy").get(
email=instance.old_full_address
)
except Users.DoesNotExist:
return
full_address = instance.full_address
user.email = full_address
user.policy.policy_name = full_address[:32]
user.policy.sa_username = full_address
user.policy.save()
user.save()
@receiver(signals.pre_delete, sender=admin_models.Mailbox)
def on_mailbox_deleted(sender, instance, **kwargs):
"""Clean amavis database when a mailbox is removed."""
if not param_tools.get_global_parameter("manual_learning"):
return
delete_user_and_policy(f"@{instance.full_address}")
@receiver(signals.post_save, sender=admin_models.AliasRecipient)
def on_aliasrecipient_created(sender, instance, **kwargs):
"""Create amavis record for the new alias recipient.
FIXME: how to deal with distibution lists ?
"""
conf = dict(param_tools.get_global_parameters("amavis"))
condition = (
not conf["manual_learning"]
or not conf["user_level_learning"]
or not instance.r_mailbox
or instance.alias.type != "alias"
)
if condition:
return
policy = Policy.objects.filter(policy_name=instance.r_mailbox.full_address).first()
if policy:
# Use mailbox policy for this new alias. We update or create
# to handle the case where an account is being replaced by an
# alias (when it is disabled).
email = instance.alias.address
Users.objects.update_or_create(
email=email, defaults={"policy": policy, "fullname": email, "priority": 7}
)
@receiver(signals.pre_delete, sender=admin_models.Alias)
def on_mailboxalias_deleted(sender, instance, **kwargs):
"""Clean amavis database when an alias is removed."""
if not param_tools.get_global_parameter("manual_learning"):
return
if instance.address.startswith("@"):
# Catchall alias, do not remove domain entry accidentally...
return
aliases = [instance.address]
Users.objects.filter(email__in=aliases).delete()
@receiver(core_signals.get_top_notifications)
def check_for_pending_requests(sender, include_all, **kwargs):
"""Check if release requests are pending."""
request = lib_signals.get_request()
condition = (
param_tools.get_global_parameter("user_can_release")
or request.user.role == "SimpleUsers"
)
if condition:
return []
nbrequests = SQLconnector(user=request.user).get_pending_requests()
if not nbrequests:
return [{"id": "nbrequests", "counter": 0}] if include_all else []
url = "/user/quarantine?requests=1"
return [
{
"id": "nbrequests",
"url": url,
"text": _("Pending requests"),
"counter": nbrequests,
"color": "error",
"target": "all",
}
]
+411
View File
@@ -0,0 +1,411 @@
import os
import re
import socket
import struct
from email.utils import parseaddr
from functools import wraps
import idna
from django.conf import settings
from django.contrib.auth.views import redirect_to_login
from django.urls import reverse
from django.utils.translation import gettext as _
from rest_framework import authentication, exceptions
from modoboa.admin import models as admin_models
from modoboa.lib.email_utils import split_address, split_local_part, split_mailbox
from modoboa.lib.exceptions import InternalError
from modoboa.lib.sysutils import exec_cmd
from modoboa.parameters import tools as param_tools
from .models import Msgrcpt, Policy, Users
from .utils import smart_bytes, smart_str
def selfservice(ssfunc=None):
"""Decorator used to expose views to the 'self-service' feature
The 'self-service' feature allows users to act on quarantined
messages without beeing authenticated.
This decorator only acts as a 'router'.
:param ssfunc: the function to call if the 'self-service'
pre-requisites are satisfied
"""
def decorator(f):
@wraps(f)
def wrapped_f(request, *args, **kwargs):
secret_id = request.GET.get("secret_id")
if not secret_id and request.user.is_authenticated:
return f(request, *args, **kwargs)
if not param_tools.get_global_parameter("self_service"):
return redirect_to_login(reverse("modoboa_amavis:index"))
return ssfunc(request, *args, **kwargs)
return wrapped_f
return decorator
class SelfServiceAuthentication(authentication.BaseAuthentication):
def authenticate(self, request):
from .sql_connector import SQLconnector
mail_id = request._request.resolver_match.kwargs.get("pk")
if request.method == "GET":
rcpt = request.GET.get("rcpt")
secret_id = request.GET.get("secret_id")
else:
rcpt = request.data.get("rcpt")
secret_id = request.data.get("secret_id")
if not mail_id or not rcpt or not secret_id:
return None
connector = SQLconnector()
try:
msgrcpt = connector.get_recipient_message(rcpt, mail_id)
except Msgrcpt.DoesNotExist:
raise exceptions.AuthenticationFailed("Invalid credentials") from None
if secret_id != smart_str(msgrcpt.mail.secret_id):
raise exceptions.AuthenticationFailed("Invalid credentials")
return (None, "selfservice")
class AMrelease:
def __init__(self):
conf = dict(param_tools.get_global_parameters("amavis"))
try:
if conf["am_pdp_mode"] == "inet":
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sock.connect((conf["am_pdp_host"], conf["am_pdp_port"]))
else:
self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
self.sock.connect(conf["am_pdp_socket"])
except OSError as err:
raise InternalError(
_("Connection to amavis failed: %s") % str(err)
) from None
def decode(self, answer):
def repl(match):
return struct.pack("B", int(match.group(0)[1:], 16))
return re.sub(rb"%([0-9a-fA-F]{2})", repl, answer)
def __del__(self):
self.sock.close()
def sendreq(self, mailid, secretid, recipient, *others):
self.sock.send(
smart_bytes(
f"""request=release
mail_id={smart_str(mailid)}
secret_id={smart_str(secretid)}
quar_type=Q
recipient={smart_str(recipient)}
"""
)
)
answer = self.sock.recv(1024)
answer = self.decode(answer)
if re.search(rb"250 [\d\.]+ Ok", answer):
return True
return False
class SpamassassinClient:
"""A stupid spamassassin client."""
def __init__(self, user, recipient_db):
"""Constructor."""
conf = dict(param_tools.get_global_parameters("amavis"))
self._sa_is_local = conf["sa_is_local"]
self._default_username = conf["default_user"]
self._recipient_db = recipient_db
self._setup_cache = {}
self._username_cache = []
if user.role == "SimpleUsers":
if conf["user_level_learning"]:
self._username = user.email
else:
self._username = None
self.error = None
if self._sa_is_local:
self._learn_cmd = self._find_binary("sa-learn")
self._learn_cmd += " --{0} --no-sync -u {1}"
self._learn_cmd_kwargs = {}
self._expected_exit_codes = [0]
self._sync_cmd = self._find_binary("sa-learn")
self._sync_cmd += " -u {0} --sync"
else:
self._learn_cmd = self._find_binary("spamc")
self._learn_cmd += " -d {} -p {}".format(
conf["spamd_address"], conf["spamd_port"]
)
self._learn_cmd += " -L {0} -u {1}"
self._learn_cmd_kwargs = {}
self._expected_exit_codes = [5, 6]
def _find_binary(self, name):
"""Find path to binary."""
code, output = exec_cmd(f"which {name}")
if not code:
return smart_str(output).strip()
known_paths = getattr(settings, "SA_LOOKUP_PATH", ("/usr/bin",))
for path in known_paths:
bpath = os.path.join(path, name)
if os.path.isfile(bpath) and os.access(bpath, os.X_OK):
return bpath
raise InternalError(_("Failed to find {} binary").format(name))
def _get_mailbox_from_rcpt(self, rcpt):
"""Retrieve a mailbox from a recipient address."""
local_part, domname, extension = split_mailbox(rcpt, return_extension=True)
try:
mailbox = admin_models.Mailbox.objects.select_related("domain").get(
address=local_part, domain__name=domname
)
except admin_models.Mailbox.DoesNotExist:
alias = admin_models.Alias.objects.filter(
address=f"{local_part}@{domname}",
aliasrecipient__r_mailbox__isnull=False,
).first()
if not alias:
raise InternalError(_("No recipient found")) from None
if alias.type != "alias":
return None
mailbox = alias.aliasrecipient_set.filter(r_mailbox__isnull=False).first()
return mailbox
def _get_domain_from_rcpt(self, rcpt):
"""Retrieve a domain from a recipient address."""
local_part, domname = split_mailbox(rcpt)
domain = admin_models.Domain.objects.filter(name=domname).first()
if not domain:
raise InternalError(_("Local domain not found"))
return domain
def _learn(self, rcpt, msg, mtype):
"""Internal method to call the learning command."""
if self._username is None:
if self._recipient_db == "global":
username = self._default_username
elif self._recipient_db == "domain":
domain = self._get_domain_from_rcpt(rcpt)
username = domain.name
condition = (
username not in self._setup_cache
and setup_manual_learning_for_domain(domain)
)
if condition:
self._setup_cache[username] = True
else:
mbox = self._get_mailbox_from_rcpt(rcpt)
if mbox is None:
username = self._default_username
else:
if isinstance(mbox, admin_models.Mailbox):
username = mbox.full_address
elif isinstance(mbox, admin_models.AliasRecipient):
username = mbox.address
else:
username = None
condition = (
username is not None
and username not in self._setup_cache
and setup_manual_learning_for_mbox(mbox)
)
if condition:
self._setup_cache[username] = True
else:
username = self._username
if username not in self._setup_cache:
mbox = self._get_mailbox_from_rcpt(username)
if mbox and setup_manual_learning_for_mbox(mbox):
self._setup_cache[username] = True
if username not in self._username_cache:
self._username_cache.append(username)
cmd = self._learn_cmd.format(mtype, username)
code, output = exec_cmd(cmd, pinput=smart_bytes(msg), **self._learn_cmd_kwargs)
if code in self._expected_exit_codes:
return True
self.error = smart_str(output)
return False
def learn_spam(self, rcpt, msg):
"""Learn new spam."""
return self._learn(rcpt, msg, "spam")
def learn_ham(self, rcpt, msg):
"""Learn new ham."""
return self._learn(rcpt, msg, "ham")
def done(self):
"""Call this method at the end of the processing."""
if self._sa_is_local:
for username in self._username_cache:
cmd = self._sync_cmd.format(username)
exec_cmd(cmd, **self._learn_cmd_kwargs)
def create_user_and_policy(name, priority=7):
"""Create records.
Create two records (a user and a policy) using :keyword:`name` as
an identifier.
:param str name: name
:return: the new ``Policy`` object
"""
policy, _ = Policy.objects.get_or_create(policy_name=name[:32])
if not Users.objects.filter(email=name).exists():
Users.objects.create(
email=name, fullname=name, priority=priority, policy=policy
)
return policy
def create_user_and_use_policy(name, policy, priority=7):
"""Create a *users* record and use an existing policy.
:param str name: user record name
:param str policy: string or Policy instance
"""
if isinstance(policy, str):
policy = Policy.objects.get(policy_name=policy[:32])
Users.objects.get_or_create(
email=name, fullname=name, priority=priority, policy=policy
)
def update_user_and_policy(oldname, newname):
"""Update records.
:param str oldname: old name
:param str newname: new name
"""
if oldname == newname:
return
u = Users.objects.get(email=oldname)
u.email = newname
u.fullname = newname
u.policy.policy_name = newname[:32]
u.policy.save(update_fields=["policy_name"])
u.save()
def delete_user_and_policy(name):
"""Delete records.
:param str name: identifier
"""
try:
u = Users.objects.get(email=name)
except Users.DoesNotExist:
return
u.policy.delete()
u.delete()
def delete_user(name):
"""Delete a *users* record.
:param str name: user record name
"""
try:
Users.objects.get(email=name).delete()
except Users.DoesNotExist:
pass
def manual_learning_enabled(user):
"""Check if manual learning is enabled or not.
Also check for :kw:`user` if necessary.
:return: True if learning is enabled, False otherwise.
"""
conf = dict(param_tools.get_global_parameters("amavis"))
if not conf["manual_learning"]:
return False
if user.role != "SuperAdmins":
if user.has_perm("admin.view_domain"):
manual_learning = (
conf["domain_level_learning"] or conf["user_level_learning"]
)
else:
manual_learning = conf["user_level_learning"]
return manual_learning
return True
def setup_manual_learning_for_domain(domain):
"""Setup manual learning if necessary.
:return: True if learning has been setup, False otherwise
"""
if Policy.objects.filter(sa_username=domain.name).exists():
return False
policy = Policy.objects.get(policy_name=f"@{domain.name[:32]}")
policy.sa_username = domain.name
policy.save()
return True
def setup_manual_learning_for_mbox(mbox):
"""Setup manual learning if necessary.
:return: True if learning has been setup, False otherwise
"""
result = False
if isinstance(mbox, admin_models.AliasRecipient) and mbox.r_mailbox is not None:
mbox = mbox.r_mailbox
if isinstance(mbox, admin_models.Mailbox):
pname = mbox.full_address[:32]
if not Policy.objects.filter(policy_name=pname).exists():
policy = create_user_and_policy(pname)
policy.sa_username = mbox.full_address
policy.save()
for alias in mbox.alias_addresses:
create_user_and_use_policy(alias, policy)
result = True
return result
def make_query_args(address, exact_extension=True, wildcard=None, domain_search=False):
assert isinstance(address, str), "address should be of type str"
conf = dict(param_tools.get_global_parameters("amavis"))
local_part, domain = split_address(address)
if not conf["localpart_is_case_sensitive"]:
local_part = local_part.lower()
if domain:
domain = domain.lstrip("@").rstrip(".")
domain = domain.lower()
orig_domain = domain
domain = idna.encode(domain, uts46=True).decode("ascii")
delimiter = conf["recipient_delimiter"]
local_part, extension = split_local_part(local_part, delimiter=delimiter)
query_args = []
if conf["localpart_is_case_sensitive"] or (domain and domain != orig_domain):
query_args.append(address)
if extension:
query_args.append(f"{local_part}{delimiter}{extension}@{domain}")
if delimiter and not exact_extension and wildcard:
query_args.append(f"{local_part}{delimiter}{wildcard}@{domain}")
query_args.append(f"{local_part}@{domain}")
if domain_search:
query_args.append(f"@{domain}")
query_args.append("@.")
return query_args
def cleanup_email_address(address):
address = parseaddr(address)
if address[0]:
return f"{address[0]} <{address[1]}>"
return address[1]
@@ -0,0 +1,99 @@
from django.contrib.sites import models as sites_models
from django.core import mail
from django.core.management.base import BaseCommand
from django.template.loader import render_to_string
from django.utils.translation import gettext as _
from modoboa.admin.models import Domain
from modoboa.core.models import User
from modoboa.parameters import tools as param_tools
from ...models import Msgrcpt
from ...sql_connector import SQLconnector
class Command(BaseCommand):
help = "Amavis notification tool" # NOQA:A003
sender = None
baseurl = None
listingurl = None
def add_arguments(self, parser):
"""Add extra arguments to command line."""
parser.add_argument(
"--smtp_host",
type=str,
default="localhost",
help="The address of the SMTP server used to send notifications",
)
parser.add_argument(
"--smtp_port",
type=int,
default=25,
help=(
"The listening port of the SMTP server used to send " "notifications"
),
)
parser.add_argument(
"--verbose", action="store_true", help="Activate verbose mode"
)
def handle(self, *args, **options):
self.options = options
self.notify_admins_pending_requests()
def _build_message(self, rcpt, total, reqs):
"""Build new EmailMessage instance."""
if self.options["verbose"]:
print(f"Sending notification to {rcpt}")
context = {
"total": total,
"requests": reqs,
"baseurl": self.baseurl,
"listingurl": self.listingurl,
}
content = render_to_string(
"amavis/notifications/pending_requests.html", context
)
msg = mail.EmailMessage(
_("[modoboa] Pending release requests"), content, self.sender, [rcpt]
)
return msg
def notify_admins_pending_requests(self):
self.sender = param_tools.get_global_parameter(
"notifications_sender", app="amavis"
)
self.baseurl = f"https://{sites_models.Site.objects.get_current().domain}"
self.listingurl = f"{self.baseurl}/user/quarantine?requests=1"
messages = []
# Check domain administators first.
for da in User.objects.filter(groups__name="DomainAdmins"):
if not hasattr(da, "mailbox"):
continue
rcpt = da.mailbox.full_address
reqs = SQLconnector().get_domains_pending_requests(
Domain.objects.get_for_admin(da).values_list("name", flat=True)
)
total = reqs.count()
reqs = reqs.all()[:10]
if reqs.count():
messages.append(self._build_message(rcpt, total, reqs))
# Then super administators.
reqs = Msgrcpt.objects.filter(rs="p")
total = reqs.count()
if total:
reqs = reqs.all()[:10]
for su in User.objects.filter(is_superuser=True):
if not hasattr(su, "mailbox"):
continue
rcpt = su.mailbox.full_address
messages.append(self._build_message(rcpt, total, reqs))
# Finally, send emails.
if not len(messages):
return
kwargs = {"host": self.options["smtp_host"], "port": self.options["smtp_port"]}
with mail.get_connection(**kwargs) as connection:
connection.send_messages(messages)
@@ -0,0 +1,84 @@
#!/usr/bin/env python
import time
from django.core.management.base import BaseCommand
from django.db.models import Count
from modoboa.parameters import tools as param_tools
from ...models import Maddr, Msgrcpt, Msgs
class Command(BaseCommand):
args = ""
help = "Amavis quarantine cleanup" # NOQA:A003
def add_arguments(self, parser):
"""Add extra arguments to command line."""
parser.add_argument(
"--debug", action="store_true", default=False, help="Activate debug output"
)
parser.add_argument(
"--verbose",
action="store_true",
default=False,
help="Display informational messages",
)
def __vprint(self, msg):
if not self.verbose:
return
print(msg)
def handle(self, *args, **options):
if options["debug"]:
import logging
log = logging.getLogger("django.db.backends")
log.setLevel(logging.DEBUG)
log.addHandler(logging.StreamHandler())
self.verbose = options["verbose"]
conf = dict(param_tools.get_global_parameters("amavis"))
flags = ["D"]
if conf["released_msgs_cleanup"]:
flags += ["R"]
self.__vprint("Deleting marked messages...")
ids = Msgrcpt.objects.filter(rs__in=flags).values("mail_id").distinct()
for msg in Msgs.objects.filter(mail_id__in=ids):
if not msg.msgrcpt_set.exclude(rs__in=flags).count():
msg.delete()
self.__vprint(
"Deleting messages older than {} days...".format(conf["max_messages_age"])
)
limit = int(time.time()) - (conf["max_messages_age"] * 24 * 3600)
while True:
qset = Msgs.objects.filter(
pk__in=list(
Msgs.objects.filter(time_num__lt=limit).values_list(
"pk", flat=True
)[:5000]
)
)
if not qset.exists():
break
qset.delete()
self.__vprint("Deleting unreferenced e-mail addresses...")
while True:
res = (
Maddr.objects.annotate(
msgs_count=Count("msgs"), msgrcpt_count=Count("msgrcpt")
)
.filter(msgs_count=0, msgrcpt_count=0)
.values_list("id", flat=True)[:100000]
)
if not res.exists():
break
Maddr.objects.filter(id__in=list(res)).delete()
self.__vprint("Done.")
+340
View File
@@ -0,0 +1,340 @@
from django.db import models, migrations
class Migration(migrations.Migration):
dependencies = []
operations = [
migrations.CreateModel(
name="Maddr",
fields=[
("partition_tag", models.IntegerField(default=0)),
("id", models.BigIntegerField(serialize=False, primary_key=True)),
("email", models.CharField(unique=True, max_length=255)),
("domain", models.CharField(max_length=765)),
],
options={
"db_table": "maddr",
"managed": False,
},
bases=(models.Model,),
),
migrations.CreateModel(
name="Mailaddr",
fields=[
("id", models.IntegerField(serialize=False, primary_key=True)),
("priority", models.IntegerField()),
("email", models.CharField(unique=True, max_length=255)),
],
options={
"db_table": "mailaddr",
"managed": False,
},
bases=(models.Model,),
),
migrations.CreateModel(
name="Msgs",
fields=[
("partition_tag", models.IntegerField(default=0)),
(
"mail_id",
models.CharField(max_length=12, serialize=False, primary_key=True),
),
("secret_id", models.CharField(max_length=12, blank=True)),
("am_id", models.CharField(max_length=60)),
("time_num", models.IntegerField()),
("time_iso", models.CharField(max_length=48)),
("policy", models.CharField(max_length=765, blank=True)),
("client_addr", models.CharField(max_length=765, blank=True)),
("size", models.IntegerField()),
("originating", models.CharField(max_length=3)),
("content", models.CharField(max_length=1, blank=True)),
("quar_type", models.CharField(max_length=1, blank=True)),
("quar_loc", models.CharField(max_length=255, blank=True)),
("dsn_sent", models.CharField(max_length=3, blank=True)),
("spam_level", models.FloatField(null=True, blank=True)),
("message_id", models.CharField(max_length=765, blank=True)),
("from_addr", models.CharField(max_length=765, blank=True)),
("subject", models.CharField(max_length=765, blank=True)),
("host", models.CharField(max_length=765)),
],
options={
"db_table": "msgs",
"managed": False,
},
bases=(models.Model,),
),
migrations.CreateModel(
name="Msgrcpt",
fields=[
("partition_tag", models.IntegerField(default=0)),
(
"mail",
models.ForeignKey(
primary_key=True,
serialize=False,
to="amavis.Msgs",
on_delete=models.CASCADE,
),
),
("rseqnum", models.IntegerField(default=0)),
("is_local", models.CharField(max_length=3)),
("content", models.CharField(max_length=3)),
("ds", models.CharField(max_length=3)),
("rs", models.CharField(max_length=3)),
("bl", models.CharField(max_length=3, blank=True)),
("wl", models.CharField(max_length=3, blank=True)),
("bspam_level", models.FloatField(null=True, blank=True)),
("smtp_resp", models.CharField(max_length=765, blank=True)),
],
options={
"db_table": "msgrcpt",
"managed": False,
},
bases=(models.Model,),
),
migrations.CreateModel(
name="Policy",
fields=[
(
"id",
models.AutoField(
verbose_name="ID",
serialize=False,
auto_created=True,
primary_key=True,
),
),
("policy_name", models.CharField(max_length=32, blank=True)),
("virus_lover", models.CharField(max_length=3, null=True, blank=True)),
("spam_lover", models.CharField(max_length=3, null=True, blank=True)),
(
"unchecked_lover",
models.CharField(max_length=3, null=True, blank=True),
),
(
"banned_files_lover",
models.CharField(max_length=3, null=True, blank=True),
),
(
"bad_header_lover",
models.CharField(max_length=3, null=True, blank=True),
),
(
"bypass_virus_checks",
models.CharField(
default=b"",
choices=[(b"N", "yes"), (b"Y", "no"), (b"", "default")],
max_length=3,
help_text="Bypass virus checks or not. Choose 'default' to use global settings.",
null=True,
verbose_name="Virus filter",
),
),
(
"bypass_spam_checks",
models.CharField(
default=b"",
choices=[(b"N", "yes"), (b"Y", "no"), (b"", "default")],
max_length=3,
help_text="Bypass spam checks or not. Choose 'default' to use global settings.",
null=True,
verbose_name="Spam filter",
),
),
(
"bypass_banned_checks",
models.CharField(
default=b"",
choices=[(b"N", "yes"), (b"Y", "no"), (b"", "default")],
max_length=3,
help_text="Bypass banned checks or not. Choose 'default' to use global settings.",
null=True,
verbose_name="Banned filter",
),
),
(
"bypass_header_checks",
models.CharField(max_length=3, null=True, blank=True),
),
(
"virus_quarantine_to",
models.CharField(max_length=192, null=True, blank=True),
),
(
"spam_quarantine_to",
models.CharField(max_length=192, null=True, blank=True),
),
(
"banned_quarantine_to",
models.CharField(max_length=192, null=True, blank=True),
),
(
"unchecked_quarantine_to",
models.CharField(max_length=192, null=True, blank=True),
),
(
"bad_header_quarantine_to",
models.CharField(max_length=192, null=True, blank=True),
),
(
"clean_quarantine_to",
models.CharField(max_length=192, null=True, blank=True),
),
(
"archive_quarantine_to",
models.CharField(max_length=192, null=True, blank=True),
),
("spam_tag_level", models.FloatField(null=True, blank=True)),
("spam_tag2_level", models.FloatField(null=True, blank=True)),
("spam_tag3_level", models.FloatField(null=True, blank=True)),
("spam_kill_level", models.FloatField(null=True, blank=True)),
("spam_dsn_cutoff_level", models.FloatField(null=True, blank=True)),
(
"spam_quarantine_cutoff_level",
models.FloatField(null=True, blank=True),
),
(
"addr_extension_virus",
models.CharField(max_length=192, null=True, blank=True),
),
(
"addr_extension_spam",
models.CharField(max_length=192, null=True, blank=True),
),
(
"addr_extension_banned",
models.CharField(max_length=192, null=True, blank=True),
),
(
"addr_extension_bad_header",
models.CharField(max_length=192, null=True, blank=True),
),
(
"warnvirusrecip",
models.CharField(max_length=3, null=True, blank=True),
),
(
"warnbannedrecip",
models.CharField(max_length=3, null=True, blank=True),
),
(
"warnbadhrecip",
models.CharField(max_length=3, null=True, blank=True),
),
(
"newvirus_admin",
models.CharField(max_length=192, null=True, blank=True),
),
(
"virus_admin",
models.CharField(max_length=192, null=True, blank=True),
),
(
"banned_admin",
models.CharField(max_length=192, null=True, blank=True),
),
(
"bad_header_admin",
models.CharField(max_length=192, null=True, blank=True),
),
("spam_admin", models.CharField(max_length=192, null=True, blank=True)),
(
"spam_subject_tag",
models.CharField(max_length=192, null=True, blank=True),
),
(
"spam_subject_tag2",
models.CharField(
default=None,
max_length=192,
blank=True,
help_text="Modify spam subject using the specified text. Choose 'default' to use global settings.",
null=True,
verbose_name="Spam marker",
),
),
(
"spam_subject_tag3",
models.CharField(max_length=192, null=True, blank=True),
),
("message_size_limit", models.IntegerField(null=True, blank=True)),
(
"banned_rulenames",
models.CharField(max_length=192, null=True, blank=True),
),
(
"disclaimer_options",
models.CharField(max_length=192, null=True, blank=True),
),
(
"forward_method",
models.CharField(max_length=192, null=True, blank=True),
),
(
"sa_userconf",
models.CharField(max_length=192, null=True, blank=True),
),
(
"sa_username",
models.CharField(max_length=192, null=True, blank=True),
),
],
options={
"db_table": "policy",
"managed": False,
},
bases=(models.Model,),
),
migrations.CreateModel(
name="Quarantine",
fields=[
("partition_tag", models.IntegerField(default=0)),
(
"mail",
models.ForeignKey(
primary_key=True,
serialize=False,
to="amavis.Msgs",
on_delete=models.CASCADE,
),
),
("chunk_ind", models.IntegerField()),
("mail_text", models.TextField()),
],
options={
"ordering": ["-mail__time_num"],
"db_table": "quarantine",
"managed": False,
},
bases=(models.Model,),
),
migrations.CreateModel(
name="Users",
fields=[
("id", models.AutoField(serialize=False, primary_key=True)),
("priority", models.IntegerField()),
("email", models.CharField(unique=True, max_length=255)),
("fullname", models.CharField(max_length=765, blank=True)),
],
options={
"db_table": "users",
"managed": False,
},
bases=(models.Model,),
),
migrations.CreateModel(
name="Wblist",
fields=[
("rid", models.IntegerField(serialize=False, primary_key=True)),
("sid", models.IntegerField(primary_key=True)),
("wb", models.CharField(max_length=30)),
],
options={
"db_table": "wblist",
"managed": False,
},
bases=(models.Model,),
),
]
+226
View File
@@ -0,0 +1,226 @@
# This is an auto-generated Django model module.
# You'll have to do the following manually to clean this up:
# * Rearrange models' order
# * Make sure each model has one field with primary_key=True
# Feel free to rename the models, but don't rename db_table values
# or field names.
#
# Also note: You'll have to insert the output of
# 'django-admin.py sqlcustom [appname]'into your database.
#
# Original Amavis version : 2.6.2
from datetime import datetime
from django.db import models
from django.utils.translation import gettext_lazy
class Maddr(models.Model):
partition_tag = models.IntegerField(default=0)
id = models.BigIntegerField(primary_key=True) # NOQA:A003
email = models.CharField(max_length=255)
domain = models.CharField(max_length=255)
class Meta:
db_table = "maddr"
unique_together = [("partition_tag", "email")]
managed = False
class Mailaddr(models.Model):
id = models.IntegerField(primary_key=True) # NOQA:A003
priority = models.IntegerField()
email = models.CharField(unique=True, max_length=255)
class Meta:
db_table = "mailaddr"
managed = False
class Msgs(models.Model):
partition_tag = models.IntegerField(default=0)
mail_id = models.BinaryField(max_length=16, primary_key=True)
secret_id = models.BinaryField()
am_id = models.CharField(max_length=60)
time_num = models.IntegerField()
time_iso = models.CharField(max_length=48)
sid = models.ForeignKey(Maddr, db_column="sid", on_delete=models.CASCADE)
policy = models.CharField(max_length=765, blank=True)
client_addr = models.CharField(max_length=765, blank=True)
size = models.IntegerField()
originating = models.CharField(max_length=3)
content = models.CharField(max_length=1, blank=True)
quar_type = models.CharField(max_length=1, blank=True)
quar_loc = models.CharField(max_length=255, blank=True)
dsn_sent = models.CharField(max_length=3, blank=True)
spam_level = models.FloatField(null=True, blank=True)
message_id = models.CharField(max_length=765, blank=True)
from_addr = models.CharField(max_length=765, blank=True)
subject = models.CharField(max_length=765, blank=True)
host = models.CharField(max_length=765)
class Meta:
db_table = "msgs"
managed = False
unique_together = ("partition_tag", "mail_id")
@property
def time_datetime(self) -> datetime:
return datetime.fromtimestamp(self.time_num)
class Msgrcpt(models.Model):
partition_tag = models.IntegerField(default=0)
mail = models.ForeignKey(Msgs, primary_key=True, on_delete=models.CASCADE)
rid = models.ForeignKey(Maddr, db_column="rid", on_delete=models.CASCADE)
rseqnum = models.IntegerField(default=0)
is_local = models.CharField(max_length=3)
content = models.CharField(max_length=3)
ds = models.CharField(max_length=3)
rs = models.CharField(max_length=3)
bl = models.CharField(max_length=3, blank=True)
wl = models.CharField(max_length=3, blank=True)
bspam_level = models.FloatField(null=True, blank=True)
smtp_resp = models.CharField(max_length=765, blank=True)
class Meta:
db_table = "msgrcpt"
managed = False
unique_together = ("partition_tag", "mail", "rseqnum")
class Policy(models.Model):
policy_name = models.CharField(max_length=32, blank=True)
virus_lover = models.CharField(max_length=3, blank=True, null=True)
spam_lover = models.CharField(max_length=3, blank=True, null=True)
unchecked_lover = models.CharField(max_length=3, blank=True, null=True)
banned_files_lover = models.CharField(max_length=3, blank=True, null=True)
bad_header_lover = models.CharField(max_length=3, blank=True, null=True)
bypass_virus_checks = models.CharField(
gettext_lazy("Virus filter"),
default="",
null=True,
choices=(
("N", gettext_lazy("yes")),
("Y", gettext_lazy("no")),
("", gettext_lazy("default")),
),
max_length=3,
help_text=gettext_lazy(
"Bypass virus checks or not. Choose 'default' to use global " "settings."
),
)
bypass_spam_checks = models.CharField(
gettext_lazy("Spam filter"),
default="",
null=True,
choices=(
("N", gettext_lazy("yes")),
("Y", gettext_lazy("no")),
("", gettext_lazy("default")),
),
max_length=3,
help_text=gettext_lazy(
"Bypass spam checks or not. Choose 'default' to use global " "settings."
),
)
bypass_banned_checks = models.CharField(
gettext_lazy("Banned filter"),
default="",
null=True,
choices=(
("N", gettext_lazy("yes")),
("Y", gettext_lazy("no")),
("", gettext_lazy("default")),
),
max_length=3,
help_text=gettext_lazy(
"Bypass banned checks or not. Choose 'default' to use global " "settings."
),
)
bypass_header_checks = models.CharField(max_length=3, blank=True, null=True)
virus_quarantine_to = models.CharField(max_length=192, blank=True, null=True)
spam_quarantine_to = models.CharField(max_length=192, blank=True, null=True)
banned_quarantine_to = models.CharField(max_length=192, blank=True, null=True)
unchecked_quarantine_to = models.CharField(max_length=192, blank=True, null=True)
bad_header_quarantine_to = models.CharField(max_length=192, blank=True, null=True)
clean_quarantine_to = models.CharField(max_length=192, blank=True, null=True)
archive_quarantine_to = models.CharField(max_length=192, blank=True, null=True)
spam_tag_level = models.FloatField(null=True, blank=True)
spam_tag2_level = models.FloatField(null=True, blank=True)
spam_tag3_level = models.FloatField(null=True, blank=True)
spam_kill_level = models.FloatField(null=True, blank=True)
spam_dsn_cutoff_level = models.FloatField(null=True, blank=True)
spam_quarantine_cutoff_level = models.FloatField(null=True, blank=True)
addr_extension_virus = models.CharField(max_length=192, blank=True, null=True)
addr_extension_spam = models.CharField(max_length=192, blank=True, null=True)
addr_extension_banned = models.CharField(max_length=192, blank=True, null=True)
addr_extension_bad_header = models.CharField(max_length=192, blank=True, null=True)
warnvirusrecip = models.CharField(max_length=3, blank=True, null=True)
warnbannedrecip = models.CharField(max_length=3, blank=True, null=True)
warnbadhrecip = models.CharField(max_length=3, blank=True, null=True)
newvirus_admin = models.CharField(max_length=192, blank=True, null=True)
virus_admin = models.CharField(max_length=192, blank=True, null=True)
banned_admin = models.CharField(max_length=192, blank=True, null=True)
bad_header_admin = models.CharField(max_length=192, blank=True, null=True)
spam_admin = models.CharField(max_length=192, blank=True, null=True)
spam_subject_tag = models.CharField(max_length=192, blank=True, null=True)
spam_subject_tag2 = models.CharField(
gettext_lazy("Spam marker"),
default=None,
max_length=192,
blank=True,
null=True,
help_text=gettext_lazy(
"Modify spam subject using the specified text. "
"Choose 'default' to use global settings."
),
)
spam_subject_tag3 = models.CharField(max_length=192, blank=True, null=True)
message_size_limit = models.IntegerField(null=True, blank=True)
banned_rulenames = models.CharField(max_length=192, blank=True, null=True)
disclaimer_options = models.CharField(max_length=192, blank=True, null=True)
forward_method = models.CharField(max_length=192, blank=True, null=True)
sa_userconf = models.CharField(max_length=192, blank=True, null=True)
sa_username = models.CharField(max_length=192, blank=True, null=True)
class Meta:
db_table = "policy"
managed = False
class Quarantine(models.Model):
partition_tag = models.IntegerField(default=0)
mail = models.ForeignKey(Msgs, primary_key=True, on_delete=models.CASCADE)
chunk_ind = models.IntegerField()
mail_text = models.BinaryField()
class Meta:
db_table = "quarantine"
managed = False
ordering = ["-mail__time_num"]
unique_together = ("partition_tag", "mail", "chunk_ind")
class Users(models.Model):
id = models.AutoField(primary_key=True) # NOQA:A003
priority = models.IntegerField()
policy = models.ForeignKey(Policy, on_delete=models.CASCADE)
email = models.CharField(unique=True, max_length=255)
fullname = models.CharField(max_length=765, blank=True)
class Meta:
db_table = "users"
managed = False
class Wblist(models.Model):
rid = models.IntegerField(primary_key=True)
sid = models.IntegerField()
wb = models.CharField(max_length=30)
class Meta:
db_table = "wblist"
managed = False
unique_together = [("rid", "sid")]
+139
View File
@@ -0,0 +1,139 @@
"""Amavis serializers."""
from django.utils.translation import gettext as _
from rest_framework import serializers
from modoboa.amavis import models
class GlobalParametersSerializer(serializers.Serializer):
localpart_is_case_sensitive = serializers.BooleanField(default=False)
recipient_delimiter = serializers.CharField(default="")
max_messages_age = serializers.IntegerField(default=14)
released_msgs_cleanup = serializers.BooleanField(default=False)
am_pdp_mode = serializers.ChoiceField(
choices=[("inet", "inet"), ("unix", "unix")],
default="unix",
)
am_pdp_host = serializers.CharField(default="localhost", required=False)
am_pdp_port = serializers.IntegerField(default=9998, required=False)
am_pdp_socket = serializers.CharField(
default="/var/amavis/amavisd.sock", required=False
)
user_can_release = serializers.BooleanField(default=False)
self_service = serializers.BooleanField(default=False)
notifications_sender = serializers.EmailField(default="noreply@domain.tld")
manual_learning = serializers.BooleanField(default=True)
sa_is_local = serializers.BooleanField(default=True)
default_user = serializers.CharField(default="amavis", required=False)
spamd_address = serializers.CharField(default="127.0.0.1", required=False)
spamd_port = serializers.IntegerField(default=783, required=False)
domain_level_learning = serializers.BooleanField(default=False)
user_level_learning = serializers.BooleanField(default=False)
def validate(self, data):
am_pdp_mode = data.get("am_pdp_mode")
errors = {}
error = _("This field is required")
if am_pdp_mode == "inet":
for name in ["am_pdp_host", "am_pdp_port"]:
if name not in data:
errors[name] = error
else:
name = "am_pdp_socket"
if name not in data:
errors[name] = error
manual_learning = data.get("manual_learning")
if manual_learning:
name = "default_user"
if name not in data:
errors[name] = error
sa_is_local = data.get("sa_is_local")
if sa_is_local:
for name in ["spamd_address", "spamd_port"]:
if name not in data:
errors[name] = error
if errors:
raise serializers.ValidationError(errors)
return data
class UserPreferencesSerializer(serializers.Serializer):
messages_per_page = serializers.IntegerField(default=40)
class HeaderSerializer(serializers.Serializer):
name = serializers.CharField()
value = serializers.CharField()
class MessageHeadersSerializer(serializers.Serializer):
headers = HeaderSerializer(many=True)
class MessageSerializer(serializers.Serializer):
qtype = serializers.CharField()
qreason = serializers.CharField()
headers = HeaderSerializer(many=True)
body = serializers.CharField()
class CompactMessageSerializer(serializers.Serializer):
mailid = serializers.CharField()
type = serializers.CharField()
status = serializers.CharField()
score = serializers.CharField()
to_address = serializers.CharField()
from_address = serializers.CharField()
subject = serializers.CharField()
datetime = serializers.DateTimeField()
style = serializers.CharField(required=False)
class PaginatedMessageListSerializer(serializers.Serializer):
count = serializers.IntegerField()
first_index = serializers.IntegerField()
last_index = serializers.IntegerField()
prev_page = serializers.IntegerField()
next_page = serializers.IntegerField()
results = CompactMessageSerializer(many=True)
class MessageIdentifierSerializer(serializers.Serializer):
mailid = serializers.CharField()
rcpt = serializers.CharField()
secret_id = serializers.CharField(required=False)
class MessageSelectionSerializer(serializers.Serializer):
selection = MessageIdentifierSerializer(many=True)
class MarkMessageSelectionSerializer(MessageSelectionSerializer):
type = serializers.CharField()
database = serializers.CharField(required=False)
class PolicySerializer(serializers.ModelSerializer):
class Meta:
model = models.Policy
fields = (
"bypass_virus_checks",
"bypass_spam_checks",
"bypass_banned_checks",
"spam_tag2_level",
"spam_kill_level",
"spam_subject_tag2",
)
+240
View File
@@ -0,0 +1,240 @@
"""SQL connector module."""
import datetime
from django.db.models import Q
from modoboa.admin.models import Domain
from modoboa.lib.email_utils import decode
from .lib import cleanup_email_address, make_query_args
from .models import Maddr, Msgrcpt, Quarantine
from .utils import ConvertFrom, fix_utf8_encoding, smart_bytes, smart_str
def reverse_domain_names(domains):
"""Return a list of reversed domain names."""
return [".".join(reversed(domain.split("."))) for domain in domains]
class SQLconnector:
"""This class handles all database operations."""
ORDER_TRANSLATION_TABLE = {
"type": "content",
"score": "bspam_level",
"datetime": "mail__time_num",
"subject": "mail__subject",
"from_address": "mail__from_addr",
"to_address": "rid__email",
}
QUARANTINE_FIELDS = [
"content",
"bspam_level",
"rs",
"rid__email",
"mail__from_addr",
"mail__subject",
"mail__mail_id",
"mail__time_num",
]
def __init__(self, user=None, ordering: str | None = None) -> None:
"""Constructor."""
self.user = user
self.messages = None
self.ordering = ordering
self._messages_count = None
self._annotations = {}
def _exec(self, query, args):
"""Execute a raw SQL query.
:param string query: query to execute
:param list args: a list of arguments to replace in :kw:`query`
"""
from django.db import connections, transaction
with transaction.atomic():
cursor = connections["amavis"].cursor()
cursor.execute(query, args)
def _apply_msgrcpt_simpleuser_filter(self, flt):
"""Apply specific filter for simple users."""
if "str_email" not in self._annotations:
self._annotations["str_email"] = ConvertFrom("rid__email")
rcpts = [self.user.email]
if hasattr(self.user, "mailbox"):
rcpts += self.user.mailbox.alias_addresses
query_rcpts = []
for rcpt in rcpts:
query_rcpts += make_query_args(rcpt, exact_extension=False, wildcard=".*")
re = f"({'|'.join(query_rcpts)})"
return flt & Q(str_email__regex=re)
def _apply_msgrcpt_filters(self, flt):
"""Apply filters based on user's role."""
if self.user.role == "SimpleUsers":
flt = self._apply_msgrcpt_simpleuser_filter(flt)
elif not self.user.is_superuser:
doms = Domain.objects.get_for_admin(self.user).values_list(
"name", flat=True
)
flt &= Q(rid__domain__in=reverse_domain_names(doms))
return flt
def _get_quarantine_content(self, request):
"""Fetch quarantine content.
Filters: rs, rid, content
"""
flt = (
Q(rs__in=[" ", "V", "R", "p", "S", "H"])
if request.GET.get("viewrequests", "0") != "1"
else Q(rs="p")
)
flt = self._apply_msgrcpt_filters(flt)
search = request.GET.get("search")
if search:
criteria = request.GET.get("criteria", "both")
if criteria == "both":
criteria = "from_addr,subject,to"
search_flt = None
for crit in criteria.split(","):
if crit == "from_addr":
nfilter = Q(mail__from_addr__icontains=search)
elif crit == "subject":
nfilter = Q(mail__subject__icontains=search)
elif crit == "to":
if "str_email" not in self._annotations:
self._annotations["str_email"] = ConvertFrom("rid__email")
nfilter = Q(str_email__icontains=search)
else:
continue
search_flt = nfilter if search_flt is None else search_flt | nfilter
if search_flt:
flt &= search_flt
msgtype = request.GET.get("msgtype")
if msgtype is not None:
flt &= Q(content=msgtype)
flt &= Q(mail__in=Quarantine.objects.filter(chunk_ind=1).values("mail_id"))
return (
Msgrcpt.objects.annotate(**self._annotations)
.select_related("mail", "rid")
.filter(flt)
)
def messages_count(self, request) -> int:
"""
Return the total number of messages living in the quarantine.
We also store the built queryset for a later use.
"""
if self.user is None:
return None
if self._messages_count is None:
self.messages = self._get_quarantine_content(request)
self.messages = self.messages.values(*self.QUARANTINE_FIELDS)
order = self.ordering
if order is not None:
sign = ""
if order[0] == "-":
sign = "-"
order = order[1:]
order = self.ORDER_TRANSLATION_TABLE.get(order)
if order:
self.messages = self.messages.order_by(sign + order)
self._messages_count = len(self.messages)
return self._messages_count
def fetch(self, start=None, stop=None):
"""Fetch a range of messages from the internal cache."""
emails = []
for qm in self.messages[start - 1 : stop]:
if qm["rs"] == "D":
continue
m = {
"from_address": cleanup_email_address(
fix_utf8_encoding(qm["mail__from_addr"])
),
"to_address": smart_str(qm["rid__email"]),
"subject": fix_utf8_encoding(qm["mail__subject"]),
"mailid": smart_str(qm["mail__mail_id"]),
"datetime": datetime.datetime.fromtimestamp(qm["mail__time_num"]),
"type": qm["content"],
"score": qm["bspam_level"],
"status": qm["rs"],
}
if qm["rs"] in ["", " "]:
m["style"] = "unseen"
elif qm["rs"] == "p":
m["style"] = "pending"
emails.append(m)
return emails
def get_recipient_message(self, address, mailid):
"""Retrieve a message for a given recipient."""
assert isinstance(address, str), "address should be of type str"
return Msgrcpt.objects.annotate(str_email=ConvertFrom("rid__email")).get(
mail=mailid.encode("ascii"), str_email=address
)
def set_msgrcpt_status(self, address, mailid: str, status):
"""Change the status (rs field) of a message recipient.
:param string status: status
"""
assert isinstance(address, str), "address should be of type str"
addr = Maddr.objects.annotate(str_email=ConvertFrom("email")).get(
str_email=address
)
self._exec(
"UPDATE msgrcpt SET rs=%s WHERE mail_id=%s AND rid=%s",
[status, mailid.encode("ascii"), addr.id],
)
def get_domains_pending_requests(self, domains):
"""Retrieve pending release requests for a list of domains."""
return Msgrcpt.objects.filter(
rs="p", rid__domain__in=reverse_domain_names(domains)
)
def get_pending_requests(self):
"""Return the number of requests currently pending."""
rq = Q(rs="p")
if not self.user.is_superuser:
doms = Domain.objects.get_for_admin(self.user)
if not doms.exists():
return 0
doms_q = Q(
rid__domain__in=reverse_domain_names(
doms.values_list("name", flat=True)
)
)
rq &= doms_q
return Msgrcpt.objects.filter(rq).count()
def get_mail_content(self, mailid) -> str:
"""Retrieve the content of a message."""
content_bytes = smart_bytes("").join(
[
smart_bytes(qmail.mail_text)
for qmail in Quarantine.objects.filter(mail=mailid)
]
)
content = decode(
content_bytes, "utf-8", append_to_error=f"; mail_id={smart_str(mailid)}"
)
return content
+66
View File
@@ -0,0 +1,66 @@
"""An email representation based on a database record."""
from html2text import HTML2Text
from django.template.loader import render_to_string
from modoboa.lib.email_utils import Email
from .sql_connector import SQLconnector
from .utils import fix_utf8_encoding, smart_str
class SQLemail(Email):
"""The SQL version of the Email class."""
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.qtype = ""
self.qreason = ""
qreason = self.msg["X-Amavis-Alert"]
if qreason:
if "," in qreason:
self.qtype, qreason = qreason.split(",", 1)
elif qreason.startswith("BAD HEADER SECTION "):
# Workaround for amavis <= 2.8.0 :p
self.qtype = "BAD HEADER SECTION"
qreason = qreason[19:]
qreason = " ".join([x.strip() for x in qreason.splitlines()])
self.qreason = qreason
def _fetch_message(self) -> str:
return SQLconnector().get_mail_content(self.mailid)
@property
def body(self):
if self._body is None:
super().body # noqa
self._body = fix_utf8_encoding(self._body)
# if there's no plain text version available attempt to make one by
# sanitising the html version. The output isn't always pretty but it
# is readable, better than a blank screen and helps the user decide
# if the message is spam or ham.
if (
self.dformat == "plain"
and not self.contents["plain"]
and self.contents["html"]
):
h = HTML2Text()
h.ignore_tables = True
h.images_to_alt = True
mail_text = h.handle(self.contents["html"])
self.contents["plain"] = self._post_process_plain(smart_str(mail_text))
self._body = self.viewmail_plain()
self._body = fix_utf8_encoding(self._body)
return self._body
def render_headers(self, **kwargs):
context = {
"qtype": self.qtype,
"qreason": self.qreason,
"headers": self.headers,
}
return render_to_string("modoboa_amavis/mailheaders.html", context)
+33
View File
@@ -0,0 +1,33 @@
"""Async tasks."""
# from django.utils.translation import ngettext
from modoboa.core import models as core_models
from .lib import SpamassassinClient
from .sql_connector import SQLconnector
def manual_learning(user_pk: int, mtype: str, selection: list[dict], recipient_db: str):
"""Task to trigger manual learning for given selection."""
user = core_models.User.objects.get(pk=user_pk)
connector = SQLconnector()
saclient = SpamassassinClient(user, recipient_db)
for item in selection:
content = connector.get_mail_content(item["mailid"].encode("ascii"))
result = (
saclient.learn_spam(item["rcpt"], content)
if mtype == "spam"
else saclient.learn_ham(item["rcpt"], content)
)
if not result:
break
connector.set_msgrcpt_status(item["rcpt"], item["mailid"], mtype[0].upper())
if saclient.error is None:
saclient.done()
# message = ngettext("%(count)d message processed successfully",
# "%(count)d messages processed successfully",
# len(selection)) % {"count": len(selection)}
# else:
# message = saclient.error
@@ -0,0 +1,16 @@
{% load i18n %}
{% blocktranslate trimmed count counter=total %}
{{ counter }} release request is pending for action.
{% plural %}
{{ counter }} release requests are pending for action.
{% endblocktranslate %}
{% translate "Sketch:" %}
{% for msg in requests %}
{% translate "From:" %} {{ msg.mail.sid.email }}
{% translate "To:" %} {{ msg.rid.email }}
{% translate "Date:" %} {{ msg.mail.time_datetime|date:"DATETIME_FORMAT" }}
{% translate "Subject:" %} {{ msg.mail.subject }}
{% translate "Act on this message:" %} {{ baseurl }}/user/quarantine/{{ msg.mail.mail_id }}/{{ msg.rid.email }}
{% endfor %}
{% blocktranslate %}Please visit {{ listingurl }} for a full listing.{% endblocktranslate %}
View File
+3
View File
@@ -0,0 +1,3 @@
#!/bin/sh
exit 0
@@ -0,0 +1,80 @@
X-Envelope-From: <it-edu@evil.example.net>
X-Envelope-To: <me@example.net>
X-Envelope-To-Blocked: <me@example.net>
X-Quarantine-ID: <nZkKQ_MUuyil>
X-Amavis-Alert: BAD HEADER SECTION, Non-encoded non-ASCII data (and not UTF-8)
(char 85 hex): Subject: I think I saw you in my dreams\x{85}
X-Spam-Flag: YES
X-Spam-Score: 8.178
X-Spam-Level: ********
X-Spam-Status: Yes, score=8.178 tag=-999 tag2=3.9 kill=5
tests=[HEADER_FROM_DIFFERENT_DOMAINS=0.25, HTML_IMAGE_ONLY_28=0.726,
HTML_MESSAGE=0.001, MIME_HTML_ONLY=1.105, RCVD_IN_MSPIKE_H2=-0.001,
TVD_PH_BODY_ACCOUNTS_PRE=0.001, T_REMOTE_IMAGE=0.01,
T_RP_MATCHES_RCVD=-0.01, URIBL_BLACK=1.7, URIBL_DBL_ABUSE_SPAM=2,
URI_WPADMIN=2.396] autolearn=no autolearn_force=no
Received: from mail.example.net ([127.0.0.1])
by mail.example.net (mail.example.net [127.0.0.1]) (amavisd-new, port 10024)
with LMTP id nZkKQ_MUuyil for <me@example.net>;
Sat, 16 Dec 2017 13:09:49 +0000 (GMT)
Received: from evil.example.net (mail.evil.example.net [10.0.0.1])
by mail.example.net (Postfix) with ESMTPS id 62B2E1AF12D
for <me@example.net>; Sat, 16 Dec 2017 13:09:49 +0000 (GMT)
Received: from it-edu by evil.example.net with local (Exim 4.82)
(envelope-from <it-edu@evil.example.net>)
id 1eQCDr-0005NE-IT
for me@example.net; Sat, 16 Dec 2017 16:09:47 +0300
To: me@example.net
Subject: =?UTF-8?Q?Account_Suspension_Notification_=21?=
X-PHP-Originating-Script: 520:maill.php
Date: Sat, 16 Dec 2017 16:09:47 +0300
From: Notice <Notice@fake.example.net>
Reply-To: Notice@fake.example.net
Message-ID: <6619a5295cefcf484a58944fc280eb90@evil.example.net>
X-Priority: 1
X-Mailer: PHPMailer 5.2.10 (https://github.com/PHPMailer/PHPMailer/)
MIME-Version: 1.0
Content-Type: text/html; charset=iso-8859-1
Content-Transfer-Encoding: 8bit
<!DOCTYPE html>
<html>
<HEAD><STYLE>
.cssage P
{
margin:0px;
padding:0px
}
body.cssage
{
font-size: 12pt;
font-family:Calibri
}
</STYLE>
</HEAD>
<BODY class="cssage">
<DIV dir="ltr"><FONT size=2 face="Arial, Helvetica, sans-serif"></FONT><BR>
<DIV>
<DIV>
<TABLE style="FONT-FAMILY: 'Times New Roman'" border=0 cellSpacing=0 cellPadding=0 width=600 align="center">
<TR class=header>
<TD vAlign=bottom><SPAN style="FONT-FAMILY: 'Trebuchet MS', Arial, Helvetica, sans-serif; COLOR: rgb(159,159,159); FONT-SIZE: 12px" >This is an automated email, please do not reply</SPAN></TD>
<TD align=right><IMG style="WIDTH: 215px; HEIGHT: 66px" alt="" src="http://im55.gulfup.com/oLrUdE.jpg"></TD></TR>
<TR >
<TD height=14 vAlign=bottom colSpan=2><IMG src="https://www.payza.com/emails/images/bar.png" width="100%" height=3></TD></TR>
<TR>
<TD colSpan=2>
<H1 style="PADDING-BOTTOM: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; FONT-FAMILY: 'Trebuchet MS', Arial, Helvetica, sans-serif; COLOR: rgb(189,151,0); FONT-SIZE: 24px; FONT-WEIGHT: normal; PADDING-TOP: 10px">Dear Client</H1>
<P style="LINE-HEIGHT: 21px; FONT-FAMILY: 'Trebuchet MS', Arial, Helvetica, sans-serif; COLOR: rgb(84,84,84); FONT-SIZE: 14px">We've noticed that some of your account information appears to be missing or incorrect
We need to verify your account information in order to continue using your Apple ID, Please Verify your account information by clicking on the link below<BR><BR><B><A style="COLOR: rgb(27,144,234)" href="http://chiikulab.com/wp-admin/images/Update/Apple2018%20V2.1/
" target=_blank>Click here to Verify your ID</A></B></P></TD></TR>
<TR>
<TD colSpan=2>
<DIV><SPAN style="FONT-FAMILY: 'Trebuchet MS', Arial, Helvetica, sans-serif; COLOR: rgb(51,102,204); FONT-SIZE: 15px" ></SPAN><BR></DIV><br><SPAN style="FONT-FAMILY: 'Trebuchet MS', Arial, Helvetica, sans-serif; COLOR: rgb(202,162,0); FONT-SIZE: 17px" class=ecxthanks>Thanks for choosing Apple,</SPAN><BR style="COLOR: rgb(202,162,0)"><SPAN style="FONT-FAMILY: 'Trebuchet MS', Arial, Helvetica, sans-serif; COLOR: rgb(202,162,0); FONT-SIZE: 15px" >Apple Team</SPAN></TD></TR>
<TR >
<TD height=14 vAlign=bottom colSpan=2><IMG src="https://www.payza.com/emails/images/bar.png" width="100%" height=3></TD></TR>
<TR>
<TD colSpan=2>
<P style="PADDING-BOTTOM: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; FONT-FAMILY: 'Trebuchet MS', Arial, Helvetica, sans-serif; COLOR: rgb(84,84,84); FONT-SIZE: 12px; PADDING-TOP: 10px" >&copy; 2017 Apple. All rights reserved.</P>
<P style="FONT-FAMILY: 'Trebuchet MS', Arial, Helvetica, sans-serif; COLOR: rgb(186,148,0); FONT-SIZE: 11px">Email ID: 163327</P></TD></TR></TABLE></DIV></DIV></DIV></BODY></html>
@@ -0,0 +1,17 @@
<pre>This is an automated email, please do not reply
# Dear Client
We&#x27;ve noticed that some of your account information appears to be missing or
incorrect We need to verify your account information in order to continue
using your Apple ID, Please Verify your account information by clicking on the
link below
**Click here to Verify your ID**
Thanks for choosing Apple,
Apple Team
© 2017 Apple. All rights reserved.
Email ID: 163327</pre>
+3
View File
@@ -0,0 +1,3 @@
#!/bin/sh
exit 5
+25
View File
@@ -0,0 +1,25 @@
from django.test import TestCase
from django.test.utils import override_settings
from ..checks import settings_checks
class CheckSessionCookieSecureTest(TestCase):
databases = "__all__"
@override_settings(AMAVIS_DEFAULT_DATABASE_ENCODING="LATIN-1")
def test_amavis_database_encoding_incorrect(self):
"""
If AMAVIS_DEFAULT_DATABASE_ENCODING is incorrect provide one warning.
"""
self.assertEqual(
settings_checks.check_amavis_database_encoding(None), [settings_checks.W001]
)
@override_settings(AMAVIS_DEFAULT_DATABASE_ENCODING="UTF-8")
def test_amavis_database_encoding_correct(self):
"""
If AMAVIS_DEFAULT_DATABASE_ENCODING is correct, there's no warning.
"""
self.assertEqual(settings_checks.check_amavis_database_encoding(None), [])
+214
View File
@@ -0,0 +1,214 @@
"""Amavis tests."""
import os
from django.test import override_settings
from django.urls import reverse
from modoboa.admin import factories as admin_factories, models as admin_models
from modoboa.core import models as core_models
from modoboa.lib.tests import ModoAPITestCase
from modoboa.transport import factories as tr_factories
from .. import factories, lib, models
class DomainTestCase(ModoAPITestCase):
"""Check that database is populated."""
databases = "__all__"
def setUp(self):
"""Initiate test context."""
self.admin = core_models.User.objects.get(username="admin")
def test_create_domain(self):
"""Test domain creation."""
domain = admin_factories.DomainFactory(name="domain.test")
name = f"@{domain.name}"
policy = models.Policy.objects.get(policy_name=name)
user = models.Users.objects.filter(policy=policy).first()
self.assertIsNot(user, None)
self.assertEqual(user.email, name)
# Create a domain alias
self.client.force_authenticate(self.admin)
url = reverse("v2:domain_alias-list")
data = {"name": "dalias.test", "target": domain.pk}
resp = self.client.post(url, data, format="json")
self.assertEqual(resp.status_code, 201)
name = "@dalias.test"
self.assertFalse(models.Policy.objects.filter(policy_name=name).exists())
user = models.Users.objects.get(email=name)
self.assertEqual(user.policy, policy)
# Delete domain alias
url = reverse("v2:domain_alias-detail", args=[resp.json()["pk"]])
resp = self.client.delete(url)
self.assertEqual(resp.status_code, 204)
self.assertFalse(models.Users.objects.filter(email=name).exists())
def test_rename_domain(self):
"""Test domain rename."""
domain = admin_factories.DomainFactory(name="domain.test")
domain.name = "domain1.test"
domain.save()
name = f"@{domain.name}"
self.assertTrue(models.Users.objects.filter(email=name).exists())
self.assertTrue(models.Policy.objects.filter(policy_name=name).exists())
# Now from form
self.client.force_authenticate(self.admin)
rdomain = admin_factories.DomainFactory(name="domain.relay", type="relaydomain")
rdomain.transport = tr_factories.TransportFactory(
pattern=rdomain.name,
service="relay",
_settings={
"relay_target_host": "external.host.tld",
"relay_target_port": "25",
"relay_verify_recipients": False,
},
)
rdomain.save()
url = reverse("v2:domain-detail", args=[rdomain.pk])
values = {
"name": "domain2.relay",
"quota": rdomain.quota,
"default_mailbox_quota": rdomain.default_mailbox_quota,
"type": "relaydomain",
"enabled": rdomain.enabled,
"transport": {
"service": rdomain.transport.service,
"settings": {
"relay_target_host": "127.0.0.1",
"relay_target_port": 25,
},
},
}
resp = self.client.put(url, values, format="json")
self.assertTrue(resp.status_code, 200)
def test_delete_domain(self):
"""Test domain removal."""
domain = admin_factories.DomainFactory(name="domain.test")
domain.delete(None)
name = f"@{domain.name}"
self.assertFalse(models.Users.objects.filter(email=name).exists())
self.assertFalse(models.Policy.objects.filter(policy_name=name).exists())
def test_update_domain_policy(self):
"""Check domain policy edition."""
self.client.force_authenticate(self.admin)
domain = admin_factories.DomainFactory(name="domain.test")
url = reverse("v2:amavis-policy-detail", args=[domain.pk])
custom_title = "This is SPAM!"
data = {"bypass_virus_checks": "Y", "spam_subject_tag2": custom_title}
resp = self.client.patch(url, data, format="json")
self.assertEqual(resp.status_code, 200)
name = f"@{domain.name}"
policy = models.Policy.objects.get(policy_name=name)
self.assertEqual(policy.spam_subject_tag2, custom_title)
@override_settings(SA_LOOKUP_PATH=(os.path.dirname(__file__),))
class ManualLearningTestCase(ModoAPITestCase):
"""Check manual learning mode."""
databases = "__all__"
@classmethod
def setUpTestData(cls): # NOQA:N802
"""Create test data."""
super().setUpTestData()
admin_factories.populate_database()
def test_alias_creation(self):
"""Check alias creation."""
self.set_global_parameter("user_level_learning", True)
# Fake activation because we don't have test data yet for
# amavis...
lib.setup_manual_learning_for_mbox(
admin_models.Mailbox.objects.get(address="user", domain__name="test.com")
)
lib.setup_manual_learning_for_mbox(
admin_models.Mailbox.objects.get(address="admin", domain__name="test.com")
)
url = reverse("v2:alias-list")
values = {
"address": "alias1000@test.com",
"recipients": ["admin@test.com"],
"enabled": True,
}
resp = self.client.post(url, values, format="json")
self.assertEqual(resp.status_code, 201)
policy = models.Policy.objects.get(policy_name=values["recipients"][0])
user = models.Users.objects.get(email=values["address"])
self.assertEqual(user.policy, policy)
values = {
"address": "user@test.com",
"recipients": ["admin@test.com"],
"enabled": True,
}
resp = self.client.post(url, values, format="json")
self.assertEqual(resp.status_code, 201)
policy = models.Policy.objects.get(policy_name=values["recipients"][0])
user = models.Users.objects.get(email=values["address"])
self.assertEqual(user.policy, policy)
def test_mailbox_rename(self):
"""Check rename case."""
self.set_global_parameter("user_level_learning", True)
lib.setup_manual_learning_for_mbox(
admin_models.Mailbox.objects.get(address="user", domain__name="test.com")
)
user = core_models.User.objects.get(username="user@test.com")
url = reverse("v2:account-detail", args=[user.pk])
values = {
"username": "user2@test.com",
"role": "SimpleUsers",
"mailbox": {"use_domain_quota": True},
}
resp = self.client.put(url, values, format="json")
self.assertEqual(resp.status_code, 200)
self.assertTrue(models.Users.objects.filter(email=values["username"]).exists())
def test_learn_alias_spam_as_admin(self):
"""Check learning spam for an alias address as admin user."""
user = core_models.User.objects.get(username="admin")
recipient_db = "user"
rcpt = "alias@test.com"
sender = "spam@evil.corp"
content = factories.SPAM_BODY.format(rcpt=rcpt, sender=sender)
saclient = lib.SpamassassinClient(user, recipient_db)
result = saclient.learn_spam(rcpt, content)
self.assertTrue(result)
def test_delete_catchall_alias(self):
"""Check that Users record is not deleted."""
self.set_global_parameter("user_level_learning", True)
# Fake activation because we don't have test data yet for
# amavis...
lib.setup_manual_learning_for_mbox(
admin_models.Mailbox.objects.get(address="admin", domain__name="test.com")
)
url = reverse("v2:alias-list")
values = {
"address": "@test.com",
"recipients": ["admin@test.com"],
"enabled": True,
}
resp = self.client.post(url, values, format="json")
self.assertTrue(resp.status_code, 201)
alias = admin_models.Alias.objects.get(address="@test.com")
url = reverse("v2:alias-detail", args=[alias.pk])
resp = self.client.delete(url)
self.assertEqual(resp.status_code, 204)
self.assertTrue(models.Users.objects.get(email="@test.com"))
+90
View File
@@ -0,0 +1,90 @@
from django.test import SimpleTestCase
from modoboa.lib.tests import ModoTestCase
from modoboa.amavis.lib import cleanup_email_address, make_query_args
class MakeQueryArgsTests(ModoTestCase):
"""Tests for modoboa_amavis.lib.make_query_args()."""
def test_simple_email_address_001(self):
"""Check case insensitive email address without recipient delimiter."""
self.set_global_parameter("localpart_is_case_sensitive", False)
self.set_global_parameter("recipient_delimiter", "")
address = "User+Foo@sub.exAMPLE.COM"
expected_output = [
"user+foo@sub.example.com",
]
output = make_query_args(address)
self.assertEqual(output, expected_output)
def test_simple_email_address_002(self):
"""Check case sensitive email address with recipient delimiter."""
self.set_global_parameter("localpart_is_case_sensitive", True)
self.set_global_parameter("recipient_delimiter", "+")
address = "User+Foo@sub.exAMPLE.COM"
expected_output = [
"User+Foo@sub.exAMPLE.COM",
"User+Foo@sub.example.com",
"User@sub.example.com",
]
output = make_query_args(address)
self.assertEqual(output, expected_output)
def test_simple_email_address_003(self):
"""Check email address with recipient delimiter wildcard."""
self.set_global_parameter("localpart_is_case_sensitive", False)
self.set_global_parameter("recipient_delimiter", "+")
address = "User+Foo@sub.exAMPLE.COM"
expected_output = [
"user+foo@sub.example.com",
"user+.*@sub.example.com",
"user@sub.example.com",
]
output = make_query_args(address, exact_extension=False, wildcard=".*")
self.assertEqual(output, expected_output)
def test_simple_email_address_004(self):
"""Check domain search."""
self.set_global_parameter("localpart_is_case_sensitive", False)
self.set_global_parameter("recipient_delimiter", "+")
address = "User+Foo@sub.exAMPLE.COM"
expected_output = [
"user+foo@sub.example.com",
"user+.*@sub.example.com",
"user@sub.example.com",
"@sub.example.com",
"@.",
]
output = make_query_args(
address, exact_extension=False, wildcard=".*", domain_search=True
)
self.assertEqual(output, expected_output)
def test_simple_email_address_idn(self):
"""Check email address with international domain name."""
self.set_global_parameter("localpart_is_case_sensitive", False)
self.set_global_parameter("recipient_delimiter", "")
address = "Pingüino@Pájaro.Niño.exAMPLE.COM"
expected_output = [
"Pingüino@Pájaro.Niño.exAMPLE.COM",
"pingüino@xn--pjaro-xqa.xn--nio-8ma.example.com",
]
output = make_query_args(address)
self.assertEqual(output, expected_output)
class FixUTF8EncodingTests(SimpleTestCase):
"""Tests for modoboa_amavis.lib.cleanup_email_address()."""
def test_value_with_newline(self):
value = '"John Smith" <john.smith@example.com>\n'
expected_output = "John Smith <john.smith@example.com>"
output = cleanup_email_address(value)
self.assertEqual(output, expected_output)
def test_no_name(self):
value = "<john.smith@example.com>"
expected_output = "john.smith@example.com"
output = cleanup_email_address(value)
self.assertEqual(output, expected_output)
@@ -0,0 +1,45 @@
"""Management commands tests."""
from dateutil.relativedelta import relativedelta
from django.core.management import call_command
from django.utils import timezone
from modoboa.lib.tests import ModoTestCase
from .. import factories, models
class ManagementCommandTestCase(ModoTestCase):
"""Management commands tests."""
databases = "__all__"
def test_qcleanup(self):
"""Test qcleanup command."""
factories.create_spam("user@test.com", rs="D")
call_command("qcleanup")
self.assertEqual(models.Quarantine.objects.count(), 0)
self.assertEqual(models.Msgs.objects.count(), 0)
self.assertEqual(models.Maddr.objects.count(), 0)
self.assertEqual(models.Msgrcpt.objects.count(), 0)
factories.create_spam("user@test.com", rs="D")
msgrcpt = factories.create_spam("user@test.com", rs="R")
call_command("qcleanup")
# Should not raise anything
msgrcpt.refresh_from_db()
self.set_global_parameter("released_msgs_cleanup", True)
call_command("qcleanup")
with self.assertRaises(models.Msgrcpt.DoesNotExist):
msgrcpt.refresh_from_db()
msgrcpt = factories.create_spam("user@test.com")
msgrcpt.mail.time_num = int(
(timezone.now() - relativedelta(days=40)).strftime("%s")
)
msgrcpt.mail.save(update_fields=["time_num"])
self.set_global_parameter("max_messages_age", 30)
call_command("qcleanup")
with self.assertRaises(models.Msgrcpt.DoesNotExist):
msgrcpt.refresh_from_db()
+67
View File
@@ -0,0 +1,67 @@
"""Tests for sql_email."""
import os
from django.test import TestCase
from django.utils.encoding import smart_str
from ..sql_email import SQLemail
SAMPLES_DIR = os.path.realpath(
os.path.join(os.path.dirname(__file__), "sample_messages")
)
class EmailTestImplementation(SQLemail):
def _fetch_message(self):
message_path = os.path.join(SAMPLES_DIR, f"{self.mailid}-input.txt")
assert os.path.isfile(message_path), f"{message_path} does not exist."
with open(message_path, "rb") as fp:
mail_text = fp.read()
return mail_text
class EmailTests(TestCase):
"""Tests for modoboa_amavis.sql_email.SQLEmail
When writing new sample messages use the following naming convention for
the sample files stored in sample_messages:
input: {message_id}-input.txt
output: {message_id}-output-{dformat}_{no,}links.txt
"""
def _get_expected_output(self, message_id, **kwargs):
ext = kwargs["dformat"] if "dformat" in kwargs else "plain"
ext += "_links" if "links" in kwargs and kwargs["links"] else "_nolinks"
message_path = os.path.join(SAMPLES_DIR, f"{message_id}-output-{ext}.txt")
assert os.path.isfile(message_path), f"{message_path} does not exist."
with open(message_path, "rb") as fp:
# output should always be unicode (py2) or str (py3)
mail_text = smart_str(fp.read())
return mail_text
def _test_email(self, message_id, **kwargs):
"""Boiler plate code for testing e-mails."""
expected_output = self._get_expected_output(message_id, **kwargs)
output = EmailTestImplementation(message_id, **kwargs).body
self.assertEqual(output, expected_output)
def test_amavis_aleart_header(self):
email = EmailTestImplementation("quarantined")
self.assertEqual(email.qtype, "BAD HEADER SECTION")
self.assertEqual(
email.qreason,
"Non-encoded non-ASCII data (and not UTF-8) (char 85 "
"hex): Subject: I think I saw you in my dreams\\x{85}",
)
def test_email_multipart_with_no_text(self):
"""for a multipart message without a text/plain part convert the
text/html to text/plain"""
self._test_email("quarantined")
+19
View File
@@ -0,0 +1,19 @@
from django.test import SimpleTestCase
from modoboa.amavis.utils import fix_utf8_encoding
class FixUTF8EncodingTests(SimpleTestCase):
"""Tests for modoboa_amavis.utils.fix_utf8_encoding()."""
def test_4_byte_unicode(self):
value = "\xf0\x9f\x99\x88"
expected_output = "\U0001f648" # == See No Evil Moneky
output = fix_utf8_encoding(value)
self.assertEqual(output, expected_output)
def test_truncated_4_byte_unicode(self):
value = "\xf0\x9f\x99"
expected_output = "\xf0\x9f\x99"
output = fix_utf8_encoding(value)
self.assertEqual(output, expected_output)
+288
View File
@@ -0,0 +1,288 @@
import os
from unittest import mock
from rq import SimpleWorker
from django.core import mail
from django.core.management import call_command
from django.test import override_settings
from django.urls import reverse
import django_rq
from modoboa.admin import factories as admin_factories, models as admin_models
from modoboa.amavis import factories, models
from modoboa.amavis.utils import smart_str
from modoboa.core import models as core_models
from modoboa.lib.tests import ModoAPITestCase
class TestDataMixin:
"""A mixin to provide test data."""
@classmethod
def setUpTestData(cls): # NOQA:N802
"""Create some content."""
super().setUpTestData()
cls.msgrcpt = factories.create_spam("user@test.com")
@override_settings(SA_LOOKUP_PATH=(os.path.dirname(__file__),))
class QuarantineViewSetTestCase(TestDataMixin, ModoAPITestCase):
databases = "__all__"
@classmethod
def setUpTestData(cls): # NOQA:N802
"""Create test data."""
super().setUpTestData()
admin_factories.populate_database()
def tearDown(self):
"""Restore msgrcpt state."""
self.msgrcpt.rs = " "
self.msgrcpt.save(update_fields=["rs"])
self.set_global_parameter("domain_level_learning", False)
self.set_global_parameter("user_level_learning", False)
def test_list(self):
url = reverse("v2:amavis-quarantine-list")
resp = self.client.get(url)
self.assertEqual(resp.status_code, 200)
content = resp.json()
self.assertEqual(content["count"], 1)
resp = self.client.get(f"{url}?search=pouet&criteria=both")
content = resp.json()
self.assertEqual(content["count"], 0)
resp = self.client.get(f"{url}?msgtype=V")
content = resp.json()
self.assertEqual(content["count"], 0)
factories.create_virus("user@test.com")
resp = self.client.get(f"{url}?msgtype=V")
content = resp.json()
self.assertEqual(content["count"], 1)
def test_retrieve(self):
mail_id = smart_str(self.msgrcpt.mail.mail_id)
rcpt = smart_str(self.msgrcpt.rid.email)
url = reverse("v2:amavis-quarantine-detail", args=[mail_id])
resp = self.client.get(f"{url}?rcpt={rcpt}")
self.assertEqual(resp.status_code, 200)
def test_headers(self):
mail_id = smart_str(self.msgrcpt.mail.mail_id)
url = reverse("v2:amavis-quarantine-headers", args=[mail_id])
resp = self.client.get(url)
self.assertEqual(resp.status_code, 200)
def test_headers_selfservice(self):
self.client.logout()
mail_id = smart_str(self.msgrcpt.mail.mail_id)
url = reverse("v2:amavis-quarantine-headers", args=[mail_id])
url = f"{url}?secret_id={smart_str(self.msgrcpt.mail.secret_id)}"
response = self.client.get(url)
self.assertEqual(response.status_code, 403)
self.set_global_parameter("self_service", True)
response = self.client.get(url)
self.assertEqual(response.status_code, 403)
url = f"{url}&rcpt={smart_str(self.msgrcpt.rid.email)}"
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
def test_delete(self):
mail_id = smart_str(self.msgrcpt.mail.mail_id)
url = reverse("v2:amavis-quarantine-delete", args=[mail_id])
data = {"mailid": mail_id, "rcpt": smart_str(self.msgrcpt.rid.email)}
response = self.client.post(url, data, format="json")
self.assertEqual(response.status_code, 204)
self.msgrcpt.refresh_from_db()
self.assertEqual(self.msgrcpt.rs, "D")
def test_delete_selfservice(self):
self.client.logout()
mail_id = smart_str(self.msgrcpt.mail.mail_id)
url = reverse("v2:amavis-quarantine-delete", args=[mail_id])
data = {"mailid": mail_id, "rcpt": smart_str(self.msgrcpt.rid.email)}
response = self.client.post(url, data, format="json")
self.assertEqual(response.status_code, 403)
self.set_global_parameter("self_service", True)
data["secret_id"] = smart_str(self.msgrcpt.mail.secret_id)
response = self.client.post(url, data, format="json")
self.assertEqual(response.status_code, 204)
self.msgrcpt.refresh_from_db()
self.assertEqual(self.msgrcpt.rs, "D")
def test_delete_selection(self):
mail_id = smart_str(self.msgrcpt.mail.mail_id)
url = reverse("v2:amavis-quarantine-delete-selection")
data = {
"selection": [
{"mailid": mail_id, "rcpt": smart_str(self.msgrcpt.rid.email)}
]
}
response = self.client.post(url, data, format="json")
self.assertEqual(response.status_code, 204)
self.msgrcpt.refresh_from_db()
self.assertEqual(self.msgrcpt.rs, "D")
@mock.patch("socket.socket")
def test_release(self, mock_socket):
mock_socket.return_value.recv.return_value = b"250 1234 Ok\r\n"
mail_id = smart_str(self.msgrcpt.mail.mail_id)
url = reverse("v2:amavis-quarantine-release", args=[mail_id])
data = {"mailid": mail_id, "rcpt": smart_str(self.msgrcpt.rid.email)}
response = self.client.post(url, data, format="json")
self.assertEqual(response.status_code, 200)
self.msgrcpt.refresh_from_db()
self.assertEqual(self.msgrcpt.rs, "R")
@mock.patch("socket.socket")
def test_release_selfservice(self, mock_socket):
"""Test release view."""
mock_socket.return_value.recv.return_value = b"250 1234 Ok\r\n"
self.client.logout()
mail_id = smart_str(self.msgrcpt.mail.mail_id)
url = reverse("v2:amavis-quarantine-release", args=[mail_id])
self.set_global_parameter("self_service", True)
# Missing rcpt -> fails
data = {"mailid": mail_id, "secret_id": "1234"}
resp = self.client.post(url, data, format="json")
self.assertEqual(resp.status_code, 403)
# Wrong secret_id -> fails
data["rcpt"] = smart_str(self.msgrcpt.rid.email)
resp = self.client.post(url, data, format="json")
self.assertEqual(resp.status_code, 403)
# Request mode
data["secret_id"] = smart_str(self.msgrcpt.mail.secret_id)
resp = self.client.post(url, data, format="json")
self.assertEqual(resp.status_code, 200)
self.msgrcpt.refresh_from_db()
self.assertEqual(self.msgrcpt.rs, "p")
# Direct release mode
self.set_global_parameter("user_can_release", True)
resp = self.client.post(url, data, format="json")
self.assertEqual(resp.status_code, 200)
self.msgrcpt.refresh_from_db()
self.assertEqual(self.msgrcpt.rs, "R")
def test_release_request(self):
"""Test release request mode."""
user = core_models.User.objects.get(username="user@test.com")
self.client.force_authenticate(user)
mail_id = smart_str(self.msgrcpt.mail.mail_id)
url = reverse("v2:amavis-quarantine-release", args=[mail_id])
data = {"mailid": mail_id, "rcpt": smart_str(self.msgrcpt.rid.email)}
response = self.client.post(url, data, format="json")
self.assertEqual(response.status_code, 200)
self.msgrcpt.refresh_from_db()
self.assertEqual(self.msgrcpt.rs, "p")
# Send notification to admins
call_command("amnotify")
self.assertEqual(len(mail.outbox), 1)
def _test_mark_selection(self, action, status):
"""Mark message common code."""
mail_id = smart_str(self.msgrcpt.mail.mail_id)
url = reverse("v2:amavis-quarantine-mark-selection")
data = {
"selection": [
{"mailid": mail_id, "rcpt": smart_str(self.msgrcpt.rid.email)}
],
"type": action,
}
response = self.client.post(url, data, format="json")
self.assertEqual(response.status_code, 204)
queue = django_rq.get_queue("modoboa")
worker = SimpleWorker([queue], connection=queue.connection)
worker.work(burst=True)
self.msgrcpt.refresh_from_db()
self.assertEqual(self.msgrcpt.rs, status)
self.msgrcpt.rs = " "
self.msgrcpt.save(update_fields=["rs"])
self.set_global_parameter("sa_is_local", False)
response = self.client.post(url, data, format="json")
self.assertEqual(response.status_code, 204)
worker.work(burst=True)
self.msgrcpt.refresh_from_db()
self.assertEqual(self.msgrcpt.rs, status)
def test_mark_as_ham(self):
"""Test mark_as_ham view."""
self._test_mark_selection("ham", "H")
# Check domain level learning
self.set_global_parameter("domain_level_learning", True)
data = {
"selection": [
{
"rcpt": smart_str(self.msgrcpt.rid.email),
"mailid": smart_str(self.msgrcpt.mail.mail_id),
},
],
"type": "ham",
"database": "domain",
}
url = reverse("v2:amavis-quarantine-mark-selection")
response = self.client.post(url, data, format="json")
self.assertEqual(response.status_code, 204)
# Check user level learning
self.set_global_parameter("user_level_learning", True)
data["database"] = "user"
response = self.client.post(url, data, format="json")
self.assertEqual(response.status_code, 204)
def test_mark_as_spam(self):
"""Test mark_as_spam view."""
self._test_mark_selection("spam", "S")
def test_manual_learning_as_user(self):
"""Test learning when connected as a simple user."""
user = core_models.User.objects.get(username="user@test.com")
self.client.force_authenticate(user)
mail_id = smart_str(self.msgrcpt.mail.mail_id)
data = {
"selection": [
{"mailid": mail_id, "rcpt": smart_str(self.msgrcpt.rid.email)}
],
"type": "ham",
}
url = reverse("v2:amavis-quarantine-mark-selection")
response = self.client.post(url, data, format="json")
self.assertEqual(response.status_code, 200)
self.assertEqual(response.json(), {"status": "ok"})
self.set_global_parameter("user_level_learning", True)
self._test_mark_selection("ham", "H")
class PolicyViewSetTestCase(ModoAPITestCase):
databases = "__all__"
@classmethod
def setUpTestData(cls): # NOQA:N802
"""Create test data."""
super().setUpTestData()
admin_factories.populate_database()
def test_get_policy(self):
domain = admin_models.Domain.objects.get(name="test.com")
url = reverse("v2:amavis-policy-detail", args=[domain.pk])
resp = self.client.get(url)
self.assertEqual(resp.status_code, 200)
def test_update_policy(self):
domain = admin_models.Domain.objects.get(name="test.com")
data = {"bypass_virus_checks": "Y", "spam_tag2_level": 6}
url = reverse("v2:amavis-policy-detail", args=[domain.pk])
resp = self.client.patch(url, data, format="json")
self.assertEqual(resp.status_code, 200)
p = models.Policy.objects.get(users__email="@test.com")
self.assertEqual(p.bypass_virus_checks, data["bypass_virus_checks"])
self.assertEqual(p.spam_tag2_level, data["spam_tag2_level"])
+11
View File
@@ -0,0 +1,11 @@
"""Amavis urls."""
from rest_framework import routers
from modoboa.amavis import viewsets
router = routers.SimpleRouter()
router.register(r"quarantine", viewsets.QuarantineViewSet, basename="amavis-quarantine")
router.register(r"policies", viewsets.PolicyViewSet, basename="amavis-policy")
urlpatterns = router.urls
+105
View File
@@ -0,0 +1,105 @@
"""A collection of utility functions for working with the Amavis database."""
import chardet
from django.conf import settings
from django.db.models.expressions import Func
from django.utils.encoding import (
smart_bytes as django_smart_bytes,
smart_str as django_smart_str,
)
"""
Byte fields for text data are EVIL.
MySQL uses `varbyte` fields which mysqlclient client maps to `str` (Py2) or
`bytes` (Py3), Djangos smart_* functions work as expected.
PostgreSQL uses `bytea` fields which psycopg2 maps to `memoryview`,
Djangos smart_* functions don't work as expected, you must call `tobytes()` on
the memoryview for them to work.
For convenience use smart_bytes and smart_str from this file in modoboa.amavis
to avoid any headaches.
"""
def smart_bytes(value, *args, **kwargs):
if isinstance(value, memoryview):
value = value.tobytes()
return django_smart_bytes(value, *args, **kwargs)
def smart_str(value, *args, **kwargs):
if isinstance(value, memoryview):
value = value.tobytes()
return django_smart_str(value, *args, **kwargs)
def fix_utf8_encoding(value):
"""Fix utf-8 strings that contain utf-8 escaped characters.
msgs.from_addr and msgs.subject potentialy contain badly escaped utf-8
characters, this utility function fixes that and should be used anytime
these fields are accesses.
Didn't even know the raw_unicode_escape encoding existed :)
https://docs.python.org/3/library/codecs.html?highlight=raw_unicode_escape#python-specific-encodings
"""
assert isinstance(value, str), "value should be of type str"
if len(value) == 0:
# short circuit for empty strings
return ""
bytes_value = value.encode("raw_unicode_escape")
try:
value = bytes_value.decode("utf-8")
except UnicodeDecodeError:
encoding = chardet.detect(bytes_value)
try:
value = bytes_value.decode(encoding["encoding"], "replace")
except (TypeError, UnicodeDecodeError):
# ??? use the original value, we've done our best to try and
# convert it to a clean utf-8 string.
pass
return value
class ConvertFrom(Func):
"""Convert a binary value to a string.
Calls the database specific function to convert a binary value to a string
using the encoding set in AMAVIS_DEFAULT_DATABASE_ENCODING.
"""
"""PostgreSQL implementation.
See https://www.postgresql.org/docs/9.3/static/functions-string.html#FUNCTIONS-STRING-OTHER""" # NOQA:E501
function = "convert_from"
arity = 1
template = (
f"%(function)s(%(expressions)s, '{settings.AMAVIS_DEFAULT_DATABASE_ENCODING}')"
)
def as_mysql(self, compiler, connection):
"""MySQL implementation.
See https://dev.mysql.com/doc/refman/5.5/en/cast-functions.html#function_convert
""" # NOQA:E501
return super().as_sql(
compiler,
connection,
function="CONVERT",
template=f"%(function)s(%(expressions)s USING {settings.AMAVIS_DEFAULT_DATABASE_ENCODING})",
arity=1,
)
def as_sqlite(self, compiler, connection):
"""SQLite implementation.
SQLite has no equivilant function, just return the field."""
return super().as_sql(
compiler,
connection,
template="%(expressions)s",
arity=1,
)
+265
View File
@@ -0,0 +1,265 @@
"""Amavis viewsets."""
from django.http import Http404
from django.shortcuts import get_object_or_404
from django.utils.translation import gettext as _
import django_rq
from rest_framework import filters, mixins, permissions, response, viewsets
from rest_framework.decorators import action
from modoboa.amavis.sql_connector import SQLconnector
from modoboa.lib.paginator import Paginator
from modoboa.lib.permissions import CanViewDomain
from modoboa.admin import models as admin_models
from modoboa.amavis import models, serializers, tasks
from modoboa.amavis.lib import (
AMrelease,
manual_learning_enabled,
SelfServiceAuthentication,
)
from modoboa.amavis.sql_email import SQLemail
from modoboa.amavis.utils import smart_str
from modoboa.parameters import tools as param_tools
SELFSERVICE_ACTIONS = ["retrieve", "headers", "delete", "release"]
def get_user_valid_addresses(user):
"""Retrieve all valid addresses of a user."""
valid_addresses = []
if user.role == "SimpleUsers":
valid_addresses.append(user.email)
try:
mb = admin_models.Mailbox.objects.get(user=user)
except admin_models.Mailbox.DoesNotExist:
pass
else:
valid_addresses += mb.alias_addresses
return valid_addresses
class QuarantineViewSet(viewsets.GenericViewSet):
filter_backends = (filters.OrderingFilter,)
ordering_fields = [
"datetime",
"from_address",
"score",
"subject",
"to_address",
"type",
]
permission_classes = (permissions.IsAuthenticated,)
def get_serializer_class(self):
if self.action == "retrieve":
return serializers.MessageSerializer
if self.action == "headers":
return serializers.MessageHeadersSerializer
if self.action == "mark_selection":
return serializers.MarkMessageSelectionSerializer
if self.action in ["release_selection", "delete_selection"]:
return serializers.MessageSelectionSerializer
if self.action in ["delete", "release"]:
return serializers.MessageIdentifierSerializer
return serializers.PaginatedMessageListSerializer
def get_authenticators(self):
result = [auth() for auth in self.authentication_classes]
if self.request:
action = self.action_map.get(self.request.method.lower())
if action in SELFSERVICE_ACTIONS:
result = [SelfServiceAuthentication()] + result
return result
def get_permissions(self):
if self.request.auth == "selfservice" and self.action in SELFSERVICE_ACTIONS:
return []
return super().get_permissions()
def list(self, request):
ordering = request.GET.get("ordering")
connector = SQLconnector(user=request.user, ordering=ordering)
try:
page_size = int(request.GET.get("page_size"))
except (TypeError, ValueError):
page_size = request.user.parameters.get_value("messages_per_page")
total = connector.messages_count(request)
paginator = Paginator(total, page_size)
page_num = int(request.GET.get("page", 1))
page = paginator.getpage(page_num)
if not page:
serializer = self.get_serializer(
{
"count": 0,
"first_index": 0,
"last_index": 0,
"prev_page": None,
"next_page": None,
"results": [],
}
)
return response.Response(serializer.data)
email_list = connector.fetch(page.id_start, page.id_stop)
serializer = self.get_serializer(
{
"count": total,
"first_index": page_num * page_size,
"last_index": (page_num * page_size) + len(email_list),
"prev_page": page.previous_page_number if page.has_previous else None,
"next_page": page.next_page_number if page.has_next else None,
"results": email_list,
}
)
return response.Response(serializer.data)
def retrieve(self, request, pk):
rcpt = request.GET.get("rcpt")
if rcpt is None:
return response.Response({"error": _("Invalid request")}, status=400)
if request.user:
if request.user.email == rcpt:
SQLconnector().set_msgrcpt_status(rcpt, pk, "V")
elif hasattr(request.user, "mailbox"):
mb = request.user.mailbox
if rcpt == mb.full_address or rcpt in mb.alias_addresses:
SQLconnector().set_msgrcpt_status(rcpt, pk, "V")
mail = SQLemail(pk.encode("ascii"), dformat="plain")
serializer = self.get_serializer(mail)
return response.Response(serializer.data)
@action(methods=["get"], detail=True)
def headers(self, request, pk):
email = SQLemail(pk.encode("ascii"))
headers = []
for name in email.msg.keys():
headers.append({"name": name, "value": email.get_header(email.msg, name)})
serializer = self.get_serializer({"headers": headers})
return response.Response(serializer.data)
def _release_selection(self, request, selection):
connector = SQLconnector()
valid_addresses = None
if request.user:
valid_addresses = get_user_valid_addresses(request.user)
msgrcpts = []
for item in selection:
if valid_addresses and item["rcpt"] not in valid_addresses:
continue
msgrcpts += [
(
item["mailid"],
connector.get_recipient_message(item["rcpt"], item["mailid"]),
)
]
if (
not request.user or request.user.role == "SimpleUsers"
) and not param_tools.get_global_parameter("user_can_release"):
for i, msgrcpt in msgrcpts:
connector.set_msgrcpt_status(smart_str(msgrcpt.rid.email), i, "p")
return response.Response({"status": "pending"})
amr = AMrelease()
error = None
for mid, rcpt in msgrcpts:
# we can't use the .mail relation on rcpt because it leads to
# an error on Postgres (memoryview pickle error).
mail = models.Msgs.objects.get(pk=mid.encode("ascii"))
result = amr.sendreq(mid, mail.secret_id, rcpt.rid.email)
if result:
connector.set_msgrcpt_status(smart_str(rcpt.rid.email), mid, "R")
else:
error = result
break
if error:
return response.Response({"status": error})
return response.Response({"status": "released"})
@action(methods=["post"], detail=False)
def release_selection(self, request):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
return self._release_selection(request, serializer.validated_data["selection"])
@action(methods=["post"], detail=True)
def release(self, request, pk):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
return self._release_selection(request, [serializer.validated_data])
def _delete_selection(self, request, selection):
connector = SQLconnector()
valid_addresses = None
if request.user:
valid_addresses = get_user_valid_addresses(request.user)
for item in selection:
if valid_addresses and item["rcpt"] not in valid_addresses:
continue
connector.set_msgrcpt_status(item["rcpt"], item["mailid"], "D")
return response.Response(status=204)
@action(methods=["post"], detail=False)
def delete_selection(self, request):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
return self._delete_selection(request, serializer.validated_data["selection"])
@action(methods=["post"], detail=True)
def delete(self, request, pk):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
return self._delete_selection(request, [serializer.validated_data])
@action(methods=["post"], detail=False)
def mark_selection(self, request):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
if not manual_learning_enabled(request.user):
return response.Response({"status": "ok"})
recipient_db = serializer.validated_data.get("database")
if not recipient_db:
recipient_db = "user" if request.user.role == "SimpleUsers" else "global"
queue = django_rq.get_queue("modoboa")
queue.enqueue(
tasks.manual_learning,
request.user.pk,
serializer.validated_data["type"],
serializer.validated_data["selection"],
recipient_db,
)
return response.Response(status=204)
class PolicyViewSet(
mixins.RetrieveModelMixin, mixins.UpdateModelMixin, viewsets.GenericViewSet
):
permission_classes = (permissions.IsAuthenticated, CanViewDomain)
serializer_class = serializers.PolicySerializer
def get_queryset(self):
domains = [
f"@{name}"
for name in admin_models.Domain.objects.get_for_admin(
self.request.user
).values_list("name", flat=True)
]
return models.Policy.objects.filter(users__email__in=domains)
def get_object(self):
"""Return the object the view is displaying."""
domain = get_object_or_404(admin_models.Domain, pk=self.kwargs["pk"])
queryset = self.filter_queryset(self.get_queryset())
obj = queryset.filter(users__email=f"@{domain.name}").first()
if obj is None:
raise Http404
# May raise a permission denied
self.check_object_permissions(self.request, obj)
return obj
+4 -2
View File
@@ -664,9 +664,11 @@ class NotificationSerializer(serializers.Serializer):
"""Serializer used to render a notification."""
id = serializers.CharField()
url = serializers.CharField(required=False)
text = serializers.CharField()
level = serializers.CharField()
color = serializers.CharField()
target = serializers.CharField()
url = serializers.CharField(required=False)
counter = serializers.IntegerField(required=False)
class ModoboaApplicationSerializer(serializers.Serializer):
+5 -5
View File
@@ -32,11 +32,6 @@ urlpatterns += [
views.ComponentsInformationAPIView.as_view(),
name="components_information",
),
path(
"admin/notifications/",
views.NotificationsAPIView.as_view(),
name="notifications",
),
path(
"admin/news_feed/",
views.NewsFeedAPIView.as_view(),
@@ -48,5 +43,10 @@ urlpatterns += [
name="statistics",
),
path("capabilities/", views.CapabilitiesAPIView.as_view(), name="capabilities"),
path(
"notifications/",
views.NotificationsAPIView.as_view(),
name="notifications",
),
path("theme/", views.ThemeAPIView.as_view(), name="theme"),
]
+3 -1
View File
@@ -142,7 +142,9 @@ class PasswordResetConfirmView(APIView):
class ComponentsInformationAPIView(APIView):
"""Retrieve information about installed components."""
permission_classes = [permissions.IsAuthenticated, IsSuperUser]
permission_classes = [
permissions.IsAuthenticated,
]
throttle_classes = [UserLesserDdosUser]
@extend_schema(responses=serializers.ModoboaComponentSerializer(many=True))
+6 -2
View File
@@ -125,7 +125,9 @@ def check_for_new_versions(sender, include_all: bool, **kwargs) -> list:
{
"id": "newversionavailable",
"text": _("One or more updates are available"),
"level": "info",
"color": "info",
"url": "/admin/information",
"target": "admin",
}
]
elif include_all:
@@ -137,7 +139,9 @@ def check_for_new_versions(sender, include_all: bool, **kwargs) -> list:
"id": "deprecatedpasswordscheme",
"text": _("You are still using a deprecated password scheme (%s)")
% hasher.name,
"level": "warning",
"color": "warning",
"url": "/admin/information",
"target": "admin",
}
]
return result
+3
View File
@@ -111,6 +111,9 @@ def get_capabilities():
if is_rspamd_installed:
rspamd_options = get_rspamd_options()
capabilities.update({"rspamd": rspamd_options})
# Amavis
if "modoboa.amavis" in settings.MODOBOA_APPS:
capabilities.update({"amavis": {}})
# IMAP migration
if "modoboa.imap_migration" in settings.MODOBOA_APPS:
capabilities.update({"imap_migration": {}})
+1 -1
View File
@@ -334,7 +334,7 @@ def split_mailbox(mailbox, return_extension=False):
return (local_part, domain, extension)
def decode(value_bytes, encoding, append_to_error=""):
def decode(value_bytes: bytes, encoding: str, append_to_error: str = "") -> str:
"""Try to decode the given string."""
assert isinstance(value_bytes, bytes), "value_bytes should be of type bytes"
if len(value_bytes) == 0:
+7
View File
@@ -166,3 +166,10 @@ class CanCreateDomain(permissions.BasePermission):
def has_permission(self, request, view):
return request.user.has_perm("admin.add_domain")
class CanViewDomain(permissions.BasePermission):
"""Permissions class to allow users with view_domain right."""
def has_permission(self, request, view):
return request.user.has_perm("admin.view_domain")
+29
View File
@@ -0,0 +1,29 @@
"""Custom test runner."""
from django.apps import apps
from django.test.runner import DiscoverRunner
class UnManagedModelTestRunner(DiscoverRunner):
"""
Test runner that automatically makes all unmanaged models in your Django
project managed for the duration of the test run.
Many thanks to the Caktus Group: http://bit.ly/1N8TcHW
"""
unmanaged_models = []
def setup_test_environment(self, *args, **kwargs):
"""Mark amavis models as managed during testing
During database setup migrations are only run for managed models"""
for m in apps.get_models():
if m._meta.app_label == "amavis":
self.unmanaged_models.append(m)
m._meta.managed = True
super().setup_test_environment(*args, **kwargs)
def teardown_test_environment(self, *args, **kwargs):
"""Revert modoboa_amavis models to unmanaged"""
super().teardown_test_environment(*args, **kwargs)
for m in self.unmanaged_models:
m._meta.managed = False
+57 -49
View File
@@ -14,14 +14,12 @@ msgstr ""
"POT-Creation-Date: 2025-08-28 09:41+0200\n"
"PO-Revision-Date: 2020-05-06 11:16+0000\n"
"Last-Translator: Antoine Nguyen <tonio@ngyn.org>\n"
"Language-Team: Czech (Czech Republic) (http://www.transifex.com/tonio/"
"modoboa/language/cs_CZ/)\n"
"Language-Team: Czech (Czech Republic) (http://www.transifex.com/tonio/modoboa/language/cs_CZ/)\n"
"Language: cs_CZ\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=4; plural=(n == 1 && n % 1 == 0) ? 0 : (n >= 2 && n "
"<= 4 && n % 1 == 0) ? 1: (n % 1 != 0 ) ? 2 : 3;\n"
"Plural-Forms: nplurals=4; plural=(n == 1 && n % 1 == 0) ? 0 : (n >= 2 && n <= 4 && n % 1 == 0) ? 1: (n % 1 != 0 ) ? 2 : 3;\n"
#: admin/api/v1/serializers.py:39
msgid ""
@@ -188,11 +186,11 @@ msgstr "Platné MX záznamy"
#: admin/app_settings.py:37
msgid ""
"A list of IP or network address every MX record should match. A warning will "
"be sent if a record does not respect it."
"A list of IP or network address every MX record should match. A warning will"
" be sent if a record does not respect it."
msgstr ""
"Seznam IP nebo síťových adres, které by každý MX záznam měl obsahovat. Pokud "
"toto záznam nerespektuje, bude odesláno varování."
"Seznam IP nebo síťových adres, které by každý MX záznam měl obsahovat. Pokud"
" toto záznam nerespektuje, bude odesláno varování."
#: admin/app_settings.py:47
msgid "New domains must use authorized MX(s)"
@@ -385,7 +383,8 @@ msgid "Automatic domain/mailbox creation"
msgstr "Automatické vytvoření domény/schránky"
#: admin/app_settings.py:221
msgid "Create a domain and a mailbox when an account is automatically created."
msgid ""
"Create a domain and a mailbox when an account is automatically created."
msgstr "Při založení účtu automaticky vytvořit doménu a schránku."
#: admin/app_settings.py:230
@@ -728,8 +727,8 @@ msgid ""
"and ask them to unlist detected IP address(es)."
msgstr ""
"Reputace domény bude ovlivněna, a je možné, že e-maily přicházející z ní "
"jsou považovány za spam. Měli byste kontaktovat tyto poskytovatele a požádat "
"je o odstranění IP adresy (adres) ze seznamu."
"jsou považovány za spam. Měli byste kontaktovat tyto poskytovatele a požádat"
" je o odstranění IP adresy (adres) ze seznamu."
#: admin/templates/admin/notifications/domain_invalid_mx.html:3
#, python-format
@@ -776,14 +775,16 @@ msgstr "Obecné"
#: autoreply/app_settings.py:18
#, fuzzy
#| msgid "Timeout in seconds between two auto-replies to the same recipient"
#| msgid ""
#| "Timeout in seconds between two auto-replies to the same recipient"
msgid "Period between two auto-replies"
msgstr ""
"Interval v sekundách mezi dvěmi automatickými odpověďmi stejnému příjemci"
#: autoreply/app_settings.py:20
#, fuzzy
#| msgid "Timeout in seconds between two auto-replies to the same recipient"
#| msgid ""
#| "Timeout in seconds between two auto-replies to the same recipient"
msgid ""
"Number of days to wait before sending a new auto-reply to the same recipient"
msgstr ""
@@ -1015,7 +1016,8 @@ msgstr "Neplatný počet cyklů"
msgid "This code is invalid"
msgstr ""
#: core/api/v2/serializers.py:503 core/views/auth.py:194 core/views/auth.py:247
#: core/api/v2/serializers.py:503 core/views/auth.py:194
#: core/views/auth.py:247
msgid "Please use the following code to recover your Modoboa password: {}"
msgstr ""
@@ -1071,8 +1073,8 @@ msgid ""
"Number of rounds to use (only used by sha256crypt and sha512crypt). Must be "
"between 1000 and 999999999, inclusive."
msgstr ""
"Počet cyklů (použije se pouze u sha256crypt a sha512crypt). Hodnota musí být "
"mezi 1000 a 999999999 včetně."
"Počet cyklů (použije se pouze u sha256crypt a sha512crypt). Hodnota musí být"
" mezi 1000 a 999999999 včetně."
#: core/app_settings.py:73
msgid "Update password scheme at login"
@@ -1216,8 +1218,8 @@ msgstr "Správcovské skupiny"
#: core/app_settings.py:239
msgid ""
"Members of those LDAP Posix groups will be created as domain administrators. "
"Use ';' characters to separate groups."
"Members of those LDAP Posix groups will be created as domain administrators."
" Use ';' characters to separate groups."
msgstr ""
"Členové těchto LDAP Posix skupin budou automaticky vytvořeni jako správci "
"domény. Pro oddělení skupin použijte ';'."
@@ -1406,13 +1408,15 @@ msgstr "Zobrazit vlastní RSS zdroj distributorům a správcům domény"
#: core/app_settings.py:506
#, fuzzy
#| msgid "Display custom RSS feed to resellers and domain administrators"
#| msgid ""
#| "Display custom RSS feed to resellers and domain administrators"
msgid "Display custom RSS feed to super admins"
msgstr "Zobrazit vlastní RSS zdroj distributorům a správcům domény"
#: core/app_settings.py:509
#, fuzzy
#| msgid "Display custom RSS feed to resellers and domain administrators"
#| msgid ""
#| "Display custom RSS feed to resellers and domain administrators"
msgid "Display custom RSS feed also to super administrators"
msgstr "Zobrazit vlastní RSS zdroj distributorům a správcům domény"
@@ -1532,8 +1536,8 @@ msgstr "Počet dnů pro neaktivní účet"
#: core/app_settings.py:686
msgid ""
"Allow the administrator to set a threshold (in days) beyond which an account "
"is considered inactive if the user hasn't logged in"
"Allow the administrator to set a threshold (in days) beyond which an account"
" is considered inactive if the user hasn't logged in"
msgstr ""
#: core/app_settings.py:695
@@ -1542,8 +1546,8 @@ msgstr "Počet dnů pro neaktivní účet"
#: core/app_settings.py:698
msgid ""
"An account with a last login date greater than this threshold (in days) will "
"be considered as inactive"
"An account with a last login date greater than this threshold (in days) will"
" be considered as inactive"
msgstr ""
"Účet s datem posledního přihlášení starším než práh (ve dnech) bude "
"považován za neaktivní"
@@ -1619,8 +1623,9 @@ msgstr ""
#: core/checks.py:34
msgid ""
"Visit : https://modoboa.readthedocs.io/en/latest/manual_installation/"
"dovecot.html#dovecot-oauth2"
"Visit : "
"https://modoboa.readthedocs.io/en/latest/manual_installation/dovecot.html#dovecot-"
"oauth2"
msgstr ""
#: core/checks.py:41
@@ -1631,8 +1636,9 @@ msgstr ""
#: core/checks.py:45
msgid ""
"Visit : https://modoboa.readthedocs.io/en/latest/manual_installation/"
"radicale.html#radicale-oauth2"
"Visit : "
"https://modoboa.readthedocs.io/en/latest/manual_installation/radicale.html#radicale-"
"oauth2"
msgstr ""
#: core/constants.py:6
@@ -2240,10 +2246,11 @@ msgstr "Doménové aliasy"
#: limits/app_settings.py:52
#, fuzzy
#| msgid "Maximum number of allowed domain aliases for a new administrator"
#| msgid ""
#| "Maximum number of allowed domain aliases for a new administrator"
msgid ""
"Maximum number of allowed domain aliases for a new administrator. (0 to deny "
"any creation, -1 to allow unlimited creations)"
"Maximum number of allowed domain aliases for a new administrator. (0 to deny"
" any creation, -1 to allow unlimited creations)"
msgstr "Maximální povolený počet doménových aliasů (nastavení nového správce)"
#: limits/app_settings.py:64
@@ -2296,13 +2303,14 @@ msgstr ""
#| msgid ""
#| "Maximum number of allowed domain administrators for a new administrator"
msgid ""
"Maximum number of allowed domain administrators for a new domain. (0 to deny "
"any creation, -1 to allow unlimited creations)"
"Maximum number of allowed domain administrators for a new domain. (0 to deny"
" any creation, -1 to allow unlimited creations)"
msgstr "Maximální povolený počet správců domény (nastavení nového správce)"
#: limits/app_settings.py:126
#, fuzzy
#| msgid "Maximum number of allowed domain aliases for a new administrator"
#| msgid ""
#| "Maximum number of allowed domain aliases for a new administrator"
msgid ""
"Maximum number of allowed domain aliases for a new domain. (0 to deny any "
"creation, -1 to allow unlimited creations)"
@@ -2320,8 +2328,8 @@ msgstr "Maximální povolený počet schránek (nastavení nového správce)"
#, fuzzy
#| msgid "Maximum number of allowed aliases for a new administrator"
msgid ""
"Maximum number of allowed aliases for a new domain. (0 to deny any creation, "
"-1 to allow unlimited creations)"
"Maximum number of allowed aliases for a new domain. (0 to deny any creation,"
" -1 to allow unlimited creations)"
msgstr "Maximální povolený počet aliasů (nastavení nového správce)"
#: limits/apps.py:16
@@ -2567,8 +2575,8 @@ msgid ""
"Generate a new document only when a new account is created. If set to no, a "
"new document will be created each time a password is updated."
msgstr ""
"Vytvářet nové dokumenty pouze při vytvoření účtu. Je-li nastaveno na hodnotu "
"ne, bude nový dokument vytvořen pokaždé, když dojde ke změne hesla."
"Vytvářet nové dokumenty pouze při vytvoření účtu. Je-li nastaveno na hodnotu"
" ne, bude nový dokument vytvořen pokaždé, když dojde ke změne hesla."
#: pdfcredentials/app_settings.py:84
msgid "Customization options"
@@ -2696,8 +2704,7 @@ msgid ""
"your contacts.\n"
msgstr ""
"\n"
"Zde si kdykoliv můžete prohlédnout své emaily, vytvořit filtry nebo "
"spravovat Vaše kontakty.\n"
"Zde si kdykoliv můžete prohlédnout své emaily, vytvořit filtry nebo spravovat Vaše kontakty.\n"
#: pdfcredentials/documents.py:126
msgid "Please change your password!"
@@ -2725,7 +2732,8 @@ msgstr "PDF přístupové údaje"
#: pdfcredentials/lib.py:29
#, fuzzy
#| msgid "Failed to create the directory that will contain PDF documents (%s)"
#| msgid ""
#| "Failed to create the directory that will contain PDF documents (%s)"
msgid "Can't write to selected directory to store PDF documents"
msgstr "Vytváření adresáře pro uložení PDF dokumentů (%s) selhalo "
@@ -2807,8 +2815,8 @@ msgstr ""
#: rspamd/app_settings.py:21
msgid ""
"Absolute path of the file which contains paths to DKIM private keys. Must be "
"readable by _rspamd group or user."
"Absolute path of the file which contains paths to DKIM private keys. Must be"
" readable by _rspamd group or user."
msgstr ""
#: rspamd/app_settings.py:30
@@ -2827,8 +2835,8 @@ msgstr ""
#: rspamd/app_settings.py:53
msgid ""
"Location of the rspamd dashboard. Can either be a relative URL (eg. '/"
"rspamd') or a full URL (eg. 'https://rspamd.domain.tld/').Only use for "
"Location of the rspamd dashboard. Can either be a relative URL (eg. "
"'/rspamd') or a full URL (eg. 'https://rspamd.domain.tld/').Only use for "
"guidance on the Super-Admin dashboard."
msgstr ""
@@ -3095,7 +3103,8 @@ msgid ""
"To initiate the password reset process for your %(username)s Modoboa "
"account, click the link below:"
msgstr ""
"Klikněte na odkaz níže pro resetování hesla vašeho Modoboa účtu %(username)s:"
"Klikněte na odkaz níže pro resetování hesla vašeho Modoboa účtu "
"%(username)s:"
#: templates/registration/password_reset_email.html:10
#: templates/registration/password_reset_email_v2.html:10
@@ -3137,8 +3146,8 @@ msgstr "Původní heslo"
#: templates/registration/twofactor_code_verify.html:35
msgid ""
"Enter the code from the two-factor app on your mobile device. If you've lost "
"your device, you may enter one of your recovery codes."
"Enter the code from the two-factor app on your mobile device. If you've lost"
" your device, you may enter one of your recovery codes."
msgstr ""
#: templates/registration/twofactor_code_verify.html:42
@@ -3396,6 +3405,5 @@ msgid "Attachment is too big (limit: %s)"
msgstr "Příloha je příliš velká (omezení: %s)"
#, fuzzy, python-brace-format
#~| msgid "Connection to IMAP server failed: %s"
#~ msgid "Connection to IMAP server failed: {error}"
#~ msgstr "Spojení se serverem IMAP selhalo: %s"
+4 -2
View File
@@ -174,7 +174,8 @@ msgstr "Dieses Feld erlaubt nur gültige IP-Adressen (oder Netzwerke)"
#: admin/api/v2/serializers.py:292
msgid "Please disable imap migration before disabling this option."
msgstr "Bitte IMAP Migration deaktivieren bevor Sie diese Option deaktivieren."
msgstr ""
"Bitte IMAP Migration deaktivieren bevor Sie diese Option deaktivieren."
#: admin/api/v2/serializers.py:305
msgid "Define at least one authorized network / address"
@@ -427,7 +428,8 @@ msgstr "Konto Import fehlgeschlagen (%s): ungültiger Quota-Wert"
#: admin/lib.py:121
msgid "You are not allowed to import domains"
msgstr "Sie verfügen nicht über ausreichend Rechte, um Domains zu importieren."
msgstr ""
"Sie verfügen nicht über ausreichend Rechte, um Domains zu importieren."
#: admin/lib.py:130
msgid "You are not allowed to import domain aliases."
+72 -63
View File
@@ -12,8 +12,7 @@ msgstr ""
"POT-Creation-Date: 2025-08-28 09:41+0200\n"
"PO-Revision-Date: 2017-10-12 19:37+0000\n"
"Last-Translator: Kostas Moumouris <moumouriskostas@gmail.com>\n"
"Language-Team: Greek (Greece) (http://www.transifex.com/tonio/modoboa/"
"language/el_GR/)\n"
"Language-Team: Greek (Greece) (http://www.transifex.com/tonio/modoboa/language/el_GR/)\n"
"Language: el_GR\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -198,8 +197,8 @@ msgstr "Έγκυρα MXς"
#: admin/app_settings.py:37
msgid ""
"A list of IP or network address every MX record should match. A warning will "
"be sent if a record does not respect it."
"A list of IP or network address every MX record should match. A warning will"
" be sent if a record does not respect it."
msgstr ""
"Μια λίστα από IP ή δικτυακές διευθύνσεις που κάθε εγράφη MX πρέπει να "
"ταιριάζει. "
@@ -213,8 +212,8 @@ msgid ""
"Prevent the creation of a new domain if its MX record does not use one of "
"the defined addresses."
msgstr ""
"Αποτροπή δημιουργίας νέου domain, εάν η εγράφη MX χρησιμοποιεί μια από τις "
"είδη ορισμένες διευθύνσεις."
"Αποτροπή δημιουργίας νέου domain, εάν η εγράφη MX χρησιμοποιεί μια από τις"
" είδη ορισμένες διευθύνσεις."
#: admin/app_settings.py:59
#, fuzzy
@@ -364,7 +363,8 @@ msgid ""
"value specified. A value of 0 means no quota."
msgstr ""
"Προκαθορισμένο quota γραμματοκιβωτίου (σε MB) που εφαρμόζεται στα νέα "
"domains χωρίς προκαθορισμένες τιμές. Μια τιμή 0 σημαίνει ότι δεν έχει quota. "
"domains χωρίς προκαθορισμένες τιμές. Μια τιμή 0 σημαίνει ότι δεν έχει quota."
" "
#: admin/app_settings.py:197
#, fuzzy
@@ -385,14 +385,16 @@ msgstr "Αυτόματη αφαίρεση λογαριασμών"
#: admin/app_settings.py:209
msgid "When a mailbox is removed, also remove the associated account"
msgstr ""
"Όταν αφαιρείται ένα γραμματοκιβώτιο, να αφαιρείται και ο σχετικός λογαριασμός"
"Όταν αφαιρείται ένα γραμματοκιβώτιο, να αφαιρείται και ο σχετικός "
"λογαριασμός"
#: admin/app_settings.py:218
msgid "Automatic domain/mailbox creation"
msgstr "Αυτόματη δημιουργία domain/γραμματοκιβωτίων"
#: admin/app_settings.py:221
msgid "Create a domain and a mailbox when an account is automatically created."
msgid ""
"Create a domain and a mailbox when an account is automatically created."
msgstr ""
"Δημιουργία domain και γραμματοκιβωτίου κατά την αυτόματη δημιουργία "
"λογαριασμού"
@@ -675,8 +677,8 @@ msgstr ""
#| msgid "Default mailbox quota cannot be greater than domain quota"
msgid "{}: default mailbox quota cannot be greater than domain quota"
msgstr ""
"Το προεπιλεγμένο quota για το γραμματοκιβώτιο δεν πρέπει να είναι μεγαλύτερο "
"από το domain quota. "
"Το προεπιλεγμένο quota για το γραμματοκιβώτιο δεν πρέπει να είναι μεγαλύτερο"
" από το domain quota. "
#: admin/models/domain_alias.py:36
msgid "The alias name"
@@ -739,8 +741,8 @@ msgid ""
msgstr ""
"Η φήμη (reputation) του domain θα επηρεαστεί και υπάρχει πιθανότητα τα "
"μηνύματα ηλεκτρονικού ταχυδρομείου που προέρχονται από αυτό να θεωρούνται "
"ανεπιθύμητα. Θα πρέπει να επικοινωνήσετε με αυτούς τους παροχους και να τους "
"ζητήσετε να σας βγάλουν από τη λίστα ανεπιθύμητων διευθύνσεων IP."
"ανεπιθύμητα. Θα πρέπει να επικοινωνήσετε με αυτούς τους παροχους και να τους"
" ζητήσετε να σας βγάλουν από τη λίστα ανεπιθύμητων διευθύνσεων IP."
#: admin/templates/admin/notifications/domain_invalid_mx.html:3
#, python-format
@@ -789,7 +791,8 @@ msgstr "Γενικά"
#: autoreply/app_settings.py:18
#, fuzzy
#| msgid "Timeout in seconds between two auto-replies to the same recipient"
#| msgid ""
#| "Timeout in seconds between two auto-replies to the same recipient"
msgid "Period between two auto-replies"
msgstr ""
"Χρονικό όριο λήξης σε δευτερόλεπτα μεταξύ δύο αυτόματων απαντήσεων προς τον "
@@ -797,7 +800,8 @@ msgstr ""
#: autoreply/app_settings.py:20
#, fuzzy
#| msgid "Timeout in seconds between two auto-replies to the same recipient"
#| msgid ""
#| "Timeout in seconds between two auto-replies to the same recipient"
msgid ""
"Number of days to wait before sending a new auto-reply to the same recipient"
msgstr ""
@@ -1037,7 +1041,8 @@ msgstr "Λάθος αριθμός επαναλήψεων "
msgid "This code is invalid"
msgstr ""
#: core/api/v2/serializers.py:503 core/views/auth.py:194 core/views/auth.py:247
#: core/api/v2/serializers.py:503 core/views/auth.py:194
#: core/views/auth.py:247
msgid "Please use the following code to recover your Modoboa password: {}"
msgstr ""
@@ -1236,8 +1241,8 @@ msgstr "Χρήση ασφαλής σύνδεσης"
#: core/app_settings.py:221
msgid "Use an SSL/STARTTLS connection to access the LDAP server"
msgstr ""
"Χρησιμοποιήστε μια σύνδεση SSL / STARTTLS για να συνδεθήκατε στον διακομιστή "
"LDAP"
"Χρησιμοποιήστε μια σύνδεση SSL / STARTTLS για να συνδεθήκατε στον διακομιστή"
" LDAP"
#: core/app_settings.py:228
msgid "Active Directory"
@@ -1253,11 +1258,11 @@ msgstr "Groups Διαχειριστών"
#: core/app_settings.py:239
msgid ""
"Members of those LDAP Posix groups will be created as domain administrators. "
"Use ';' characters to separate groups."
"Members of those LDAP Posix groups will be created as domain administrators."
" Use ';' characters to separate groups."
msgstr ""
"Τα μέλη αυτών των LDAP Posix ομάδων χρηστών θα δημιουργηθούν ως διαχειριστές "
"domain. Χρησιμοποιείστε τον χαραχτήρα ';' για να ξεχωρίσετε τις ομάδες."
"Τα μέλη αυτών των LDAP Posix ομάδων χρηστών θα δημιουργηθούν ως διαχειριστές"
" domain. Χρησιμοποιείστε τον χαραχτήρα ';' για να ξεχωρίσετε τις ομάδες."
#: core/app_settings.py:248
msgid "Group type"
@@ -1335,8 +1340,8 @@ msgid ""
"An optional filter string (e.g. '(objectClass=person)'). In order to be "
"valid, it must be enclosed in parentheses."
msgstr ""
"Προαιρετικό φίλτρο (π.χ. '(objectClass=person)'). Για να είναι έγκυρο πρέπει "
"να περικλείεται σε παρενθέσεις."
"Προαιρετικό φίλτρο (π.χ. '(objectClass=person)'). Για να είναι έγκυρο πρέπει"
" να περικλείεται σε παρενθέσεις."
#: core/app_settings.py:339
msgid "User DN template"
@@ -1458,14 +1463,16 @@ msgstr ""
#: core/app_settings.py:506
#, fuzzy
#| msgid "Display custom RSS feed to resellers and domain administrators"
#| msgid ""
#| "Display custom RSS feed to resellers and domain administrators"
msgid "Display custom RSS feed to super admins"
msgstr ""
"Προβολή κατά παραγγελία RSS feed για μεταπωλητές και διαχειριστές τομέα"
#: core/app_settings.py:509
#, fuzzy
#| msgid "Display custom RSS feed to resellers and domain administrators"
#| msgid ""
#| "Display custom RSS feed to resellers and domain administrators"
msgid "Display custom RSS feed also to super administrators"
msgstr ""
"Προβολή κατά παραγγελία RSS feed για μεταπωλητές και διαχειριστές τομέα"
@@ -1588,8 +1595,8 @@ msgstr "Όριο απενεργοποιημένων λογαριασμών "
#: core/app_settings.py:686
msgid ""
"Allow the administrator to set a threshold (in days) beyond which an account "
"is considered inactive if the user hasn't logged in"
"Allow the administrator to set a threshold (in days) beyond which an account"
" is considered inactive if the user hasn't logged in"
msgstr ""
#: core/app_settings.py:695
@@ -1598,8 +1605,8 @@ msgstr "Όριο απενεργοποιημένων λογαριασμών "
#: core/app_settings.py:698
msgid ""
"An account with a last login date greater than this threshold (in days) will "
"be considered as inactive"
"An account with a last login date greater than this threshold (in days) will"
" be considered as inactive"
msgstr "Όριο (σε ημέρες) για να απενεργοποιηθεί ένας Λογαριασμός."
#: core/app_settings.py:707
@@ -1673,8 +1680,9 @@ msgstr ""
#: core/checks.py:34
msgid ""
"Visit : https://modoboa.readthedocs.io/en/latest/manual_installation/"
"dovecot.html#dovecot-oauth2"
"Visit : "
"https://modoboa.readthedocs.io/en/latest/manual_installation/dovecot.html#dovecot-"
"oauth2"
msgstr ""
#: core/checks.py:41
@@ -1685,8 +1693,9 @@ msgstr ""
#: core/checks.py:45
msgid ""
"Visit : https://modoboa.readthedocs.io/en/latest/manual_installation/"
"radicale.html#radicale-oauth2"
"Visit : "
"https://modoboa.readthedocs.io/en/latest/manual_installation/radicale.html#radicale-"
"oauth2"
msgstr ""
#: core/constants.py:6
@@ -1825,7 +1834,8 @@ msgstr ""
#: core/models.py:150
msgid "Failed to update password: LDAP module not installed"
msgstr ""
"Σφάλμα κατά την ενημέρωση του κωδικού: το LDAP module δεν είναι εγκατεστημένο"
"Σφάλμα κατά την ενημέρωση του κωδικού: το LDAP module δεν είναι "
"εγκατεστημένο"
#: core/models.py:185 policyd/core.py:117
msgid "account"
@@ -2300,8 +2310,8 @@ msgstr "Ψευδώνυμα domain"
#: limits/app_settings.py:52
msgid ""
"Maximum number of allowed domain aliases for a new administrator. (0 to deny "
"any creation, -1 to allow unlimited creations)"
"Maximum number of allowed domain aliases for a new administrator. (0 to deny"
" any creation, -1 to allow unlimited creations)"
msgstr ""
"Μέγιστος αριθμός από επιτρεπόμενα ψευδώνυμα για domain, για νέους "
"διαχειριστές. (Το 0 δεν επιτρέπει κανένα, το -1 επιτρέπει απεριόριστα) "
@@ -2336,8 +2346,8 @@ msgid ""
"The quota a reseller will be allowed to share between the domains he "
"creates. (0 means no quota)"
msgstr ""
"To quota που ένας μεταπωλητής επιτρέπεται να μοιράζει μεταξύ των domains που "
"δημιουργεί. (0 σημαίνει χωρίς quota)"
"To quota που ένας μεταπωλητής επιτρέπεται να μοιράζει μεταξύ των domains που"
" δημιουργεί. (0 σημαίνει χωρίς quota)"
#: limits/app_settings.py:98
msgid "Default per-domain limits"
@@ -2353,8 +2363,8 @@ msgstr "Ενεργοποίηση ή απενεργοποίηση ορίων αν
#: limits/app_settings.py:114
msgid ""
"Maximum number of allowed domain administrators for a new domain. (0 to deny "
"any creation, -1 to allow unlimited creations)"
"Maximum number of allowed domain administrators for a new domain. (0 to deny"
" any creation, -1 to allow unlimited creations)"
msgstr ""
"Μέγιστος αριθμός από επιτρεπόμενους διαχειριστές domain για ένα νέο domain. "
"(0 απαγορεύει την δημιουργία, -1 επιτρέπει άπειρες δημιουργίες)"
@@ -2377,8 +2387,8 @@ msgstr ""
#: limits/app_settings.py:149
msgid ""
"Maximum number of allowed aliases for a new domain. (0 to deny any creation, "
"-1 to allow unlimited creations)"
"Maximum number of allowed aliases for a new domain. (0 to deny any creation,"
" -1 to allow unlimited creations)"
msgstr ""
"Μέγιστος αριθμός από επιτρεπόμενα ψευδώνυμα για ένα νέο domain. (0 "
"απαγορεύει την δημιουργία, -1 επιτρέπει άπειρες δημιουργίες)"
@@ -2433,8 +2443,8 @@ msgstr ""
#: limits/constants.py:93
msgid "Maximum number of mailbox aliases allowed for this domain."
msgstr ""
"Μέγιστος αριθμός από ψευδώνυμα γραμματοκιβωτίων που επιτρέπονται για αυτό το "
"domain. "
"Μέγιστος αριθμός από ψευδώνυμα γραμματοκιβωτίων που επιτρέπονται για αυτό το"
" domain. "
#: limits/constants.py:102
msgid "Maximum number of domain admins allowed for this domain."
@@ -2751,8 +2761,7 @@ msgid ""
"your contacts.\n"
msgstr ""
"\n"
"Εδώ μπορείτε να προβάλετε τα ηλεκτρονικά σας μηνύματα σε πραγματικό χρόνο, "
"να δημιουργήσετε φίλτρα ή να διαχειριστείτε\n"
"Εδώ μπορείτε να προβάλετε τα ηλεκτρονικά σας μηνύματα σε πραγματικό χρόνο, να δημιουργήσετε φίλτρα ή να διαχειριστείτε\n"
" τις επαφές σας.\n"
#: pdfcredentials/documents.py:126
@@ -2783,18 +2792,19 @@ msgstr "Διαπιστευτήρια PDF"
#: pdfcredentials/lib.py:29
#, fuzzy
#| msgid "Failed to create the directory that will contain PDF documents (%s)"
#| msgid ""
#| "Failed to create the directory that will contain PDF documents (%s)"
msgid "Can't write to selected directory to store PDF documents"
msgstr ""
"Σφάλμα στην δημιουργία του καταλόγου αρχείων για την αποθήκευση PDF εγγράφων "
"(%s)"
"Σφάλμα στην δημιουργία του καταλόγου αρχείων για την αποθήκευση PDF εγγράφων"
" (%s)"
#: pdfcredentials/lib.py:35
#, python-format
msgid "Failed to create the directory that will contain PDF documents (%s)"
msgstr ""
"Σφάλμα στην δημιουργία του καταλόγου αρχείων για την αποθήκευση PDF εγγράφων "
"(%s)"
"Σφάλμα στην δημιουργία του καταλόγου αρχείων για την αποθήκευση PDF εγγράφων"
" (%s)"
#: pdfcredentials/lib.py:82
msgid ""
@@ -2865,8 +2875,8 @@ msgstr ""
#: rspamd/app_settings.py:21
msgid ""
"Absolute path of the file which contains paths to DKIM private keys. Must be "
"readable by _rspamd group or user."
"Absolute path of the file which contains paths to DKIM private keys. Must be"
" readable by _rspamd group or user."
msgstr ""
#: rspamd/app_settings.py:30
@@ -2885,8 +2895,8 @@ msgstr ""
#: rspamd/app_settings.py:53
msgid ""
"Location of the rspamd dashboard. Can either be a relative URL (eg. '/"
"rspamd') or a full URL (eg. 'https://rspamd.domain.tld/').Only use for "
"Location of the rspamd dashboard. Can either be a relative URL (eg. "
"'/rspamd') or a full URL (eg. 'https://rspamd.domain.tld/').Only use for "
"guidance on the Super-Admin dashboard."
msgstr ""
@@ -3119,8 +3129,8 @@ msgid ""
"The password reset link was invalid, possibly because it has already been "
"used. Please request a new password reset."
msgstr ""
"Ο σύνδεσμος για την επαναφορά του κωδικού ήταν άκυρος, πιθανότατα γιατί είχε "
"είδη χρησιμοποιηθεί. Παρακαλώ ζητήστε μια νέα επαναφορά κωδικού."
"Ο σύνδεσμος για την επαναφορά του κωδικού ήταν άκυρος, πιθανότατα γιατί είχε"
" είδη χρησιμοποιηθεί. Παρακαλώ ζητήστε μια νέα επαναφορά κωδικού."
#: templates/registration/password_reset_confirm_code.html:22
msgid "Enter the code you've just received by SMS"
@@ -3144,8 +3154,8 @@ msgstr ""
"Σας έχουμε αποστείλει με ηλεκτρονικό ταχυδρομείο οδηγίες για να ορίσετε των "
"κωδικό σας, εφόσον υπάρχει ένας λογαριασμός με το διεύθυνση ηλεκτρονικής "
"αλληλογραφίας που καταχωρήσατε. Θα πρέπει να το λάβετε σύντομα. <p><p>Εάν "
"δεν λάβατε το email, παρακαλώ συγουρευτείτε ότι εισάγατε σωστά την διεύθυνση "
"σας και ελέγξτε τον φάκελο τον Spam σας. </p> "
"δεν λάβατε το email, παρακαλώ συγουρευτείτε ότι εισάγατε σωστά την διεύθυνση"
" σας και ελέγξτε τον φάκελο τον Spam σας. </p> "
#: templates/registration/password_reset_email.html:4
#: templates/registration/password_reset_email_v2.html:4
@@ -3197,8 +3207,8 @@ msgstr "Παλιός κωδικός"
#: templates/registration/twofactor_code_verify.html:35
msgid ""
"Enter the code from the two-factor app on your mobile device. If you've lost "
"your device, you may enter one of your recovery codes."
"Enter the code from the two-factor app on your mobile device. If you've lost"
" your device, you may enter one of your recovery codes."
msgstr ""
#: templates/registration/twofactor_code_verify.html:42
@@ -3459,6 +3469,5 @@ msgid "Attachment is too big (limit: %s)"
msgstr "Το συνημμένο είναι πολύ μεγάλο (όριο: %s)"
#, fuzzy, python-brace-format
#~| msgid "Connection to IMAP server failed: %s"
#~ msgid "Connection to IMAP server failed: {error}"
#~ msgstr "Η σύνδεση στο διακομιστή IMAP απέτυχε:%s"
+70 -59
View File
@@ -19,8 +19,7 @@ msgstr ""
"POT-Creation-Date: 2025-08-28 09:41+0200\n"
"PO-Revision-Date: 2020-05-06 11:16+0000\n"
"Last-Translator: Antoine Nguyen <tonio@ngyn.org>\n"
"Language-Team: Spanish (http://www.transifex.com/tonio/modoboa/language/"
"es/)\n"
"Language-Team: Spanish (http://www.transifex.com/tonio/modoboa/language/es/)\n"
"Language: es\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -205,8 +204,8 @@ msgstr "MX Validos"
#: admin/app_settings.py:37
msgid ""
"A list of IP or network address every MX record should match. A warning will "
"be sent if a record does not respect it."
"A list of IP or network address every MX record should match. A warning will"
" be sent if a record does not respect it."
msgstr ""
"Una lista de IP o dirección de red, cada registro MX debe coincidir. Se "
"enviará una advertencia si un registro no la respeta."
@@ -323,8 +322,9 @@ msgid ""
"Default quota (in MB) applied to freshly created domains with no value "
"specified. A value of 0 means no quota."
msgstr ""
"Cuota por defecto (en MB) que se aplica a la creación de nuevos dominios que "
"no tuvieran un valor especificado. Un valor de 0 significa que no hay cuota."
"Cuota por defecto (en MB) que se aplica a la creación de nuevos dominios que"
" no tuvieran un valor especificado. Un valor de 0 significa que no hay "
"cuota."
#: admin/app_settings.py:156
#, fuzzy
@@ -396,8 +396,10 @@ msgid "Automatic domain/mailbox creation"
msgstr "Creación automática de dominio/buzón"
#: admin/app_settings.py:221
msgid "Create a domain and a mailbox when an account is automatically created."
msgstr "Crear un dominio y un buzón cuando se cree automáticamente una cuenta."
msgid ""
"Create a domain and a mailbox when an account is automatically created."
msgstr ""
"Crear un dominio y un buzón cuando se cree automáticamente una cuenta."
#: admin/app_settings.py:230
msgid "Create an alias when a mailbox is renamed"
@@ -726,8 +728,8 @@ msgid ""
"Modoboa detected that domain %(domain)s is listed by the following DNSBL "
"providers:"
msgstr ""
"Modoboa detectó que el(los) dominio(s) %(domain)s está(n) listado(s) por los "
"siguientes proveedores DNSBL:"
"Modoboa detectó que el(los) dominio(s) %(domain)s está(n) listado(s) por los"
" siguientes proveedores DNSBL:"
#: admin/templates/admin/notifications/domain_in_dnsbl.html:11
msgid ""
@@ -736,16 +738,16 @@ msgid ""
"and ask them to unlist detected IP address(es)."
msgstr ""
"La reputación de los dominios se verán afectados y existe la posibilidad de "
"que los mensajes de correo electrónico procedentes de él se consideren spam. "
"Debe comunicarse con estos proveedores y pedirles que elimine la(s) "
"que los mensajes de correo electrónico procedentes de él se consideren spam."
" Debe comunicarse con estos proveedores y pedirles que elimine la(s) "
"dirección(es) IP detectada(s)."
#: admin/templates/admin/notifications/domain_invalid_mx.html:3
#, python-format
msgid "Modoboa detected that domain %(domain)s has no valid MX record:"
msgstr ""
"Modoboa detectó que el(los) dominio(s) %(domain)s está(n) listado(s) por los "
"siguientes proveedores DNSBL:"
"Modoboa detectó que el(los) dominio(s) %(domain)s está(n) listado(s) por los"
" siguientes proveedores DNSBL:"
#: admin/tests/test_mx.py:155
#, fuzzy, python-format
@@ -788,13 +790,15 @@ msgstr "General"
#: autoreply/app_settings.py:18
#, fuzzy
#| msgid "Timeout in seconds between two auto-replies to the same recipient"
#| msgid ""
#| "Timeout in seconds between two auto-replies to the same recipient"
msgid "Period between two auto-replies"
msgstr "Tiempo en segundos entre dos autorespuestas para el mismo emisor"
#: autoreply/app_settings.py:20
#, fuzzy
#| msgid "Timeout in seconds between two auto-replies to the same recipient"
#| msgid ""
#| "Timeout in seconds between two auto-replies to the same recipient"
msgid ""
"Number of days to wait before sending a new auto-reply to the same recipient"
msgstr "Tiempo en segundos entre dos autorespuestas para el mismo emisor"
@@ -1029,7 +1033,8 @@ msgstr "Número de rondas inváldo"
msgid "This code is invalid"
msgstr ""
#: core/api/v2/serializers.py:503 core/views/auth.py:194 core/views/auth.py:247
#: core/api/v2/serializers.py:503 core/views/auth.py:194
#: core/views/auth.py:247
msgid "Please use the following code to recover your Modoboa password: {}"
msgstr ""
@@ -1085,8 +1090,8 @@ msgid ""
"Number of rounds to use (only used by sha256crypt and sha512crypt). Must be "
"between 1000 and 999999999, inclusive."
msgstr ""
"Número de rondas a usar (sólo utilizado por sha256crypr y sha512crypt). Debe "
"estar entre 1000 y 999999999, incluído."
"Número de rondas a usar (sólo utilizado por sha256crypr y sha512crypt). Debe"
" estar entre 1000 y 999999999, incluído."
#: core/app_settings.py:73
msgid "Update password scheme at login"
@@ -1231,11 +1236,11 @@ msgstr "Administrador de grupos"
#: core/app_settings.py:239
msgid ""
"Members of those LDAP Posix groups will be created as domain administrators. "
"Use ';' characters to separate groups."
"Members of those LDAP Posix groups will be created as domain administrators."
" Use ';' characters to separate groups."
msgstr ""
"Los miembros de esos grupos Posix LDAP serán creados como administradores de "
"dominio. Use caracteres \";\" para separar los grupos."
"Los miembros de esos grupos Posix LDAP serán creados como administradores de"
" dominio. Use caracteres \";\" para separar los grupos."
#: core/app_settings.py:248
msgid "Group type"
@@ -1282,8 +1287,8 @@ msgid ""
"The distinguished name to use when binding to the LDAP server. Leave empty "
"for an anonymous bind"
msgstr ""
"El nombre distinguido a usar cuando nos unimos al servidor LDAP. Dejar vació "
"para una unión anónima"
"El nombre distinguido a usar cuando nos unimos al servidor LDAP. Dejar vació"
" para una unión anónima"
#: core/app_settings.py:305 core/app_settings.py:367
msgid "Bind password"
@@ -1421,7 +1426,8 @@ msgstr ""
#: core/app_settings.py:506
#, fuzzy
#| msgid "Display custom RSS feed to resellers and domain administrators"
#| msgid ""
#| "Display custom RSS feed to resellers and domain administrators"
msgid "Display custom RSS feed to super admins"
msgstr ""
"Mostrar una fuente de agregación RSS personalizada a revendedores y "
@@ -1429,7 +1435,8 @@ msgstr ""
#: core/app_settings.py:509
#, fuzzy
#| msgid "Display custom RSS feed to resellers and domain administrators"
#| msgid ""
#| "Display custom RSS feed to resellers and domain administrators"
msgid "Display custom RSS feed also to super administrators"
msgstr ""
"Mostrar una fuente de agregación RSS personalizada a revendedores y "
@@ -1553,8 +1560,8 @@ msgstr "Límite para cuentas inactivas"
#: core/app_settings.py:686
msgid ""
"Allow the administrator to set a threshold (in days) beyond which an account "
"is considered inactive if the user hasn't logged in"
"Allow the administrator to set a threshold (in days) beyond which an account"
" is considered inactive if the user hasn't logged in"
msgstr ""
#: core/app_settings.py:695
@@ -1563,8 +1570,8 @@ msgstr "Límite para cuentas inactivas"
#: core/app_settings.py:698
msgid ""
"An account with a last login date greater than this threshold (in days) will "
"be considered as inactive"
"An account with a last login date greater than this threshold (in days) will"
" be considered as inactive"
msgstr ""
"Una cuenta inactiva con una fecha de inicio de sesión previa a este límite "
"(en días) se considerará como cuenta inactiva"
@@ -1616,9 +1623,9 @@ msgid ""
"between summer/winter time (ie the same local time occuring twice due to "
"clock change)."
msgstr ""
"A fijado USE_TZ como falso, lo que puede llevar a problemas en la transición "
"entre los horarios de verano e invierno (p.ej., que la misma hora exista dos "
"veces debido a cambios del reloj)."
"A fijado USE_TZ como falso, lo que puede llevar a problemas en la transición"
" entre los horarios de verano e invierno (p.ej., que la misma hora exista "
"dos veces debido a cambios del reloj)."
#: core/checks.py:19
msgid "Set `USE_TZ = True` in settings.py"
@@ -1640,8 +1647,9 @@ msgstr ""
#: core/checks.py:34
msgid ""
"Visit : https://modoboa.readthedocs.io/en/latest/manual_installation/"
"dovecot.html#dovecot-oauth2"
"Visit : "
"https://modoboa.readthedocs.io/en/latest/manual_installation/dovecot.html#dovecot-"
"oauth2"
msgstr ""
#: core/checks.py:41
@@ -1652,8 +1660,9 @@ msgstr ""
#: core/checks.py:45
msgid ""
"Visit : https://modoboa.readthedocs.io/en/latest/manual_installation/"
"radicale.html#radicale-oauth2"
"Visit : "
"https://modoboa.readthedocs.io/en/latest/manual_installation/radicale.html#radicale-"
"oauth2"
msgstr ""
#: core/constants.py:6
@@ -1954,7 +1963,7 @@ msgstr "Nada"
#, fuzzy
#| msgid "Quantity"
msgid "Quarantine"
msgstr "Cantidad"
msgstr "Cuarentena"
#: dmarc/models.py:12
#, fuzzy
@@ -2258,10 +2267,11 @@ msgstr "Alias del dominio"
#: limits/app_settings.py:52
#, fuzzy
#| msgid "Maximum number of allowed domain aliases for a new administrator"
#| msgid ""
#| "Maximum number of allowed domain aliases for a new administrator"
msgid ""
"Maximum number of allowed domain aliases for a new administrator. (0 to deny "
"any creation, -1 to allow unlimited creations)"
"Maximum number of allowed domain aliases for a new administrator. (0 to deny"
" any creation, -1 to allow unlimited creations)"
msgstr ""
"Número máximo permitido de alias de dominio para un nuevo administrador"
@@ -2315,15 +2325,16 @@ msgstr ""
#| msgid ""
#| "Maximum number of allowed domain administrators for a new administrator"
msgid ""
"Maximum number of allowed domain administrators for a new domain. (0 to deny "
"any creation, -1 to allow unlimited creations)"
"Maximum number of allowed domain administrators for a new domain. (0 to deny"
" any creation, -1 to allow unlimited creations)"
msgstr ""
"Número máximo de dominios permitido de administradores para un nuevo "
"administrador"
#: limits/app_settings.py:126
#, fuzzy
#| msgid "Maximum number of allowed domain aliases for a new administrator"
#| msgid ""
#| "Maximum number of allowed domain aliases for a new administrator"
msgid ""
"Maximum number of allowed domain aliases for a new domain. (0 to deny any "
"creation, -1 to allow unlimited creations)"
@@ -2342,8 +2353,8 @@ msgstr "Número máximo de mailboxes permitidas para un nuevo administrador"
#, fuzzy
#| msgid "Maximum number of allowed aliases for a new administrator"
msgid ""
"Maximum number of allowed aliases for a new domain. (0 to deny any creation, "
"-1 to allow unlimited creations)"
"Maximum number of allowed aliases for a new domain. (0 to deny any creation,"
" -1 to allow unlimited creations)"
msgstr "Número máxido de alias permitidos para un nuevo administrador"
#: limits/apps.py:16
@@ -2816,8 +2827,8 @@ msgstr ""
#: rspamd/app_settings.py:21
msgid ""
"Absolute path of the file which contains paths to DKIM private keys. Must be "
"readable by _rspamd group or user."
"Absolute path of the file which contains paths to DKIM private keys. Must be"
" readable by _rspamd group or user."
msgstr ""
#: rspamd/app_settings.py:30
@@ -2836,8 +2847,8 @@ msgstr ""
#: rspamd/app_settings.py:53
msgid ""
"Location of the rspamd dashboard. Can either be a relative URL (eg. '/"
"rspamd') or a full URL (eg. 'https://rspamd.domain.tld/').Only use for "
"Location of the rspamd dashboard. Can either be a relative URL (eg. "
"'/rspamd') or a full URL (eg. 'https://rspamd.domain.tld/').Only use for "
"guidance on the Super-Admin dashboard."
msgstr ""
@@ -2987,7 +2998,8 @@ msgstr "Detener procesamiento"
#: sievefilters/lib.py:49
msgid "Connection to MANAGESIEVE server failed, check your configuration"
msgstr "La conexión al servidor MANAGESIEVE falló, verifique su configuración."
msgstr ""
"La conexión al servidor MANAGESIEVE falló, verifique su configuración."
#: sievefilters/lib.py:76
#, fuzzy
@@ -3088,10 +3100,10 @@ msgid ""
"primary address, and check your spam folder.</p>"
msgstr ""
"<p>Si existe una cuenta con el correo electrónico introducido, recibirá en "
"breves instantes instrucciones via email para cambiar su contraseña.</"
"p><p>Si no recibe el correo, por favor compruebe que la dirección de correo "
"electrónico introducida es su dirección principal y revise su directorio de "
"correo basura.</p>"
"breves instantes instrucciones via email para cambiar su "
"contraseña.</p><p>Si no recibe el correo, por favor compruebe que la "
"dirección de correo electrónico introducida es su dirección principal y "
"revise su directorio de correo basura.</p>"
#: templates/registration/password_reset_email.html:4
#: templates/registration/password_reset_email_v2.html:4
@@ -3143,8 +3155,8 @@ msgstr "Contraseña anterior"
#: templates/registration/twofactor_code_verify.html:35
msgid ""
"Enter the code from the two-factor app on your mobile device. If you've lost "
"your device, you may enter one of your recovery codes."
"Enter the code from the two-factor app on your mobile device. If you've lost"
" your device, you may enter one of your recovery codes."
msgstr ""
#: templates/registration/twofactor_code_verify.html:42
@@ -3407,6 +3419,5 @@ msgid "Attachment is too big (limit: %s)"
msgstr "EL adjunto es demasiado grande (límite: %s)"
#, fuzzy, python-brace-format
#~| msgid "Connection to IMAP server failed: %s"
#~ msgid "Connection to IMAP server failed: {error}"
#~ msgstr "Falló la conexión con el servidor IMAP: %s"
File diff suppressed because it is too large Load Diff
+60 -50
View File
@@ -14,8 +14,7 @@ msgstr ""
"POT-Creation-Date: 2025-08-28 09:41+0200\n"
"PO-Revision-Date: 2018-11-01 16:31+0000\n"
"Last-Translator: marcotrevisan <mrctrevisan@yahoo.it>\n"
"Language-Team: Italian (http://www.transifex.com/tonio/modoboa/language/"
"it/)\n"
"Language-Team: Italian (http://www.transifex.com/tonio/modoboa/language/it/)\n"
"Language: it\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -192,8 +191,8 @@ msgstr "MX validi"
#: admin/app_settings.py:37
msgid ""
"A list of IP or network address every MX record should match. A warning will "
"be sent if a record does not respect it."
"A list of IP or network address every MX record should match. A warning will"
" be sent if a record does not respect it."
msgstr ""
"Una lista di indirizzi IP o host a cui ciascun record MX dovrebbe "
"appartenere. Verrà inviato un avviso se un record non la rispetta. "
@@ -295,8 +294,8 @@ msgid ""
"world."
msgstr ""
"Percorso assoluto della cartella dove le chiavi private DKIM verranno "
"salvate. Assicurarsi che questa cartella sia di proprietà dell'utente root e "
"che non sia leggibile da altri."
"salvate. Assicurarsi che questa cartella sia di proprietà dell'utente root e"
" che non sia leggibile da altri."
#: admin/app_settings.py:137
msgid "Default DKIM key length"
@@ -389,7 +388,8 @@ msgid "Automatic domain/mailbox creation"
msgstr "Creazione automatica del domini/casella di posta elettronica"
#: admin/app_settings.py:221
msgid "Create a domain and a mailbox when an account is automatically created."
msgid ""
"Create a domain and a mailbox when an account is automatically created."
msgstr ""
"Crea un dominio ed una casella di posta elettronica quando si crea un "
"account utente"
@@ -472,8 +472,8 @@ msgstr "Nessun DNS server funzionante trovato"
#, python-format
msgid "DNS resolution timeout, unable to query %s at the moment"
msgstr ""
"Timeout nella risoluzione DNS del nome, problema momentaneo nell'interrogare "
"%s "
"Timeout nella risoluzione DNS del nome, problema momentaneo nell'interrogare"
" %s "
#: admin/lib.py:236
msgid "DNS name is too long: {}"
@@ -788,7 +788,8 @@ msgstr "Generale"
#: autoreply/app_settings.py:18
#, fuzzy
#| msgid "Timeout in seconds between two auto-replies to the same recipient"
#| msgid ""
#| "Timeout in seconds between two auto-replies to the same recipient"
msgid "Period between two auto-replies"
msgstr ""
"Tempo massimo in secondi tra due risposte automatiche al medesimo "
@@ -796,7 +797,8 @@ msgstr ""
#: autoreply/app_settings.py:20
#, fuzzy
#| msgid "Timeout in seconds between two auto-replies to the same recipient"
#| msgid ""
#| "Timeout in seconds between two auto-replies to the same recipient"
msgid ""
"Number of days to wait before sending a new auto-reply to the same recipient"
msgstr ""
@@ -1036,7 +1038,8 @@ msgstr "Numero di cicli non valido"
msgid "This code is invalid"
msgstr ""
#: core/api/v2/serializers.py:503 core/views/auth.py:194 core/views/auth.py:247
#: core/api/v2/serializers.py:503 core/views/auth.py:194
#: core/views/auth.py:247
msgid "Please use the following code to recover your Modoboa password: {}"
msgstr ""
@@ -1251,8 +1254,8 @@ msgstr "Gruppi degli amministratori"
#: core/app_settings.py:239
msgid ""
"Members of those LDAP Posix groups will be created as domain administrators. "
"Use ';' characters to separate groups."
"Members of those LDAP Posix groups will be created as domain administrators."
" Use ';' characters to separate groups."
msgstr ""
"Gli appartenenti a questi gruppi LDAP Posix avranno i privilegi di "
"amministratori di dominio. Utilizza il carattere ';' per separare valori "
@@ -1461,13 +1464,15 @@ msgstr "Mostra RSS feed custom a rivenditori e amministratori di dominio"
#: core/app_settings.py:506
#, fuzzy
#| msgid "Display custom RSS feed to resellers and domain administrators"
#| msgid ""
#| "Display custom RSS feed to resellers and domain administrators"
msgid "Display custom RSS feed to super admins"
msgstr "Mostra RSS feed custom a rivenditori e amministratori di dominio"
#: core/app_settings.py:509
#, fuzzy
#| msgid "Display custom RSS feed to resellers and domain administrators"
#| msgid ""
#| "Display custom RSS feed to resellers and domain administrators"
msgid "Display custom RSS feed also to super administrators"
msgstr "Mostra RSS feed custom a rivenditori e amministratori di dominio"
@@ -1587,8 +1592,8 @@ msgstr "Soglia account inattivo"
#: core/app_settings.py:686
msgid ""
"Allow the administrator to set a threshold (in days) beyond which an account "
"is considered inactive if the user hasn't logged in"
"Allow the administrator to set a threshold (in days) beyond which an account"
" is considered inactive if the user hasn't logged in"
msgstr ""
#: core/app_settings.py:695
@@ -1597,8 +1602,8 @@ msgstr "Soglia account inattivo"
#: core/app_settings.py:698
msgid ""
"An account with a last login date greater than this threshold (in days) will "
"be considered as inactive"
"An account with a last login date greater than this threshold (in days) will"
" be considered as inactive"
msgstr ""
"Un account con una data di ultimo accesso più vecchia di questa soglia (in "
"giorni) verrà considerato inattivo"
@@ -1674,8 +1679,9 @@ msgstr ""
#: core/checks.py:34
msgid ""
"Visit : https://modoboa.readthedocs.io/en/latest/manual_installation/"
"dovecot.html#dovecot-oauth2"
"Visit : "
"https://modoboa.readthedocs.io/en/latest/manual_installation/dovecot.html#dovecot-"
"oauth2"
msgstr ""
#: core/checks.py:41
@@ -1686,8 +1692,9 @@ msgstr ""
#: core/checks.py:45
msgid ""
"Visit : https://modoboa.readthedocs.io/en/latest/manual_installation/"
"radicale.html#radicale-oauth2"
"Visit : "
"https://modoboa.readthedocs.io/en/latest/manual_installation/radicale.html#radicale-"
"oauth2"
msgstr ""
#: core/constants.py:6
@@ -1877,7 +1884,8 @@ msgstr[1] "La password deve contenere almeno {} caratteri speciali."
#: core/password_validation.py:70
msgid "Your password must contain a combination of different character types."
msgstr ""
"La tua password deve contenere una combinazione di diversi tipi di carattere."
"La tua password deve contenere una combinazione di diversi tipi di "
"carattere."
#: core/sms_backends/ovh.py:21 core/sms_backends/ovh.py:102
msgid "API endpoint"
@@ -1997,7 +2005,7 @@ msgstr "Nessuno"
#: dmarc/models.py:11
msgid "Quarantine"
msgstr "Quarantina"
msgstr "Quarantena"
#: dmarc/models.py:12
msgid "Reject"
@@ -2286,8 +2294,8 @@ msgid ""
"Maximum number of allowed domains for a new administrator. (0 to deny any "
"creation, -1 to allow unlimited creations)"
msgstr ""
"Il numero massimo di domini per nuovi amministratori. (0 per disabilitare la "
"creazione, -1 per permettere la creazione illimitata)"
"Il numero massimo di domini per nuovi amministratori. (0 per disabilitare la"
" creazione, -1 per permettere la creazione illimitata)"
#: limits/app_settings.py:49 limits/app_settings.py:123 limits/constants.py:22
#: limits/constants.py:76
@@ -2296,8 +2304,8 @@ msgstr "Alias del dominio"
#: limits/app_settings.py:52
msgid ""
"Maximum number of allowed domain aliases for a new administrator. (0 to deny "
"any creation, -1 to allow unlimited creations)"
"Maximum number of allowed domain aliases for a new administrator. (0 to deny"
" any creation, -1 to allow unlimited creations)"
msgstr ""
"Il numero massimo di alias per nuovi amministratori. (0 per disabilitare la "
"creazione, -1 per permettere la creazione illimitata)"
@@ -2349,11 +2357,11 @@ msgstr "Abilita o disabilita i limiti per dominio"
#: limits/app_settings.py:114
msgid ""
"Maximum number of allowed domain administrators for a new domain. (0 to deny "
"any creation, -1 to allow unlimited creations)"
"Maximum number of allowed domain administrators for a new domain. (0 to deny"
" any creation, -1 to allow unlimited creations)"
msgstr ""
"Numero massimo di amministratori di dominio consentiti per un nuovo dominio. "
"(0 per negare qualunque creazione, -1 per permetterne senza limiti)"
"Numero massimo di amministratori di dominio consentiti per un nuovo dominio."
" (0 per negare qualunque creazione, -1 per permetterne senza limiti)"
#: limits/app_settings.py:126
msgid ""
@@ -2373,8 +2381,8 @@ msgstr ""
#: limits/app_settings.py:149
msgid ""
"Maximum number of allowed aliases for a new domain. (0 to deny any creation, "
"-1 to allow unlimited creations)"
"Maximum number of allowed aliases for a new domain. (0 to deny any creation,"
" -1 to allow unlimited creations)"
msgstr ""
"Numero massimo di alias consentiti per un nuovo dominio. (0 per negare "
"qualunque creazione, -1 per permetterne senza limiti)"
@@ -2614,8 +2622,8 @@ msgid ""
"new document will be created each time a password is updated."
msgstr ""
"Generare un nuovo documento solo quando si crea un nuovo account. Se "
"impostato su no , un nuovo documento verrà creato ogni volta che la password "
"viene aggiornata."
"impostato su no , un nuovo documento verrà creato ogni volta che la password"
" viene aggiornata."
#: pdfcredentials/app_settings.py:84
msgid "Customization options"
@@ -2654,8 +2662,8 @@ msgid ""
"Include required SMTP and IMAP connection information to configure a mail "
"client, a tablet or a phone"
msgstr ""
"Includi le informazioni di connessione SMTP e IMAP richieste per configurare "
"un client di posta, un tablet o telefono"
"Includi le informazioni di connessione SMTP e IMAP richieste per configurare"
" un client di posta, un tablet o telefono"
#: pdfcredentials/app_settings.py:123 pdfcredentials/documents.py:133
msgid "SMTP server address"
@@ -2772,7 +2780,8 @@ msgstr "Credenziali PDF"
#: pdfcredentials/lib.py:29
#, fuzzy
#| msgid "Failed to create the directory that will contain PDF documents (%s)"
#| msgid ""
#| "Failed to create the directory that will contain PDF documents (%s)"
msgid "Can't write to selected directory to store PDF documents"
msgstr "Impossibile creare la cartella che conterrà i documenti PDF (%s)"
@@ -2850,8 +2859,8 @@ msgstr ""
#: rspamd/app_settings.py:21
msgid ""
"Absolute path of the file which contains paths to DKIM private keys. Must be "
"readable by _rspamd group or user."
"Absolute path of the file which contains paths to DKIM private keys. Must be"
" readable by _rspamd group or user."
msgstr ""
#: rspamd/app_settings.py:30
@@ -2870,8 +2879,8 @@ msgstr ""
#: rspamd/app_settings.py:53
msgid ""
"Location of the rspamd dashboard. Can either be a relative URL (eg. '/"
"rspamd') or a full URL (eg. 'https://rspamd.domain.tld/').Only use for "
"Location of the rspamd dashboard. Can either be a relative URL (eg. "
"'/rspamd') or a full URL (eg. 'https://rspamd.domain.tld/').Only use for "
"guidance on the Super-Admin dashboard."
msgstr ""
@@ -3088,7 +3097,8 @@ msgid ""
"Your password has been set. You may go ahead and <a href=\"%(url)s\">sign "
"in</a> now."
msgstr ""
"La tua password è stata impostata. Ora puoi <a href=\"%(url)s\">accedere</a>."
"La tua password è stata impostata. Ora puoi <a "
"href=\"%(url)s\">accedere</a>."
#: templates/registration/password_reset_confirm.html:8
msgid "Change password"
@@ -3183,8 +3193,8 @@ msgstr "Vecchia password"
#: templates/registration/twofactor_code_verify.html:35
msgid ""
"Enter the code from the two-factor app on your mobile device. If you've lost "
"your device, you may enter one of your recovery codes."
"Enter the code from the two-factor app on your mobile device. If you've lost"
" your device, you may enter one of your recovery codes."
msgstr ""
#: templates/registration/twofactor_code_verify.html:42
@@ -3283,7 +3293,8 @@ msgstr "Modalità di visualizzazione del messaggio predefinita"
#| msgid "The default redirection used when no application is specified"
msgid "The default mode used when displaying a message"
msgstr ""
"La modalità di visualizzazione predefinita quando viene mostrato il messaggio"
"La modalità di visualizzazione predefinita quando viene mostrato il "
"messaggio"
#: webmail/app_settings.py:133
msgid "Enable HTML links display"
@@ -3445,6 +3456,5 @@ msgid "Attachment is too big (limit: %s)"
msgstr "L'allegato è troppo grande (limite: %s)"
#, fuzzy, python-brace-format
#~| msgid "Connection to IMAP server failed: %s"
#~ msgid "Connection to IMAP server failed: {error}"
#~ msgstr "Connessione al server IMAP fallita: %s"
+72 -60
View File
@@ -22,8 +22,7 @@ msgstr ""
"POT-Creation-Date: 2025-08-28 09:41+0200\n"
"PO-Revision-Date: 2024-07-17 11:46+0200\n"
"Last-Translator: J Rosier <vertalen@tagora.nl>\n"
"Language-Team: Dutch (Netherlands) (http://www.transifex.com/tonio/modoboa/"
"language/nl_NL/)\n"
"Language-Team: Dutch (Netherlands) (http://www.transifex.com/tonio/modoboa/language/nl_NL/)\n"
"Language: nl_NL\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -194,11 +193,11 @@ msgstr "Geldige MX'en"
#: admin/app_settings.py:37
msgid ""
"A list of IP or network address every MX record should match. A warning will "
"be sent if a record does not respect it."
"A list of IP or network address every MX record should match. A warning will"
" be sent if a record does not respect it."
msgstr ""
"Een lijst van IP-adressen waaraan alle MX-records moeten voldoen. Er zal een "
"waarschuwing getoond worden voor records die niet overeenkomen."
"Een lijst van IP-adressen waaraan alle MX-records moeten voldoen. Er zal een"
" waarschuwing getoond worden voor records die niet overeenkomen."
#: admin/app_settings.py:47
msgid "New domains must use authorized MX(s)"
@@ -372,9 +371,11 @@ msgid "Automatic domain/mailbox creation"
msgstr "Domein en mailbox automatisch aanmaken"
#: admin/app_settings.py:221
msgid "Create a domain and a mailbox when an account is automatically created."
msgid ""
"Create a domain and a mailbox when an account is automatically created."
msgstr ""
"Maak een domein en mailbox aan wanneer een account automatisch is aangemaakt."
"Maak een domein en mailbox aan wanneer een account automatisch is "
"aangemaakt."
#: admin/app_settings.py:230
msgid "Create an alias when a mailbox is renamed"
@@ -382,7 +383,8 @@ msgstr "Maak een alias aan als een mailbox hernoemd wordt."
#: admin/app_settings.py:233
msgid "Create an alias using the old address when a mailbox is renamed."
msgstr "Maak een alias aan voor het oude adres als een mailbox hernoemd wordt."
msgstr ""
"Maak een alias aan voor het oude adres als een mailbox hernoemd wordt."
#: admin/app_settings.py:287 core/api/v2/viewsets.py:174
msgid "Administration"
@@ -698,8 +700,8 @@ msgid ""
"coming from it are considered as spam. You should contact those providers "
"and ask them to unlist detected IP address(es)."
msgstr ""
"De reputatie van dit domein wordt hierdoor aangetast er bestaat een kans dat "
"e-mail van dit domein als spam wordt gezien. Je zou contact moeten opnemen "
"De reputatie van dit domein wordt hierdoor aangetast er bestaat een kans dat"
" e-mail van dit domein als spam wordt gezien. Je zou contact moeten opnemen "
"met deze providers en hun vragen om deze IP adressen van de lijst te halen."
#: admin/templates/admin/notifications/domain_invalid_mx.html:3
@@ -749,14 +751,16 @@ msgstr "Algemeen"
#: autoreply/app_settings.py:18
#, fuzzy
#| msgid "Timeout in seconds between two auto-replies to the same recipient"
#| msgid ""
#| "Timeout in seconds between two auto-replies to the same recipient"
msgid "Period between two auto-replies"
msgstr ""
"Minimale tijd in seconden tussen twee auto-antwoorden naar dezelfde afzender"
#: autoreply/app_settings.py:20
#, fuzzy
#| msgid "Timeout in seconds between two auto-replies to the same recipient"
#| msgid ""
#| "Timeout in seconds between two auto-replies to the same recipient"
msgid ""
"Number of days to wait before sending a new auto-reply to the same recipient"
msgstr ""
@@ -770,8 +774,8 @@ msgstr "Standaard onderwerp"
msgid ""
"Default subject used when an auto-reply message is created automatically"
msgstr ""
"Standaard onderwerp gebruikt wanneer een automatisch antwoord automatisch is "
"aangemaakt"
"Standaard onderwerp gebruikt wanneer een automatisch antwoord automatisch is"
" aangemaakt"
#: autoreply/app_settings.py:38
#, python-format
@@ -994,7 +998,8 @@ msgstr "Ongeldig nummer van rondes"
msgid "This code is invalid"
msgstr ""
#: core/api/v2/serializers.py:503 core/views/auth.py:194 core/views/auth.py:247
#: core/api/v2/serializers.py:503 core/views/auth.py:194
#: core/views/auth.py:247
msgid "Please use the following code to recover your Modoboa password: {}"
msgstr "Gebruik de volgende code om het Modoboa wachtwoord te herstellen: {}"
@@ -1202,8 +1207,8 @@ msgstr "Beheerdergroepen"
#: core/app_settings.py:239
msgid ""
"Members of those LDAP Posix groups will be created as domain administrators. "
"Use ';' characters to separate groups."
"Members of those LDAP Posix groups will be created as domain administrators."
" Use ';' characters to separate groups."
msgstr ""
"Leden van deze LDAP POSIX-groepen zullen aangemaakt worden als "
"domeinbeheerders. Gebruik ';' karakters om groepen te scheiden."
@@ -1311,7 +1316,8 @@ msgstr "Activeer export naar LDAP"
msgid ""
"Enable automatic synchronization between local database and LDAP directory"
msgstr ""
"Activeer automatische synchronisatie tussen lokale database en LDAP directory"
"Activeer automatische synchronisatie tussen lokale database en LDAP "
"directory"
#: core/app_settings.py:389
msgid "Delete remote LDAP account when local account is deleted"
@@ -1344,7 +1350,8 @@ msgstr "Activeer import van LDAP"
#: core/app_settings.py:414
msgid "Enable account synchronization from LDAP directory to local database"
msgstr "Activeer accountsynchronisatie van LDAP directory naar lokale database"
msgstr ""
"Activeer accountsynchronisatie van LDAP directory naar lokale database"
#: core/app_settings.py:444
msgid "Username attribute"
@@ -1399,13 +1406,15 @@ msgstr "Toon aangepaste RSS feed aan resellers en domein beheerders. "
#: core/app_settings.py:506
#, fuzzy
#| msgid "Display custom RSS feed to resellers and domain administrators"
#| msgid ""
#| "Display custom RSS feed to resellers and domain administrators"
msgid "Display custom RSS feed to super admins"
msgstr "Toon aangepaste RSS feed aan resellers en domein beheerders. "
#: core/app_settings.py:509
#, fuzzy
#| msgid "Display custom RSS feed to resellers and domain administrators"
#| msgid ""
#| "Display custom RSS feed to resellers and domain administrators"
msgid "Display custom RSS feed also to super administrators"
msgstr "Toon aangepaste RSS feed aan resellers en domein beheerders. "
@@ -1525,8 +1534,8 @@ msgstr "Drempelwaarde inactieve gebruikers"
#: core/app_settings.py:686
msgid ""
"Allow the administrator to set a threshold (in days) beyond which an account "
"is considered inactive if the user hasn't logged in"
"Allow the administrator to set a threshold (in days) beyond which an account"
" is considered inactive if the user hasn't logged in"
msgstr ""
#: core/app_settings.py:695
@@ -1535,8 +1544,8 @@ msgstr "Drempelwaarde inactieve gebruikers"
#: core/app_settings.py:698
msgid ""
"An account with a last login date greater than this threshold (in days) will "
"be considered as inactive"
"An account with a last login date greater than this threshold (in days) will"
" be considered as inactive"
msgstr ""
"Een gebruiker die langer dan dit aantal dagen niet ingelogd is, wordt op "
"inactief gezet."
@@ -1615,8 +1624,9 @@ msgstr ""
#: core/checks.py:34
msgid ""
"Visit : https://modoboa.readthedocs.io/en/latest/manual_installation/"
"dovecot.html#dovecot-oauth2"
"Visit : "
"https://modoboa.readthedocs.io/en/latest/manual_installation/dovecot.html#dovecot-"
"oauth2"
msgstr ""
#: core/checks.py:41
@@ -1627,8 +1637,9 @@ msgstr ""
#: core/checks.py:45
msgid ""
"Visit : https://modoboa.readthedocs.io/en/latest/manual_installation/"
"radicale.html#radicale-oauth2"
"Visit : "
"https://modoboa.readthedocs.io/en/latest/manual_installation/radicale.html#radicale-"
"oauth2"
msgstr ""
#: core/constants.py:6
@@ -2214,7 +2225,8 @@ msgid ""
"Maximum number of allowed domain administrators for a new administrator. (0 "
"to deny any creation, -1 to allow unlimited creations)"
msgstr ""
"Maximum aantal toegestane domein administrators voor een nieuwe administrator"
"Maximum aantal toegestane domein administrators voor een nieuwe "
"administrator"
#: limits/app_settings.py:41
#, fuzzy
@@ -2231,10 +2243,11 @@ msgstr "Domeinaliassen"
#: limits/app_settings.py:52
#, fuzzy
#| msgid "Maximum number of allowed domain aliases for a new administrator"
#| msgid ""
#| "Maximum number of allowed domain aliases for a new administrator"
msgid ""
"Maximum number of allowed domain aliases for a new administrator. (0 to deny "
"any creation, -1 to allow unlimited creations)"
"Maximum number of allowed domain aliases for a new administrator. (0 to deny"
" any creation, -1 to allow unlimited creations)"
msgstr "Maximum aantal domein aliassen voor een nieuwe administrator"
#: limits/app_settings.py:64
@@ -2287,14 +2300,16 @@ msgstr ""
#| msgid ""
#| "Maximum number of allowed domain administrators for a new administrator"
msgid ""
"Maximum number of allowed domain administrators for a new domain. (0 to deny "
"any creation, -1 to allow unlimited creations)"
"Maximum number of allowed domain administrators for a new domain. (0 to deny"
" any creation, -1 to allow unlimited creations)"
msgstr ""
"Maximum aantal toegestane domein administrators voor een nieuwe administrator"
"Maximum aantal toegestane domein administrators voor een nieuwe "
"administrator"
#: limits/app_settings.py:126
#, fuzzy
#| msgid "Maximum number of allowed domain aliases for a new administrator"
#| msgid ""
#| "Maximum number of allowed domain aliases for a new administrator"
msgid ""
"Maximum number of allowed domain aliases for a new domain. (0 to deny any "
"creation, -1 to allow unlimited creations)"
@@ -2312,8 +2327,8 @@ msgstr "Maximum aantal toegestane mailboxen voor een nieuwe administrator"
#, fuzzy
#| msgid "Maximum number of allowed aliases for a new administrator"
msgid ""
"Maximum number of allowed aliases for a new domain. (0 to deny any creation, "
"-1 to allow unlimited creations)"
"Maximum number of allowed aliases for a new domain. (0 to deny any creation,"
" -1 to allow unlimited creations)"
msgstr "Maximum aantal aliassen voor een nieuwe administrator"
#: limits/apps.py:16
@@ -2553,8 +2568,8 @@ msgid ""
"new document will be created each time a password is updated."
msgstr ""
"Genereer een document enkel wanneer een account is nieuw aangemaakt. Indien "
"'nee' is geselecteerd zal bij iedere wachtwoord wijziging een nieuw document "
"worden gemaakt. "
"'nee' is geselecteerd zal bij iedere wachtwoord wijziging een nieuw document"
" worden gemaakt. "
#: pdfcredentials/app_settings.py:84
msgid "Customization options"
@@ -2681,8 +2696,7 @@ msgid ""
"your contacts.\n"
msgstr ""
"\n"
"Hier kunt u uw e-mails online bekijken, filters aanmaken, of contactpersonen "
"beheren.\n"
"Hier kunt u uw e-mails online bekijken, filters aanmaken, of contactpersonen beheren.\n"
#: pdfcredentials/documents.py:126
msgid "Please change your password!"
@@ -2710,7 +2724,8 @@ msgstr "PDF gegevens"
#: pdfcredentials/lib.py:29
#, fuzzy
#| msgid "Failed to create the directory that will contain PDF documents (%s)"
#| msgid ""
#| "Failed to create the directory that will contain PDF documents (%s)"
msgid "Can't write to selected directory to store PDF documents"
msgstr "Het aanmaken van de map voor de PDF documenten is mislukt (%s)"
@@ -2792,8 +2807,8 @@ msgstr ""
#: rspamd/app_settings.py:21
msgid ""
"Absolute path of the file which contains paths to DKIM private keys. Must be "
"readable by _rspamd group or user."
"Absolute path of the file which contains paths to DKIM private keys. Must be"
" readable by _rspamd group or user."
msgstr ""
#: rspamd/app_settings.py:30
@@ -2812,8 +2827,8 @@ msgstr ""
#: rspamd/app_settings.py:53
msgid ""
"Location of the rspamd dashboard. Can either be a relative URL (eg. '/"
"rspamd') or a full URL (eg. 'https://rspamd.domain.tld/').Only use for "
"Location of the rspamd dashboard. Can either be a relative URL (eg. "
"'/rspamd') or a full URL (eg. 'https://rspamd.domain.tld/').Only use for "
"guidance on the Super-Admin dashboard."
msgstr ""
@@ -2969,7 +2984,8 @@ msgstr ""
#, fuzzy
#| msgid "Connection to IMAP server failed: %s"
msgid "Connection to MANAGESIEVE server failed, check your configuration"
msgstr "Verbinding naar MANAGESIEVE server mislukt, controleer uw configuratie"
msgstr ""
"Verbinding naar MANAGESIEVE server mislukt, controleer uw configuratie"
#: sievefilters/lib.py:76
#, fuzzy
@@ -3028,8 +3044,7 @@ msgstr "Wachtwoord vergeten?"
msgid ""
"Your password has been set. You may go ahead and <a href=\"%(url)s\">sign "
"in</a> now."
msgstr ""
"Je wachtwoord is ingesteld. Je kunt nu <a href=\"%(url)s\">inloggen</a>"
msgstr "Je wachtwoord is ingesteld. Je kunt nu <a href=\"%(url)s\">inloggen</a>"
#: templates/registration/password_reset_confirm.html:8
msgid "Change password"
@@ -3068,10 +3083,8 @@ msgid ""
"<p>If you don't receive an email, please make sure you've entered your "
"primary address, and check your spam folder.</p>"
msgstr ""
"<p>We hebben je instructies gemailt om je wachtwoord in te stellen. Als het "
"door jou ingevulde email adres bestaat, zal je hem binnenkort ontvangen</p>\n"
"<p>Als je geen email ontvangt, controleer dan of je het juiste email adres "
"hebt ingevuld, en controleer je spam folder. </p>"
"<p>We hebben je instructies gemailt om je wachtwoord in te stellen. Als het door jou ingevulde email adres bestaat, zal je hem binnenkort ontvangen</p>\n"
"<p>Als je geen email ontvangt, controleer dan of je het juiste email adres hebt ingevuld, en controleer je spam folder. </p>"
#: templates/registration/password_reset_email.html:4
#: templates/registration/password_reset_email_v2.html:4
@@ -3123,8 +3136,8 @@ msgstr "Oud wachtwoord"
#: templates/registration/twofactor_code_verify.html:35
msgid ""
"Enter the code from the two-factor app on your mobile device. If you've lost "
"your device, you may enter one of your recovery codes."
"Enter the code from the two-factor app on your mobile device. If you've lost"
" your device, you may enter one of your recovery codes."
msgstr ""
#: templates/registration/twofactor_code_verify.html:42
@@ -3236,7 +3249,7 @@ msgstr "(De)activeer weergave van HTML-koppelingen"
#, fuzzy
#| msgid "Number of displayed items per page"
msgid "Number of displayed emails per page"
msgstr "Aantal weergegeven e-mails per pagina"
msgstr "Aantal weergegeven emails per pagina"
#: webmail/app_settings.py:147
msgid "Sets the maximum number of messages displayed in a page"
@@ -3376,6 +3389,5 @@ msgid "Attachment is too big (limit: %s)"
msgstr "Bijlage is te groot (maximaal toegestane grootte: %s)"
#, fuzzy, python-brace-format
#~| msgid "Connection to IMAP server failed: %s"
#~ msgid "Connection to IMAP server failed: {error}"
#~ msgstr "Verbinding naar IMAP server mislukt: %s"
+84 -77
View File
@@ -18,23 +18,20 @@ msgstr ""
"POT-Creation-Date: 2025-08-28 09:41+0200\n"
"PO-Revision-Date: 2021-07-09 07:40+0000\n"
"Last-Translator: KrystianPlichta <polandtorros@gmail.com>\n"
"Language-Team: Polish (Poland) (http://www.transifex.com/tonio/modoboa/"
"language/pl_PL/)\n"
"Language-Team: Polish (Poland) (http://www.transifex.com/tonio/modoboa/language/pl_PL/)\n"
"Language: pl_PL\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=4; plural=(n==1 ? 0 : (n%10>=2 && n%10<=4) && "
"(n%100<12 || n%100>14) ? 1 : n!=1 && (n%10>=0 && n%10<=1) || (n%10>=5 && "
"n%10<=9) || (n%100>=12 && n%100<=14) ? 2 : 3);\n"
"Plural-Forms: nplurals=4; plural=(n==1 ? 0 : (n%10>=2 && n%10<=4) && (n%100<12 || n%100>14) ? 1 : n!=1 && (n%10>=0 && n%10<=1) || (n%10>=5 && n%10<=9) || (n%100>=12 && n%100<=14) ? 2 : 3);\n"
#: admin/api/v1/serializers.py:39
msgid ""
"Quota shared between mailboxes. Can be expressed in KB, MB (default) or GB. "
"A value of 0 means no quota."
msgstr ""
"Miejsce dzielone między skrzynki. Może być wyrażone w KB, MB (domyślnie) lub "
"GB. Wartość 0 oznacza brak limitu."
"Miejsce dzielone między skrzynki. Może być wyrażone w KB, MB (domyślnie) lub"
" GB. Wartość 0 oznacza brak limitu."
#: admin/api/v1/serializers.py:46
msgid "Default quota in MB applied to mailboxes. A value of 0 means no quota."
@@ -196,11 +193,11 @@ msgstr "Poprawne MXy"
#: admin/app_settings.py:37
msgid ""
"A list of IP or network address every MX record should match. A warning will "
"be sent if a record does not respect it."
"A list of IP or network address every MX record should match. A warning will"
" be sent if a record does not respect it."
msgstr ""
"Lista adresów IP lub sieci dla każdego pasującego rekordu MX. Monit zostanie "
"wysłany w przypadku błędu."
"Lista adresów IP lub sieci dla każdego pasującego rekordu MX. Monit zostanie"
" wysłany w przypadku błędu."
#: admin/app_settings.py:47
msgid "New domains must use authorized MX(s)"
@@ -284,8 +281,8 @@ msgid ""
"sure this directory belongs to root user and is not readable by the outside "
"world."
msgstr ""
"Ścieżka bezwzględna do katalogu w którym będą trzymane klucze prywatne DKIM. "
"Upewnij się że właścicielem katalogu jest \"użytkownik root\" i że katalog "
"Ścieżka bezwzględna do katalogu w którym będą trzymane klucze prywatne DKIM."
" Upewnij się że właścicielem katalogu jest \"użytkownik root\" i że katalog "
"nie jest publicznie dostępny do odczytu."
#: admin/app_settings.py:137
@@ -317,8 +314,8 @@ msgid ""
"Number of messages freshly created domains will be allowed to send per day. "
"Leave empty for no limit."
msgstr ""
"Liczba wiadomości, które świeżo utworzone domeny będą mogły wysłać dziennie. "
"Pozostaw puste dla braku limitu."
"Liczba wiadomości, które świeżo utworzone domeny będą mogły wysłać dziennie."
" Pozostaw puste dla braku limitu."
#: admin/app_settings.py:170 limits/app_settings.py:61
#: limits/app_settings.py:135 limits/constants.py:31 limits/constants.py:84
@@ -334,8 +331,8 @@ msgid ""
"Rename or remove mailboxes on the filesystem when they get renamed or "
"removed within Modoboa"
msgstr ""
"Zmieniaj lub usuwaj skrzynki na filesystemie jeśli zostały zmodyfikowane lub "
"usuniętę przez Modoboa"
"Zmieniaj lub usuwaj skrzynki na filesystemie jeśli zostały zmodyfikowane lub"
" usuniętę przez Modoboa"
#: admin/app_settings.py:186 admin/models/domain.py:36
msgid "Default mailbox quota"
@@ -344,8 +341,8 @@ msgstr "Domyślna przestrzeń dla konta pocztowego"
#: admin/app_settings.py:188
#, fuzzy
#| msgid ""
#| "Default mailbox quota (in MB) applied to freshly created mailboxes with "
#| "no value specified. A value of 0 means no quota."
#| "Default mailbox quota (in MB) applied to freshly created mailboxes with no "
#| "value specified. A value of 0 means no quota."
msgid ""
"Default mailbox quota (in MB) applied to freshly created domains with no "
"value specified. A value of 0 means no quota."
@@ -378,7 +375,8 @@ msgid "Automatic domain/mailbox creation"
msgstr "Automatyczne tworzenie domeny/skrzynki"
#: admin/app_settings.py:221
msgid "Create a domain and a mailbox when an account is automatically created."
msgid ""
"Create a domain and a mailbox when an account is automatically created."
msgstr "Utwórz domenę i skrzynkę gdy tworzone jest konto"
#: admin/app_settings.py:230
@@ -454,8 +452,8 @@ msgstr "Znaleziono nie działające serwery nazw"
#, python-format
msgid "DNS resolution timeout, unable to query %s at the moment"
msgstr ""
"Upłynąć czas na rozwiązanie nazwy w DNS, w tym momencie nie potrafię odpytać "
"%s"
"Upłynąć czas na rozwiązanie nazwy w DNS, w tym momencie nie potrafię odpytać"
" %s"
#: admin/lib.py:236
msgid "DNS name is too long: {}"
@@ -618,8 +616,8 @@ msgstr "Włącz podpisywanie DKIM"
msgid ""
"If you activate this feature, a DKIM key will be generated for this domain."
msgstr ""
"Jeśli włączysz tą funkcjonalność, dla tej domeny zostanie wygenerowany klucz "
"DKIM"
"Jeśli włączysz tą funkcjonalność, dla tej domeny zostanie wygenerowany klucz"
" DKIM"
#: admin/models/domain.py:70
msgid "Key length"
@@ -764,14 +762,16 @@ msgstr "Ogólne"
#: autoreply/app_settings.py:18
#, fuzzy
#| msgid "Timeout in seconds between two auto-replies to the same recipient"
#| msgid ""
#| "Timeout in seconds between two auto-replies to the same recipient"
msgid "Period between two auto-replies"
msgstr ""
"Limit w sek. pomiędzie dwiema auto-odpowiedziami dla tego samego odbiorcy"
#: autoreply/app_settings.py:20
#, fuzzy
#| msgid "Timeout in seconds between two auto-replies to the same recipient"
#| msgid ""
#| "Timeout in seconds between two auto-replies to the same recipient"
msgid ""
"Number of days to wait before sending a new auto-reply to the same recipient"
msgstr ""
@@ -1006,7 +1006,8 @@ msgstr "Nieprawidłowa liczba rund"
msgid "This code is invalid"
msgstr "Ten kod jest nieprawidłowy"
#: core/api/v2/serializers.py:503 core/views/auth.py:194 core/views/auth.py:247
#: core/api/v2/serializers.py:503 core/views/auth.py:194
#: core/views/auth.py:247
msgid "Please use the following code to recover your Modoboa password: {}"
msgstr "Proszę użyć następującego kodu, aby odzyskać hasło Modoboa: {}"
@@ -1217,11 +1218,11 @@ msgstr "Administrator grup"
#: core/app_settings.py:239
msgid ""
"Members of those LDAP Posix groups will be created as domain administrators. "
"Use ';' characters to separate groups."
"Members of those LDAP Posix groups will be created as domain administrators."
" Use ';' characters to separate groups."
msgstr ""
"Członkowie tych grup LDAP Posix będą utworzeni jako administratorzy domeny. "
"Użyj znaku ';' jako separatora grup."
"Członkowie tych grup LDAP Posix będą utworzeni jako administratorzy domeny."
" Użyj znaku ';' jako separatora grup."
#: core/app_settings.py:248
msgid "Group type"
@@ -1321,7 +1322,8 @@ msgstr "Włącz export do LDAP"
#: core/app_settings.py:380
msgid ""
"Enable automatic synchronization between local database and LDAP directory"
msgstr "Włącz automatyczną synchronizację lokalnej bazy danych i katalogu LDAP"
msgstr ""
"Włącz automatyczną synchronizację lokalnej bazy danych i katalogu LDAP"
#: core/app_settings.py:389
msgid "Delete remote LDAP account when local account is deleted"
@@ -1332,8 +1334,8 @@ msgid ""
"Delete remote LDAP account when local account is deleted, otherwise it will "
"be disabled."
msgstr ""
"Skasuj konto na zdalnym LDAP kiedy zostanie skasowane konto lokalne, w innym "
"przypadku zostanie ono wyłączone."
"Skasuj konto na zdalnym LDAP kiedy zostanie skasowane konto lokalne, w innym"
" przypadku zostanie ono wyłączone."
#: core/app_settings.py:401
msgid "Account DN template"
@@ -1345,8 +1347,8 @@ msgid ""
"The template used to construct an account's DN. It should contain one "
"placeholder (ie. %(user)s)"
msgstr ""
"Szablon używany do budowy DN konta. Powinien zawierać jeden placeholder (ie. "
"%(user)s)"
"Szablon używany do budowy DN konta. Powinien zawierać jeden placeholder (ie."
" %(user)s)"
#: core/app_settings.py:412
msgid "Enable import from LDAP"
@@ -1371,7 +1373,8 @@ msgstr "Włącz synchronizację Dovecot LDAP"
#: core/app_settings.py:457
msgid "LDAP authentication settings will be applied to Dovecot configuration."
msgstr ""
"Ustawienia uwierzytelniania LDAP zostaną zastosowane do konfiguracji Dovecot."
"Ustawienia uwierzytelniania LDAP zostaną zastosowane do konfiguracji "
"Dovecot."
#: core/app_settings.py:465
msgid "Dovecot LDAP config file"
@@ -1412,14 +1415,16 @@ msgstr ""
#: core/app_settings.py:506
#, fuzzy
#| msgid "Display custom RSS feed to resellers and domain administrators"
#| msgid ""
#| "Display custom RSS feed to resellers and domain administrators"
msgid "Display custom RSS feed to super admins"
msgstr ""
"Wyświetl spersonalizowany kanał RSS odsprzedawcy i administratorom domen"
#: core/app_settings.py:509
#, fuzzy
#| msgid "Display custom RSS feed to resellers and domain administrators"
#| msgid ""
#| "Display custom RSS feed to resellers and domain administrators"
msgid "Display custom RSS feed also to super administrators"
msgstr ""
"Wyświetl spersonalizowany kanał RSS odsprzedawcy i administratorom domen"
@@ -1529,7 +1534,8 @@ msgstr "Wyślij statystyki"
#: core/app_settings.py:664
msgid "Send statistics to Modoboa public API (counters and used extensions)"
msgstr ""
"Prześlij statystyki do publicznego API Modoboa (licznik i użyte rozszerzenia)"
"Prześlij statystyki do publicznego API Modoboa (licznik i użyte "
"rozszerzenia)"
#: core/app_settings.py:683
#, fuzzy
@@ -1539,8 +1545,8 @@ msgstr "Próg nieaktywności konta"
#: core/app_settings.py:686
msgid ""
"Allow the administrator to set a threshold (in days) beyond which an account "
"is considered inactive if the user hasn't logged in"
"Allow the administrator to set a threshold (in days) beyond which an account"
" is considered inactive if the user hasn't logged in"
msgstr ""
#: core/app_settings.py:695
@@ -1549,8 +1555,8 @@ msgstr "Próg nieaktywności konta"
#: core/app_settings.py:698
msgid ""
"An account with a last login date greater than this threshold (in days) will "
"be considered as inactive"
"An account with a last login date greater than this threshold (in days) will"
" be considered as inactive"
msgstr ""
"Konto z datą ostatniego logowania większą niż podany próg (w dniach) "
"zostanie uznane za nieaktywne. "
@@ -1627,8 +1633,9 @@ msgstr ""
#: core/checks.py:34
msgid ""
"Visit : https://modoboa.readthedocs.io/en/latest/manual_installation/"
"dovecot.html#dovecot-oauth2"
"Visit : "
"https://modoboa.readthedocs.io/en/latest/manual_installation/dovecot.html#dovecot-"
"oauth2"
msgstr ""
#: core/checks.py:41
@@ -1639,8 +1646,9 @@ msgstr ""
#: core/checks.py:45
msgid ""
"Visit : https://modoboa.readthedocs.io/en/latest/manual_installation/"
"radicale.html#radicale-oauth2"
"Visit : "
"https://modoboa.readthedocs.io/en/latest/manual_installation/radicale.html#radicale-"
"oauth2"
msgstr ""
#: core/constants.py:6
@@ -1956,7 +1964,7 @@ msgstr "Brak"
#, fuzzy
#| msgid "Quantity"
msgid "Quarantine"
msgstr "Ilość"
msgstr "Kwarantanna"
#: dmarc/models.py:12
#, fuzzy
@@ -2239,16 +2247,16 @@ msgid ""
"Maximum number of allowed domain administrators for a new administrator. (0 "
"to deny any creation, -1 to allow unlimited creations)"
msgstr ""
"Maksymalna dozwolona liczba administratorów domen dla nowego administratora. "
"(0 - tworzenie niedozwolone, -1 nielimitowana ilość)"
"Maksymalna dozwolona liczba administratorów domen dla nowego administratora."
" (0 - tworzenie niedozwolone, -1 nielimitowana ilość)"
#: limits/app_settings.py:41
msgid ""
"Maximum number of allowed domains for a new administrator. (0 to deny any "
"creation, -1 to allow unlimited creations)"
msgstr ""
"Maksymalna dozwolona ilość domen dla nowego administratora. (0 dla tworzenie "
"niedozwolone, -1 nielimitowana ilość)"
"Maksymalna dozwolona ilość domen dla nowego administratora. (0 dla tworzenie"
" niedozwolone, -1 nielimitowana ilość)"
#: limits/app_settings.py:49 limits/app_settings.py:123 limits/constants.py:22
#: limits/constants.py:76
@@ -2257,8 +2265,8 @@ msgstr "Aliasy domen"
#: limits/app_settings.py:52
msgid ""
"Maximum number of allowed domain aliases for a new administrator. (0 to deny "
"any creation, -1 to allow unlimited creations)"
"Maximum number of allowed domain aliases for a new administrator. (0 to deny"
" any creation, -1 to allow unlimited creations)"
msgstr ""
"Maksymalna dozwolona ilość aliasów domen dla nowego administratora. (0 dla "
"tworzenie niedozwolone, -1 nielimitowana ilość)"
@@ -2310,8 +2318,8 @@ msgstr "Włącz lub wyłącz limity na domenę"
#: limits/app_settings.py:114
msgid ""
"Maximum number of allowed domain administrators for a new domain. (0 to deny "
"any creation, -1 to allow unlimited creations)"
"Maximum number of allowed domain administrators for a new domain. (0 to deny"
" any creation, -1 to allow unlimited creations)"
msgstr ""
"Max liczba administratrów nowej domeny. (0 tworzenie niedozwolone, -1 dla "
"braku limitu)"
@@ -2334,8 +2342,8 @@ msgstr ""
#: limits/app_settings.py:149
msgid ""
"Maximum number of allowed aliases for a new domain. (0 to deny any creation, "
"-1 to allow unlimited creations)"
"Maximum number of allowed aliases for a new domain. (0 to deny any creation,"
" -1 to allow unlimited creations)"
msgstr ""
"Max liczba aliasów dla nowej domeny. (0 tworzenie niedozwolone, -1 "
"nielimitowana ilość)"
@@ -2549,7 +2557,8 @@ msgid ""
"Automatically delete a document just after its first download from this "
"interface"
msgstr ""
"Automatycznie usuwaj dokumenty jak tylko zostaną pobranie przez ten interfejs"
"Automatycznie usuwaj dokumenty jak tylko zostaną pobranie przez ten "
"interfejs"
#: pdfcredentials/app_settings.py:68
msgid "Generate documents only at account creation"
@@ -2561,7 +2570,8 @@ msgid ""
"new document will be created each time a password is updated."
msgstr ""
"Generuj nowy dokument tylko wtedy, kiedy nowe konto jest zakładane. Jeśli "
"ustawione na nie, to nowy dokument będzie tworzony przy każdej zmianie hasła."
"ustawione na nie, to nowy dokument będzie tworzony przy każdej zmianie "
"hasła."
#: pdfcredentials/app_settings.py:84
msgid "Customization options"
@@ -2664,9 +2674,7 @@ msgid ""
"the document as soon as possible.\n"
msgstr ""
"\n"
"Drogi użytkowniku %s, ten dokument zawiera dane uwierzytelniające które "
"będzeisz potrzebował to połączenia się. Zapoznaj się z nim i usuń go "
"najszybciej jak to możliwe.\n"
"Drogi użytkowniku %s, ten dokument zawiera dane uwierzytelniające które będzeisz potrzebował to połączenia się. Zapoznaj się z nim i usuń go najszybciej jak to możliwe.\n"
#: pdfcredentials/documents.py:95
msgid "Web panel:"
@@ -2687,8 +2695,7 @@ msgid ""
"your contacts.\n"
msgstr ""
"\n"
"Pod tym adresem możesz online przeczytać swoje wiadomości, stworzyć filtry "
"lub zarządzać\n"
"Pod tym adresem możesz online przeczytać swoje wiadomości, stworzyć filtry lub zarządzać\n"
" listą kontaktów.\n"
#: pdfcredentials/documents.py:126
@@ -2717,7 +2724,8 @@ msgstr "Poświadczenia PDF"
#: pdfcredentials/lib.py:29
#, fuzzy
#| msgid "Failed to create the directory that will contain PDF documents (%s)"
#| msgid ""
#| "Failed to create the directory that will contain PDF documents (%s)"
msgid "Can't write to selected directory to store PDF documents"
msgstr "Nie można utworzyć katalogu do przechowywania PDF'ów (%s)"
@@ -2795,8 +2803,8 @@ msgstr ""
#: rspamd/app_settings.py:21
msgid ""
"Absolute path of the file which contains paths to DKIM private keys. Must be "
"readable by _rspamd group or user."
"Absolute path of the file which contains paths to DKIM private keys. Must be"
" readable by _rspamd group or user."
msgstr ""
#: rspamd/app_settings.py:30
@@ -2815,8 +2823,8 @@ msgstr ""
#: rspamd/app_settings.py:53
msgid ""
"Location of the rspamd dashboard. Can either be a relative URL (eg. '/"
"rspamd') or a full URL (eg. 'https://rspamd.domain.tld/').Only use for "
"Location of the rspamd dashboard. Can either be a relative URL (eg. "
"'/rspamd') or a full URL (eg. 'https://rspamd.domain.tld/').Only use for "
"guidance on the Super-Admin dashboard."
msgstr ""
@@ -3129,8 +3137,8 @@ msgstr "Stare hasło"
#: templates/registration/twofactor_code_verify.html:35
msgid ""
"Enter the code from the two-factor app on your mobile device. If you've lost "
"your device, you may enter one of your recovery codes."
"Enter the code from the two-factor app on your mobile device. If you've lost"
" your device, you may enter one of your recovery codes."
msgstr ""
#: templates/registration/twofactor_code_verify.html:42
@@ -3142,7 +3150,7 @@ msgstr "Kod weryfikacyjny"
#: templates/registration/twofactor_code_verify.html:45
#: templates/registration/twofactor_code_verify.html:51
msgid "Back"
msgstr ""
msgstr "Wstecz"
#: templates/registration/twofactor_code_verify.html:49
msgid "Log using Webauthn"
@@ -3215,7 +3223,7 @@ msgstr "Preferowany mechanizm uwierzytelnienia"
#: webmail/app_settings.py:118
msgid "Display"
msgstr ""
msgstr "Wyświetl"
#: webmail/app_settings.py:124
msgid "Default message display mode"
@@ -3239,7 +3247,7 @@ msgstr ""
#, fuzzy
#| msgid "Number of displayed items per page"
msgid "Number of displayed emails per page"
msgstr "Liczba wyświetlanych elementów na stronie"
msgstr "Liczba wyświetlanych wiadomości na stronie"
#: webmail/app_settings.py:147
msgid "Sets the maximum number of messages displayed in a page"
@@ -3395,6 +3403,5 @@ msgid "Attachment is too big (limit: %s)"
msgstr ""
#, fuzzy, python-brace-format
#~| msgid "Connection to IMAP server failed: %s"
#~ msgid "Connection to IMAP server failed: {error}"
#~ msgstr "Błąd połączenia do serwera IMAP: %s"
+76 -71
View File
@@ -28,16 +28,13 @@ msgstr ""
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-08-28 09:41+0200\n"
"PO-Revision-Date: 2011-07-01 08:15+0000\n"
"Last-Translator: Rafael Barretto Alves <ch3yd@hotmail.com>, "
"2013,2015-2017,2025\n"
"Language-Team: Portuguese (Brazil) (http://app.transifex.com/tonio/modoboa/"
"language/pt_BR/)\n"
"Last-Translator: Rafael Barretto Alves <ch3yd@hotmail.com>, 2013,2015-2017,2025\n"
"Language-Team: Portuguese (Brazil) (http://app.transifex.com/tonio/modoboa/language/pt_BR/)\n"
"Language: pt_BR\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % "
"1000000 == 0 ? 1 : 2;\n"
"Plural-Forms: nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;\n"
#: admin/api/v1/serializers.py:39
msgid ""
@@ -205,11 +202,11 @@ msgstr "MXs válidos"
#: admin/app_settings.py:37
msgid ""
"A list of IP or network address every MX record should match. A warning will "
"be sent if a record does not respect it."
"A list of IP or network address every MX record should match. A warning will"
" be sent if a record does not respect it."
msgstr ""
"Uma lista de endereços IP ou de rede que cada registro MX deve corresponder. "
"Um aviso será enviado se um registro não for respeitado."
"Uma lista de endereços IP ou de rede que cada registro MX deve corresponder."
" Um aviso será enviado se um registro não for respeitado."
#: admin/app_settings.py:47
msgid "New domains must use authorized MX(s)"
@@ -246,8 +243,8 @@ msgstr "Ativar verificações DKIM"
#: admin/app_settings.py:80
msgid "Check if every domain with DKIM signin enabled has a valid DNS record"
msgstr ""
"Verifique se todos os domínios com login DKIM habilitado têm um registro DNS "
"válido"
"Verifique se todos os domínios com login DKIM habilitado têm um registro DNS"
" válido"
#: admin/app_settings.py:88
msgid "Enable DMARC checks"
@@ -295,8 +292,8 @@ msgid ""
"world."
msgstr ""
"Caminho absoluto do diretório onde as chaves privadas DKIM serão "
"armazenadas. Certifique-se que este diretório pertença ao usuário root e não "
"seja legível pelo mundo exterior."
"armazenadas. Certifique-se que este diretório pertença ao usuário root e não"
" seja legível pelo mundo exterior."
#: admin/app_settings.py:137
msgid "Default DKIM key length"
@@ -356,8 +353,8 @@ msgid ""
"Default mailbox quota (in MB) applied to freshly created domains with no "
"value specified. A value of 0 means no quota."
msgstr ""
"Cota de caixa de correio padrão (em MB) aplicada para domínios recém-criados "
"sem nenhum valor especificado. Um valor 0 significa que não há cota."
"Cota de caixa de correio padrão (em MB) aplicada para domínios recém-criados"
" sem nenhum valor especificado. Um valor 0 significa que não há cota."
#: admin/app_settings.py:197
msgid "Default mailbox sending limit"
@@ -385,7 +382,8 @@ msgid "Automatic domain/mailbox creation"
msgstr "Criação automática de domínio/caixa de correio"
#: admin/app_settings.py:221
msgid "Create a domain and a mailbox when an account is automatically created."
msgid ""
"Create a domain and a mailbox when an account is automatically created."
msgstr ""
"Crie um domínio e uma caixa de correio quando uma conta for criada "
"automaticamente."
@@ -716,7 +714,8 @@ msgid ""
msgstr ""
"A reputação do domínio será afetada e há uma chance de que os e-mails "
"provenientes dele sejam considerados spam. Você deve entrar em contato com "
"esses provedores e pedir que eles retirem a lista de endereços IP detectados."
"esses provedores e pedir que eles retirem a lista de endereços IP "
"detectados."
#: admin/templates/admin/notifications/domain_invalid_mx.html:3
#, python-format
@@ -759,7 +758,8 @@ msgstr "Geral"
#: autoreply/app_settings.py:18
#, fuzzy
#| msgid "Timeout in seconds between two auto-replies to the same recipient"
#| msgid ""
#| "Timeout in seconds between two auto-replies to the same recipient"
msgid "Period between two auto-replies"
msgstr ""
"Tempo limite, em segundos, entre duas respostas automáticas para o mesmo "
@@ -767,7 +767,8 @@ msgstr ""
#: autoreply/app_settings.py:20
#, fuzzy
#| msgid "Timeout in seconds between two auto-replies to the same recipient"
#| msgid ""
#| "Timeout in seconds between two auto-replies to the same recipient"
msgid ""
"Number of days to wait before sending a new auto-reply to the same recipient"
msgstr ""
@@ -993,7 +994,8 @@ msgstr "Número de ciclos inválido"
msgid "This code is invalid"
msgstr "Este código é inválido"
#: core/api/v2/serializers.py:503 core/views/auth.py:194 core/views/auth.py:247
#: core/api/v2/serializers.py:503 core/views/auth.py:194
#: core/views/auth.py:247
msgid "Please use the following code to recover your Modoboa password: {}"
msgstr ""
"Por favor, use o seguinte código para recuperar sua senha do Modoboa: {}"
@@ -1198,8 +1200,8 @@ msgstr "Grupos de administradores"
#: core/app_settings.py:239
msgid ""
"Members of those LDAP Posix groups will be created as domain administrators. "
"Use ';' characters to separate groups."
"Members of those LDAP Posix groups will be created as domain administrators."
" Use ';' characters to separate groups."
msgstr ""
"Membros dos grupos do LDAP Posix serão criados como administradores de "
"domínio. Use o caractere ';' para separar grupos."
@@ -1249,8 +1251,8 @@ msgid ""
"The distinguished name to use when binding to the LDAP server. Leave empty "
"for an anonymous bind"
msgstr ""
"O nome distinto para usar quando vincular ao servidor LDAP. Deixe vazio para "
"vincular anonimamente"
"O nome distinto para usar quando vincular ao servidor LDAP. Deixe vazio para"
" vincular anonimamente"
#: core/app_settings.py:305 core/app_settings.py:367
msgid "Bind password"
@@ -1290,8 +1292,8 @@ msgid ""
"The template used to construct a user's DN. It should contain one "
"placeholder (ie. %(user)s)"
msgstr ""
"A template usada para construir um DN de usuário. Deve conter um placeholder "
"(por ex: %(user)s)"
"A template usada para construir um DN de usuário. Deve conter um placeholder"
" (por ex: %(user)s)"
#: core/app_settings.py:350
msgid "LDAP synchronization settings"
@@ -1305,8 +1307,8 @@ msgstr "Habilitar exportação para LDAP"
msgid ""
"Enable automatic synchronization between local database and LDAP directory"
msgstr ""
"Ativar a sincronização automática entre o banco de dados local e o diretório "
"LDAP"
"Ativar a sincronização automática entre o banco de dados local e o diretório"
" LDAP"
#: core/app_settings.py:389
msgid "Delete remote LDAP account when local account is deleted"
@@ -1402,7 +1404,8 @@ msgstr ""
#: core/app_settings.py:506
#, fuzzy
#| msgid "Display custom RSS feed to resellers and domain administrators"
#| msgid ""
#| "Display custom RSS feed to resellers and domain administrators"
msgid "Display custom RSS feed to super admins"
msgstr ""
"Mostrar um feed RSS personalizado para revendedores e administradores de "
@@ -1410,7 +1413,8 @@ msgstr ""
#: core/app_settings.py:509
#, fuzzy
#| msgid "Display custom RSS feed to resellers and domain administrators"
#| msgid ""
#| "Display custom RSS feed to resellers and domain administrators"
msgid "Display custom RSS feed also to super administrators"
msgstr ""
"Mostrar um feed RSS personalizado para revendedores e administradores de "
@@ -1531,8 +1535,8 @@ msgstr "Ativar rastreamento de conta inativa"
#: core/app_settings.py:686
msgid ""
"Allow the administrator to set a threshold (in days) beyond which an account "
"is considered inactive if the user hasn't logged in"
"Allow the administrator to set a threshold (in days) beyond which an account"
" is considered inactive if the user hasn't logged in"
msgstr ""
"Permitir que o administrador defina um limite (em dias) além do qual uma "
"conta é considerada inativa se o usuário não tiver feito login"
@@ -1543,8 +1547,8 @@ msgstr "Limite de conta inativa"
#: core/app_settings.py:698
msgid ""
"An account with a last login date greater than this threshold (in days) will "
"be considered as inactive"
"An account with a last login date greater than this threshold (in days) will"
" be considered as inactive"
msgstr ""
"Uma conta com uma data de login maior que este limite (em dias) será "
"considerada como inativa"
@@ -1620,8 +1624,9 @@ msgstr ""
#: core/checks.py:34
msgid ""
"Visit : https://modoboa.readthedocs.io/en/latest/manual_installation/"
"dovecot.html#dovecot-oauth2"
"Visit : "
"https://modoboa.readthedocs.io/en/latest/manual_installation/dovecot.html#dovecot-"
"oauth2"
msgstr ""
#: core/checks.py:41
@@ -1632,8 +1637,9 @@ msgstr ""
#: core/checks.py:45
msgid ""
"Visit : https://modoboa.readthedocs.io/en/latest/manual_installation/"
"radicale.html#radicale-oauth2"
"Visit : "
"https://modoboa.readthedocs.io/en/latest/manual_installation/radicale.html#radicale-"
"oauth2"
msgstr ""
#: core/constants.py:6
@@ -2235,8 +2241,8 @@ msgstr "Apelidos de domínios"
#: limits/app_settings.py:52
msgid ""
"Maximum number of allowed domain aliases for a new administrator. (0 to deny "
"any creation, -1 to allow unlimited creations)"
"Maximum number of allowed domain aliases for a new administrator. (0 to deny"
" any creation, -1 to allow unlimited creations)"
msgstr ""
"Número máximo de apelidos de domínio permitidos para um novo administrador. "
"(0 para negar qualquer criação, -1 para permitir criações ilimitadas)"
@@ -2246,8 +2252,8 @@ msgid ""
"Maximum number of allowed mailboxes for a new administrator. (0 to deny any "
"creation, -1 to allow unlimited creations)"
msgstr ""
"Número máximo de caixas de correio permitidas para um novo administrador. (0 "
"para negar qualquer criação, -1 para permitir criações ilimitadas)"
"Número máximo de caixas de correio permitidas para um novo administrador. (0"
" para negar qualquer criação, -1 para permitir criações ilimitadas)"
#: limits/app_settings.py:73 limits/app_settings.py:146 limits/constants.py:39
#: limits/constants.py:92
@@ -2288,11 +2294,11 @@ msgstr "Habilitar ou desabilitar limites por domínio"
#: limits/app_settings.py:114
msgid ""
"Maximum number of allowed domain administrators for a new domain. (0 to deny "
"any creation, -1 to allow unlimited creations)"
"Maximum number of allowed domain administrators for a new domain. (0 to deny"
" any creation, -1 to allow unlimited creations)"
msgstr ""
"Número máximo de administradores de domínio permitidos para um novo domínio. "
"(0 para negar qualquer criação, -1 para permitir criações ilimitadas)"
"Número máximo de administradores de domínio permitidos para um novo domínio."
" (0 para negar qualquer criação, -1 para permitir criações ilimitadas)"
#: limits/app_settings.py:126
msgid ""
@@ -2312,8 +2318,8 @@ msgstr ""
#: limits/app_settings.py:149
msgid ""
"Maximum number of allowed aliases for a new domain. (0 to deny any creation, "
"-1 to allow unlimited creations)"
"Maximum number of allowed aliases for a new domain. (0 to deny any creation,"
" -1 to allow unlimited creations)"
msgstr ""
"Número máximo de apelidos permitidos para um novo domínio. (0 para negar "
"qualquer criação, -1 para permitir criações ilimitadas)"
@@ -2539,8 +2545,9 @@ msgid ""
"Generate a new document only when a new account is created. If set to no, a "
"new document will be created each time a password is updated."
msgstr ""
"Gere um novo documento somente quando uma nova conta for criada. Se definido "
"como não, um novo documento será criado sempre que uma senha for atualizada."
"Gere um novo documento somente quando uma nova conta for criada. Se definido"
" como não, um novo documento será criado sempre que uma senha for "
"atualizada."
#: pdfcredentials/app_settings.py:84
msgid "Customization options"
@@ -2579,8 +2586,8 @@ msgid ""
"Include required SMTP and IMAP connection information to configure a mail "
"client, a tablet or a phone"
msgstr ""
"Incluir as informações de conexão SMTP e IMAP necessárias para configurar um "
"cliente de e-mail, um tablet ou um telefone"
"Incluir as informações de conexão SMTP e IMAP necessárias para configurar um"
" cliente de e-mail, um tablet ou um telefone"
#: pdfcredentials/app_settings.py:123 pdfcredentials/documents.py:133
msgid "SMTP server address"
@@ -2666,8 +2673,7 @@ msgid ""
"your contacts.\n"
msgstr ""
"\n"
"Aqui você pode visualizar online seus e-mails a qualquer momento, criar "
"filtros ou gerenciar\n"
"Aqui você pode visualizar online seus e-mails a qualquer momento, criar filtros ou gerenciar\n"
"seus contatos.\n"
#: pdfcredentials/documents.py:126
@@ -2687,8 +2693,8 @@ msgid ""
"Failed to create PDF_credentials directory. Please check the permissions or "
"the path."
msgstr ""
"Falha ao criar diretório PDF_credentials. Por favor, verifique as permissões "
"ou o caminho."
"Falha ao criar diretório PDF_credentials. Por favor, verifique as permissões"
" ou o caminho."
#: pdfcredentials/handlers.py:64
msgid "Download PDF credentials"
@@ -2771,8 +2777,8 @@ msgstr ""
#: rspamd/app_settings.py:21
msgid ""
"Absolute path of the file which contains paths to DKIM private keys. Must be "
"readable by _rspamd group or user."
"Absolute path of the file which contains paths to DKIM private keys. Must be"
" readable by _rspamd group or user."
msgstr ""
#: rspamd/app_settings.py:30
@@ -2791,8 +2797,8 @@ msgstr ""
#: rspamd/app_settings.py:53
msgid ""
"Location of the rspamd dashboard. Can either be a relative URL (eg. '/"
"rspamd') or a full URL (eg. 'https://rspamd.domain.tld/').Only use for "
"Location of the rspamd dashboard. Can either be a relative URL (eg. "
"'/rspamd') or a full URL (eg. 'https://rspamd.domain.tld/').Only use for "
"guidance on the Super-Admin dashboard."
msgstr ""
@@ -2855,7 +2861,7 @@ msgstr "Qualquer um dos seguintes"
#: sievefilters/constants.py:12
msgid "All messages"
msgstr "Todas as mensagens"
msgstr "Todas mensagens"
#: sievefilters/constants.py:16
msgid "contains"
@@ -3017,8 +3023,8 @@ msgid ""
"primary address, and check your spam folder.</p>"
msgstr ""
"<p>Enviamos instruções por e-mail para definir sua senha, se houver uma "
"conta com o e-mail que você digitou. Você deve recebê-lo em breve.</p> <p>Se "
"você não receber um e-mail, certifique-se de ter digitado seu endereço "
"conta com o e-mail que você digitou. Você deve recebê-lo em breve.</p> <p>Se"
" você não receber um e-mail, certifique-se de ter digitado seu endereço "
"principal e verifique sua pasta de spam.</p>"
#: templates/registration/password_reset_email.html:4
@@ -3037,8 +3043,8 @@ msgid ""
"If clicking the link above doesn't work, please copy and paste the URL in a "
"new browser window instead."
msgstr ""
"Se clicar no link acima não funcionar, copie e cole a URL em uma nova janela "
"do navegador."
"Se clicar no link acima não funcionar, copie e cole a URL em uma nova janela"
" do navegador."
#: templates/registration/password_reset_email.html:14
#: templates/registration/password_reset_email_v2.html:14
@@ -3067,11 +3073,11 @@ msgstr "Senha de uso único"
#: templates/registration/twofactor_code_verify.html:35
msgid ""
"Enter the code from the two-factor app on your mobile device. If you've lost "
"your device, you may enter one of your recovery codes."
"Enter the code from the two-factor app on your mobile device. If you've lost"
" your device, you may enter one of your recovery codes."
msgstr ""
"Digite o código do aplicativo de dois fatores em seu celular. Se você perdeu "
"seu dispositivo, pode digitar um de seus códigos de recuperação."
"Digite o código do aplicativo de dois fatores em seu celular. Se você perdeu"
" seu dispositivo, pode digitar um de seus códigos de recuperação."
#: templates/registration/twofactor_code_verify.html:42
msgid "Verify code"
@@ -3335,6 +3341,5 @@ msgstr "Anexo muito grande (limite: %s)"
#~ msgstr "IDs de alarme inválidos recebidos"
#, fuzzy, python-brace-format
#~| msgid "Connection to IMAP server failed: %s"
#~ msgid "Connection to IMAP server failed: {error}"
#~ msgstr "Falha na conexão com o servidor IMAP: %s"
+47 -40
View File
@@ -16,8 +16,7 @@ msgstr ""
"POT-Creation-Date: 2025-08-28 09:41+0200\n"
"PO-Revision-Date: 2024-07-17 11:45+0200\n"
"Last-Translator: Mike C. <miguelmclara@gmail.com>\n"
"Language-Team: Portuguese (Portugal) (http://www.transifex.com/projects/p/"
"modoboa/language/pt_PT/)\n"
"Language-Team: Portuguese (Portugal) (http://www.transifex.com/projects/p/modoboa/language/pt_PT/)\n"
"Language: pt_PT\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -211,8 +210,8 @@ msgstr ""
#: admin/app_settings.py:37
msgid ""
"A list of IP or network address every MX record should match. A warning will "
"be sent if a record does not respect it."
"A list of IP or network address every MX record should match. A warning will"
" be sent if a record does not respect it."
msgstr ""
#: admin/app_settings.py:47
@@ -385,7 +384,8 @@ msgid "Automatic domain/mailbox creation"
msgstr "Criação automatica de domino/caixa de correio"
#: admin/app_settings.py:221
msgid "Create a domain and a mailbox when an account is automatically created."
msgid ""
"Create a domain and a mailbox when an account is automatically created."
msgstr ""
"Criar um dominio e uma caixa de correio quando uma conta é criada "
"automátiamente."
@@ -775,7 +775,8 @@ msgstr "Geral"
#: autoreply/app_settings.py:18
#, fuzzy
#| msgid "Timeout in seconds between two auto-replies to the same recipient"
#| msgid ""
#| "Timeout in seconds between two auto-replies to the same recipient"
msgid "Period between two auto-replies"
msgstr ""
"Tempo limite em segundos entre duas respostas automáticas para o mesmo "
@@ -783,7 +784,8 @@ msgstr ""
#: autoreply/app_settings.py:20
#, fuzzy
#| msgid "Timeout in seconds between two auto-replies to the same recipient"
#| msgid ""
#| "Timeout in seconds between two auto-replies to the same recipient"
msgid ""
"Number of days to wait before sending a new auto-reply to the same recipient"
msgstr ""
@@ -1020,7 +1022,8 @@ msgstr "Número de linhas inválido"
msgid "This code is invalid"
msgstr ""
#: core/api/v2/serializers.py:503 core/views/auth.py:194 core/views/auth.py:247
#: core/api/v2/serializers.py:503 core/views/auth.py:194
#: core/views/auth.py:247
msgid "Please use the following code to recover your Modoboa password: {}"
msgstr ""
@@ -1234,8 +1237,8 @@ msgstr "Grupos de Administrador"
#: core/app_settings.py:239
msgid ""
"Members of those LDAP Posix groups will be created as domain administrators. "
"Use ';' characters to separate groups."
"Members of those LDAP Posix groups will be created as domain administrators."
" Use ';' characters to separate groups."
msgstr ""
"Os membros destes grupos \"LDAP Posix\" serão criados como administradores "
"de domínio. Use ';' para separar os grupos."
@@ -1298,8 +1301,7 @@ msgstr "Password para bind"
#: core/app_settings.py:307 core/app_settings.py:369
msgid "The password to use when binding to the LDAP server (with 'Bind DN')"
msgstr ""
"A password usada para fazer o \"bind\" ao servidor LDAP (com 'Bind DN')"
msgstr "A password usada para fazer o \"bind\" ao servidor LDAP (com 'Bind DN')"
#: core/app_settings.py:317 core/app_settings.py:422
msgid "Users search base"
@@ -1558,8 +1560,8 @@ msgstr ""
#: core/app_settings.py:686
msgid ""
"Allow the administrator to set a threshold (in days) beyond which an account "
"is considered inactive if the user hasn't logged in"
"Allow the administrator to set a threshold (in days) beyond which an account"
" is considered inactive if the user hasn't logged in"
msgstr ""
#: core/app_settings.py:695
@@ -1568,8 +1570,8 @@ msgstr ""
#: core/app_settings.py:698
msgid ""
"An account with a last login date greater than this threshold (in days) will "
"be considered as inactive"
"An account with a last login date greater than this threshold (in days) will"
" be considered as inactive"
msgstr ""
#: core/app_settings.py:707
@@ -1645,8 +1647,9 @@ msgstr ""
#: core/checks.py:34
msgid ""
"Visit : https://modoboa.readthedocs.io/en/latest/manual_installation/"
"dovecot.html#dovecot-oauth2"
"Visit : "
"https://modoboa.readthedocs.io/en/latest/manual_installation/dovecot.html#dovecot-"
"oauth2"
msgstr ""
#: core/checks.py:41
@@ -1657,8 +1660,9 @@ msgstr ""
#: core/checks.py:45
msgid ""
"Visit : https://modoboa.readthedocs.io/en/latest/manual_installation/"
"radicale.html#radicale-oauth2"
"Visit : "
"https://modoboa.readthedocs.io/en/latest/manual_installation/radicale.html#radicale-"
"oauth2"
msgstr ""
#: core/constants.py:6
@@ -1826,8 +1830,8 @@ msgstr "O simple utilizador '%s' deve ter endereço de e-mail válido"
#| msgid "username and email fields must not differ for '%s'"
msgid "username and email fields must not differ for '{}'"
msgstr ""
"Os campos nome de utilizador e endereço de email não deve ser diferente para "
"'%s'"
"Os campos nome de utilizador e endereço de email não deve ser diferente para"
" '%s'"
#: core/password_validation.py:25
msgid "Password must contain at least {} digit."
@@ -1983,7 +1987,7 @@ msgstr "Nenhum"
#, fuzzy
#| msgid "Quantity"
msgid "Quarantine"
msgstr "Quantidade"
msgstr "Quarentena"
#: dmarc/models.py:12
#, fuzzy
@@ -2288,10 +2292,11 @@ msgstr "Aliases de domínio"
#: limits/app_settings.py:52
#, fuzzy
#| msgid "Maximum number of allowed domain aliases for a new administrator"
#| msgid ""
#| "Maximum number of allowed domain aliases for a new administrator"
msgid ""
"Maximum number of allowed domain aliases for a new administrator. (0 to deny "
"any creation, -1 to allow unlimited creations)"
"Maximum number of allowed domain aliases for a new administrator. (0 to deny"
" any creation, -1 to allow unlimited creations)"
msgstr ""
"Número máximo permitido de aliases de domínio para um novo administrador"
@@ -2345,15 +2350,16 @@ msgstr ""
#| msgid ""
#| "Maximum number of allowed domain administrators for a new administrator"
msgid ""
"Maximum number of allowed domain administrators for a new domain. (0 to deny "
"any creation, -1 to allow unlimited creations)"
"Maximum number of allowed domain administrators for a new domain. (0 to deny"
" any creation, -1 to allow unlimited creations)"
msgstr ""
"Número máximo permitido de administradores de domínio para um novo "
"administrador"
#: limits/app_settings.py:126
#, fuzzy
#| msgid "Maximum number of allowed domain aliases for a new administrator"
#| msgid ""
#| "Maximum number of allowed domain aliases for a new administrator"
msgid ""
"Maximum number of allowed domain aliases for a new domain. (0 to deny any "
"creation, -1 to allow unlimited creations)"
@@ -2372,8 +2378,8 @@ msgstr "Número máximo permitido de caixas de correio para novo administrador"
#, fuzzy
#| msgid "Maximum number of allowed aliases for a new administrator"
msgid ""
"Maximum number of allowed aliases for a new domain. (0 to deny any creation, "
"-1 to allow unlimited creations)"
"Maximum number of allowed aliases for a new domain. (0 to deny any creation,"
" -1 to allow unlimited creations)"
msgstr "Número máximo de aliases permitidas para um novo administrador"
#: limits/apps.py:16
@@ -2395,7 +2401,8 @@ msgstr "Número máximo de caixas de correio que este utilizador por criar"
#: limits/constants.py:40
msgid "Maximum number of mailbox aliases this user can create"
msgstr ""
"Número máximo de aliases para caixas de correio que este utilizador por criar"
"Número máximo de aliases para caixas de correio que este utilizador por "
"criar"
#: limits/constants.py:49
msgid "Maximum number of domain administrators this user can create"
@@ -2423,7 +2430,8 @@ msgstr "Número máximo de caixas de correio que este utilizador por criar"
#| msgid "Maximum number of mailbox aliases this user can create"
msgid "Maximum number of mailbox aliases allowed for this domain."
msgstr ""
"Número máximo de aliases para caixas de correio que este utilizador por criar"
"Número máximo de aliases para caixas de correio que este utilizador por "
"criar"
#: limits/constants.py:102
#, fuzzy
@@ -2833,8 +2841,8 @@ msgstr ""
#: rspamd/app_settings.py:21
msgid ""
"Absolute path of the file which contains paths to DKIM private keys. Must be "
"readable by _rspamd group or user."
"Absolute path of the file which contains paths to DKIM private keys. Must be"
" readable by _rspamd group or user."
msgstr ""
#: rspamd/app_settings.py:30
@@ -2853,8 +2861,8 @@ msgstr ""
#: rspamd/app_settings.py:53
msgid ""
"Location of the rspamd dashboard. Can either be a relative URL (eg. '/"
"rspamd') or a full URL (eg. 'https://rspamd.domain.tld/').Only use for "
"Location of the rspamd dashboard. Can either be a relative URL (eg. "
"'/rspamd') or a full URL (eg. 'https://rspamd.domain.tld/').Only use for "
"guidance on the Super-Admin dashboard."
msgstr ""
@@ -3149,8 +3157,8 @@ msgstr "Password antiga"
#: templates/registration/twofactor_code_verify.html:35
msgid ""
"Enter the code from the two-factor app on your mobile device. If you've lost "
"your device, you may enter one of your recovery codes."
"Enter the code from the two-factor app on your mobile device. If you've lost"
" your device, you may enter one of your recovery codes."
msgstr ""
#: templates/registration/twofactor_code_verify.html:42
@@ -3401,6 +3409,5 @@ msgid "Attachment is too big (limit: %s)"
msgstr "Anexo demasiado grande (limite %s)"
#, fuzzy, python-brace-format
#~| msgid "Connection to IMAP server failed: %s"
#~ msgid "Connection to IMAP server failed: {error}"
#~ msgstr "Ligação ao servidor IMAP falhou : %s"
+55 -48
View File
@@ -17,15 +17,12 @@ msgstr ""
"POT-Creation-Date: 2025-08-28 09:41+0200\n"
"PO-Revision-Date: 2020-05-06 11:16+0000\n"
"Last-Translator: Antoine Nguyen <tonio@ngyn.org>\n"
"Language-Team: Russian (http://www.transifex.com/tonio/modoboa/language/"
"ru/)\n"
"Language-Team: Russian (http://www.transifex.com/tonio/modoboa/language/ru/)\n"
"Language: ru\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
"n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || "
"(n%100>=11 && n%100<=14)? 2 : 3);\n"
"Plural-Forms: nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%100>=11 && n%100<=14)? 2 : 3);\n"
#: admin/api/v1/serializers.py:39
msgid ""
@@ -200,8 +197,8 @@ msgstr ""
#: admin/app_settings.py:37
msgid ""
"A list of IP or network address every MX record should match. A warning will "
"be sent if a record does not respect it."
"A list of IP or network address every MX record should match. A warning will"
" be sent if a record does not respect it."
msgstr ""
#: admin/app_settings.py:47
@@ -361,7 +358,8 @@ msgid "Automatic domain/mailbox creation"
msgstr "Домен создан"
#: admin/app_settings.py:221
msgid "Create a domain and a mailbox when an account is automatically created."
msgid ""
"Create a domain and a mailbox when an account is automatically created."
msgstr ""
#: admin/app_settings.py:230
@@ -744,13 +742,15 @@ msgstr "Основные"
#: autoreply/app_settings.py:18
#, fuzzy
#| msgid "Timeout in seconds between two auto-replies to the same recipient"
#| msgid ""
#| "Timeout in seconds between two auto-replies to the same recipient"
msgid "Period between two auto-replies"
msgstr "Промежуток между автоматическими ответами"
#: autoreply/app_settings.py:20
#, fuzzy
#| msgid "Timeout in seconds between two auto-replies to the same recipient"
#| msgid ""
#| "Timeout in seconds between two auto-replies to the same recipient"
msgid ""
"Number of days to wait before sending a new auto-reply to the same recipient"
msgstr "Промежуток между автоматическими ответами"
@@ -978,7 +978,8 @@ msgstr "Неправильное количество циклов"
msgid "This code is invalid"
msgstr ""
#: core/api/v2/serializers.py:503 core/views/auth.py:194 core/views/auth.py:247
#: core/api/v2/serializers.py:503 core/views/auth.py:194
#: core/views/auth.py:247
msgid "Please use the following code to recover your Modoboa password: {}"
msgstr ""
@@ -1034,8 +1035,8 @@ msgid ""
"Number of rounds to use (only used by sha256crypt and sha512crypt). Must be "
"between 1000 and 999999999, inclusive."
msgstr ""
"Количество циклов (используется только для sha256crypt и sha512crypt), Может "
"быть от 1000 до 999999999, включительно."
"Количество циклов (используется только для sha256crypt и sha512crypt), Может"
" быть от 1000 до 999999999, включительно."
#: core/app_settings.py:73
msgid "Update password scheme at login"
@@ -1180,8 +1181,8 @@ msgstr "Администратор груп"
#: core/app_settings.py:239
msgid ""
"Members of those LDAP Posix groups will be created as domain administrators. "
"Use ';' characters to separate groups."
"Members of those LDAP Posix groups will be created as domain administrators."
" Use ';' characters to separate groups."
msgstr ""
"Члены этих LDAP Posix групп должны быть созданы администратором домена. "
"Используйте ';' для как разделитель груп"
@@ -1259,8 +1260,8 @@ msgid ""
"An optional filter string (e.g. '(objectClass=person)'). In order to be "
"valid, it must be enclosed in parentheses."
msgstr ""
"Необязательная срока поиска (например '(objectClass=person)') Значение нужно "
"заключить в скобки"
"Необязательная срока поиска (например '(objectClass=person)') Значение нужно"
" заключить в скобки"
#: core/app_settings.py:339
msgid "User DN template"
@@ -1272,8 +1273,8 @@ msgid ""
"The template used to construct a user's DN. It should contain one "
"placeholder (ie. %(user)s)"
msgstr ""
"Шаблон используется для построения запросов к DN Он должен содержать атрибут "
"например (%(user)s)"
"Шаблон используется для построения запросов к DN Он должен содержать атрибут"
" например (%(user)s)"
#: core/app_settings.py:350
msgid "LDAP synchronization settings"
@@ -1368,7 +1369,8 @@ msgstr ""
#: core/app_settings.py:506
#, fuzzy
#| msgid "Display custom RSS feed to resellers and domain administrators"
#| msgid ""
#| "Display custom RSS feed to resellers and domain administrators"
msgid "Display custom RSS feed to super admins"
msgstr ""
"Отображать пользовательскую ленту RSS для реселлеров и администраторов "
@@ -1376,7 +1378,8 @@ msgstr ""
#: core/app_settings.py:509
#, fuzzy
#| msgid "Display custom RSS feed to resellers and domain administrators"
#| msgid ""
#| "Display custom RSS feed to resellers and domain administrators"
msgid "Display custom RSS feed also to super administrators"
msgstr ""
"Отображать пользовательскую ленту RSS для реселлеров и администраторов "
@@ -1388,7 +1391,8 @@ msgstr "Спрятать виджет новых функций"
#: core/app_settings.py:519
msgid "Hide features widget for resellers and domain administrators"
msgstr "Спрятать виджет новых функций для реселлеров и администраторов доменов"
msgstr ""
"Спрятать виджет новых функций для реселлеров и администраторов доменов"
#: core/app_settings.py:531
msgid "Theme"
@@ -1498,8 +1502,8 @@ msgstr "Порог неактивного аккаунта"
#: core/app_settings.py:686
msgid ""
"Allow the administrator to set a threshold (in days) beyond which an account "
"is considered inactive if the user hasn't logged in"
"Allow the administrator to set a threshold (in days) beyond which an account"
" is considered inactive if the user hasn't logged in"
msgstr ""
#: core/app_settings.py:695
@@ -1508,8 +1512,8 @@ msgstr "Порог неактивного аккаунта"
#: core/app_settings.py:698
msgid ""
"An account with a last login date greater than this threshold (in days) will "
"be considered as inactive"
"An account with a last login date greater than this threshold (in days) will"
" be considered as inactive"
msgstr ""
"Аккаунт с датой последнего входа, превышающей этот порог (в днях), будет "
"считаться неактивным"
@@ -1552,7 +1556,8 @@ msgstr "Порог перенаправления по умолчанию"
#: core/app_settings.py:748
msgid "The default redirection used when no application is specified"
msgstr "Если приложение не указано. Используется перенаправление по умолчанию."
msgstr ""
"Если приложение не указано. Используется перенаправление по умолчанию."
#: core/checks.py:15
msgid ""
@@ -1581,8 +1586,9 @@ msgstr ""
#: core/checks.py:34
msgid ""
"Visit : https://modoboa.readthedocs.io/en/latest/manual_installation/"
"dovecot.html#dovecot-oauth2"
"Visit : "
"https://modoboa.readthedocs.io/en/latest/manual_installation/dovecot.html#dovecot-"
"oauth2"
msgstr ""
#: core/checks.py:41
@@ -1593,8 +1599,9 @@ msgstr ""
#: core/checks.py:45
msgid ""
"Visit : https://modoboa.readthedocs.io/en/latest/manual_installation/"
"radicale.html#radicale-oauth2"
"Visit : "
"https://modoboa.readthedocs.io/en/latest/manual_installation/radicale.html#radicale-"
"oauth2"
msgstr ""
#: core/constants.py:6
@@ -2202,10 +2209,11 @@ msgstr "Синонимы доменов"
#: limits/app_settings.py:52
#, fuzzy
#| msgid "Maximum number of allowed domain aliases for a new administrator"
#| msgid ""
#| "Maximum number of allowed domain aliases for a new administrator"
msgid ""
"Maximum number of allowed domain aliases for a new administrator. (0 to deny "
"any creation, -1 to allow unlimited creations)"
"Maximum number of allowed domain aliases for a new administrator. (0 to deny"
" any creation, -1 to allow unlimited creations)"
msgstr "Максимальное количество синонимов доменов для нового администратора"
#: limits/app_settings.py:64
@@ -2258,14 +2266,15 @@ msgstr ""
#| msgid ""
#| "Maximum number of allowed domain administrators for a new administrator"
msgid ""
"Maximum number of allowed domain administrators for a new domain. (0 to deny "
"any creation, -1 to allow unlimited creations)"
"Maximum number of allowed domain administrators for a new domain. (0 to deny"
" any creation, -1 to allow unlimited creations)"
msgstr ""
"Максимальное количество администраторов домена для нового администратора"
#: limits/app_settings.py:126
#, fuzzy
#| msgid "Maximum number of allowed domain aliases for a new administrator"
#| msgid ""
#| "Maximum number of allowed domain aliases for a new administrator"
msgid ""
"Maximum number of allowed domain aliases for a new domain. (0 to deny any "
"creation, -1 to allow unlimited creations)"
@@ -2283,8 +2292,8 @@ msgstr "Максимальное количество почтовых ящик
#, fuzzy
#| msgid "Maximum number of allowed aliases for a new administrator"
msgid ""
"Maximum number of allowed aliases for a new domain. (0 to deny any creation, "
"-1 to allow unlimited creations)"
"Maximum number of allowed aliases for a new domain. (0 to deny any creation,"
" -1 to allow unlimited creations)"
msgstr "Максимальное количество синонимов для нового администратора"
#: limits/apps.py:16
@@ -2772,8 +2781,8 @@ msgstr ""
#: rspamd/app_settings.py:21
msgid ""
"Absolute path of the file which contains paths to DKIM private keys. Must be "
"readable by _rspamd group or user."
"Absolute path of the file which contains paths to DKIM private keys. Must be"
" readable by _rspamd group or user."
msgstr ""
#: rspamd/app_settings.py:30
@@ -2792,8 +2801,8 @@ msgstr ""
#: rspamd/app_settings.py:53
msgid ""
"Location of the rspamd dashboard. Can either be a relative URL (eg. '/"
"rspamd') or a full URL (eg. 'https://rspamd.domain.tld/').Only use for "
"Location of the rspamd dashboard. Can either be a relative URL (eg. "
"'/rspamd') or a full URL (eg. 'https://rspamd.domain.tld/').Only use for "
"guidance on the Super-Admin dashboard."
msgstr ""
@@ -3080,8 +3089,8 @@ msgstr "Старый пароль"
#: templates/registration/twofactor_code_verify.html:35
msgid ""
"Enter the code from the two-factor app on your mobile device. If you've lost "
"your device, you may enter one of your recovery codes."
"Enter the code from the two-factor app on your mobile device. If you've lost"
" your device, you may enter one of your recovery codes."
msgstr ""
#: templates/registration/twofactor_code_verify.html:42
@@ -3342,7 +3351,5 @@ msgid "Attachment is too big (limit: %s)"
msgstr "Вложения слишком велики (лимит: %s)"
#, fuzzy, python-brace-format
#~| msgid "Connection to MANAGESIEVE server failed, check your configuration"
#~ msgid "Connection to IMAP server failed: {error}"
#~ msgstr ""
#~ "Соединение с сервером MANAGESIEVE не удалось, проверьте конфигурацию"
#~ msgstr "Соединение с сервером MANAGESIEVE не удалось, проверьте конфигурацию"
+76 -66
View File
@@ -12,10 +12,8 @@ msgstr ""
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-08-28 09:41+0200\n"
"PO-Revision-Date: 2011-07-01 08:15+0000\n"
"Last-Translator: Olle Gustafsson <olle@dalnix.se>, "
"2013,2015-2018,2020,2022-2023,2025\n"
"Language-Team: Swedish (http://app.transifex.com/tonio/modoboa/language/"
"sv/)\n"
"Last-Translator: Olle Gustafsson <olle@dalnix.se>, 2013,2015-2018,2020,2022-2023,2025\n"
"Language-Team: Swedish (http://app.transifex.com/tonio/modoboa/language/sv/)\n"
"Language: sv\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -27,8 +25,8 @@ msgid ""
"Quota shared between mailboxes. Can be expressed in KB, MB (default) or GB. "
"A value of 0 means no quota."
msgstr ""
"Kvot som delas mellan brevlådor. Kan uttryckas i KB, MB (standard) eller GB. "
"Ett värde på 0 betyder ingen kvot."
"Kvot som delas mellan brevlådor. Kan uttryckas i KB, MB (standard) eller GB."
" Ett värde på 0 betyder ingen kvot."
#: admin/api/v1/serializers.py:46
msgid "Default quota in MB applied to mailboxes. A value of 0 means no quota."
@@ -184,8 +182,8 @@ msgstr "Giltiga MX"
#: admin/app_settings.py:37
msgid ""
"A list of IP or network address every MX record should match. A warning will "
"be sent if a record does not respect it."
"A list of IP or network address every MX record should match. A warning will"
" be sent if a record does not respect it."
msgstr ""
"En lista med IP- eller nätverksadresser som varje MX-post ska matcha. En "
"varning kommer att skickas om en post inte respekterar den."
@@ -199,8 +197,8 @@ msgid ""
"Prevent the creation of a new domain if its MX record does not use one of "
"the defined addresses."
msgstr ""
"Förhindra skapandet av en ny domän om dess MX-post inte använder någon av de "
"definierade adresserna."
"Förhindra skapandet av en ny domän om dess MX-post inte använder någon av de"
" definierade adresserna."
#: admin/app_settings.py:59
msgid "Enable IPV6 checks"
@@ -344,8 +342,8 @@ msgid ""
"Number of messages freshly created mailboxes will be allowed to send per "
"day. Leave empty for no limit."
msgstr ""
"Antal meddelanden som nyskapade brevlådor tillåts skicka per dag. Lämna tomt "
"utan gräns."
"Antal meddelanden som nyskapade brevlådor tillåts skicka per dag. Lämna tomt"
" utan gräns."
#: admin/app_settings.py:207
msgid "Automatic account removal"
@@ -360,7 +358,8 @@ msgid "Automatic domain/mailbox creation"
msgstr "Automatisk domän-/brevlådeskapande"
#: admin/app_settings.py:221
msgid "Create a domain and a mailbox when an account is automatically created."
msgid ""
"Create a domain and a mailbox when an account is automatically created."
msgstr "Skapa en domän och en postlåda när ett konto skapas automatiskt."
#: admin/app_settings.py:230
@@ -681,8 +680,8 @@ msgid ""
"coming from it are considered as spam. You should contact those providers "
"and ask them to unlist detected IP address(es)."
msgstr ""
"Domänens rykte kommer att påverkas och det finns en chans att e-"
"postmeddelanden som kommer från den betraktas som spam. Du bör kontakta "
"Domänens rykte kommer att påverkas och det finns en chans att "
"e-postmeddelanden som kommer från den betraktas som spam. Du bör kontakta "
"dessa leverantörer och be dem att ta bort upptäckta IP-adresser."
#: admin/templates/admin/notifications/domain_invalid_mx.html:3
@@ -915,7 +914,8 @@ msgstr "2FA redan aktiverat"
#| msgid "Failed TFA settings editing attempt from '%s' as user '%s'"
msgid "Failed TFA settings editing attempt from '%(addr)s' as user '%(user)s'"
msgstr ""
"Misslyckades TFA-inställningar redigeringsförsök från '%s' som användare '%s'"
"Misslyckades TFA-inställningar redigeringsförsök från '%s' som användare "
"'%s'"
#: core/api/v1/serializers.py:91 core/api/v2/serializers.py:445
msgid "Invalid password"
@@ -946,7 +946,8 @@ msgstr "Ogiltigt antal omgångar"
msgid "This code is invalid"
msgstr "Denna kod är ogiltig"
#: core/api/v2/serializers.py:503 core/views/auth.py:194 core/views/auth.py:247
#: core/api/v2/serializers.py:503 core/views/auth.py:194
#: core/views/auth.py:247
msgid "Please use the following code to recover your Modoboa password: {}"
msgstr "Använd följande kod för att återställa ditt Modoboa lösenord: {}"
@@ -1150,8 +1151,8 @@ msgstr "Administratörsgrupper"
#: core/app_settings.py:239
msgid ""
"Members of those LDAP Posix groups will be created as domain administrators. "
"Use ';' characters to separate groups."
"Members of those LDAP Posix groups will be created as domain administrators."
" Use ';' characters to separate groups."
msgstr ""
"Användare av dessa LDAP Posix grupper kommer skapas som "
"domänadministratörer. Använd ';' för att separera grupper."
@@ -1243,8 +1244,8 @@ msgid ""
"The template used to construct a user's DN. It should contain one "
"placeholder (ie. %(user)s)"
msgstr ""
"Mallen som används för att konstruera en användares DN. Den bör innehålla en "
"platshållare (dvs. %(user)s)"
"Mallen som används för att konstruera en användares DN. Den bör innehålla en"
" platshållare (dvs. %(user)s)"
#: core/app_settings.py:350
msgid "LDAP synchronization settings"
@@ -1269,7 +1270,8 @@ msgid ""
"Delete remote LDAP account when local account is deleted, otherwise it will "
"be disabled."
msgstr ""
"Radera LDAP-fjärrkonto när det lokala kontot raderas, annars inaktiveras det."
"Radera LDAP-fjärrkonto när det lokala kontot raderas, annars inaktiveras "
"det."
#: core/app_settings.py:401
msgid "Account DN template"
@@ -1306,7 +1308,8 @@ msgstr "Aktivera Dovecot LDAP-synkronisering"
#: core/app_settings.py:457
msgid "LDAP authentication settings will be applied to Dovecot configuration."
msgstr "LDAP-autentiseringsinställningar tillämpas på Dovecot-konfigurationen."
msgstr ""
"LDAP-autentiseringsinställningar tillämpas på Dovecot-konfigurationen."
#: core/app_settings.py:465
msgid "Dovecot LDAP config file"
@@ -1344,21 +1347,26 @@ msgstr "Användardefinierat RSS-flöde"
#: core/app_settings.py:497
msgid "Display custom RSS feed to resellers and domain administrators"
msgstr ""
"Visa användardefinierat RSS-flöde för återförsäljare och domänadministratörer"
"Visa användardefinierat RSS-flöde för återförsäljare och "
"domänadministratörer"
#: core/app_settings.py:506
#, fuzzy
#| msgid "Display custom RSS feed to resellers and domain administrators"
#| msgid ""
#| "Display custom RSS feed to resellers and domain administrators"
msgid "Display custom RSS feed to super admins"
msgstr ""
"Visa användardefinierat RSS-flöde för återförsäljare och domänadministratörer"
"Visa användardefinierat RSS-flöde för återförsäljare och "
"domänadministratörer"
#: core/app_settings.py:509
#, fuzzy
#| msgid "Display custom RSS feed to resellers and domain administrators"
#| msgid ""
#| "Display custom RSS feed to resellers and domain administrators"
msgid "Display custom RSS feed also to super administrators"
msgstr ""
"Visa användardefinierat RSS-flöde för återförsäljare och domänadministratörer"
"Visa användardefinierat RSS-flöde för återförsäljare och "
"domänadministratörer"
#: core/app_settings.py:517
msgid "Hide features widget"
@@ -1474,8 +1482,8 @@ msgstr "Aktivera spårning av inaktiva konton"
#: core/app_settings.py:686
msgid ""
"Allow the administrator to set a threshold (in days) beyond which an account "
"is considered inactive if the user hasn't logged in"
"Allow the administrator to set a threshold (in days) beyond which an account"
" is considered inactive if the user hasn't logged in"
msgstr ""
"Tillåt administratören att ställa in en tröskel (i dagar) över vilken ett "
"konto anses inaktivt om användaren inte har loggat in"
@@ -1486,8 +1494,8 @@ msgstr "Gräns för inaktiva konton"
#: core/app_settings.py:698
msgid ""
"An account with a last login date greater than this threshold (in days) will "
"be considered as inactive"
"An account with a last login date greater than this threshold (in days) will"
" be considered as inactive"
msgstr ""
"Ett konto som inte har loggat in innan denna gräns (antal dagar) kommer "
"anses som inaktivt"
@@ -1562,8 +1570,9 @@ msgstr ""
#: core/checks.py:34
msgid ""
"Visit : https://modoboa.readthedocs.io/en/latest/manual_installation/"
"dovecot.html#dovecot-oauth2"
"Visit : "
"https://modoboa.readthedocs.io/en/latest/manual_installation/dovecot.html#dovecot-"
"oauth2"
msgstr ""
#: core/checks.py:41
@@ -1574,8 +1583,9 @@ msgstr ""
#: core/checks.py:45
msgid ""
"Visit : https://modoboa.readthedocs.io/en/latest/manual_installation/"
"radicale.html#radicale-oauth2"
"Visit : "
"https://modoboa.readthedocs.io/en/latest/manual_installation/radicale.html#radicale-"
"oauth2"
msgstr ""
#: core/constants.py:6
@@ -1751,7 +1761,8 @@ msgstr[1] "Lösenord måste innehålla minst {} specialtecken."
#: core/password_validation.py:70
msgid "Your password must contain a combination of different character types."
msgstr "Ditt lösenord måste innehålla en kombination av olika typer av tecken."
msgstr ""
"Ditt lösenord måste innehålla en kombination av olika typer av tecken."
#: core/sms_backends/ovh.py:21 core/sms_backends/ovh.py:102
msgid "API endpoint"
@@ -2141,8 +2152,8 @@ msgid ""
"Maximum number of allowed domain administrators for a new administrator. (0 "
"to deny any creation, -1 to allow unlimited creations)"
msgstr ""
"Maximalt antal tillåtna domänadministratörer för en ny administratör. (0 för "
"att neka någon skapelse, -1 för att tillåta obegränsade skapelser)"
"Maximalt antal tillåtna domänadministratörer för en ny administratör. (0 för"
" att neka någon skapelse, -1 för att tillåta obegränsade skapelser)"
#: limits/app_settings.py:41
msgid ""
@@ -2159,8 +2170,8 @@ msgstr "Domän alias"
#: limits/app_settings.py:52
msgid ""
"Maximum number of allowed domain aliases for a new administrator. (0 to deny "
"any creation, -1 to allow unlimited creations)"
"Maximum number of allowed domain aliases for a new administrator. (0 to deny"
" any creation, -1 to allow unlimited creations)"
msgstr ""
"Maximalt antal tillåtna domänalias för en ny administratör. (0 för att neka "
"någon skapelse, -1 för att tillåta obegränsade skapelser)"
@@ -2183,8 +2194,8 @@ msgid ""
"Maximum number of allowed aliases for a new administrator. (0 to deny any "
"creation, -1 to allow unlimited creations)"
msgstr ""
"Maximalt antal tillåtna alias för en ny administratör. (0 för att neka någon "
"skapelse, -1 för att tillåta obegränsade skapelser)"
"Maximalt antal tillåtna alias för en ny administratör. (0 för att neka någon"
" skapelse, -1 för att tillåta obegränsade skapelser)"
#: limits/app_settings.py:84 limits/constants.py:59
msgid "Quota"
@@ -2212,8 +2223,8 @@ msgstr "Aktivera eller inaktivera gränser per domän"
#: limits/app_settings.py:114
msgid ""
"Maximum number of allowed domain administrators for a new domain. (0 to deny "
"any creation, -1 to allow unlimited creations)"
"Maximum number of allowed domain administrators for a new domain. (0 to deny"
" any creation, -1 to allow unlimited creations)"
msgstr ""
"Maximalt antal tillåtna domänadministratörer för en ny domän. (0 för att "
"neka någon skapelse, -1 för att tillåta obegränsade skapelser)"
@@ -2236,8 +2247,8 @@ msgstr ""
#: limits/app_settings.py:149
msgid ""
"Maximum number of allowed aliases for a new domain. (0 to deny any creation, "
"-1 to allow unlimited creations)"
"Maximum number of allowed aliases for a new domain. (0 to deny any creation,"
" -1 to allow unlimited creations)"
msgstr ""
"Maximalt antal tillåtna alias för en ny domän. (0 för att neka någon "
"skapelse, -1 för att tillåta obegränsade skapelser)"
@@ -2456,8 +2467,8 @@ msgid ""
"Generate a new document only when a new account is created. If set to no, a "
"new document will be created each time a password is updated."
msgstr ""
"Skapa ett nytt dokument först när ett nytt konto har skapats. Om inställt på "
"nej kommer ett nytt dokument att skapas varje gång ett lösenord uppdateras."
"Skapa ett nytt dokument först när ett nytt konto har skapats. Om inställt på"
" nej kommer ett nytt dokument att skapas varje gång ett lösenord uppdateras."
#: pdfcredentials/app_settings.py:84
msgid "Customization options"
@@ -2583,8 +2594,7 @@ msgid ""
"your contacts.\n"
msgstr ""
"\n"
"Här kan du se dina e-postmeddelanden när som helst online, skapa filter "
"eller hantera\n"
"Här kan du se dina e-postmeddelanden när som helst online, skapa filter eller hantera\n"
"dina kontakter.\n"
#: pdfcredentials/documents.py:126
@@ -2685,11 +2695,11 @@ msgstr "Sökväg till nyckelkarta"
#: rspamd/app_settings.py:21
msgid ""
"Absolute path of the file which contains paths to DKIM private keys. Must be "
"readable by _rspamd group or user."
"Absolute path of the file which contains paths to DKIM private keys. Must be"
" readable by _rspamd group or user."
msgstr ""
"Absolut sökväg till filen som innehåller sökvägar till DKIM privata nycklar. "
"Måste vara läsbar av _rspamd-gruppen eller användaren."
"Absolut sökväg till filen som innehåller sökvägar till DKIM privata nycklar."
" Måste vara läsbar av _rspamd-gruppen eller användaren."
#: rspamd/app_settings.py:30
msgid "Selector map path"
@@ -2709,8 +2719,8 @@ msgstr "Plats för Rspamd-dashboard"
#: rspamd/app_settings.py:53
msgid ""
"Location of the rspamd dashboard. Can either be a relative URL (eg. '/"
"rspamd') or a full URL (eg. 'https://rspamd.domain.tld/').Only use for "
"Location of the rspamd dashboard. Can either be a relative URL (eg. "
"'/rspamd') or a full URL (eg. 'https://rspamd.domain.tld/').Only use for "
"guidance on the Super-Admin dashboard."
msgstr ""
"Plats för Rspamd-dashboarden. Kan vara en relativ URL (t.ex. '/rspamd') "
@@ -2939,9 +2949,9 @@ msgid ""
"primary address, and check your spam folder.</p>"
msgstr ""
"<p>Vi har e-postat dig instruktioner för att ändra ditt lösenord, om ett "
"konto finns med den e-post adress du angav. Du borde få detta brev inom kort."
"</p> <p>Om du inte fått något brev, var vänlig kontrollera att du angav rätt "
"e-post adress, och kolla din skräpkatalog.</p>"
"konto finns med den e-post adress du angav. Du borde få detta brev inom "
"kort.</p> <p>Om du inte fått något brev, var vänlig kontrollera att du angav"
" rätt e-post adress, och kolla din skräpkatalog.</p>"
#: templates/registration/password_reset_email.html:4
#: templates/registration/password_reset_email_v2.html:4
@@ -2950,8 +2960,8 @@ msgid ""
"To initiate the password reset process for your %(username)s Modoboa "
"account, click the link below:"
msgstr ""
"För att starta processen för återställning av lösenord för ditt %(username)s "
"Modoboa konto, klicka på länken nedanför:"
"För att starta processen för återställning av lösenord för ditt %(username)s"
" Modoboa konto, klicka på länken nedanför:"
#: templates/registration/password_reset_email.html:10
#: templates/registration/password_reset_email_v2.html:10
@@ -2989,8 +2999,8 @@ msgstr "Engångslösenord"
#: templates/registration/twofactor_code_verify.html:35
msgid ""
"Enter the code from the two-factor app on your mobile device. If you've lost "
"your device, you may enter one of your recovery codes."
"Enter the code from the two-factor app on your mobile device. If you've lost"
" your device, you may enter one of your recovery codes."
msgstr ""
"Ange koden från tvåfaktorsappen på din mobila enhet. Om du har tappat bort "
"din enhet kan du ange en av dina återställningskoder."
@@ -3062,7 +3072,7 @@ msgstr "Servern behöver autentisering"
#: webmail/app_settings.py:118
msgid "Display"
msgstr "Visa"
msgstr "Visning"
#: webmail/app_settings.py:124
msgid "Default message display mode"
@@ -3082,7 +3092,7 @@ msgstr "Aktivera/inaktivera HTML-länkvisning"
#: webmail/app_settings.py:144
msgid "Number of displayed emails per page"
msgstr "Antal visade e-postmeddelanden per sida"
msgstr "Antalet visade e-postmeddelanden per sida"
#: webmail/app_settings.py:147
msgid "Sets the maximum number of messages displayed in a page"
+6
View File
@@ -43,6 +43,12 @@ elif DB == "sqlite":
"PORT": "",
"ATOMIC_REQUESTS": True,
},
"amavis": {
"ENGINE": "django.db.backends.sqlite3",
"NAME": "amavis.db",
"PORT": "",
"ATOMIC_REQUESTS": True,
},
}
else:
DATABASES = {
+14 -8
View File
@@ -392,13 +392,19 @@ WEBMAIL_DEV_PASSWORD = os.environ.get("WEBMAIL_DEV_PASSWORD", "")
# Amavis
DATABASES["amavis"] = { # NOQA
"ENGINE": "django.db.backends.mysql",
"HOST": "mariadb",
"NAME": "amavis",
"USER": "root",
"PASSWORD": "Password1000",
}
MIGRATION_MODULES = {"amavis": None}
TEST_RUNNER = "modoboa.lib.test_runners.UnManagedModelTestRunner"
# Uncomment this in dev mode
# DATABASES["amavis"] = { # NOQA
# "ENGINE": "django.db.backends.mysql",
# "HOST": "mariadb",
# "NAME": "amavis",
# "USER": "root",
# "PASSWORD": "Password1000",
# }
DATABASE_ROUTERS = ["modoboa.amavis.dbrouter.AmavisRouter"]
AMAVIS_DEFAULT_DATABASE_ENCODING = "LATIN1"
AMAVIS_DEFAULT_DATABASE_ENCODING = "UTF-8"
# AMAVIS_DEFAULT_DATABASE_ENCODING = "LATIN1"